Commit | Line | Data |
---|---|---|
adacb0fe DC |
1 | // This file is part of Moodle - http://moodle.org/ |
2 | // | |
3 | // Moodle is free software: you can redistribute it and/or modify | |
4 | // it under the terms of the GNU General Public License as published by | |
5 | // the Free Software Foundation, either version 3 of the License, or | |
6 | // (at your option) any later version. | |
7 | // | |
8 | // Moodle is distributed in the hope that it will be useful, | |
9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 | // GNU General Public License for more details. | |
12 | // | |
13 | // You should have received a copy of the GNU General Public License | |
14 | // along with Moodle. If not, see <http://www.gnu.org/licenses/>. | |
15 | ||
1bcb7eb5 | 16 | /** |
adacb0fe DC |
17 | * Comment Helper |
18 | * @author Dongsheng Cai <dongsheng@moodle.com> | |
1bcb7eb5 | 19 | */ |
ef502357 PS |
20 | M.core_comment = { |
21 | /** | |
22 | * Initialize commenting system | |
23 | */ | |
3b01539c | 24 | init: function(Y, options) { |
ef502357 PS |
25 | var CommentHelper = function(args) { |
26 | CommentHelper.superclass.constructor.apply(this, arguments); | |
27 | } | |
28 | CommentHelper.NAME = "COMMENT"; | |
29 | CommentHelper.ATTRS = { | |
30 | options: {}, | |
31 | lang: {} | |
32 | }; | |
33 | Y.extend(CommentHelper, Y.Base, { | |
34 | api: M.cfg.wwwroot+'/comment/comment_ajax.php', | |
35 | initializer: function(args) { | |
36 | var scope = this; | |
37 | this.client_id = args.client_id; | |
38 | this.itemid = args.itemid; | |
39 | this.commentarea = args.commentarea; | |
40 | this.courseid = args.courseid; | |
41 | this.contextid = args.contextid; | |
76951100 DC |
42 | this.env = args.env; |
43 | // expand comments? | |
ef502357 PS |
44 | if (args.autostart) { |
45 | this.view(args.page); | |
46 | } | |
76951100 | 47 | // hide toggle link |
ef502357 PS |
48 | if (args.notoggle) { |
49 | Y.one('#comment-link-'+this.client_id).setStyle('display', 'none'); | |
50 | } | |
51 | // load comments | |
52 | Y.one('#comment-link-'+this.client_id).on('click', function(e) { | |
53 | e.preventDefault(); | |
54 | this.view(0); | |
55 | return false; | |
56 | }, this); | |
4b201bc6 DC |
57 | CommentHelper.confirmoverlay = new Y.Overlay({ |
58 | bodyContent: '<a href="###" id="confirmdelete-'+this.client_id+'">'+M.str.moodle.sure+'</a> <a href="###" id="canceldelete-'+this.client_id+'">'+M.str.moodle.cancel+'</a>', | |
59 | visible: false | |
60 | }); | |
61 | CommentHelper.confirmoverlay.render(document.body); | |
ef502357 PS |
62 | }, |
63 | post: function() { | |
64 | var ta = Y.one('#dlg-content-'+this.client_id); | |
65 | var scope = this; | |
66 | var value = ta.get('value'); | |
2b728cb5 | 67 | if (value && value != M.str.moodle.addcomment) { |
ef502357 PS |
68 | var params = {'content': value}; |
69 | this.request({ | |
70 | action: 'add', | |
71 | scope: scope, | |
72 | params: params, | |
73 | callback: function(id, obj, args) { | |
74 | var scope = args.scope; | |
75 | var cid = scope.client_id; | |
76 | var ta = Y.one('#dlg-content-'+cid); | |
77 | ta.set('value', ''); | |
78 | var container = Y.one('#comment-list-'+cid); | |
79 | var result = scope.render([obj], true); | |
80 | var newcomment = Y.Node.create(result.html); | |
81 | container.appendChild(newcomment); | |
82 | var ids = result.ids; | |
83 | var linktext = Y.one('#comment-link-text-'+cid); | |
2b728cb5 | 84 | linktext.set('innerHTML', M.str.moodle.comments + ' ('+obj.count+')'); |
ef502357 PS |
85 | for(var i in ids) { |
86 | var attributes = { | |
87 | color: { to: '#06e' }, | |
88 | backgroundColor: { to: '#FFE390' } | |
89 | }; | |
90 | var anim = new YAHOO.util.ColorAnim(ids[i], attributes); | |
91 | anim.animate(); | |
92 | } | |
76951100 DC |
93 | scope.register_pagination(); |
94 | scope.register_delete_buttons(); | |
adacb0fe | 95 | } |
ef502357 PS |
96 | }, true); |
97 | } else { | |
98 | var attributes = { | |
99 | backgroundColor: { from: '#FFE390', to:'#FFFFFF' } | |
100 | }; | |
101 | var anim = new YAHOO.util.ColorAnim('dlg-content-'+cid, attributes); | |
102 | anim.animate(); | |
103 | } | |
104 | }, | |
105 | request: function(args, noloading) { | |
106 | var params = {}; | |
107 | var scope = this; | |
108 | if (args['scope']) { | |
109 | scope = args['scope']; | |
110 | } | |
111 | //params['page'] = args.page?args.page:''; | |
112 | params['env'] = ''; | |
113 | // the form element only accept certain file types | |
114 | params['sesskey'] = M.cfg.sesskey; | |
115 | params['action'] = args.action?args.action:''; | |
116 | params['client_id'] = this.client_id; | |
117 | params['itemid'] = this.itemid; | |
118 | params['area'] = this.commentarea; | |
119 | params['courseid'] = this.courseid; | |
120 | params['contextid'] = this.contextid; | |
121 | if (args['params']) { | |
122 | for (i in args['params']) { | |
123 | params[i] = args['params'][i]; | |
adacb0fe | 124 | } |
adacb0fe | 125 | } |
ef502357 PS |
126 | var cfg = { |
127 | method: 'POST', | |
128 | on: { | |
129 | complete: function(id,o,p) { | |
130 | if (!o) { | |
131 | alert('IO FATAL'); | |
4b201bc6 | 132 | return false; |
ef502357 | 133 | } |
384ab39a | 134 | var data = Y.JSON.parse(o.responseText); |
ef502357 PS |
135 | if (data.error) { |
136 | alert(data.error); | |
137 | return false; | |
138 | } else { | |
139 | args.callback(id,data,p); | |
140 | return true; | |
141 | } | |
7e7d2e64 | 142 | } |
ef502357 PS |
143 | }, |
144 | arguments: { | |
145 | scope: scope | |
146 | }, | |
147 | headers: { | |
148 | 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', | |
149 | 'User-Agent': 'MoodleComment/3.0' | |
150 | }, | |
151 | data: build_querystring(params) | |
152 | }; | |
153 | if (args.form) { | |
154 | cfg.form = args.form; | |
adacb0fe | 155 | } |
ef502357 PS |
156 | Y.io(this.api, cfg); |
157 | if (!noloading) { | |
158 | this.wait(); | |
159 | } | |
160 | }, | |
161 | render: function(list, newcmt) { | |
162 | var ret = {}; | |
163 | ret.ids = []; | |
164 | var template = Y.one('#cmt-tmpl'); | |
165 | var html = ''; | |
166 | for(var i in list) { | |
167 | var htmlid = 'comment-'+list[i].id+'-'+this.client_id; | |
168 | var val = template.get('innerHTML'); | |
169 | val = val.replace('___name___', list[i].username); | |
170 | if (list[i]['delete']||newcmt) { | |
2b728cb5 | 171 | list[i].content = '<div class="comment-delete"><a href="###" id ="comment-delete-'+this.client_id+'-'+list[i].id+'" title="'+M.str.moodle.deletecomment+'"><img src="'+M.util.image_url('t/delete', 'core')+'" /></a></div>' + list[i].content; |
adacb0fe | 172 | } |
ef502357 PS |
173 | val = val.replace('___time___', list[i].time); |
174 | val = val.replace('___picture___', list[i].avatar); | |
175 | val = val.replace('___content___', list[i].content); | |
176 | val = '<li id="'+htmlid+'">'+val+'</li>'; | |
177 | ret.ids.push(htmlid); | |
178 | html = (val+html); | |
adacb0fe | 179 | } |
ef502357 PS |
180 | ret.html = html; |
181 | return ret; | |
182 | }, | |
183 | load: function(page) { | |
184 | var scope = this; | |
185 | var container = Y.one('#comment-ctrl-'+this.client_id); | |
186 | var params = { | |
4b201bc6 | 187 | 'page': page |
1bcb7eb5 | 188 | } |
ef502357 PS |
189 | this.request({ |
190 | scope: scope, | |
191 | params: params, | |
192 | callback: function(id, ret, args) { | |
193 | var linktext = Y.one('#comment-link-text-'+scope.client_id); | |
2b728cb5 | 194 | linktext.set('innerHTML', M.str.moodle.comments + ' ('+ret.count+')'); |
ef502357 PS |
195 | var container = Y.one('#comment-list-'+scope.client_id); |
196 | var pagination = Y.one('#comment-pagination-'+scope.client_id); | |
197 | if (ret.pagination) { | |
198 | pagination.set('innerHTML', ret.pagination); | |
199 | } else { | |
200 | //empty paging bar | |
201 | pagination.set('innerHTML', ''); | |
adacb0fe | 202 | } |
ef502357 PS |
203 | var result = scope.render(ret.list); |
204 | container.set('innerHTML', result.html); | |
205 | args.scope.register_pagination(); | |
206 | args.scope.register_delete_buttons(); | |
207 | } | |
208 | }); | |
209 | }, | |
4c508047 | 210 | |
bdf69389 | 211 | dodelete: function(id) { // note: delete is a reserved word in javascript, chrome and safary do not like it at all here! |
ef502357 PS |
212 | var scope = this; |
213 | var params = {'commentid': id}; | |
4b201bc6 | 214 | scope.cancel_delete(); |
ef502357 PS |
215 | function remove_dom(type, anmi, cmt) { |
216 | cmt.remove(); | |
adacb0fe | 217 | } |
ef502357 PS |
218 | this.request({ |
219 | action: 'delete', | |
220 | scope: scope, | |
221 | params: params, | |
222 | callback: function(id, resp, args) { | |
223 | var htmlid= 'comment-'+resp.commentid+'-'+resp.client_id; | |
224 | var attributes = { | |
225 | width:{to:0}, | |
226 | height:{to:0} | |
227 | }; | |
228 | var cmt = Y.one('#'+htmlid); | |
229 | cmt.setStyle('overflow', 'hidden'); | |
230 | var anim = new YAHOO.util.Anim(htmlid, attributes, 1, YAHOO.util.Easing.easeOut); | |
231 | anim.onComplete.subscribe(remove_dom, cmt, this); | |
232 | anim.animate(); | |
233 | } | |
234 | }, true); | |
235 | }, | |
236 | register_actions: function() { | |
237 | // add new comment | |
238 | Y.one('#comment-action-post-'+this.client_id).on('click', function(e) { | |
239 | e.preventDefault(); | |
240 | this.post(); | |
241 | return false; | |
242 | }, this); | |
243 | // cancel comment box | |
244 | var cancel = Y.one('#comment-action-cancel-'+this.client_id); | |
245 | if (cancel) { | |
246 | cancel.on('click', function(e) { | |
247 | e.preventDefault(); | |
248 | this.view(0); | |
249 | return false; | |
250 | }, this); | |
adacb0fe | 251 | } |
ef502357 PS |
252 | }, |
253 | register_delete_buttons: function() { | |
254 | var scope = this; | |
255 | // page buttons | |
256 | Y.all('div.comment-content a').each( | |
257 | function(node, id) { | |
2057b5ef | 258 | var theid = node.get('id'); |
4b201bc6 DC |
259 | var parseid = new RegExp("comment-delete-"+scope.client_id+"-(\\d+)", "i"); |
260 | var commentid = theid.match(parseid); | |
261 | if (commentid[1]) { | |
2057b5ef DC |
262 | Y.Event.purgeElement('#'+theid, false, 'click'); |
263 | } | |
ef502357 | 264 | node.on('click', function(e, node) { |
4b201bc6 DC |
265 | var width = CommentHelper.confirmoverlay.bodyNode.getStyle('width'); |
266 | var re = new RegExp("(\\d+).*", "i"); | |
267 | var result = width.match(re); | |
ef502357 | 268 | if (result[1]) { |
4b201bc6 DC |
269 | width = Number(result[1]); |
270 | } else { | |
271 | width = 0; | |
ef502357 | 272 | } |
4b201bc6 DC |
273 | CommentHelper.confirmoverlay.set('xy', [e.pageX-(width/2), e.pageY+10]); |
274 | CommentHelper.confirmoverlay.set('visible', true); | |
275 | // XXX: YUI3 bug, a temp workaround in firefox, still have problem on webkit | |
276 | CommentHelper.confirmoverlay.bodyNode.setStyle('visibility', 'visible'); | |
277 | Y.one('#canceldelete-'+scope.client_id).on('click', function() { | |
278 | scope.cancel_delete(); | |
279 | }); | |
280 | Y.Event.purgeElement('#confirmdelete-'+scope.client_id, false, 'click'); | |
281 | Y.one('#confirmdelete-'+scope.client_id).on('click', function() { | |
282 | if (commentid[1]) { | |
283 | scope.dodelete(commentid[1]); | |
284 | } | |
285 | }); | |
ef502357 PS |
286 | }, scope, node); |
287 | } | |
288 | ); | |
289 | }, | |
4b201bc6 DC |
290 | cancel_delete: function() { |
291 | CommentHelper.confirmoverlay.set('visible', false); | |
292 | // XXX: YUI3 bug, a temp workaround in firefox, still have problem on webkit | |
293 | CommentHelper.confirmoverlay.bodyNode.setStyle('visibility', 'hidden'); | |
294 | }, | |
ef502357 PS |
295 | register_pagination: function() { |
296 | var scope = this; | |
297 | // page buttons | |
3e34183a | 298 | Y.all('#comment-pagination-'+this.client_id+' a').each( |
ef502357 PS |
299 | function(node, id) { |
300 | node.on('click', function(e, node) { | |
301 | var id = node.get('id'); | |
302 | var re = new RegExp("comment-page-"+this.client_id+"-(\\d+)", "i"); | |
303 | var result = id.match(re); | |
304 | this.load(result[1]); | |
305 | }, scope, node); | |
306 | } | |
307 | ); | |
308 | }, | |
309 | view: function(page) { | |
310 | var container = Y.one('#comment-ctrl-'+this.client_id); | |
311 | var ta = Y.one('#dlg-content-'+this.client_id); | |
312 | var img = Y.one('#comment-img-'+this.client_id); | |
313 | var d = container.getStyle('display'); | |
314 | if (d=='none'||d=='') { | |
315 | // show | |
76951100 DC |
316 | if (this.env != 'block_comments') { |
317 | this.load(page); | |
318 | } else { | |
319 | this.register_delete_buttons(); | |
320 | this.register_pagination(); | |
321 | } | |
ef502357 | 322 | container.setStyle('display', 'block'); |
bca09754 | 323 | img.src=M.util.image_url('t/expanded', 'core'); |
ef502357 PS |
324 | } else { |
325 | // hide | |
326 | container.setStyle('display', 'none'); | |
bca09754 | 327 | img.src=M.util.image_url('t/collapsed', 'core'); |
ef502357 | 328 | ta.set('value',''); |
adacb0fe | 329 | } |
ef502357 PS |
330 | //toggle_textarea.apply(ta, [false]); |
331 | //// reset textarea size | |
332 | ta.on('click', function() { | |
333 | this.toggle_textarea(true); | |
334 | }, this) | |
335 | //ta.onkeypress = function() { | |
336 | //if (this.scrollHeight > this.clientHeight && !window.opera) | |
337 | //this.rows += 1; | |
338 | //} | |
339 | ta.on('blur', function() { | |
340 | this.toggle_textarea(false); | |
341 | }, this); | |
342 | this.register_actions(); | |
343 | return false; | |
344 | }, | |
345 | toggle_textarea: function(focus) { | |
346 | var t = Y.one('#dlg-content-'+this.client_id); | |
347 | if (focus) { | |
2b728cb5 | 348 | if (t.get('value') == M.str.moodle.addcomment) { |
ef502357 PS |
349 | t.set('value', ''); |
350 | t.setStyle('color', 'black'); | |
351 | } | |
352 | }else{ | |
353 | if (t.get('value') == '') { | |
2b728cb5 | 354 | t.set('value', M.str.moodle.addcomment); |
ef502357 | 355 | t.setStyle('color','grey'); |
76951100 | 356 | t.set('rows', 2); |
ef502357 | 357 | } |
adacb0fe | 358 | } |
ef502357 PS |
359 | }, |
360 | wait: function() { | |
361 | var container = Y.one('#comment-list-'+this.client_id); | |
5aaa76ea | 362 | container.set('innerHTML', '<div class="mdl-align"><img src="'+M.util.image_url('i/loading', 'core')+'" /></div>'); |
adacb0fe | 363 | } |
ef502357 PS |
364 | }); |
365 | ||
366 | new CommentHelper(options); | |
34e20eb4 DC |
367 | }, |
368 | init_admin: function(Y) { | |
369 | var select_all = Y.one('#comment_select_all'); | |
370 | select_all.on('click', function() { | |
371 | var comments = document.getElementsByName('comments'); | |
372 | var checked = false; | |
373 | for (var i in comments) { | |
374 | if (comments[i].checked) { | |
375 | checked=true; | |
376 | } | |
377 | } | |
4b201bc6 | 378 | for (i in comments) { |
34e20eb4 DC |
379 | comments[i].checked = !checked; |
380 | } | |
381 | this.set('checked', !checked); | |
382 | }); | |
383 | ||
384 | var comments_delete = Y.one('#comments_delete'); | |
385 | if (comments_delete) { | |
386 | comments_delete.on('click', function(e) { | |
387 | e.preventDefault(); | |
388 | var list = ''; | |
389 | var comments = document.getElementsByName('comments'); | |
390 | for (var i in comments) { | |
391 | if (typeof comments[i] == 'object' && comments[i].checked) { | |
392 | list += (comments[i].value + '-'); | |
393 | } | |
394 | } | |
395 | if (!list) { | |
396 | return; | |
397 | } | |
398 | var args = {}; | |
399 | args.message = M.str.admin.confirmdeletecomments; | |
400 | args.callback = function() { | |
401 | var url = M.cfg.wwwroot + '/comment/index.php'; | |
402 | ||
403 | var data = { | |
404 | 'commentids': list, | |
405 | 'sesskey': M.cfg.sesskey, | |
406 | 'action': 'delete' | |
407 | } | |
408 | var cfg = { | |
409 | method: 'POST', | |
410 | on: { | |
411 | complete: function(id,o,p) { | |
412 | if (!o) { | |
413 | alert('IO FATAL'); | |
414 | return; | |
415 | } | |
416 | if (o.responseText == 'yes') { | |
417 | location.reload(); | |
418 | } | |
419 | } | |
420 | }, | |
421 | arguments: { | |
422 | scope: this | |
423 | }, | |
424 | headers: { | |
425 | 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', | |
426 | 'User-Agent': 'MoodleComment/3.0' | |
427 | }, | |
428 | data: build_querystring(data) | |
429 | }; | |
430 | Y.io(url, cfg); | |
431 | } | |
432 | M.util.show_confirm_dialog(e, args); | |
433 | }); | |
434 | } | |
ef502357 PS |
435 | } |
436 | }; |