1(function (window) 2{ 3 if (window.BX.frameCache) return; 4 5 var BX = window.BX; 6 var localStorageKey = "compositeCache"; 7 var lolalStorageTTL = 1440; 8 var compositeMessageIds = ["bitrix_sessid", "USER_ID", "SERVER_TIME", "USER_TZ_OFFSET", "USER_TZ_AUTO"]; 9 var compositeDataFile = "/bitrix/tools/composite_data.php"; 10 var sessidWasUpdated = false; 11 12 BX.frameCache = function() 13 { 14 }; 15 16 if (typeof(localStorage) !== "undefined") 17 { 18 BX.frameCache.localStorage = new BX.localStorage(); 19 } 20 else 21 { 22 BX.frameCache.localStorage = { 23 set : BX.DoNothing, 24 get : function() { return null; }, 25 remove : BX.DoNothing 26 }; 27 } 28 29 BX.frameCache.localStorage.prefix = function() 30 { 31 return "bx-"; 32 }; 33 34 BX.frameCache.init = function() 35 { 36 this.cacheDataBase = null; 37 this.tableParams = 38 { 39 tableName: "composite", 40 fields: [ 41 {name: "id", unique: true}, 42 "content", 43 "hash", 44 "props" 45 ] 46 }; 47 48 this.frameDataReceived = false; 49 this.frameDataInserted = false; 50 51 if (BX.type.isString(window.frameDataString) && window.frameDataString.length > 0) 52 { 53 BX.frameCache.onFrameDataReceived(window.frameDataString); 54 } 55 56 this.vars = window.frameCacheVars ? window.frameCacheVars : { 57 dynamicBlocks: {}, 58 page_url: "", 59 params: {}, 60 storageBlocks: [] 61 }; 62 63 //local storage warming up 64 var lsCache = BX.frameCache.localStorage.get(localStorageKey) || {}; 65 for (var i = 0; i < compositeMessageIds.length; i++) 66 { 67 var messageId = compositeMessageIds[i]; 68 if (typeof(BX.message[messageId]) != "undefined") 69 { 70 lsCache[messageId] = BX.message[messageId]; 71 } 72 } 73 BX.frameCache.localStorage.set(localStorageKey, lsCache, lolalStorageTTL); 74 75 BX.addCustomEvent("onBXMessageNotFound", function(mess) 76 { 77 if (BX.util.in_array(mess, compositeMessageIds)) 78 { 79 var cache = BX.frameCache.localStorage.get(localStorageKey); 80 if (cache && typeof(cache[mess]) != "undefined") 81 { 82 BX.message[mess] = cache[mess]; 83 } 84 else 85 { 86 BX.frameCache.getCompositeMessages(); 87 } 88 } 89 }); 90 91 if (!window.frameUpdateInvoked) 92 { 93 this.update(false); 94 window.frameUpdateInvoked = true; 95 } 96 97 if (window.frameRequestStart) 98 { 99 BX.ready(function() { 100 BX.onCustomEvent("onCacheDataRequestStart"); 101 BX.frameCache.tryUpdateSessid(); 102 }); 103 } 104 105 if (window.frameRequestFail) 106 { 107 BX.ready(function() { 108 setTimeout(function() { 109 BX.onCustomEvent("onFrameDataRequestFail", [window.frameRequestFail]); 110 }, 0); 111 }); 112 } 113 114 BX.frameCache.insertBanner(); 115 }; 116 117 BX.frameCache.getCompositeMessages = function() 118 { 119 try { 120 BX.ajax({ 121 method: "GET", 122 dataType: "json", 123 url: compositeDataFile, 124 async : false, 125 data: '', 126 onsuccess: function(json) 127 { 128 BX.frameCache.setCompositeVars(json); 129 } 130 }); 131 } 132 catch (exeption) 133 { 134 BX.debug("Composite sync request failed."); 135 } 136 }; 137 138 BX.frameCache.setCompositeVars = function(vars) 139 { 140 if (!vars) 141 { 142 return; 143 } 144 else if (vars.lang) 145 { 146 vars = vars.lang; 147 } 148 149 var lsCache = BX.frameCache.localStorage.get(localStorageKey) || {}; 150 for (var name in vars) 151 { 152 if (vars.hasOwnProperty(name)) 153 { 154 BX.message[name] = vars[name]; 155 156 if (BX.util.in_array(name, compositeMessageIds)) 157 { 158 lsCache[name] = vars[name]; 159 } 160 } 161 } 162 163 BX.frameCache.localStorage.set(localStorageKey, lsCache, lolalStorageTTL); 164 }; 165 166 BX.frameCache.insertBlock = function(block, callback) 167 { 168 if (!BX.type.isFunction(callback)) 169 { 170 callback = function() {}; 171 } 172 173 if (!block) 174 { 175 callback(); 176 return; 177 } 178 179 var container = null; 180 var dynamicStart = null; 181 var dynamicEnd = null; 182 183 var autoContainerPrefix = "bxdynamic_"; 184 if (block.ID.substr(0, autoContainerPrefix.length) === autoContainerPrefix) 185 { 186 dynamicStart = BX(block.ID + "_start"); 187 dynamicEnd = BX(block.ID + "_end"); 188 if (!dynamicStart || !dynamicEnd) 189 { 190 BX.debug("Dynamic area " + block.ID + " was not found"); 191 callback(); 192 return; 193 } 194 } 195 else 196 { 197 container = BX(block.ID); 198 if (!container) 199 { 200 BX.debug("Container " + block.ID + " was not found"); 201 callback(); 202 return; 203 } 204 } 205 206 let htmlWasInserted = false;
207 let scriptsLoaded = false; 208 const assets = getAssets(); 209 210 processStrings(); 211 processAssets(() => { 212 scriptsLoaded = true; 213 insertHTML(); 214 }); 215 216 function processAssets(callback) 217 { 218 let styles = assets.styles; 219 if (BX.type.isArray(block.PROPS.CSS) && block.PROPS.CSS.length > 0) 220 { 221 styles = block.PROPS.CSS.concat(styles); 222 } 223 224 let scripts = assets.externalJS; 225 if (BX.type.isArray(block.PROPS.JS) && block.PROPS.JS.length > 0) 226 { 227 scripts = scripts.concat(block.PROPS.JS); 228 } 229 230 const items = styles.concat(scripts); 231 if (items.length > 0) 232 { 233 BX.load(items, callback); 234 } 235 else 236 { 237 callback(); 238 } 239 } 240 241 function insertHTML() 242 { 243 if (container) 244 { 245 if (block.PROPS.USE_ANIMATION) 246 { 247 container.style.opacity = 0; 248 container.innerHTML = block.CONTENT; 249 (new BX.easing({ 250 duration : 1500, 251 start : { opacity: 0 }, 252 finish : { opacity: 100 }, 253 transition : BX.easing.makeEaseOut(BX.easing.transitions.quart), 254 step : function(state){ 255 container.style.opacity = state.opacity / 100; 256 }, 257 complete : function() { 258 container.style.cssText = ''; 259 } 260 })).animate(); 261 } 262 else 263 { 264 container.innerHTML = block.CONTENT; 265 } 266 } 267 else 268 { 269 BX.frameCache.removeNodes(dynamicStart, dynamicEnd); 270 dynamicStart.insertAdjacentHTML("afterEnd", block.CONTENT); 271 } 272 273 htmlWasInserted = true; 274 if (scriptsLoaded) 275 { 276 processInlineJS(); 277 } 278 } 279 280 function processStrings() 281 { 282 if (BX.Type.isStringFilled(assets.html)) 283 { 284 document.head.insertAdjacentHTML("beforeend", assets.html); 285 } 286 287 BX.evalGlobal(assets.inlineJS.join(";")); 288 } 289 290 function getAssets() 291 { 292 var result = { styles: [], inlineJS: [], externalJS: [], html: "" }; 293 if (!BX.type.isArray(block.PROPS.STRINGS) || block.PROPS.STRINGS.length < 1) 294 { 295 return result; 296 } 297 298 var parts = BX.processHTML(block.PROPS.STRINGS.join(""), false); 299 for (var i = 0, l = parts.SCRIPT.length; i < l; i++) 300 { 301 var script = parts.SCRIPT[i]; 302 if (script.isInternal) 303 { 304 result.inlineJS.push(script.JS); 305 } 306 else 307 { 308 result.externalJS.push(script.JS); 309 } 310 } 311 312 result.styles = parts.STYLE; 313 result.html = parts.HTML; 314 315 return result; 316 } 317 318 function processInlineJS() 319 { 320 scriptsLoaded = true; 321 if (htmlWasInserted) 322 { 323 BX.ajax.processRequestData(block.CONTENT, {scriptsRunFirst: false, dataType: "HTML"}); 324 325 if (BX.type.isArray(block.PROPS.BUNDLE_JS)) 326 { 327 BX.setJSList(block.PROPS.BUNDLE_JS); 328 } 329 330 if (BX.type.isArray(block.PROPS.BUNDLE_CSS)) 331 { 332 BX.setCSSList(block.PROPS.BUNDLE_CSS); 333 } 334 335 callback(); 336 } 337 } 338 }; 339 340 BX.frameCache.removeNodes = function(fromElement, toElement) 341 { 342 var startFound = false; 343 var parent = fromElement.parentNode; 344 var nodes = Array.prototype.slice.call(parent.childNodes); 345 for (var i = 0, length = nodes.length; i < length; i++) 346 { 347 if (startFound) 348 { 349 if (nodes[i] === toElement) 350 { 351 break; 352 } 353 else 354 { 355 parent.removeChild(nodes[i]); 356 } 357 } 358 else if (nodes[i] === fromElement) 359 { 360 startFound = true; 361 } 362 } 363 }; 364 365 BX.frameCache.update = function(makeRequest, noInvoke) 366 { 367 noInvoke = !!noInvoke; 368 makeRequest = typeof(makeRequest) == "undefined" ? true : makeRequest; 369 if (makeRequest) 370 { 371 this.requestData(); 372 } 373 374 if (!noInvoke) 375 { 376 BX.ready(BX.proxy(function() { 377 if (!this.frameDataReceived) 378 { 379 this.invokeCache(); 380 } 381 }, this)); 382 } 383 }; 384 385 BX.frameCache.invokeCache = function() 386 { 387 //getting caching dynamic blocks 388 if (this.vars.storageBlocks && this.vars.storageBlocks.length > 0) 389 { 390 BX.onCustomEvent(this, "onCacheInvokeBefore", [this.vars.storageBlocks]); 391 this.readCacheWithID(this.vars.storageBlocks, BX.proxy(this.insertFromCache, this)); 392 } 393 }; 394 395 BX.frameCache.handleResponse = function(json) 396 { 397 if (json == null) 398 return; 399 400 BX.onCustomEvent("onFrameDataReceivedBefore", [json]); 401 402 if (json.dynamicBlocks && json.dynamicBlocks.length > 0)//we have dynamic blocks 403 { 404 this.insertBlocks(json.dynamicBlocks, false); 405 this.writeCache(json.dynamicBlocks); 406 } 407 408 BX.onCustomEvent("onFrameDataReceived", [json]); 409 410 if ( 411 json.isManifestUpdated == "1" 412 && this.vars.CACHE_MODE === "APPCACHE" 413 && window.applicationCache 414 && ( 415 window.applicationCache.status == window.applicationCache.IDLE 416 || window.applicationCache.status == window.applicationCache.UPDATEREADY 417 ) 418 ) //the manifest has been changed 419 {
420 window.applicationCache.update(); 421 } 422 423 if (json.htmlCacheChanged === true && this.vars.CACHE_MODE === "HTMLCACHE") 424 { 425 BX.onCustomEvent("onHtmlCacheChanged", [json]); 426 } 427 428 if (BX.type.isArray(json.spread)) 429 { 430 for (var i = 0; i < json.spread.length; i++) 431 { 432 new Image().src = json.spread[i]; 433 } 434 } 435 436 }; 437 438 BX.frameCache.requestData = function() 439 { 440 var headers = [ 441 { name: "BX-ACTION-TYPE", value: "get_dynamic" }, 442 { name: "BX-REF", value: document.referrer }, 443 { name: "BX-CACHE-MODE", value: this.vars.CACHE_MODE }, 444 { name: "BX-CACHE-BLOCKS", value: this.vars.dynamicBlocks ? JSON.stringify(this.vars.dynamicBlocks) : "" } 445 ]; 446 447 if (this.vars.AUTO_UPDATE === false && this.vars.AUTO_UPDATE_TTL && this.vars.AUTO_UPDATE_TTL > 0) 448 { 449 var lastModified = Date.parse(document.lastModified); 450 if (!isNaN(lastModified)) 451 { 452 var now = new Date().getTime(); 453 if ((lastModified + this.vars.AUTO_UPDATE_TTL * 1000) < now) 454 { 455 headers.push({ name: "BX-INVALIDATE-CACHE", value: "Y" }); 456 } 457 } 458 } 459 460 if (this.vars.CACHE_MODE === "APPCACHE") 461 { 462 headers.push({ name: "BX-APPCACHE-PARAMS", value: JSON.stringify(this.vars.PARAMS) }); 463 headers.push({ name: "BX-APPCACHE-URL", value: this.vars.PAGE_URL ? this.vars.PAGE_URL : "" }); 464 } 465 466 BX.onCustomEvent("onCacheDataRequestStart"); 467 468 var requestURI = window.location.href; 469 var index = requestURI.indexOf("#"); 470 if (index > 0) 471 { 472 requestURI = requestURI.substring(0, index); 473 } 474 requestURI += (requestURI.indexOf("?") >= 0 ? "&" : "?") + "bxrand=" + new Date().getTime(); 475 476 BX.ajax({ 477 timeout: 60, 478 method: "GET", 479 url: requestURI, 480 data: {}, 481 headers: headers, 482 skipBxHeader : true, 483 processData: false, 484 onsuccess: BX.proxy(BX.frameCache.onFrameDataReceived, this), 485 onfailure: function() 486 { 487 window.frameRequestFail = { 488 error: true, 489 reason: "bad_response", 490 url : requestURI, 491 xhr: this.xhr, 492 status: this.xhr ? this.xhr.status : 0 493 }; 494 495 BX.onCustomEvent("onFrameDataRequestFail", [window.frameRequestFail]); 496 } 497 }); 498 }; 499 500 BX.frameCache.onFrameDataReceived = function(response) 501 { 502 var result = null; 503 try 504 { 505 result = JSON.parse(response); 506 } 507 catch (e) 508 { 509 var error = { 510 error: true, 511 reason: "bad_eval", 512 response: response 513 }; 514 515 window.frameRequestFail = error; 516 517 BX.ready(function() { 518 setTimeout(function() { 519 BX.onCustomEvent("onFrameDataRequestFail", [error]); 520 }, 0); 521 }); 522 523 return; 524 } 525 526 this.frameDataReceived = true; 527 528 if (result && BX.type.isNotEmptyString(result.redirect_url)) 529 { 530 window.location = result.redirect_url; 531 return; 532 } 533 534 if (result && result.error === true) 535 { 536 window.frameRequestFail = result; 537 538 BX.ready(BX.proxy(function() { 539 setTimeout(BX.proxy(function() { 540 BX.onCustomEvent("onFrameDataRequestFail", [result]); 541 }, this), 0); 542 }, this)); 543 544 return; 545 } 546 547 BX.frameCache.setCompositeVars(result); 548 BX.ready(BX.proxy(function() { 549 this.handleResponse(result); 550 this.tryUpdateSessid(); 551 }, this)); 552 }; 553 554 BX.frameCache.insertFromCache = function(resultSet, transaction) 555 { 556 if (!this.frameDataReceived) 557 { 558 var items = resultSet.items; 559 if (items.length > 0) 560 { 561 for (var i = 0; i < items.length; i++) 562 { 563 items[i].PROPS = JSON.parse(items[i].PROPS); 564 } 565 566 this.insertBlocks(items, true); 567 } 568 569 BX.onCustomEvent(this, "onCacheInvokeAfter", [this.vars.storageBlocks, resultSet]); 570 } 571 }; 572 573 BX.frameCache.insertBlocks = function(blocks, fromCache) 574 { 575 var blocksToInsert = new Set(); 576 for (var i = 0; i < blocks.length; i++) 577 { 578 var block = blocks[i]; 579 BX.onCustomEvent("onBeforeDynamicBlockUpdate", [block, fromCache]); 580 581 if (block.PROPS.AUTO_UPDATE === false) 582 { 583 continue; 584 } 585 586 blocksToInsert.add(block); 587 } 588 589 let inserted = 0; 590 591 const finalize = () => { 592 if (window.performance) 593 { 594 var entries = performance.getEntries(); 595 for (var i = 0; i < entries.length; i++) 596 { 597 var entry = entries[i]; 598 if (entry.initiatorType === 'xmlhttprequest' && entry.name && entry.name.match(/bxrand=[0-9]+/)) 599 { 600 // uses in ba.js 601 this.requestTiming = entry; 602 } 603 } 604 605 if (window.performance.measure) 606 { 607 window.performance.measure('Composite:LCP'); 608 609 var lcpEntries = performance.getEntriesByName('Composite:LCP'); 610 if (lcpEntries.length > 0 && lcpEntries[0].duration) 611 { 612 // uses in ba.js 613 this.lcp = Math.ceil(lcpEntries[0].duration); 614 } 615 } 616 } 617 618 BX.onCustomEvent("onFrameDataProcessed", [blocks, fromCache]); 619 this.frameDataInserted = true; 620 }; 621 622 const handleBlockInsertion = () => { 623 if (++inserted === blocksToInsert.size) 624 { 625 finalize(); 626 } 627 }; 628 629 if (blocksToInsert.size === 0) 630 { 631 finalize(); 632 } 633 else 634 { 635 blocksToInsert.forEach(function(block) { 636 637 if (block && block.HASH && block.PROPS && block.PROPS.ID) 638 { 639 this.vars.dynamicBlocks[block.PROPS.ID] = block.HASH; 640 } 641 642 this.insertBlock(block, handleBlockInsertion); 643 }, this); 644 } 645 }; 646 647 BX.frameCache.writeCache = function(blocks) 648 { 649 for (var i = 0; i < blocks.length; i++) 650 { 651 if (blocks[i].PROPS.USE_BROWSER_STORAGE === true) 652 {
653 this.writeCacheWithID( 654 blocks[i].ID, 655 blocks[i].CONTENT, 656 blocks[i].HASH, 657 JSON.stringify(blocks[i].PROPS) 658 ); 659 } 660 } 661 }; 662 663 BX.frameCache.openDatabase = function() 664 { 665 var isDatabaseOpened = (this.cacheDataBase != null); 666 667 if(!isDatabaseOpened) 668 { 669 this.cacheDataBase = new BX.Dexie("composite"); 670 if(this.cacheDataBase != null) 671 { 672 this.cacheDataBase.version(1).stores({ 673 composite: '&ID,CONTENT,HASH,PROPS' 674 }); 675 isDatabaseOpened = true; 676 } 677 } 678 679 return isDatabaseOpened; 680 }; 681 682 BX.frameCache.writeCacheWithID = function(id, content, hash, props) 683 { 684 if(BX.frameCache.openDatabase()) 685 { 686 if (typeof props == "object") 687 { 688 props = JSON.stringify(props); 689 } 690 691 this.cacheDataBase.composite.put({ 692 ID: id, 693 CONTENT: content, 694 HASH: hash, 695 PROPS : props 696 }); 697 } 698 }; 699 700 BX.frameCache.readCacheWithID = function(id, callback) 701 { 702 if(BX.frameCache.openDatabase()) 703 { 704 this.cacheDataBase.composite 705 .where("ID").anyOf(id).toArray() 706 .then((function(items){ 707 callback({items:items}); 708 }).bind(this)); 709 } 710 else if(typeof callback != "undefined") 711 { 712 callback({items:[]}); 713 } 714 }; 715 716 BX.frameCache.insertBanner = function() 717 { 718 if (!this.vars.banner || !BX.type.isNotEmptyString(this.vars.banner.text)) 719 { 720 return; 721 } 722 723 BX.ready(BX.proxy(function() { 724 var banner = BX.create("a", { 725 props : { 726 className : "bx-composite-btn" + ( 727 BX.type.isNotEmptyString(this.vars.banner.style) ? 728 " bx-btn-" + this.vars.banner.style : 729 "" 730 ), 731 href : this.vars.banner.url 732 }, 733 attrs : { 734 target : "_blank" 735 }, 736 text : this.vars.banner.text 737 }); 738 739 if (BX.type.isNotEmptyString(this.vars.banner.bgcolor)) 740 { 741 banner.style.backgroundColor = this.vars.banner.bgcolor; 742 if (BX.util.in_array(this.vars.banner.bgcolor.toUpperCase(), ["#FFF", "#FFFFFF", "WHITE"])) 743 { 744 BX.addClass(banner, "bx-btn-border"); 745 } 746 } 747 748 var container = BX("bx-composite-banner"); 749 if (container) 750 { 751 container.appendChild(banner); 752 } 753 else 754 { 755 BX.addClass(banner, "bx-composite-btn-fixed"); 756 document.body.appendChild(BX.create("div", { 757 style : { position: "relative" }, 758 children: [ banner ] 759 })); 760 } 761 }, this)); 762 }; 763 764 BX.frameCache.tryUpdateSessid = function() 765 { 766 if (sessidWasUpdated) 767 { 768 return; 769 } 770 771 var name = "bitrix_sessid"; 772 var sessid = false; 773 774 if (typeof(BX.message[name]) != "undefined") 775 { 776 sessid = BX.message[name]; 777 } 778 else 779 { 780 var cache = BX.frameCache.localStorage.get(localStorageKey) || {}; 781 if (typeof(cache[name]) != "undefined") 782 { 783 sessid = cache[name]; 784 } 785 } 786 787 if (sessid !== false) 788 { 789 sessidWasUpdated = true; 790 this.updateSessid(sessid); 791 } 792 }; 793 794 BX.frameCache.updateSessid = function(sessid) 795 { 796 var inputs = document.getElementsByName("sessid"); 797 for (var i = 0; i < inputs.length; i++) 798 { 799 inputs[i].value = sessid; 800 } 801 }; 802 803 //initialize 804 BX.frameCache.init(); 805 806})(window);
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.