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