632616b95e0253f75f3ef1d444e34c6340d04c17
[fnpeditor.git] / src / editor / modules / documentCanvas / canvas / comments / comments.js
1 define(function(require) {
2     
3 'use strict';
4 /* globals Node, gettext */
5
6
7 var $ = require('libs/jquery'),
8     _ = require('libs/underscore'),
9     datetime = require('fnpjs/datetime'),
10     commentsTemplate = require('libs/text!./comments.html'),
11     commentTemplate = require('libs/text!./comment.html');
12
13
14 var View = function(node, user) {
15     this.node = node;
16     this.user = user;
17     this.dom = $(_.template(commentsTemplate)());
18     this.list = this.dom.find('.list');
19     this.textarea = this.dom.find('textarea');
20     this.addButton = this.dom.find('button.btnAdd');
21     this.cancelButton = this.dom.find('button.btnCancel');
22
23     this.textarea.on('input', function() {
24         this.addButton.attr('disabled', this.textarea.val() === '');
25
26         if (this.textarea.prop('scrollHeight') > this.textarea.prop('clientHeight')) {
27             this.textarea.height(this.textarea.prop('scrollHeight'));
28         }
29
30
31     }.bind(this));
32     this.addButton.hide();
33     this.cancelButton.hide();
34     this.textarea.on('focus', function() {
35         this.addButton.show();
36         this.cancelButton.show();
37     }.bind(this));
38
39     this.addButton.on('click', function() {
40         if(!this.node) {
41             return;
42         }
43
44         this.node.document.transaction(function() {
45             var commentNode = this.node.document.createDocumentNode({tagName: 'aside', attrs: {'class': 'comment'}}),
46                 metadata = commentNode.getMetadata(),
47                 creator;
48
49             if(this.user) {
50                 creator = this.user.name;
51                 if(this.user.email) {
52                     creator += ' (' + this.user.email + ')';
53                 }
54             } else {
55                 creator = 'anonymous';
56             }
57
58             metadata.add({key: 'creator', value: creator});
59             metadata.add({key: 'date', value: datetime.currentStrfmt()});
60             commentNode.append({text: this.textarea.val()});
61
62             this.node.append(commentNode);
63         }.bind(this), {
64             metadata: {
65                 description: gettext('Add comment')
66             },
67             success: function() {
68                 this.textarea.val('');
69             }.bind(this)
70         });
71
72     }.bind(this));
73
74     this.cancelButton.on('click', function() {
75         this.addButton.hide();
76         this.cancelButton.hide();
77         this.textarea.val('');
78     }.bind(this));
79
80     this.render();
81     this.onDeactivated();
82
83 };
84
85 _.extend(View.prototype, {
86     render: function() {
87         this.list.empty();
88
89         // while(this.node.getTagName() === 'span' && this.node.parent()) {
90         //     this.node = this.node.parent();
91         // }
92         this.textarea.attr('placeholder', gettext('Comment'));
93
94         this.node.contents()
95             .filter(function(child) {
96                 return child.nodeType === Node.ELEMENT_NODE && child.getTagName() === 'aside' && child.getClass() === 'comment';
97                 //return child.is({tag: 'aside', klass: 'comment'});
98
99             })
100             .forEach(function(commentNode) {
101                 var commentView = new CommentView(commentNode);
102                 this.list.append(commentView.dom);
103                 this.textarea.attr('placeholder', gettext('Respond') + '...');
104             }.bind(this));
105         
106     },
107     onActivated: function() {
108         //if(this.list.find('.comment').length === 0) {
109             this.dom.find('.newComment').toggle(true);
110         //}
111        //this.dom.show();
112
113     },
114     onDeactivated: function() {
115       this.dom.find('.newComment').toggle(false);
116       this.addButton.hide();
117       this.cancelButton.hide();
118       //this.dom.hide();
119
120     },
121
122     getHeight: function() {
123         return this.dom.outerHeight();
124     }
125
126 });
127
128
129 var CommentView = function(commentNode) {
130     this.node = commentNode;
131
132     var metaData = this.node.getMetadata(),
133         author, date;
134
135     metaData.some(function(row) {
136         author = row.getValue();
137         if(author) {
138             author = author.split(' ')[0];
139         }
140         return true;
141     }, 'creator');
142     
143     metaData.some(function(row) {
144         date = row.getValue();
145         if(/[0-9][0-9]:[0-9][0-9]:[0-9][0-9]$/g.test(date)) {
146             date = date.split(':');
147             date.pop();
148             date = date.join(':');
149         }
150         return true;
151     }, 'date');
152
153     this.dom = $(_.template(commentTemplate)({
154         author: author ||'?',
155         date: date || '?',
156         content: this.node.object.getText() || '?'
157     }));
158
159     this.contentElement = this.dom.find('.content');
160     this.editElement = this.dom.find('.edit');
161     this.deleteDialogElement = this.dom.find('.deleteDialog');
162
163     this.dom.find('.remove-btn').on('click', function() {
164         this.deleteDialogElement.show();
165     }.bind(this));
166
167     this.dom.find('.deleteDialog-confirm').on('click', function() {
168         this.node.document.transaction(function() {
169             this.node.detach();
170         }.bind(this), {
171             metadata: {
172                 description: gettext('Remove comment')
173             }
174         });
175     }.bind(this));
176
177     this.dom.find('.deleteDialog-cancel').on('click', function() {
178         this.deleteDialogElement.hide();
179     }.bind(this));
180
181     this.dom.find('.edit-start-btn').on('click', function() {
182         this.startEditing();
183     }.bind(this));
184
185     this.dom.find('.edit-save-btn').on('click', function() {
186         this.saveEditing();
187     }.bind(this));
188
189     this.dom.find('.edit-cancel-btn').on('click', function() {
190         this.cancelEditing();
191     }.bind(this));
192
193     this.textarea = this.editElement.find('textarea');
194     this.textarea.on('input', function() {
195         this.dom.find('.edit-save-btn').attr('disabled', this.textarea.val() === '');
196
197         if (this.textarea.prop('scrollHeight') > this.textarea.prop('clientHeight')) {
198             this.textarea.height(this.textarea.prop('scrollHeight'));
199         }
200
201
202     }.bind(this));
203 };
204
205 $.extend(CommentView.prototype, {
206     startEditing: function() {
207         this.contentElement.hide();
208         this.editElement.show();
209         this.textarea.val(this.node.object.getText());
210         if(this.textarea.prop('scrollHeight') > this.textarea.prop('clientHeight')) {
211             this.textarea.height(this.textarea.prop('scrollHeight'));
212         }
213         this.textarea.focus();
214     },
215     saveEditing: function() {
216         var newContent = this.editElement.find('textarea').val();
217         this.node.document.transaction(function() {
218             this.node.object.setText(newContent);
219         }.bind(this), {
220             metadata: {
221                 description: gettext('Edit comment')
222             }
223         });
224     },
225     cancelEditing: function() {
226         this.contentElement.show();
227         this.editElement.find('textarea').val('');
228         this.editElement.hide();
229     },
230 });
231
232
233 return View;
234
235 });