PageSourceSearch

https://www.nirix.com/shout/web/v6.51.1.R20260831/shout/modules/comment/resources/js/comment.js

js nirix.com collected 2026-09-29 09:33:59 UTC 16,186 bytes, 591 lines download raw bytes

1(function($)
2{
3
4var Comment = window.Comment = function Comment(pageId, location, publicKey, showCaptcha, maxChars, contentId) {
5    this.g_direction = "asc" ;
6    this.g_orderBy = "created";
7    this.pageId = pageId;
8    this.parentComment = null;
9    this.maxText = maxChars;
10    this.location = location;
11    this.lastReply = null;
12    this.captchaPublicKey = publicKey;
13    this.showCaptcha = showCaptcha;
14    this.contentId = contentId;
15
16    this.lastSearchObj = null;
17    this.lastSearchTime = null;
18}
19
20Comment.prototype.htmlId = function(prefix)
21{
22    var id = prefix + '-' + this.contentId;
23
24    return id;
25};
26
27Comment.prototype.onCommentBodyChange = function(oldValue)
28{
29    // Reset our search object;
30    this.completeQuery();
31
32    var txtCommentBody = document.getElementById(this.htmlId('comment-body'));
33
34    var diff = this.maxText - txtCommentBody.value.length;
35
36    if( diff <= 0 )
37    {
38        diff = 0;
39        txtCommentBody.value = txtCommentBody.value.substr(0, this.maxText );
40    }
41
42    document.getElementById(this.htmlId('comment-body-count')).innerHTML = diff;
43
44};
45
46Comment.prototype.orderBy = function(orderBy, direction) {
47
48    // Alias for jQuery post below.
49    commentObj = this;
50
51    if(orderBy.length == 0)
52    {
53        orderBy = this.g_orderBy;
54    }
55    else
56    {
57        this.g_orderBy = orderBy;
58    }
59
60    if(direction.length == 0)
61    {
62        orderBy = this.g_direction;
63    }
64    else
65    {
66        this.g_direction = direction;
67    }
68
69    searchObj = {
70        'showcomment': true,
71        'orderBy' : orderBy,
72        'direction' : direction,
73        'content_id': this.contentId
74    };
75
76     // Set our last search obj for future reference
77     this.lastSearchObj = searchObj;
78     this.lastSearchTime = new Date();
79
80    jQuery.post(
81        this.location,
82        searchObj,
83        function(data) {
84            commentObj.onShowComment(searchObj,data);
85        },"html");
86};
87
88Comment.prototype.onShowComment = function(searchObj, data)
89{
90    // Reset our search object
91    this.completeQuery();
92
93    /* move our form out of the comment tree
94    so that the replacement doesn't kill it */
95    replyForm = jQuery("#" + this.htmlId('comment-post-form'));
96    replyHeader = jQuery("#" + this.htmlId('comment-header'));
97    replyHeader.after(replyForm);
98    replyForm.hide();
99    this.lastReply = null;
100
101    parentList = jQuery("#" + this.htmlId('comment-container'));
102    commentNode = jQuery(data);
103
104    parentList.replaceWith(commentNode);
105};
106
107Comment.prototype.saveComment = function( subject, body, parentComment )
108{
109    // Alias for jQuery post below.
110    commentObj = this;
111
112    // Fetch some additional fields for captcha.
113    if(this.showCaptcha) {
114        captchaResult = ShoutcmsCaptcha.extractCaptchaPostParameters();
115        ShoutcmsCaptcha.resetCaptcha();
116    }
117    else
118    {
119        captchaResult = {};
120    }
121
122
123    searchObj = {
124            'savecomment': true,
125            'subject' : subject,
126            'body' : body,
127            'parent_comment': parentComment,
128            'content_id': this.contentId
129        }
130
131    searchObj = $.extend(searchObj, captchaResult);
132
133
134    // Clear previous errors.
135    this.clearError();
136
137    jQuery.post(
138        this.location,
139        searchObj,
140        function(data) {
141            commentObj.onCommentSaved(searchObj,data);
142    },"html");
143
144};
145
146Comment.prototype.deleteComment = function (deletecomment)
147{
148    if(confirm("Are you sure you want to delete the comment?")){
149        /* move our form out of the comment tree
150        so that the replacement doesn't kill it */
151        replyForm = jQuery("#" + this.htmlId('comment-post-form'));
152        replyHeader = jQuery("#" + this.htmlId('comment-header'));
153        replyHeader.after(replyForm);
154        replyForm.hide();
155        this.lastReply = null;
156
157        var commentObj = this;
158        searchObj = {
159            'deletecomment' : deletecomment,
160            'content_id': this.contentId
161        };
162
163        // Simple double submission check
164        currTime = new Date();
165        if( (this.lastSearchObj == null) ||
166            ( (this.lastSearchObj) &&
167              (this.lastSearchObj['deletecomment'] != searchObj.delete
167comment) &&
168              (this.lastSearchTime < currTime.getTime() - 1000) )
169            )
170        {
171            // On success, lets delete the comment
172            jQuery.post(
173                this.location,
174                searchObj,
175                function(data) {
176                    commentObj.onCommentDelete(searchObj,data);
177                 } , "html" );
178        }
179        else
180        {
181            // Double submission attempt.
182        }
183
184        this.lastSearchObj = searchObj;
185        this.lastSearchTime = (new Date()).getTime();
186    }
187};
188
189Comment.prototype.onCommentDelete = function(searchObj, data)
190{
191    // Reset our search object;
192    this.completeQuery();
193
194    // Note: the logic here is confusing, mutable and highly dependent on the
195    // integrity and conventions in comment node contstruction being maintained.
196    // changes in server side rendering will need to be reflected here.
197    if(this.hasNest(searchObj.deletecomment) )
198    {
199        // Find this nodes child node container list item element.
200        // Find Comment->Find parent li->immediate sibling (next) should be a "comment nest container" li.
201        var nestedLINode = jQuery("#comment-number-"+searchObj.deletecomment).parent("div").next();
202
203        // Dig through the nested list and get the children.
204        var nestedChildren = nestedLINode.children(".comment-nested").children();
205
206        jQuery("#comment-number-"+searchObj.deletecomment).parent("div").replaceWith(nestedChildren);
207    }
208    else
209    {
210        jQuery("#comment-number-"+searchObj.deletecomment).parent("div").empty();
211    }
212};
213
214Comment.prototype.refresh = function()
215{
216    this.orderBy(this.g_orderBy,this.g_direction);
217    if (typeof Recaptcha != 'undefined')
218    {
219        Recaptcha.reload();
220    }
221};
222
223Comment.prototype.completeQuery = function()
224{
225    this.lastSearchObj = null;
226    this.lastSearchTime = null;
227};
228
229Comment.prototype.hasNest = function(comment_id)
230{
231    parentComment = jQuery("#comment-number-"+comment_id).parent("div");
232    hasNest = parentComment.next().children(".comment-nested").length > 0 ? true : false;
233    return hasNest;
234};
235
236Comment.prototype.appendReply = function(parent_id, commentData)
237{
238    parentComment = jQuery("#comment-number-"+parent_id).parent("div");
239
240    commentNode = jQuery(commentData);
241    hasNest = 	parentComment.next().children(".comment-nested").length > 0 ? true : false;
242    if(hasNest)
243    {
244        commentNode.wrap("<div></div>");
245        // Select parent, commentNode still points to div, not li.
246        parentComment.next().children(".comment-nested").prepend(commentNode.parent());
247    }
248    else
249    {
250        // Select parent, commentNode still points to div, not li.
251        commentNode.wrap("<div class = 'comment-nest-container'><div class = 'comment-nested'><div></div></div></div>");
252
253        parentComment.after(commentNode.parent().parent().parent());
254    }
255
256    // Clear comment data
257    jQuery("#" + this.htmlId('comment-subject')).val("");
258    jQuery("#" + this.htmlId('comment-body')).val("");
259};
260
261Comment.prototype.appendMain = function(commentData)
262{
263    parentList = jQuery("#" + this.htmlId('comment-tree-main'));
264    commentNode = jQuery(commentData);
265    commentNode.wrap("<div></div>");
266    parentList.prepend(commentNode.parent());
267
268    // Clear comment data
269    jQuery("#" + this.htmlId('comment-subject')).val("");
270    jQuery("#" + this.htmlId('comment-body')).val("");
271
272};
273
274Comment.prototype.replyTo = function(post_id)
275{
276    if(this.showCaptcha) {
277        jQuery("#" + this.htmlId('recaptcha-container')).show();
278//        Recaptcha.create(this.captchaPublicKey,
279//        "recaptcha-container", {
280//           theme: "clean",
281//           callback: Recaptcha.focus_response_field
282//        });
283    }
284    parentComment = jQuery("#comment-number-"+post_id);
285    replyForm = jQuery("#" + this.htmlId('comment-post-form'));
286
287    if(this.lastReply == post_id) {
288        replyForm.hide();
289        this.lastReply = null;
290    } else {
291        replyForm.show();
292        this.lastReply = post_id;
293    }
294    replyForm.children("#" + this.htmlId('comment-subject') + ", #" + this.htmlId('comment-body')).val("");
295    parentComment.after(replyForm);
296    jQuery(replyForm).children("#" + this.htmlId('comment-parent')).val(post_id);
297
298};
299
300Comment.prototype.replyMain = function()
301{
302    if(this.showCaptcha)
303    {
304        jQuery("#" + this.htmlId('recaptcha-container')).show();
305//		Recaptcha.create(this.captchaPublicKey,
306//		"recaptcha-container", {
307//		   theme: "clean",
308//		   callback: Recaptcha.focus_response_field
309//		});
310    }
311    replyForm = jQuery("#" + this.htmlId('comment-post-form'));
312    replyHeader = jQuery("#" + this.htmlId('comment-header'));
313
314    if(this.lastReply != -1) {
315        replyForm.show();
316        this.lastReply = -1;
317    }
318    else
319    {
320        replyForm.hide();
321        this.lastReply = null;
322    }
323
324    replyForm.insertAfter(jQuery(replyHeader));
325    jQuery(replyForm).children("#" + this.htmlId('comment-parent')).val(-1);
326};
327
328
329Comment.prototype.onPostCommentClick = function()
330{
331    var data = this.getCommentData();
332    this.saveComment(data.subject,data.body,data.parentval);
333
334    // Clear comment data fields.
335    jQuery('#' + this.htmlId('comment-subject')).val('');
336    jQuery('#' + this.htmlId('comment-body')).val('');
337};
338
339Comment.prototype.getCommentData = function()
340{
341    var data = {
342        'subject': jQuery("#" + this.htmlId('comment-subject')).val(),
343        'body': jQuery("#" + this.htmlId('comment-body')).val(),
344        'parentval': jQuery("#" + this.htmlId('comment-parent')).val()
345    };
346
347    return data;
348};
349
350Comment.prototype.onCommentSaved = function(searchObj, data)
351{
352    // Reset our search object;
353    this.completeQuery();
354
355    // Check for errors post submission (ie recaptcha failure).
356    if (jQuery(data).hasClass("error"))
357    {
358        if (this.showCaptcha && (typeof Recaptcha != 'undefined'))
359        {
360            Recaptcha.reload();
361            Recaptcha.focus_response_field();
362        }
363
364        if (jQuery(data).hasClass('data'))
365        {
366            var inputData = jQuery.parseJSON(jQuery(jQuery(data).get(1)).val());
367
368            jQuery('#' + this.htmlId('comment-subject')).val(inputData.subject);
369            jQuery('#' + this.htmlId('comment-body')).val(inputData.body);
370        }
371
372        this.displayError(jQuery(data).get(0));
373    }
374    else
375    {
376        /* move our form out of the comment tree
377        so that the replacement doesn't kill it */
378        replyForm = jQuery("#" + this.htmlId('comment-post-form'));
379        replyHeader = jQuery("#" + this.htmlId('comment-header'));
380        replyHeader.after(replyForm);
381        replyForm.hide();
382        this.lastReply = null;
383
384        jQuery('#' + this.htmlId('comment-body')).text('');
385        jQuery('#' + this.htmlId('comment-subject')).val('');
386
387        this.refresh();
388    }
389};
390
391Comment.prototype.toggleDirection = function() {
392    if(this.g_direction == 'asc') {
393        jQuery("#" + this.htmlId('comment-direction')).addClass("comment-desc");
394        jQuery("#" + this.htmlId('comment-direction')).removeClass("comment-asc");
395
396        this.g_direction = 'desc';
397    } else {
398        jQuery("#" + this.htmlId('comment-direction')).removeClass("comment-desc");
399        jQuery("#" + this.htmlId('comment-direction')).addClass("comment-asc");
400
401        this.g_direction = 'asc';
402    }
403
404    this.orderBy(this.g_orderBy,this.g_direction);
405};
406
407Comment.prototype.toggleOrderBy = function(order, caller) {
408    var orderObj = jQuery("#" + this.htmlId('comment-order'));
409    orderObj.children("#" + this.htmlId('comment-order-display')).text(order);
410    orderObj.children("#" + this.htmlId('comment-order-display')).text(jQuery(caller).text());
411    this.g_orderBy = order;
412
413    this.orderBy(this.g_orderBy,this.g_direction);
414};
415
416Comment.prototype.displayError = function(data)
417{
418    jQuery("#" + this.htmlId('comment-error')).show();
419    jQuery("#" + this.htmlId('comment-error')).html(data);
420};
421
422Comment.prototype.clearError = function()
423{
424    jQuery("#" + this.htmlId('comment-error')).empty();
425};
426
427var InPlace = window.InPlace = function InPlace(field, location, params) {
428    this.originalField = jQuery(field);
429    this.wrapperField = null;
430    this.clickOutside = null;
431    this.params = params;
432    this.location = location;
433
434    switch(this.originalField.get(0).nodeName) {
435        case 'H1':
436        case 'H2':
437        case 'STRONG':
438        case 'H3':
439            this.input(this.originalField);
440            break;
441        case 'P':
442            this.textArea(this.originalField);
443            break;
444    };
445
446};
447
448InPlace.prototype.release = function(evt)
449{
450    jQuery('body').off('mousedown',this.clickOutside);
451
452    if(this.wrapperField != null) {
453        this.originalField.css('display','');
454        this.wrapperField.css('display','none');
455    }
456
457};
458
459InPlace.prototype.wrapper = function (field )
460{
461    var inPlaceObj = this;
462
463
464    var wrapperEl = jQuery('<div id="'+field.get(0).id+'_inplace" class = "inplace '+this.params['nodeType']+'"></div>');
465    var controlEl = jQuery('<div class="control"></div>');
466    var cancelEl = jQuery('<div class = "cancel"><span>cancel</span></div>');
467    var okEl = jQuery('<div class = "ok"><span>okay</span></div>');
468
469    var width = 0;
470    var height = 0;
471    if(this.params['nodeType'] == 'input') {
472        var inputEl = jQuery('<input class = "input" name="data" value=""></input>');
473        width = field.innerWidth();
474        height = field.innerHeight();
475    }
476    else if(this.params['nodeType'] == 'textarea'){
477        var inputEl = jQuery('<textarea class = "textarea" name="data" value=""></textarea>');
478        width = field.innerWidth();
479        height = field.innerHeight() - 24;
480        if(height < 30) {
481            height = 60;
482        }
483    }
484
485    wrapperEl.width(width);
486    wrapperEl.height(height);
487
488    inputEl.width(width);
489    inputEl.height(height);
490
491    inputEl.val(jQuery.trim(field.text()));
492
493    cancelEl.mousedown(
494        function(evt)
495        {
496            evt.stopPropagation();
497            inPlaceObj.release(evt);
498        }
499    );
500
501    inputEl.mousedown(
502        function(evt) {
503            evt.stopPropagation();
504        }
505    );
506
507    if(this.params['nodeType'] == 'input') {
508
509    }
510
511    okEl.mousedown(
512        function(evt) {
513            evt.stopPropagation();
514            inPlaceObj.params['inplace_data'] = inputEl.val();
515            jQuery.post(
516                inPlaceObj.location,
517                inPlaceObj.params,
518                function(data, textResponse) {
519                    inPlaceObj.update(data);
520                }
521            );
522            return false;
523        }
524    );
525
526    wrapperEl.mousedown(
527        function (evt) {
528            evt.stopPropagation();
529            return false;
530        }
531    );
532
533    this.clickOutside = function(evt)
534    {
535        evt.stopPropagation();
536        inPlaceObj.release();
537        return false;
538    }
539
540    jQuery('body').on('mousedown',this.clickOutside);
541    // Force dimensions on controlEl
542    jQuery('body').append(controlEl);
543    jQuery('body').append(wrapperEl);
544
545    controlEl.append(cancelEl);
546    controlEl.append(okEl);
547
548    wrapperEl.append(inputEl);
549    wrapperEl.append(controlEl);
550
551    wrapperEl.css('position','absolute');
552
553    dim = field.offset();
554    wrapperEl.css('top',dim.top+'px');
555    wrapperEl.css('left',dim.left+'px');
556
557    jQuery('body').append(wrapperEl);
558
559    controlEl.fadeIn(5,0.6);
560    //new DropShadow(controlEl, 3, -2);
561
562    return wrapperEl;
563};
564
565InPlace.prototype.textArea = function (field)
566{
567    jQuery.extend(this.params, {'nodeType':'textarea'});
568
569    this.wrapperField = this.wrapper(field);
570
571    this.originalField.css('display','');
572
573};
574
575InPlace.prototype.input = function(field)
576{
577    jQuery.extend(this.params, {'nodeType':'input'});
578
579    this.wrapperField = this.wrapper(field);
580
581    this.originalField.css('display','');
582
583};
584
585InPlace.prototype.update = function( data )
586{
587    this.originalField.html(data);
588    this.release();
589};
590
591})(jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.