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