1function JCommentsEvents() { 2} 3 4function JCommentsInput() { 5} 6 7function JCommentsIndicator() { 8 this.init(); 9} 10 11function JCommentsForm(id, editor) { 12 this.init(id, editor); 13} 14 15function JCommentsEditor(textarea, resizable) { 16 this.init(textarea, resizable); 17} 18 19function JComments(oi, og, r) { 20 this.init(oi, og, r); 21} 22 23JCommentsEvents.prototype = { 24 add: function (o, e, f) { 25 if (o.addEventListener) { 26 o.addEventListener(e, f, false); 27 return true; 28 } else if (o.attachEvent) { 29 return o.attachEvent("on" + e, f); 30 } else { 31 return false; 32 } 33 }, 34 remove: function (o, e, f) { 35 if (o.removeEventListener) { 36 o.removeEventListener(e, f, false); 37 } else if (o.detachEvent) { 38 o.detachEvent("on" + e, o[e + f]); 39 o[e + f] = null; 40 o["e" + e + f] = null; 41 } 42 }, 43 cancel: function (e) { 44 if (e.stopPropagation) { 45 e.cancelBubble = true; 46 e.preventDefault(); 47 e.stopPropagation(); 48 } 49 e.returnValue = false; 50 return false; 51 }, 52 target: function (e) { 53 var t; 54 if (!e) e = window.event; 55 if (e.target) t = e.target; else if (e.srcElement) t = e.srcElement; 56 if (t.nodeType == 3) t = t.parentNode; 57 return t; 58 } 59}; 60 61JCommentsInput.prototype = { 62 register: function (el) { 63 if (el) { 64 var th = this, events = new JCommentsEvents(); 65 events.add(el, 'focus', function (e) { 66 return th.onFocus(e); 67 }); 68 events.add(el, 'blur', function (e) { 69 return th.onBlur(e); 70 }); 71 } 72 }, 73 unregister: function (el) { 74 if (el) { 75 var th = this, events = new JCommentsEvents(); 76 events.remove(el, 'focus', function (e) { 77 return th.onFocus(e); 78 }); 79 events.remove(el, 'blur', function (e) { 80 return th.onBlur(e); 81 }); 82 } 83 }, 84 onFocus: function (e) { 85 var t = JCommentsEvents.prototype.target(e); 86 if (t != null) { 87 t.className = t.className.replace('error', '') + ' selected'; 88 } 89 }, 90 onBlur: function (e) { 91 var t = JCommentsEvents.prototype.target(e); 92 if (t != null) { 93 var c = t.className.replace('error', ''); 94 c = c.replace('error', ''); 95 c = c.replace('selected', ''); 96 t.className = c.replace(/^\s+/g, ""); 97 } 98 } 99}; 100 101JCommentsEditor.prototype = { 102 ta: null, 103 l10n: {}, 104 tags: {}, 105 smiles: {}, 106 events: null, 107 counter: null, 108 focused: false, 109 resizable: true, 110 111 init: function (textareaID, r) { 112 this.ta = JComments.prototype.$(textareaID); 113 this.l10n = { counterPre: '', counterPost: ' symbols left' }; 114 this.resizable = r; 115 this.events = new JCommentsEvents(); 116 this.defaultHeight = this.ta.clientHeight; 117 this.defaultRows = this.ta.rows; 118 if (this.resizable) { 119 this.addGrippie(); 120 } 121 this.isWebkit = /webkit/.test(navigator.userAgent.toLowerCase()); 122 123 var th = this; 124 this.events.add(document, !window.opera && document.all ? 'keydown' : 'keypress', function (e) { 125 return th.onKeyPress(e); 126 }); 127 this.events.add(this.ta, 'click', function (e) { 128 th.closeSmiles(); 129 return th.storeCaret(this.ta); 130 }); 131 this.events.add(this.ta, 'select', function (e) { 132 return th.storeCaret(this.ta); 133 }); 134 this.events.add(this.ta, 'change', function (e) { 135 th.onChange(); 136 return th.storeCaret(this.ta); 137 }); 138 this.events.add(this.ta, 'keyup', function (e) { 139 return th.onChange(); 140 }); 141 this.events.add(this.ta, 'focus', function (e) { 142 th.closeSmiles(); 143 return th.focused = true; 144 }); 145 this.events.add(this.ta, 'blur', function (e) { 146 return th.focused = false; 147 }); 148 }, 149 onKeyPress: function (e) { 150 if (!this.focused) { 151 return; 152 } 153 var k = String.fromCharCode(e.keyCode ? e.keyCode : e.charCode), t; 154 for (var id in this.tags) { 155 t = this.tags[id]; 156 if (!t.key || k.toUpperCase() != t.key.toUpperCase()) continue; 157 if (t.ctrl && !e[t.ctrl + "Key"]) continue; 158 this.insertTag(id); 159 return this.events.cancel(e); 160 } 161 return e.returnValue; 162 }, 163 defined: function (v) { 164 return (typeof (v) != "undefined"); 165 }, 166 clear: function () { 167 this.ta.value = ''; 168 if (this.defaultHeight) { 169 this.ta.style.height = this.defaultHeight + 'px'; 170 } 171 this.updateCounter(); 172 }, 173 focus: function () { 174 this.ta.focus(); 175 }, 176 storeCaret: function () { 177 var ta = this.ta; 178 if (ta.createTextRange) ta.caretPos = document.selection.createRange().duplicate(); 179 }, 180 getElementPos: function (e) { 181 var p = { left: 0, top: 0, right: 0, bottom: 0 }; 182 while (e != null) { 183 p.left += e.offsetLeft; 184 p.top += e.offsetTop; 185 e = e.offsetParent; 186 } 187 p.right += p.left; 188 p.bottom += p.top; 189 return p; 190 }, 191 getSelection: function () { 192 var ta = this.ta, s = ''; 193 if (document.selection && document.selection.createRange) { 194 s = document.selection.createRange().text; 195 } else { 196 s = ta.value.substr(ta.selectionStart, ta.selectionEnd - ta.selectionStart); 197 } 198 return s; 199 }, 200 insertText: function (text) { 201 var ta = this.ta; 202 if (this.defined(ta.caretPos) && ta.createTextRange) { 203 ta.focus(); 204 var sel = document.selection.createRange(); 205 sel.text = sel.text + text; 206 ta.focus(); 207 } else if (this.defined(ta.selectionStart)) { 208 var ss = ta.value.substr(0, ta.selectionStart); 209 var se = ta.value.substr(ta.selectionEnd), sp = ta.scrollTop; 210 ta.value = ss + text + se; 211 if (ta.setSelectionRange) { 212 ta.focus(); 213 ta.setSelectionRange(ss.length + text.length, ss.length + text.length); 214 } 215 ta.scrollTop = sp; 216 } else { 217 ta.value += text; 218 ta.focus(ta.value.length - 1); 219 } 220 }, 221 surroundText: function (t1, t2) { 222 var ta = this.ta; 223 if (this.defined(ta.caretPos) && ta.createTextRange) { 224 var cp = ta.caretPos, tl = cp.text.length; 225 cp.text = cp.text.charAt(cp.text.length - 1) == ' ' ? t1 + cp.text + t2 + ' ' : t1 + cp.text + t2; 226 if (tl == 0) { 227 cp.moveStart("character", -t2.length); 228 cp.moveEnd("character", -t2.length); 229 cp.select(); 230 } else { 231 ta.focus(cp); 232 } 233 } else if (this.defined(ta.selectionStart)) { 234 var ss = ta.value.substr(0, ta.selectionStart), se = ta.value.substr(ta.selectionEnd); 235 var sl = ta.value.substr(ta.selectionStart, ta.selectionEnd - ta.selectionStart); 236 var nc = ta.selectionStart, sp = ta.scrollTop; 237 ta.value = ss + t1 + sl + t2 + se; 238 if (ta.setSelectionRange) { 239 if (sl.length == 0) { 240 ta.setSelectionRange(nc + t1.length, nc + t1.length); 241 } else { 242 ta.setSelectionRange(nc, nc + t1.length + sl.length + t2.length); 243 } 244 ta.focus(); 245 } 246 ta.scrollTop = sp; 247 } else { 248 ta.value += t1 + t2; 249 ta.focus(ta.value.length - 1); 250 } 251 }, 252 insertTag: function (id) { 253 var tag = this.tags[id]; 254 if (!tag) return;
255 var s = this.getSelection(); 256 if (s.length > 0) { 257 this.surroundText(tag.open, tag.close); 258 } 259 }, 260 initTags: function () { 261 if (this.bbc == null || this.bbc.length == 0) { 262 this.bbc = {}; 263 this.bbc['b'] = { id: 'bbcode-b', open: '[b]', close: '[/b]', key: 'B', ctrl: 'ctrl', hint: 'Bold' }; 264 this.bbc['i'] = { id: 'bbcode-i', open: '[i]', close: '[/i]', key: 'I', ctrl: 'ctrl', hint: 'Italic' }; 265 this.bbc['u'] = { id: 'bbcode-u', open: '[u]', close: '[/u]', key: 'U', ctrl: 'ctrl', hint: 'Underline' }; 266 this.bbc['s'] = { id: 'bbcode-s', open: '[s]', close: '[/s]', key: null, ctrl: null, hint: 'Strikeout' }; 267 this.bbc['img'] = { id: 'bbcode-img', open: '[img]', close: '[/img]', key: null, ctrl: null, hint: 'Image' }; 268 this.bbc['url'] = { id: 'bbcode-url', open: '[url]', close: '[/url]', key: null, ctrl: null, hint: 'Link' }; 269 this.bbc['hide'] = { 270 id: 'bbcode-hide', 271 open: '[hide]', 272 close: '[/hide]', 273 key: null, 274 ctrl: null, 275 hint: 'Hidden' 276 }; 277 this.bbc['quote'] = { 278 id: 'bbcode-quote', 279 open: '[quote]', 280 close: '[/quote]', 281 key: null, 282 ctrl: null, 283 hint: 'Quote' 284 }; 285 this.bbc['list'] = { 286 id: 'bbcode-list', 287 open: '[list][*]', 288 close: '[/list]', 289 key: null, 290 ctrl: null, 291 hint: 'List' 292 }; 293 } 294 }, 295 296 createButton: function (i, t, c, f, img) { 297 var e; 298 if (img == null || img == "") { 299 e = document.createElement('a'); 300 e.style.display = 'block'; 301 e.setAttribute('href', '#'); 302 } else { 303 e = document.createElement('img'); 304 if (t) { 305 e.setAttribute('alt', t); 306 } 307 e.setAttribute('src', img); 308 if (!c) { 309 c = 'custombbcode'; 310 } 311 } 312 if (i) { 313 e.setAttribute('id', i); 314 } 315 if (t) { 316 e.setAttribute('title', t); 317 } 318 if (c) { 319 e.className = c; 320 } 321 var ee = e; 322 e.onclick = (f != null ? function () { 323 f(ee); 324 return false; 325 } : function () { 326 return false; 327 }); 328 return e; 329 }, 330 331 addButton: function (id, h, p, ot, ct, css, img) { 332 if (this.ta) { 333 this.initTags(); 334 var tag = this.bbc[id], th = this; 335 if (!tag) { 336 if (ot && ct) { 337 this.bbc[id] = { id: id, open: ot, close: ct, key: null, ctrl: null, hint: h }; 338 tag = this.bbc[id]; 339 } else { 340 return; 341 } 342 } 343 if (this.bbcPanel == null) { 344 this.bbcPanel = document.createElement('div'); 345 this.bbcPanel.className = 'bbcode'; 346 this.bbcPanel.style.display = 'block'; 347 this.ta.parentNode.insertBefore(this.bbcPanel, this.ta); 348 } 349 var f = function () { 350 var s = th.getSelection(); 351 if (s.length > 0) { 352 th.surroundText(tag.open, tag.close); 353 } else { 354 var v = prompt(p, ''); 355 if (null != v && '' != v) { 356 th.insertText(tag.open + v + tag.close); 357 } 358 } 359 return false; 360 }; 361 tag.e = this.createButton(tag.id, (h != null ? h : tag.hint), (css ? css : tag.id), f, img); 362 this.bbcPanel.appendChild(tag.e); 363 this.tags[tag.id] = tag; 364 } 365 }, 366 367 initSmiles: function (path) { 368 this.smilesPath = path; 369 370 if (this.ta) { 371 this.smilesPanel = document.createElement('div'); 372 373 if (this.bbcPanel) { 374 document.body.appendChild(this.smilesPanel); 375 this.smilesPanel.id = 'comments-form-smilespanel'; 376 this.smilesPanel.setAttribute('style', 'display:none;top:0;left:0;position:absolute;'); 377 this.smilesPanel.onclick = function () { 378 this.style.display = 'none'; 379 }; 380 var jc = this, f = function (e) { 381 var sp = jc.smilesPanel, p = jc.getElementPos(e); 382 383 if (sp) { 384 var sps = sp.style; 385 sps.display = (sps.display === 'none' || sps.display === '' ? 'block' : 'none'); 386 sps.left = p.left + "px"; 387 sps.top = p.bottom + e.offsetHeight + "px"; 388 sps.zIndex = 99; 389 } 390 391 return false; 392 }; 393 394 this.bbcPanel.appendChild(this.createButton(null, null, 'bbcode-smile', f)); 395 } else { 396 this.smilesPanel.className = 'smiles'; 397 this.ta.parentNode.insertBefore(this.smilesPanel, this.ta); 398 } 399 } 400 }, 401 closeSmiles: function () { 402 if (this.smilesPanel && this.bbcPanel) { 403 this.smilesPanel.style.display = 'none'; 404 } 405 }, 406 addSmile: function (code, image) { 407 if (this.ta) { 408 if (!this.smilesPath || !this.smilesPanel) { 409 return; 410 } 411 var th = this, e = document.createElement('img'); 412 e.setAttribute('src', this.smilesPath + image); 413 e.setAttribute('alt', code); 414 e.className = 'smile'; 415 e.onclick = function () { 416 th.insertText(' ' + code + ' '); 417 }; 418 this.smilesPanel.appendChild(e); 419 } 420 }, 421 addCounter: function (m, pre, post, className) { 422 if (this.ta) { 423 if (pre != null) { 424 this.l10n.counterPre = pre; 425 } 426 if (post != null) { 427 this.l10n.counterPost = post; 428 } 429 var ch = document.createElement('span'); 430 ch.className = className != null ? className : ''; 431 var t1 = document.createTextNode(this.l10n.counterPre + ' '), 432 t2 = document.createTextNode(' ' + this.l10n.counterPost); 433 var c = document.createElement('span'); 434 ch.appendChild(t1); 435 ch.appendChild(c); 436 ch.appendChild(t2); 437 if (this.resizable) {
438 if (this.grippie != null) { 439 this.grippie.appendChild(ch); 440 } 441 } else { 442 var d = document.createElement('div'); 443 d.className = 'counterpanel'; 444 this.ta.parentNode.insertBefore(d, this.ta.nextSibling); 445 d.appendChild(ch); 446 } 447 this.counter = { e: c, max: m }; 448 this.updateCounter(); 449 } 450 }, 451 addGrippie: function () { 452 this.offset = null; 453 this.dragging = false; 454 this.grippie = document.createElement('div'); 455 this.grippie.className = 'grippie'; 456 this.ta.parentNode.insertBefore(this.grippie, this.ta.nextSibling); 457 var th = this; 458 this.events.add(this.grippie, 'mousedown', function (e) { 459 return th.onMouseDown(e); 460 }); 461 }, 462 updateCounter: function () { 463 if (this.counter != null) { 464 var ta = this.ta, e = this.counter.e; 465 try { 466 var n = document.createElement(e.tagName), v = this.counter.max; 467 if (ta.value.length > 0) { 468 v = v - ta.value.length; 469 var ln = ta.value.match(/[^\r]\n/g); 470 if (ln) { 471 v = v - ln.length; 472 } 473 } 474 n.innerHTML = (v >= 0) ? v : 0; 475 e.parentNode.replaceChild(n, e); 476 this.counter.e = n; 477 } catch (ex) { 478 } 479 } 480 }, 481 mousePosition: function (e) { 482 var px = 0, py = 0; 483 if (!e) { 484 e = window.event; 485 } 486 if (e.pageX || e.pageY) { 487 px = e.pageX; 488 py = e.pageY; 489 } else if (e.clientX || e.clientY) { 490 px = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; 491 py = e.clientY + document.body.scrollTop + document.documentElement.scrollTop; 492 } 493 return { x: px, y: py }; 494 }, 495 onChange: function () { 496 this.updateCounter(); 497 if (this.ta && !this.isWebkit) { 498 var l = this.ta.value.split('\n'); 499 this.ta.rows = (l.length < this.defaultRows) ? this.defaultRows : l.length + 1; 500 } 501 return false; 502 }, 503 onMouseDown: function (e) { 504 this.offset = this.mousePosition(e).y; 505 this.height = this.ta.clientHeight; 506 this.dragging = true; 507 var th = this; 508 this.events.add(document, 'mousemove', function (e) { 509 return th.onMouseMove(e); 510 }); 511 this.events.add(document, 'mouseup', function (e) { 512 return th.onMouseUp(e); 513 }); 514 return false; 515 }, 516 onMouseUp: function (e) { 517 this.dragging = false; 518 }, 519 onMouseMove: function (e) { 520 if (this.dragging) this.ta.style.height = Math.max(this.defaultHeight, this.height + this.mousePosition(e).y - this.offset) + 'px'; 521 return false; 522 } 523}; 524 525var JCommentsScroll = JCommentsScroll || { 526 getElementRect: function (e) { 527 var x = 0, y = 0, w = e.offsetWidth, h = e.offsetHeight; 528 if (e.getBoundingClientRect) { 529 var b = e.getBoundingClientRect(), de = document.documentElement, db = document.body; 530 var st = window.pageYOffset || de.scrollTop || db.scrollTop; 531 var sl = window.pageXOffset || de.scrollLeft || db.scrollLeft; 532 var ct = de.clientTop || db.clientTop || 0; 533 var cl = de.clientLeft || db.clientLeft || 0; 534 x = b.left + sl - cl; 535 y = b.top + st - ct; 536 } else { 537 while (e.offsetParent !== null) { 538 x += e.offsetLeft; 539 y += e.offsetTop; 540 e = e.offsetParent; 541 } 542 x = Math.round(x); 543 y = Math.round(y); 544 } 545 return [x, y, x + w, y + h]; 546 }, 547 getPageRect: function () { 548 var de = document.documentElement, db = document.body; 549 var x = window.pageXOffset || de.scrollLeft || db.scrollLeft; 550 var y = window.pageYOffset || de.scrollTop || db.scrollTop; 551 var w = 'innerWidth' in window ? window.innerWidth : (de.clientWidth || db.clientWidth); 552 var h = 'innerHeight' in window ? window.innerHeight : (de.clientHeight || db.clientHeight); 553 return [x, y, x + w, y + h]; 554 }, 555 scroll: function (element) { 556 var a = this.getElementRect(element), b = this.getPageRect(); 557 if (!(a[0] < b[2] && a[2] > b[0] && a[1] < b[3] && a[3] > b[1])) { 558 window.scrollTo(a[0], a[1]); 559 } 560 } 561}; 562 563JCommentsForm.prototype = { 564 id: null, 565 form: null, 566 events: null, 567 editor: null, 568 elements: {}, 569 store: new Array('name', 'email', 'homepage'), 570 fadeTimer: null, 571 572 init: function (id, editor) { 573 this.id = id; 574 this.form = this.$(id); 575 this.editor = editor; 576 this.events = new JCommentsEvents(); 577 this.setElements(new Array('name', 'email', 'homepage', 'title', 'comment')); 578 this.restoreValues(); 579 this.clear('captcha'); 580 this.setCaptcha(); 581 }, 582 setCaptcha: function () { 583 this.captchaImage = this.$(this.id + '-captcha-image'); 584 this.register('captcha'); 585 }, 586 setEditor: function (e) { 587 this.editor = e; 588 }, 589 setElements: function (e) { 590 for (var i = 0; i < e.length; i++) { 591 try { 592 this.register(e[i]); 593 } catch (e) { 594 } 595 } 596 }, 597 $: function (e) { 598 return JComments.prototype.$(e); 599 }, 600 register: function (n) { 601 var f = this, e = this.$(this.id + '-' + n); 602 if (e) { 603 this.elements[n] = e; 604 JCommentsInput.prototype.register(e); 605 this.events.add(e, !window.opera && document.all ? 'keydown' : 'keypress', function (e) { 606 return f.keypress(e); 607 }); 608 } 609 }, 610 error: function (n) { 611 var e = this.elements[n]; 612 if (e) { 613 e.focus(); 614 var c = e.className.replace('/\berror\b/g', '') + ' error'; 615 e.className = c.replace(/\s{2,}/g, ' '); 616 } 617 }, 618 619 clear: function (n) { 620 if (n == null) { 621 if (this.form != null) { 622 this.form.reset(); 623 } 624 return; 625 } 626 switch (n) { 627 case 'comment': 628 if (this.editor != null) { 629 this.editor.clear(); 630 } 631 break; 632 case 'captcha': 633 var cim = this.captchaImage, cin = this.elements['captcha']; 634 if (cim) { 635 var r = new String(Math.floor(Math.random() * 100000)); 636 if (/\d+$/g.test(cim.src)) { 637 cim.src = cim.src.replace(/\d+$/g, r); 638 } else if (/\?/g.test(cim.src)) { 639 cim.src = cim.src + '&r=' + r; 640 } else { 641 cim.src = cim.src + '?r=' + new String(Math.floor(Math.random() * 100000)); 642 } 643 } 644 if (cin) { 645 cin.value = ''; 646 } 647 break; 648 default: 649 var e = this.elements[n]; 650 if (e) { 651 e.value = ''; 652 } 653 break; 654 } 655 },
656 focus: function (n) { 657 var e; 658 if (n == null) { 659 for (var nm in this.elements) { 660 e = this.elements[nm]; 661 if (e) { 662 e.focus(); 663 break; 664 } 665 } 666 } else { 667 e = this.elements[n]; 668 if (e) { 669 e.focus(); 670 } 671 } 672 }, 673 keypress: function (e) { 674 if (e.ctrlKey && (e.keyCode == 13 || (e.type == 'keypress' && e.keyCode == 10))) { 675 this.submit(); 676 e.returnValue = false; 677 return this.events.cancel(e); 678 } 679 return this.keypressed(e); 680 }, 681 add: function (n, i, v) { 682 if (this.form != null) { 683 var e = document.createElement('input'); 684 e.setAttribute('type', 'hidden'); 685 e.setAttribute('name', n); 686 e.setAttribute('id', i); 687 e.setAttribute('value', v); 688 this.form.appendChild(e); 689 } 690 }, 691 remove: function (i) { 692 var e = this.$(i); 693 if (e) { 694 e.value = 0; 695 e.parentNode.removeChild(e); 696 } 697 }, 698 setText: function (n, t) { 699 if (n == 'comment') { 700 if (this.editor != null) { 701 this.editor.clear(); 702 this.editor.insertText(t); 703 } 704 } else { 705 var e = this.elements[n]; 706 if (e) { 707 e.value = t; 708 } 709 } 710 }, 711 insertText: function (n, t) { 712 if (n == 'comment') { 713 if (this.editor != null) { 714 this.editor.insertText(t); 715 } 716 } else { 717 var e = this.elements[n]; 718 if (e) { 719 e.value += t; 720 } 721 } 722 }, 723 storeValues: function () { 724 for (var i = 0; i < this.store.length; i++) { 725 try { 726 var el = JComments.prototype.$(this.id + '-' + this.store[i]); 727 if (el) { 728 JComments.prototype.setCookie(this.store[i], encodeURIComponent(el.value), 14); 729 } 730 } catch (e) { 731 } 732 } 733 }, 734 restoreValues: function () { 735 for (var i = 0; i < this.store.length; i++) { 736 try { 737 var el = JComments.prototype.$(this.id + '-' + this.store[i]); 738 if (el) { 739 if (el.type && el.type == 'hidden') { 740 return; 741 } else { 742 el.value = decodeURIComponent(JComments.prototype.getCookie(this.store[i])); 743 } 744 } 745 } catch (e) { 746 } 747 } 748 }, 749 submit: function () { 750 }, 751 keypressed: function (e) { 752 } 753}; 754 755JCommentsIndicator.prototype = { 756 e: null, 757 init: function () { 758 if (this.e == null) { 759 this.e = document.createElement('div'); 760 this.e.className = 'busy'; 761 } 762 }, 763 move: function (p, b) { 764 if (p) { 765 if (this.e.parentNode) { 766 this.e.parentNode.removeChild(this.e); 767 } 768 if (b) { 769 p.insertBefore(this.e, b); 770 } else { 771 p.appendChild(this.e); 772 } 773 } 774 }, 775 show: function () { 776 this.e.style.display = 'block'; 777 }, 778 hide: function () { 779 this.e.style.display = 'none'; 780 }, 781 start: function (p, b) { 782 this.move(p, b); 783 this.show(); 784 }, 785 stop: function () { 786 this.hide(); 787 } 788}; 789 790JComments.prototype = { 791 oi: null, 792 og: null, 793 requestURI: '', 794 busy: null, 795 form: null, 796 cache: {}, 797 mode: 'add', 798 readyList: [], 799 isReady: false, 800 801 init: function (oi, og, r) { 802 var ua = navigator.userAgent.toLowerCase(); 803 this.browser = { 804 safari: /webkit/.test(ua), 805 opera: /opera/.test(ua), 806 msie: /msie/.test(ua) && !(/opera/.test(ua)), 807 mozilla: /mozilla/.test(ua) && !(/(compatible|webkit)/.test(ua)) 808 }; 809 this.oi = oi; 810 this.og = og; 811 this.busy = new JCommentsIndicator(); 812 this.requestURI = r; 813 var th = this; 814 jtajax.startLoading = function () { 815 th.busy.show(); 816 }; 817 jtajax.finishLoading = function () { 818 th.busy.hide(); 819 }; 820 }, 821 reinit: function (oi, og) { 822 this.oi = oi; 823 this.og = og; 824 var foi = this.$('object_id'); 825 if (foi) { 826 foi.value = oi; 827 } 828 var fog = this.$('object_group'); 829 if (fog) { 830 fog.value = og; 831 } 832 this.showPage(oi, og, 0); 833 }, 834 setForm: function (f) { 835 this.form = f; 836 this.form_id = f.id; 837 this.setMode('add', null); 838 var jc = this; 839 this.form.submit = function () { 840 jc.saveComment(); 841 }; 842 this.form.keypressed = function (e) { 843 if (e.keyCode == 27 && jc.mode == 'reply') { 844 jc.restoreForm(false); 845 } 846 }; 847 this.formLoaded(); 848 }, 849 setList: function (l) { 850 this.list_id = l; 851 }, 852 setMode: function (m, i) { 853 var b = this.$('comments-form-cancel'), jc = this; 854 if (b != null) { 855 //b.style.display = (m != 'add') ? '' : 'none'; 856 b.onclick = (m == 'edit' ? function () { 857 jc.cancelEdit(i); 858 } : (m == 'reply' ? function () { 859 jc.cancelReply(); 860 } : null)); 861 } 862 this.mode = m; 863 }, 864 $: function (id) { 865 if (!id) { 866 return null; 867 } 868 var e = document.getElementById(id); 869 if (!e && document.all) { 870 e = document.all[id]; 871 } 872 return e; 873 }, 874 ajax: function (func, args, formId) { 875 var response, prevURI = ''; 876 877 try { 878 prevURI = jtajax.options.url; 879 jtajax.setup({ url: this.requestURI }); 880 response = jtajax.call(func, args, 'post', formId); 881 jtajax.options.url = prevURI; 882 } catch (e) { 883 jtajax.options.url = prevURI; 884 } 885 return response; 886 }, 887 initOnReady: function () { 888 if (this.isReadyInited) return; 889 this.isReadyInited = 1; 890 var jc = this; 891 if (this.browser.mozilla || this.browser.opera) { 892 JCommentsEvents.prototype.add(document, 'DOMContentLoaded', jc.ready); 893 } else if (this.browser.msie) { 894 (function () { 895 try { 896 document.documentElement.doScroll('left'); 897 } catch (e) { 898 setTimeout(arguments.callee, 50); 899 return; 900 } 901 jc.ready(); 902 })(); 903 } else if (this.browser.safari) { 904 (function () { 905 if (jc.isReady) return; 906 if (document.readyState != "loaded" && document.readyState != "complete") { 907 setTimeout(arguments.callee, 0); 908 return; 909 } 910 jc.ready(); 911 })(); 912 } 913 JCommentsEvents.prototype.add(window, 'load', function () { 914 jc.ready(jc); 915 }); 916 }, 917 onReady: function (f) { 918 if (this.isReady) { 919 f(); 920 } else { 921 var jc = this; 922 jc.readyList.push(f); 923 jc.initOnReady(); 924 } 925 }, 926 ready: function () { 927 var jc = window.jcomments; 928 if (jc.isReady || jc.readyList == null) return; 929 jc.isReady = 1; 930 for (var i = 0, len = jc.readyList.length; i < len; i++) { 931 try { 932 jc.readyList[i](); 933 } catch (e) { 934 } 935 } 936 jc.readyList = null; 937 }, 938 setAntiCache: function (c, p, f) { 939 this.aca = c; 940 this.acp = p; 941 this.acf = f; 942 this.onReady(this.loadComments); 943 }, 944 loadComments: function () { 945 var jc = window.jcomments; 946 var l = document.location.href, lc = true, i = l.lastIndexOf('#comment-'); 947 jc.clear('captcha'); 948 if (jc.aca) { 949 if (i != 0) { 950 var c = l.substring(i + 9, l.length); 951 if (!isNaN(c)) { 952 lc = false;
953 jc.showComment(c); 954 } 955 } 956 } 957 if (jc.acp) { 958 if (lc) { 959 jc.showPage(jc.oi, jc.og, 0); 960 } 961 } 962 if (jc.acf) { 963 if (l.lastIndexOf('#addcomments') != -1) { 964 jc.showForm(jc.oi, jc.og, 'comments-form-link'); 965 } 966 } 967 }, 968 setCookie: function (n, v, d) { 969 var e = ''; 970 if (d) { 971 var dt = new Date(); 972 dt.setTime(dt.getTime() + (d * 24 * 60 * 60 * 1000)); 973 e = "; expires=" + dt.toGMTString(); 974 } 975 document.cookie = "jc_" + n + "=" + v + e + "; path=/"; 976 }, 977 getCookie: function (n) { 978 var re = new RegExp("(\;|^)[^;]*(" + "jc_" + n + ")\=([^;]*)(;|$)"); 979 var r = re.exec(document.cookie); 980 return r != null ? r[3] : ''; 981 }, 982 removeCookie: function (n) { 983 this.setCookie(n, "", -1); 984 }, 985 scrollTo: function (n) { 986 var e = this.$(n); 987 if (e) { 988 JCommentsScroll.scroll(e); 989 } 990 }, 991 scrollToList: function () { 992 this.scrollTo(this.list_id); 993 }, 994 scrollToForm: function () { 995 this.scrollTo(this.form_id); 996 }, 997 scrollToComment: function (id) { 998 this.scrollTo('comment-' + id); 999 }, 1000 moveElement: function (e, p, b) { 1001 if (e) { 1002 if (p) { 1003 if (e.parentNode) { 1004 e.parentNode.removeChild(e); 1005 } 1006 if (b) { 1007 p.insertBefore(e, b); 1008 } else { 1009 p.appendChild(e); 1010 } 1011 } 1012 } 1013 }, 1014 createElement: function (tag, id, className) { 1015 var e = document.createElement(tag); 1016 if (id) { 1017 e.setAttribute('id', id); 1018 } 1019 if (className) { 1020 e.className = className; 1021 } 1022 return e; 1023 }, 1024 fade: function (id, s, e, m) { 1025 var speed = Math.round(m / 100), timer = 0; 1026 if (s > e) { 1027 for (var i = s; i >= e; i--) { 1028 setTimeout("JComments.prototype.setOpacity('" + id + "'," + i + ")", (timer * speed)); 1029 timer++; 1030 } 1031 var o = JComments.prototype.$(id); 1032 if (o) { 1033 setTimeout(function () { 1034 o.style.display = 'none'; 1035 }, ((s - e) * speed)); 1036 } 1037 } else if (s < e) { 1038 for (var i = s; i <= e; i++) { 1039 setTimeout("JComments.prototype.setOpacity('" + id + "'," + i + ")", (timer * speed)); 1040 timer++; 1041 } 1042 } 1043 }, 1044 setOpacity: function (id, opacity) { 1045 var e = this.$(id); 1046 if (e) { 1047 var s = e.style; 1048 s.opacity = (opacity / 100); 1049 s.MozOpacity = (opacity / 100); 1050 s.KhtmlOpacity = (opacity / 100); 1051 s.filter = "alpha(opacity=" + opacity + ")"; 1052 } 1053 }, 1054 clear: function (n) { 1055 if (this.form != null) { 1056 this.form.clear(n); 1057 } 1058 }, 1059 insertText: function (t) { 1060 if (this.form != null) { 1061 this.form.insertText('comment', t); 1062 } else { 1063 var jc = this; 1064 window.setTimeout(function () { 1065 jc.insertText(t); 1066 }, 500); 1067 } 1068 }, 1069 busyList: function () { 1070 if (this.list_id) { 1071 var l = this.$(this.list_id); 1072 if (l) { 1073 this.busy.move(l.parentNode, l); 1074 } 1075 } 1076 }, 1077 busyForm: function () { 1078 if (this.form_id) { 1079 var f = this.$(this.form_id); 1080 if (f) { 1081 this.busy.move(f.parentNode, f); 1082 } 1083 } 1084 }, 1085 busyComment: function (i) { 1086 this.busy.move(this.$('comment-item-' + i), null); 1087 }, 1088 saveComment: function () { 1089 var f = ''; 1090 if (this.mode != 'edit') { 1091 f = 'JCommentsAddComment'; 1092 this.busyForm(); 1093 if (this.form) { 1094 this.form.storeValues(); 1095 } 1096 if (this.busy) { 1097 this.busy.show(); 1098 } 1099 } else { 1100 f = 'JCommentsSaveComment'; 1101 if (this.busy) { 1102 this.busy.show(); 1103 } 1104 } 1105 return this.ajax(f, null, this.form_id); 1106 }, 1107 saveCommentAsync: function () { 1108 return new Promise((resolve, reject) => { 1109 try { 1110 var response = this.saveComment(); 1111 resolve(response); 1112 } catch (e) { 1113 reject(e); 1114 } 1115 }); 1116 }, 1117 editComment: function (i) { 1118 this.busyComment(i); 1119 var a = arguments; 1120 if (this.form == null) { 1121 a = new Array(i, 1); 1122 } 1123 return this.ajax('JCommentsEditComment', a); 1124 }, 1125 cancelEdit: function (i) { 1126 if ((!this.cache[i]) || (this.cache[i] == '')) { 1127 this.$('comment-body-' + i).innerHTML = this.cache[i]; 1128 this.cache[i] = ''; 1129 } 1130 if (this.form) { 1131 this.form.remove('comment-id-hidden-' + i); 1132 this.restoreForm(true); 1133 } 1134 var t = this.$('comment-toolbar-' + i); 1135 if (t) { 1136 t.style.display = ''; 1137 } 1138 this.$('comments-form-cancel').style.display = 'none'; 1139 return this.ajax('JCommentsCancelComment', arguments); 1140 }, 1141 cancelReply: function () { 1142 if (this.form) { 1143 this.form.remove('comment-parent-id-hidden'); 1144 document.querySelector('#comments-form').reset(); 1145 this.$('comments-form-cancel').style.display = 'none'; 1146 this.restoreForm(false); 1147 } 1148 }, 1149 quoteComment: function (i) { 1150 var a = arguments; 1151 if (this.form == null) { 1152 a = new Array(i, 1); 1153 } 1154 return this.ajax('JCommentsQuoteComment', a); 1155 }, 1156 publishComment: function (i) { 1157 if (this.form) { 1158 this.restoreForm(); 1159 } 1160 this.busyComment(i); 1161 return this.ajax('JCommentsPublishComment', arguments); 1162 }, 1163 deleteComment: function (i) { 1164 this.busyComment(i); 1165 return this.ajax('JCommentsDeleteComment', arguments); 1166 }, 1167 jump2email: function (i) { 1168 return this.ajax('JCommentsJump2email', arguments); 1169 }, 1170 updateList: function (t, m) { 1171 if (this.list_id) { 1172 var l = this.$(this.list_id); 1173 if (!l) { 1174 l = this.$('comments'); 1175 m = 'a'; 1176 } 1177 switch (m) { 1178 case 'a': 1179 l.innerHTML = l.innerHTML + t; 1180 break; 1181 case 'p': 1182 l.innerHTML = t + l.innerHTML; 1183 break; 1184 case 'r': 1185 l.parentNode.innerHTML = t; 1186 break; 1187 } 1188 } 1189 }, 1190 updateTree: function (t, r, m) { 1191 var l; 1192 if (r == null) { 1193 l = this.$('comments'); 1194 if (l) { 1195 l.innerHTML = t; 1196 } 1197 return; 1198 } 1199 l = this.$('comments-list-' + r); 1200 if (!l) { 1201 var p = this.$('comment-item-' + r); 1202 if (p) { 1203 this.busyComment(r); 1204 l = this.createElement('div', 'comments-list-' + r, 'comments-list'); 1205 l.innerHTML = t; 1206 p.parentNode.insertBefore(l, p.nextSibling); 1207 } 1208 } else { 1209 l.innerHTML = (m == 'b' ? t + l.innerHTML : l.innerHTML + t); 1210 } 1211 this.restoreForm(true); 1212 }, 1213 updateComment: function (id, t) { 1214 if (t == '') { 1215 var c = this.$('comment-item-' + id); 1216 c.parentNode.removeChild(c); 1217 var l = this.$('comments-list-' + id); 1218 if (l) { 1219 l.parentNode.removeChild(l); 1220 } 1221 return; 1222 } 1223 this.$('comment-item-' + id).innerHTML = t; 1224 var te = this.$('comment-toolbar-' + id); 1225 if (te) { 1226 te.style.display = ''; 1227 } 1228 if (this.form) { 1229 this.form.remove('comment-id-hidden-' + id); 1230 this.restoreForm(true); 1231 } 1232 }, 1233 voteComment: function (i) { 1234 var v = this.$('comment-vote-holder-' + i); 1235 if (v) { 1236 v.innerHTML = ''; 1237 this.busy.start(v, null); 1238 } 1239 return this.ajax('JCommentsVoteComment', arguments); 1240 }, 1241 updateVote: function (i, t) { 1242 this.busy.stop(); 1243 var c = this.$('comment-vote-holder-' + i); 1244 if (c) { 1245 c.innerHTML = t; 1246 } 1247 }, 1248 showComment: function (id) { 1249 return this.ajax('JCommentsShowComment', arguments); 1250 }, 1251 showPage: function (i, g, p) { 1252 if (this.form) { 1253 this.restoreForm(); 1254 } 1255 var l = this.$(this.list_id); 1256 if (!l) { 1257 l = this.$(this.list_id + '-0'); 1258 if (l) { 1259 this.list_id = this.list_id + '-0'; 1260 } 1261 } 1262 this.busyList(); 1263 return this.ajax('JCommentsShowPage', arguments); 1264 }, 1265 showForm: function (i, g, t) { 1266 if (this.form) { 1267 this.moveElement(this.form.form, this.$(t)); 1268 return; 1269 } 1270 this.busyForm(); 1271 return this.ajax('JCommentsShowForm', arguments); 1272 }, 1273 showEdit: function (id, n, e, h, t, txt) { 1274 var jc = this; 1275 if (this.form == null) { 1276 window.setTimeout(function () { 1277 jc.showEdit(id, n, e, h, t, txt); 1278 }, 500); 1279 return; 1280 } 1281 if ((!this.cache[id]) || (this.cache[id] == '')) { 1282 this.cache[id] = this.$('comment-body-' + id).innerHTML; 1283 } 1284 this.busy.stop(); 1285 var f = this.form, ff = this.form.form, c = this.$('comment-item-' + id); 1286 if (ff != null && c != null) { 1287 f.add('id', 'comment-id-hidden-' + id, id); 1288 f.setText('name', n); 1289 f.setText('email', e); 1290 f.setText('homepage', h); 1291 f.setText('title', t); 1292 f.setText('comment', txt); 1293 var d = this.$('comments-inline-edit'); 1294 if (d) { 1295 d.parentNode.removeChild(d); 1296 } else { 1297 d = this.createElement('div', 'comments-inline-edit', 'border rounded border-top-0 comments-inline-edit'); 1298 } 1299 c.appendChild(d); 1300 this.moveElement(ff, d);
1301 this.setMode('edit', id); 1302 var te = this.$('comment-toolbar-' + id); 1303 if (te) { 1304 te.style.display = 'none'; 1305 } 1306 this.$('comments-form-cancel').style.display = 'inline-block'; 1307 this.scrollTo('comments-inline-edit'); 1308 this.form.focus('comment'); 1309 } 1310 }, 1311 showReply: function (id, q) { 1312 this.busyComment(id); 1313 this.cancelReport(); 1314 var jc = this, c = this.$('comment-item-' + id), d = this.$('comments-inline-edit'); 1315 if (d) { 1316 d.parentNode.removeChild(d); 1317 } else { 1318 d = this.createElement('div', 'comments-inline-edit', 'border rounded border-top-0 comments-inline-edit'); 1319 } 1320 c.appendChild(d); 1321 if (!this.form) { 1322 var t = 'comments-inline-edit', h = this.$('comments-form-link'); 1323 if (h) { 1324 t = 'comments-form-link'; 1325 } 1326 this.showForm(this.oi, this.og, t); 1327 var pid = id; 1328 this.formLoaded = function () { 1329 var f = jc.form; 1330 if (f != null) { 1331 f.add('parent', 'comment-parent-id-hidden', pid); 1332 } 1333 jc.setMode('reply', pid); 1334 jc.moveElement(jc.form.form, jc.$('comments-inline-edit')); 1335 jc.form.focus(); 1336 if (q) { 1337 jc.quoteComment(id); 1338 } 1339 }; 1340 } else { 1341 var f = this.form, ff = this.form.form, p = this.$('comment-parent-id-hidden'); 1342 if (ff != null && c != null) { 1343 if (!p) { 1344 f.add('parent', 'comment-parent-id-hidden', id); 1345 } else { 1346 p.value = id; 1347 } 1348 this.moveElement(ff, d); 1349 this.setMode('reply', id); 1350 this.form.focus(); 1351 if (q) { 1352 this.quoteComment(id); 1353 } 1354 } 1355 } 1356 this.$('comments-form-cancel').style.display = 'inline-block'; 1357 }, 1358 formLoaded: function () { 1359 }, 1360 restoreForm: function (c) { 1361 var f = this.form; 1362 if (f != null) { 1363 var ff = this.form.form; 1364 this.busy.stop(); 1365 if (ff != null) { 1366 if (c) { 1367 f.clear(null); 1368 } 1369 f.restoreValues();
1370 var a = this.$('addcomments'), p = this.$('comment-parent-id-hidden'); 1371 if (p) { 1372 p.value = 0; 1373 } 1374 this.moveElement(ff, a.parentNode, a); 1375 var d = this.$('comments-inline-edit'); 1376 if (d) { 1377 d.parentNode.removeChild(d); 1378 } 1379 this.setMode('add', null); 1380 } 1381 } 1382 }, 1383 hideChildComments: function (e, id) { 1384 var b = this.$('show-button-' + id); 1385 var c = this.$('comment-item-' + id); 1386 b.style.display = ''; 1387 c.classList.add('hide-children'); 1388 e.style.display = 'none'; 1389 return false; 1390 }, 1391 showChildComments: function (e, id) { 1392 var b = this.$('hide-button-' + id); 1393 var c = this.$('comment-item-' + id); 1394 b.style.display = ''; 1395 c.classList.remove('hide-children'); 1396 e.style.display = 'none'; 1397 return false; 1398 }, 1399 reportComment: function (id) { 1400 this.busyComment(id); 1401 this.cancelReply(); 1402 var c = this.$('comment-item-' + id), d = this.$('comments-inline-report'); 1403 if (d) { 1404 d.parentNode.removeChild(d); 1405 } else { 1406 d = this.createElement('div', 'comments-inline-report', 'comments-inline-report'); 1407 } 1408 c.appendChild(d); 1409 var a = new Array(id, 'comments-inline-report'); 1410 return this.ajax('JCommentsShowReportForm', a); 1411 }, 1412 saveReport: function () { 1413 this.ajax('JCommentsReportComment', null, 'comments-report-form'); 1414 1415 return true; 1416 }, 1417 cancelReport: function () { 1418 var div = document.querySelector('#comments-inline-report'); 1419 1420 if (div) { 1421 div.innerHTML = ''; 1422 } 1423 }, 1424 closeReport: function (m) { 1425 this.cancelReport(); 1426 1427 if (m) { 1428 this.showMessage(m, 'success', 'comments-inline-report'); 1429 } 1430 }, 1431 banIP: function (id) { 1432 this.ajax('JCommentsBanIP', arguments) 1433 }, 1434 error: function (m, t, n) { 1435 if (!t || t == '') { 1436 t = this.form_id; 1437 } 1438 1439 // TODO Place at the current form position 1440 //Joomla.renderMessages({'error': [m]}, '#comments-report-form-msg'); 1441 1442 this.showMessage(m, 'danger', t); 1443 1444 if (this.form != null) { 1445 this.form.error(n); 1446 } 1447 }, 1448 message: function (m, t) { 1449 if (!t || t == '') { 1450 t = this.form_id; 1451 } 1452 1453 //Joomla.renderMessages({'info': [m]}, '#comments-report-form-msg'); 1454 this.showMessage(m, 'success', t); 1455 }, 1456 showMessage: function (m, c, t) { 1457 clearTimeout(this.fadeTimer); 1458 var fe = this.$('comments-form-message'); 1459 var af = this.$(t); 1460 if (fe) { 1461 fe.parentNode.removeChild(fe); 1462 } 1463 fe = JComments.prototype.createElement('div', 'comments-form-message', ''); 1464 if (af) { 1465 JComments.prototype.moveElement(fe, af, af.firstChild); 1466 } else { 1467 alert(m); 1468 return; 1469 } 1470 if (!c) { 1471 c = 'info'; 1472 } 1473 fe.className = 'alert alert-' + c; 1474 fe.role = 'alert'; 1475 fe.innerHTML = m; 1476 fe.style.display = 'block'; 1477 JComments.prototype.setOpacity(fe.id, 100); 1478 this.fadeTimer = setTimeout(function () { 1479 JComments.prototype.fade('comments-form-message', 100, 0, 1000); 1480 }, 6000); 1481 JCommentsScroll.scroll(fe); 1482 }, 1483 go: function (l) { 1484 window.open(l); 1485 return false; 1486 } 1487}; 1488 1489document.addEventListener('DOMContentLoaded', function () { 1490 document.body.addEventListener('click', async function (e) { 1491 if (e.target && e.target.id == 'addcomments') { 1492 e.preventDefault(); 1493 var el = e.target; 1494 jcomments.showForm(el.dataset.object_id, el.dataset.object_group, 'comments-form-link'); 1495 } else if (e.target && e.target.id == 'comments-form-send') { 1496 e.preventDefault(); 1497 try { 1498 await jcomments.saveCommentAsync(); 1499 var jc = window.jcomments; 1500 if (jc) { 1501 jc.showPage(jc.oi, jc.og, 0); 1502 } 1503 } catch (error) { 1504 console.error('Error saving comment:', error); 1505 } 1506 } else if (e.target && e.target.id == 'comments-form-reset') { 1507 e.preventDefault(); 1508 1509 document.querySelector('#comments-form').reset(); 1510 } else if (e.target && (e.target.id == 'comments-form-captcha-image' || e.target.id == 'cmd-captcha-reload')) { 1511 e.preventDefault(); 1512 jcomments.clear('captcha'); 1513 } 1514 }); 1515 1516 const subscribeButton = document.querySelector('.cmd-subscribe'); 1517 if (subscribeButton) { 1518 subscribeButton.addEventListener('click', function (e) { 1519 e.preventDefault(); 1520 let href = this.getAttribute('href'); 1521 Joomla.request({ 1522 url: href + '&format=json', 1523 onSuccess: (response) => { 1524 let _response = JSON.parse(response); 1525 if (_response.success) { 1526 this.setAttribute('href', _response.data.href); 1527 this.setAttribute('title', _response.data.title); 1528 this.innerHTML = '<span aria-hidden="true" class="icon-mail icon-fw"></span> ' + _response.data.title; 1529 Joomla.renderMessages({ 'message': [_response.message] }, '.comments-list-footer'); 1530 } else { 1531 Joomla.renderMessages({ 'warning': [_response.message] }, '.comments-list-footer'); 1532 } 1533 }, 1534 onError: function (xhr) { 1535 let response = JSON.parse(xhr.responseText); 1536 Joomla.renderMessages({ 'error': [response.message] }, '.comments-list-footer'); 1537 } 1538 }); 1539 }); 1540 } 1541});
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.