1;(function() { 2 'use strict'; 3 4 BX.namespace('BX.SB.Popup'); 5 6 if (BX.SB.Popup.Manager) 7 { 8 return; 9 } 10 11 /** 12 * @class 13 * @property {Object} entities 14 * @property {Object} currentEntities 15 * @property {Object} events 16 * @property {Object} classes 17 * @property {Object} defaults 18 * @property {Object} attributes 19 * @property {Object} documentEvents 20 */ 21 BX.SB.Popup.Manager = { 22 entities: {}, 23 currentEntities: {}, 24 events: { 25 onBeforeInitialized: 'BX.SB.Popup.Manager:beforeInitialized', 26 onInitialized: 'BX.SB.Popup.Manager:afterInitialized', 27 }, 28 classes: { 29 section: 'popup-window', 30 ready: 'popup-window_ready', 31 active: 'popup-window_active', 32 popup: 'popup-window__popup', 33 popupFixedPos: 'popup-window__popup_fixed', 34 inner: 'popup-window__inner', 35 overlay: 'popup-window__overlay', 36 overlayFixedPos: 'popup-window__overlay_fixed', 37 close: 'popup-window__close', 38 preloader: 'popup-window__preloader', 39 defaultTemplate: 'popup-window_default', 40 }, 41 defaults: { 42 template: null, 43 parent: null, 44 content: null, 45 classPrefix: 'bx-sb', 46 disableDefaultTemplate: false, 47 disableOverflow: true, 48 disableOverlay: true, 49 disableOn: 0, 50 calcContentPos: false, 51 calcBgPos: false, 52 stickToNode: null, 53 stickToNodePosition: null, 54 fixedContentPos: true, 55 fixedBgPos: true, 56 closeOnExternalClick: true, 57 closeOnBgClick: true, 58 closeOnContentClick: false, 59 closeOnEscapeKey: true, 60 showPreloader: true, 61 showCloseBtn: true, 62 events: {}, 63 classes: {}, 64 attributes: {}, 65 ajax: { 66 url: null, 67 data: {}, 68 method: 'POST', 69 dataType: 'html', 70 timeout: 30, 71 async: true, 72 processData: true, 73 scriptsRunFirst: false, 74 emulateOnload: true, 75 start: true, 76 cache: true, 77 onsuccess: null, 78 onfailure: null, 79 }, 80 }, 81 attributes: { 82 section: 'data-sb-popup-window', 83 overlay: 'data-sb-popup-overlay', 84 popup: 'data-sb-popup-popup', 85 inner: 'data-sb-popup-inner', 86 close: 'data-sb-popup-window-close', 87 preloader: 'data-sb-popup-window-preloader', 88 ready: 'data-sb-popup-window-ready', 89 }, 90 documentEvents: { 91 initialClick: 'sbPopupManagerInitialClick' 92 }, 93 }; 94 95 /** 96 * @param {Object} [params.parent] 97 * @param {Object} [params.content] 98 * @param {String} [params.classPrefix] 99 * @param {Number} [params.disableDefaultTemplate] 100 * @param {Number} [params.disableOn] 101 * @param {Boolean} [params.disableOverflow] 102 * @param {Boolean} [params.disableOverlay] 103 * @param {Boolean} [params.calcContentPos] 104 * @param {Boolean} [params.calcBgPos] 105 * @param {Object} [params.stickToNode] 106 * @param {String} [params.stickToNodePosition] 107 * @param {Boolean} [params.fixedContentPos] 108 * @param {Boolean} [params.fixedBgPos] 109 * @param {Boolean} [params.closeOnExternalClick] 110 * @param {Boolean} [params.closeOnBgClick] 111 * @param {Boolean} [params.closeOnContentClick] 112 * @param {Boolean} [params.closeOnEscapeKey] 113 * @param {Boolean} [params.showPreloader] 114 * @param {Boolean} [params.showCloseBtn] 115 * @param {Object} [params.events] 116 * @param {Object} [params.classes] 117 * @param {Object} [params.attributes] 118 * @param {Object} [params.ajax] 119 * @constructor 120 */ 121 BX.SB.Popup.Window = function(params) { 122 if (!(this instanceof BX.SB.Popup.Window)) 123 { 124 return new BX.SB.Popup.Window(params); 125 } 126 127 /** @var {String} **/ 128 this._id = null; 129 /** @var {Object} **/ 130 this._window = window; 131 /** @var {Object} **/ 132 this._document = document; 133 /** @var {Object} **/ 134 this._body = this._document.body; 135 /** @var {BX.SB.Popup.Manager} **/ 136 this._manager = null; 137 /** @var {Boolean} **/ 138 this._isOpened = false; 139 /** @var {Object} **/ 140 this._events = { 141 onBeforeInitialized: 'BX.SB.Popup.Window:beforeInitialized', 142 onInitialized: 'BX.SB.Popup.Window:afterInitialized', 143 144 onBeforeDestroyed: 'BX.SB.Popup.Window:beforeDestroyed', 145 onDestroyed: 'BX.SB.Popup.Window:afterDestroyed', 146 147 onBeforeCreated: 'BX.SB.Popup.Window:beforeCreated', 148 onCreated: 'BX.SB.Popup.Window:afterCreated', 149 150 onBeforeContentUpdated: 'BX.SB.Popup.Window:beforeContentUpdated', 151 onContentUpdated: 'BX.SB.Popup.Window:afterContentUpdated', 152
153 onBeforeContentUpdatedAjax: 'BX.SB.Popup.Window:beforeContentUpdatedAjax', 154 onContentUpdatedAjax: 'BX.SB.Popup.Window:afterContentUpdatedAjax', 155 156 onContentUpdatedAjaxSuccess: 'BX.SB.Popup.Window:afterContentUpdatedAjaxSuccess', 157 onContentUpdatedAjaxFailure: 'BX.SB.Popup.Window:afterContentUpdatedAjaxFailure', 158 159 onBeforeClosed: 'BX.SB.Popup.Window:beforeClosed', 160 onClosed: 'BX.SB.Popup.Window:afterClosed', 161 162 onBeforeOpened: 'BX.SB.Popup.Window:beforeOpened', 163 onOpened: 'BX.SB.Popup.Window:afterOpened', 164 }; 165 /** @var {Object} **/ 166 this._params = params || {}; 167 /** @var {Object} **/ 168 this._nodes = { 169 section: null, 170 overlay: null, 171 popup: null, 172 inner: null, 173 close: null, 174 preloader: null, 175 }; 176 177 if (!BX.type.isNotEmptyObject(BX.SB.Popup.Manager)) 178 { 179 return; 180 } 181 182 this._manager = BX.SB.Popup.Manager; 183 184 BX.onCustomEvent(this, this._events.onBeforeInitialized); 185 186 this._init(); 187 188 BX.onCustomEvent(this, this._events.onInitialized); 189 }; 190 191 BX.SB.Popup.Window.prototype = { 192 constructor: BX.SB.Popup.Window, 193 194 /** 195 * @api private 196 */ 197 _init: function() { 198 this._params = BX.mergeEx({}, this._manager.defaults, this._params); 199 this._params.ajax = BX.mergeEx({}, this._manager.defaults.ajax, this._params.ajax || {}); 200 this._params.classes = BX.mergeEx({}, this._manager.classes, this._params.classes); 201 this._params.attributes = BX.mergeEx({}, this._manager.attributes, this._params.attributes); 202 203 this._setEntityId(this._getRandomString()); 204 this._saveEntity(); 205 }, 206 207 /** 208 * @param {Number} [windowHeight=null] 209 * @return {Number} 210 * @api private 211 */ 212 _hasScrollBar: function(windowHeight) { 213 windowHeight = windowHeight || null; 214 return this._document.body.scrollHeight > (windowHeight || this._window.innerHeight); 215 }, 216 217 /** 218 * @return {Number} 219 * @api private 220 */ 221 _getScrollbarSize: function() { 222 let scroll = this._document.createElement('DIV'); 223 scroll.style.cssText = 'position: absolute; width: 99px; height: 99px; top: -9999px; overflow: scroll;'; 224 225 this._document.body.appendChild(scroll); 226 let size = scroll.offsetWidth - scroll.clientWidth; 227 this._document.body.removeChild(scroll); 228 229 return size; 230 }, 231 232 /** 233 * @api private 234 */ 235 _checkOpening: function() { 236 return this._isOpened === true && this._manager.currentEntities.hasOwnProperty(this._getEntityId()); 237 }, 238 239 /** 240 * @api private 241 */ 242 _checkInitialClickEvent: function(event) { 243 event = event || this._window.event; 244 let isInitialClick = false; 245 246 if (typeof event !== 'undefined' && event.hasOwnProperty(this._manager.documentEvents.initialClick)) 247 { 248 isInitialClick = event.type === 'click' && event[this._manager.documentEvents.initialClick] === this._getEntityId(); 249 } 250 251 return isInitialClick; 252 }, 253 254 _setInitialClickEvent: function(event) { 255 event = event || this._window.event; 256 257 if (typeof event !== 'undefined' && event.type === 'click' && !this._checkOpening()) 258 { 259 this._window.event[this._manager.documentEvents.initialClick] = this._getEntityId(); 260 } 261 }, 262 263 /** 264 * @api private 265 */ 266 _removeCurrentEntity: function() { 267 delete this._manager.currentEntities[this._getEntityId()]; 268 }, 269 270 /** 271 * @api private 272 */ 273 _setCurrentEntity: function() { 274 this._manager.currentEntities[this._getEntityId()] = this._manager.entities[this._getEntityId()]; 275 }, 276 277 /** 278 * @api private 279 */ 280 _saveEntity: function() { 281 this._manager.entities[this._getEntityId()] = this; 282 }, 283 284 /** 285 * @param {String} id 286 * @api private 287 */ 288 _setEntityId: function(id) { 289 this._id = id; 290 }, 291 292 /** 293 * @return {String} 294 * @api private 295 */ 296 _getEntityId: function() { 297 return this._id; 298 }, 299 300 /** 301 * @param {Number} [length=5] 302 * @return {String} 303 * @api private 304 */ 305 _getRandomString: function(length) { 306 length = length ? length : 5; 307 return BX.util.getRandomString(length); 308 }, 309 310 /** 311 * @param {Object} element 312 * @param {String} attribute 313 * @param {String=} value 314 * @api private 315 */ 316 _setDataAttribute: function(element, attribute, value) { 317 value = value ? value : ''; 318 if (BX.type.isElementNode(element) && attribute.toString().length > 0) 319 { 320 element.setAttribute(attribute.toString(), value); 321 } 322 }, 323 324 /** 325 * @return {Object} 326 * @api private 327 */ 328 _getNodes: function() { 329 return this._nodes; 330 }, 331 332 /** 333 * @return {Object} 334 * @api private 335 */ 336 _getParams: function() { 337 return this._params; 338 }, 339 340 /** 341 * @param {Object} params 342 * @api private 343 */ 344 _updateParams: function(params) { 345 params = params || {}; 346 this._params = BX.mergeEx({}, this._params, params); 347 }, 348 349 /** 350 * @param {String=} html 351 * @return {Object} 352 * @api private 353 */ 354 _createElementNodeFromHtml: function(html) { 355 return BX.type.isElementNode(html) ? html : (new DOMParser().parseFromString(html, 'text/html').body.firstChild); 356 }, 357 358 /** 359 * @api private 360 */ 361 _disablePageScrollbar: function() { 362 this._document.body.style.paddingRight = this._getScrollbarSize() + 'px'; 363 this._document.body.style.overflow = 'hidden'; 364 }, 365 366 /** 367 * @api private 368 */ 369 _enablePageScrollbar: function() { 370 this._document.body.style.removeProperty('padding-right'); 371 this._document.body.style.removeProperty('overflow'); 372 }, 373 374 /** 375 * @api private 376 */ 377 _unbindParamsEvents: function() { 378 for (let event in this._params.events) 379 { 380 if (this._params.events.hasOwnProperty(event)) 381 { 382 if (this._events.hasOwnProperty(event)) 383 { 384 BX.removeCustomEvent(this, event, this._params.events[event]); 385 } 386 } 387 } 388 }, 389 390 /** 391 * @api private 392 */ 393 _bindParamsEvents: function() { 394 for (let event in this._params.events) 395 { 396 if (this._params.events.hasOwnProperty(event)) 397 { 398 if (this._events.hasOwnProperty(event)) 399 { 400 BX.addCustomEvent(this, this._events[event], this._params.events[event]); 401 } 402 } 403 } 404 }, 405 406 /** 407 * @api private 408 */ 409 _unbindEvents: function() { 410 BX.unbind(window, 'resize', BX.proxy(this._updateWindow, this)); 411 412 BX.unbind(this._nodes.close, 'click', BX.proxy(this.close, this)); 413 BX.unbind(this._document.body, 'click', BX.proxy(this._closeClickHandler, this)); 414 BX.unbind(this._document.body, 'keyup', BX.proxy(this._closeKeyUpHandler, this)); 415 416 this._unbindParamsEvents(); 417 }, 418 419 /** 420 * @api private 421 */ 422 _bindEvents: function() { 423 BX.bind(window, 'resize', BX.proxy(this._updateWindow, this)); 424 425 BX.bind(this._nodes.close, 'click', BX.proxy(this.close, this)); 426 BX.bind(this._document.body, 'click', BX.proxy(this._closeClickHandler, this)); 427 BX.bind(this._document.body, 'keyup', BX.proxy(this._closeKeyUpHandler, this)); 428 429 this._bindParamsEvents(); 430 }, 431 432 /** 433 * @param {Object|String} content 434 * @api private 435 */ 436 _updateContent: function(content) { 437 BX.onCustomEvent(this, this._events.onBeforeContentUpdated); 438 439 this._params.content = content; 440 441 if (this._nodes.inner !== null) 442 { 443 if (BX.type.isElementNode(content)) 444 { 445 BX.cleanNode(this._nodes.inner); 446 this._nodes.inner.appendChild(content); 447 } 448 else if (BX.type.isString(content)) 449 { 450 this._nodes.inner.innerHTML = content; 451 } 452 } 453 454 BX.onCustomEvent(this, this._events.onContentUpdated); 455 }, 456 457 /** 458 * @param {Object} params 459 * @api private 460 */ 461 _updateContentAjax: function(params) { 462 let _this = this; 463 params = params || this._params.ajax; 464 465 BX.onCustomEvent(this, this._events.onBeforeContentUpdatedAjax); 466 467 if (BX.type.isNotEmptyObject(params)) 468 { 469 if (BX.type.isFunction(params.onsuccess)) 470 {
471 let callOnSuccess = params.onsuccess; 472 params.onsuccess = function(data) { 473 callOnSuccess(data, this, _this); 474 475 BX.onCustomEvent(this, _this._events.onContentUpdatedAjaxSuccess); 476 }; 477 } 478 479 if (BX.type.isFunction(params.onfailure)) 480 { 481 let callOnFailure = params.onfailure; 482 params.onfailure = function(data) { 483 callOnFailure(data, this, _this); 484 485 BX.onCustomEvent(this, _this._events.onContentUpdatedAjaxFailure); 486 } 487 } 488 489 BX.ajax(params); 490 } 491 492 BX.onCustomEvent(this, this._events.onContentUpdatedAjax); 493 }, 494 495 /** 496 * @api private 497 */ 498 _updateWindow: function() { 499 if (BX.type.isElementNode(this._nodes.overlay)) 500 { 501 BX.adjust(this._nodes.overlay, { 502 style: { 503 height: this._params.calcBgPos ? false : this._document.body.clientHeight + 'px', 504 }, 505 }); 506 } 507 }, 508 509 /** 510 * @api private 511 */ 512 _destroy: function() { 513 BX.onCustomEvent(this, this._events.onBeforeDestroyed); 514 515 BX.remove(this._nodes.section); 516 517 BX.onCustomEvent(this, this._events.onDestroyed); 518 }, 519 520 /** 521 * @api private 522 */ 523 _updatePosition: function() { 524 if (this._params.calcContentPos && BX.type.isElementNode(this._nodes.popup)) 525 { 526 BX.adjust(this._nodes.popup, { 527 style: { 528 top: this._window.scrollY + (this._window.innerHeight / 2) + 'px', 529 }, 530 }); 531 } 532 533 if (this._params.calcBgPos && !this._params.disableOverlay) 534 { 535 BX.adjust(this._nodes.popup, { 536 style: { 537 height: this._document.body.clientHeight + 'px', 538 }, 539 }); 540 } 541 }, 542 543 /** 544 * @api private 545 */ 546 _create: function() { 547 BX.onCustomEvent(this, this._events.onBeforeCreated); 548 549 if (this._params.template) 550 { 551 if (!BX.type.isElementNode(this._params.template)) 552 { 553 this._params.template = this._createElementNodeFromHtml(this._params.template); 554 } 555 556 let template = this._document.createElement('DIV'); 557 template.appendChild(this._params.template); 558 559 for (let key in this._nodes) 560 { 561 if (this._nodes.hasOwnProperty(key) && this._params.attributes.hasOwnProperty(key)) 562 { 563 let element = template.querySelector('[' + this._params.attributes[key] + ']'); 564 if (BX.type.isElementNode(element)) 565 { 566 this._nodes[key] = element; 567 } 568 } 569 } 570 } 571 else 572 { 573 if (this._params.showCloseBtn) 574 { 575 this._nodes.close = BX.create('DIV', { 576 attrs: { 577 className: this.getPrefixedClassName(this._params.classes.close, this._params.classPrefix), 578 }, 579 }); 580 this._setDataAttribute(this._nodes.close, this._params.attributes.close); 581 } 582 583 if (this._params.showPreloader) 584 { 585 this._nodes.preloader = BX.create('DIV', { 586 attrs: { 587 className: this.getPrefixedClassName(this._params.classes.preloader, this._params.classPrefix), 588 }, 589 }); 590 this._setDataAttribute(this._nodes.preloader, this._params.attributes.preloader); 591 } 592 593 this._nodes.inner = BX.create('DIV', { 594 attrs: { 595 className: this.getPrefixedClassName(this._params.classes.inner, this._params.classPrefix), 596 }, 597 }); 598 599 this._nodes.popup = BX.create('DIV', { 600 attrs: { 601 className: this.getPrefixedClassName(this._params.classes.popup, this._params.classPrefix) + 602 (this._params.fixedContentPos ? ' ' + this.getPrefixedClassName(this._params.classes.popupFixedPos, this._params.classPrefix) : ''), 603 }, 604 children: [this._nodes.close, this._nodes.inner, this._nodes.preloader], 605 }); 606 607 if (this._params.disableOverlay === false) 608 { 609 this._nodes.overlay = BX.create('DIV', { 610 attrs: { 611 className: this.getPrefixedClassName(this._params.classes.overlay, this._params.classPrefix) + 612 (this._params.fixedBgPos ? ' ' + this.getPrefixedClassName(this._params.classes.overlayFixedPos, this._params.classPrefix) : ''), 613 }, 614 }); 615 } 616 617 this._nodes.section = BX.create('DIV', { 618 attrs: { 619 className: this.getPrefixedClassName(this._params.classes.section, this._params.classPrefix) + 620 (this._params.disableDefaultTemplate ? '' : ' ' + this.getPrefixedClassName(this._params.classes.defaultTemplate, this._params.classPrefix)), 621 }, 622 children: [this._nodes.popup, this._nodes.overlay], 623 }); 624 } 625 626 BX.addClass(this._nodes.section, this._params.classes.ready); 627 628 this._updatePosition(); 629 630 let parent = BX.type.isElementNode(this._params.parent) ? this._params.parent : this._body; 631 parent.appendChild(this._nodes.section); 632 633 if (BX.type.isNotEmptyObject(this._params.ajax)) 634 { 635 this._updateContentAjax(this._params.ajax); 636 } 637 if (this._params.content !== null) 638 { 639 this._updateContent(this._params.content); 640 } 641 642 BX.onCustomEvent(this, this._events.onCreated); 643 }, 644 645 /** 646 * @param {Object} event 647 * @api private 648 */ 649 _closeClickHandler: function(event) { 650 event = event || this._window.event; 651 652 if (this._checkInitialClickEvent()) 653 { 654 return; 655 } 656 657 if (this._params.closeOnExternalClick && !this._nodes.section.contains(event.target)) 658 { 659 this.close(); 660 } 661 662 if (this._params.closeOnBgClick && this._nodes.section.contains(event.target) && !this._nodes.popup.contains(event.target)) 663 { 664 this.close(); 665 } 666 667 if (this._params.closeOnContentClick && this._nodes.section.contains(event.target) && this._nodes.inner.contains(event.target)) 668 { 669 this.close(); 670 } 671 }, 672 673 /** 674 * @param {Object} event 675 * @api private 676 */ 677 _closeKeyUpHandler: function(event) { 678 event = event || this._window.event; 679 680 if (this._params.closeOnEscapeKey && event.keyCode === 27) 681 { 682 this.close(); 683 } 684 }, 685 686 /** 687 * @api private 688 */ 689 _close: function() { 690 if (!this._checkOpening()) 691 { 692 return; 693 } 694 695 BX.onCustomEvent(this, this._events.onBeforeClosed); 696 697 BX.removeClass(this._nodes.section, this._params.classes.active); 698 699 this._removeCurrentEntity(); 700 this._isOpened = false;
701 702 this._unbindEvents(); 703 704 this._destroy(); 705 706 this._enablePageScrollbar(); 707 708 BX.onCustomEvent(this, this._events.onClosed); 709 }, 710 711 /** 712 * @api private 713 */ 714 _open: function() { 715 if (this._checkOpening()) 716 { 717 return; 718 } 719 720 if (this._window.innerWidth < this._params.disableOn) 721 { 722 return; 723 } 724 725 BX.onCustomEvent(this, this._events.onBeforeOpened); 726 727 if (!this._checkInitialClickEvent()) 728 { 729 if (typeof this._window.event !== 'undefined') 730 { 731 if (this._window.event.stopPropagation) 732 { 733 this._window.event.stopPropagation(); 734 } 735 else 736 { 737 this._window.event.cancelBubble = true; 738 } 739 } 740 } 741 742 if (!this._params.disableOverflow) 743 { 744 this._disablePageScrollbar(); 745 } 746 747 this._create(); 748 749 this._bindEvents(); 750 751 BX.addClass(this._nodes.section, this._params.classes.active); 752 753 this._isOpened = true; 754 this._setCurrentEntity(); 755 756 BX.onCustomEvent(this, this._events.onOpened); 757 }, 758 759 /** 760 * @param {String} name 761 * @param {String} prefix 762 * @return {String} 763 * @api private 764 */ 765 _getPrefixedClassName: function(name, prefix) { 766 prefix = this._params.classPrefix.toString().length > 0 ? this._params.classPrefix : ''; 767 return prefix.toString().length > 0 ? prefix + '-' + name : name; 768 }, 769 770 /** 771 * @param {String} name 772 * @param {String} prefix 773 * @return {String} 774 * @api public 775 */ 776 getPrefixedClassName: function(name, prefix) { 777 return this._getPrefixedClassName(name, prefix); 778 }, 779 780 /** 781 * @return {Object} 782 * @api public 783 */ 784 getNodes: function() { 785 return this._getNodes(); 786 }, 787 788 /** 789 * @return {Object} 790 * @api public 791 */ 792 getParams: function() { 793 return this._getParams(); 794 }, 795 796 /** 797 * @param {Object} params 798 * @api public 799 */ 800 updateParams: function(params) { 801 this._updateParams(params); 802 }, 803 804 /** 805 * @param {Object|String} content 806 * @api public 807 */ 808 updateContent: function(content) { 809 this._updateContent(content); 810 }, 811 812 /** 813 * @param {Object} params 814 * @api public 815 */ 816 updateContentAjax: function(params) { 817 this._updateContentAjax(params); 818 }, 819 820 /** 821 * @api public 822 */ 823 close: function() { 824 this._close(); 825 }, 826 827 /** 828 * @api public 829 */ 830 open: function() { 831 this._open(); 832 }, 833 834 /** 835 * @api public 836 */ 837 setInitialClickEvent: function() { 838 this._setInitialClickEvent(); 839 }, 840 841 /** 842 * @api public 843 */ 844 onBeforeInitialized: function() { 845 }, 846 847 /** 848 * @api public 849 */ 850 onInitialized: function() { 851 }, 852 853 /** 854 * @api public 855 */ 856 onBeforeDestroyed: function() { 857 }, 858 859 /** 860 * @api public 861 */ 862 onDestroyed: function() { 863 }, 864 865 /** 866 * @api public 867 */ 868 onBeforeCreated: function() { 869 }, 870 871 /** 872 * @api public 873 */ 874 onCreated: function() { 875 }, 876 877 /** 878 * @api public 879 */ 880 onBeforeContentUpdated: function() { 881 }, 882 883 /** 884 * @api public 885 */ 886 onContentUpdated: function() { 887 }, 888 889 /** 890 * @api public 891 */ 892 onBeforeContentUpdatedAjax: function() { 893 }, 894 895 /** 896 * @api public 897 */ 898 onContentUpdatedAjax: function() { 899 }, 900 901 /** 902 * @api public 903 */ 904 onContentUpdatedAjaxSuccess: function() { 905 }, 906 907 /** 908 * @api public 909 */ 910 onContentUpdatedAjaxFailure: function() { 911 }, 912 913 /** 914 * @api public 915 */ 916 onBeforeClosed: function() { 917 }, 918 919 /** 920 * @api public 921 */ 922 onClosed: function() { 923 }, 924 925 /** 926 * @api public 927 */ 928 onBeforeOpened: function() { 929 }, 930 931 /** 932 * @api public 933 */ 934 onOpened: function() { 935 }, 936 }; 937 938 939})();
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.