1;(function(window){ 2 3if (window.BX.ajax) 4 return; 5 6var 7 BX = window.BX, 8 9 tempDefaultConfig = {}, 10 defaultConfig = { 11 method: 'GET', // request method: GET|POST 12 dataType: 'html', // type of data loading: html|json|script 13 timeout: 0, // request timeout in seconds. 0 for browser-default 14 async: true, // whether request is asynchronous or not 15 processData: true, // any data processing is disabled if false, only callback call 16 scriptsRunFirst: false, // whether to run _all_ found scripts before onsuccess call. script tag can have an attribute "bxrunfirst" to turn this flag on only for itself 17 emulateOnload: true, 18 skipAuthCheck: false, // whether to check authorization failure (SHOUD be set to true for CORS requests) 19 start: true, // send request immediately (if false, request can be started manually via XMLHttpRequest object returned) 20 cache: true, // whether NOT to add random addition to URL 21 preparePost: true, // whether set Content-Type x-www-form-urlencoded in POST 22 headers: false, // add additional headers, example: [{'name': 'If-Modified-Since', 'value': 'Wed, 15 Aug 2012 08:59:08 GMT'}, {'name': 'If-None-Match', 'value': '0'}] 23 lsTimeout: 30, //local storage data TTL. useless without lsId. 24 lsForce: false //wheter to force query instead of using localStorage data. useless without lsId. 25/* 26other parameters: 27 url: url to get/post 28 data: data to post 29 onsuccess: successful request callback. BX.proxy may be used. 30 onfailure: request failure callback. BX.proxy may be used. 31 32 lsId: local storage id - for constantly updating queries which can communicate via localStorage. core_ls.js needed 33 34any of the default parameters can be overridden. defaults can be changed by BX.ajax.Setup() - for all further requests! 35*/ 36 }, 37 ajax_session = null, 38 loadedScripts = {}, 39 loadedScriptsQueue = [], 40 r = { 41 'url_utf': /[^\034-\254]+/g, 42 'script_self': /\/bitrix\/js\/main\/core\/core(_ajax)*.js$/i, 43 'script_self_window': /\/bitrix\/js\/main\/core\/core_window.js$/i, 44 'script_self_admin': /\/bitrix\/js\/main\/core\/core_admin.js$/i, 45 'script_onload': /window.onload/g 46 }; 47 48// low-level method 49BX.ajax = function(config) 50{ 51 var status, data; 52
53 if (!config || !config.url || !BX.type.isString(config.url)) 54 { 55 return false; 56 } 57 58 for (var i in tempDefaultConfig) 59 if (typeof (config[i]) == "undefined") config[i] = tempDefaultConfig[i]; 60 61 tempDefaultConfig = {}; 62 63 for (i in defaultConfig) 64 if (typeof (config[i]) == "undefined") config[i] = defaultConfig[i]; 65 66 config.method = config.method.toUpperCase(); 67 68 if (!BX.localStorage) 69 config.lsId = null; 70 71 if (BX.browser.IsIE()) 72 { 73 var result = r.url_utf.exec(config.url); 74 if (result) 75 { 76 do 77 { 78 config.url = config.url.replace(result, BX.util.urlencode(result)); 79 result = r.url_utf.exec(config.url); 80 } while (result); 81 } 82 } 83 84 if(config.dataType == 'json') 85 config.emulateOnload = false; 86 87 if (!config.cache && config.method == 'GET') 88 config.url = BX.ajax._uncache(config.url); 89 90 if (config.method == 'POST' && config.preparePost) 91 { 92 config.data = BX.ajax.prepareData(config.data); 93 } 94 95 var bXHR = true; 96 if (config.lsId && !config.lsForce) 97 { 98 var v = BX.localStorage.get('ajax-' + config.lsId); 99 if (v !== null) 100 { 101 bXHR = false; 102 103 var lsHandler = function(lsData) { 104 if (lsData.key == 'ajax-' + config.lsId && lsData.value != 'BXAJAXWAIT') 105 { 106 var data = lsData.value, 107 bRemove = !!lsData.oldValue && data == null; 108 if (!bRemove) 109 BX.ajax.__run(config, data); 110 else if (config.onfailure) 111 config.onfailure("timeout"); 112 113 BX.removeCustomEvent('onLocalStorageChange', lsHandler); 114 } 115 }; 116 117 if (v == 'BXAJAXWAIT') 118 { 119 BX.addCustomEvent('onLocalStorageChange', lsHandler); 120 } 121 else 122 { 123 setTimeout(function() {lsHandler({key: 'ajax-' + config.lsId, value: v})}, 10); 124 } 125 } 126 } 127 128 if (bXHR) 129 { 130 config.xhr = BX.ajax.xhr(); 131 if (!config.xhr) return; 132 133 if (config.lsId) 134 { 135 BX.localStorage.set('ajax-' + config.lsId, 'BXAJAXWAIT', config.lsTimeout); 136 } 137 138 config.xhr.open(config.method, config.url, config.async); 139 140 if (!config.skipBxHeader && !BX.ajax.isCrossDomain(config.url)) 141 { 142 config.xhr.setRequestHeader('Bx-ajax', 'true'); 143 } 144 145 if (config.method == 'POST' && config.preparePost) 146 { 147 config.xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 148 } 149 if (typeof(config.headers) == "object") 150 { 151 for (i = 0; i < config.headers.length; i++) 152 config.xhr.setRequestHeader(config.headers[i].name, config.headers[i].value); 153 } 154 155 var bRequestCompleted = false; 156 var onreadystatechange = config.xhr.onreadystatechange = function(additional) 157 { 158 if (bRequestCompleted) 159 return; 160 161 if (additional === 'timeout') 162 { 163 if (config.onfailure) 164 { 165 config.onfailure("timeout"); 166 } 167 168 BX.onCustomEvent(config.xhr, 'onAjaxFailure', ['timeout', '', config]); 169 170 config.xhr.onreadystatechange = BX.DoNothing; 171 config.xhr.abort(); 172 173 if (config.async) 174 { 175 config.xhr = null; 176 } 177 } 178 else 179 { 180 if (config.xhr.readyState == 4 || additional == 'run') 181 { 182 status = BX.ajax.xhrSuccess(config.xhr) ? "success" : "error"; 183 bRequestCompleted = true; 184 config.xhr.onreadystatechange = BX.DoNothing; 185 186 if (status == 'success') 187 { 188 var authHeader = (!!config.skipAuthCheck || BX.ajax.isCrossDomain(config.url)) 189 ? false 190 : config.xhr.getResponseHeader('X-Bitrix-Ajax-Status'); 191 192 if(!!authHeader && authHeader == 'Authorize') 193 { 194 if (config.onfailure) 195 { 196 config.onfailure("auth", config.xhr.status); 197 } 198 199 BX.onCustomEvent(config.xhr, 'onAjaxFailure', ['auth', config.xhr.status, config]); 200 } 201 else 202 { 203 var data = config.xhr.responseText; 204 205 if (config.lsId) 206 { 207 BX.localStorage.set('ajax-' + config.lsId, data, config.lsTimeout); 208 } 209 210 BX.ajax.__run(config, data); 211 } 212 } 213 else 214 { 215 if (config.onfailure) 216 { 217 config.onfailure("status", config.xhr.status); 218 } 219 220 BX.onCustomEvent(config.xhr, 'onAjaxFailure', ['status', config.xhr.status, config]); 221 } 222 223 if (config.async) 224 { 225 config.xhr = null; 226 } 227 } 228 } 229 }; 230 231 if (config.async && config.timeout > 0) 232 { 233 setTimeout(function() { 234 if (config.xhr && !bRequestCompleted) 235 { 236 onreadystatechange("timeout"); 237 } 238 }, config.timeout * 1000); 239 } 240 241 if (config.start) 242 {
243 config.xhr.send(config.data); 244 245 if (!config.async) 246 { 247 onreadystatechange('run'); 248 } 249 } 250 251 return config.xhr; 252 } 253}; 254 255BX.ajax.xhr = function() 256{ 257 if (window.XMLHttpRequest) 258 { 259 try {return new XMLHttpRequest();} catch(e){} 260 } 261 else if (window.ActiveXObject) 262 { 263 try { return new window.ActiveXObject("Msxml2.XMLHTTP.6.0"); } 264 catch(e) {} 265 try { return new window.ActiveXObject("Msxml2.XMLHTTP.3.0"); } 266 catch(e) {} 267 try { return new window.ActiveXObject("Msxml2.XMLHTTP"); } 268 catch(e) {} 269 try { return new window.ActiveXObject("Microsoft.XMLHTTP"); } 270 catch(e) {} 271 throw new Error("This browser does not support XMLHttpRequest."); 272 } 273 274 return null; 275}; 276 277BX.ajax.isCrossDomain = function(url, location) 278{ 279 location = location || window.location; 280 281 //Relative URL gets a current protocol 282 if (url.indexOf("//") === 0) 283 { 284 url = location.protocol + url; 285 } 286 287 //Fast check 288 if (url.indexOf("http") !== 0) 289 { 290 return false; 291 } 292 293 var link = window.document.createElement("a"); 294 link.href = url; 295 296 return link.protocol !== location.protocol || 297 link.hostname !== location.hostname || 298 BX.ajax.getHostPort(link.protocol, link.host) !== BX.ajax.getHostPort(location.protocol, location.host); 299}; 300 301BX.ajax.getHostPort = function(protocol, host) 302{ 303 var match = /:(\d+)$/.exec(host); 304 if (match) 305 { 306 return match[1]; 307 } 308 else 309 { 310 if (protocol === "http:") 311 { 312 return "80"; 313 } 314 else if (protocol === "https:") 315 { 316 return "443"; 317 } 318 } 319 320 return ""; 321}; 322 323BX.ajax.__prepareOnload = function(scripts) 324{ 325 if (scripts.length > 0) 326 { 327 BX.ajax['onload_' + ajax_session] = null; 328 329 for (var i=0,len=scripts.length;i<len;i++) 330 { 331 if (scripts[i].isInternal) 332 { 333 scripts[i].JS = scripts[i].JS.replace(r.script_onload, 'BX.aja
333x.onload_' + ajax_session); 334 } 335 } 336 } 337 338 BX.CaptureEventsGet(); 339 BX.CaptureEvents(window, 'load'); 340}; 341 342BX.ajax.__runOnload = function() 343{ 344 if (null != BX.ajax['onload_' + ajax_session]) 345 { 346 BX.ajax['onload_' + ajax_session].apply(window); 347 BX.ajax['onload_' + ajax_session] = null; 348 } 349 350 var h = BX.CaptureEventsGet(); 351 352 if (h) 353 { 354 for (var i=0; i<h.length; i++) 355 h[i].apply(window); 356 } 357}; 358 359BX.ajax.__run = function(config, data) 360{ 361 if (!config.processData) 362 { 363 if (config.onsuccess) 364 { 365 config.onsuccess(data); 366 } 367 368 BX.onCustomEvent(config.xhr, 'onAjaxSuccess', [data, config]); 369 } 370 else 371 { 372 data = BX.ajax.processRequestData(data, config); 373 } 374}; 375 376 377BX.ajax._onParseJSONFailure = function(data) 378{ 379 this.jsonFailure = true; 380 this.jsonResponse = data; 381 this.jsonProactive = /^\[WAF\]/.test(data); 382}; 383 384BX.ajax.processRequestData = function(data, config) 385{ 386 var result, scripts = [], styles = []; 387 switch (config.dataType.toUpperCase()) 388 { 389 case 'JSON': 390 BX.addCustomEvent(config.xhr, 'onParseJSONFailure', BX.proxy(BX.ajax._onParseJSONFailure, config)); 391 result = BX.parseJSON(data, config.xhr); 392 BX.removeCustomEvent(config.xhr, 'onParseJSONFailure', BX.proxy(BX.ajax._onParseJSONFailure, config)); 393 394 break; 395 case 'SCRIPT': 396 scripts.push({"isInternal": true, "JS": data, bRunFirst: config.scriptsRunFirst}); 397 config.processScriptsConsecutive = true; 398 result = data; 399 break; 400 401 default: // HTML 402 var ob = BX.processHTML(data, config.scriptsRunFirst); 403 result = ob.HTML; scripts = ob.SCRIPT; styles = ob.STYLE; 404 break; 405 } 406 407 var bSessionCreated = false; 408 if (null == ajax_session) 409 { 410 ajax_session = parseInt(Math.random() * 1000000); 411 bSessionCreated = true; 412 } 413 414 if (styles.length > 0) 415 BX.loadCSS(styles); 416 417 if (config.emulateOnload) 418 BX.ajax.__prepareOnload(scripts); 419 420 var cb = BX.DoNothing; 421 if(config.emulateOnload || bSessionCreated) 422 { 423 cb = BX.defer(function() 424 { 425 if (config.emulateOnload) 426 BX.ajax.__runOnload(); 427 if (bSessionCreated) 428 ajax_session = null; 429 BX.onCustomEvent(config.xhr, 'onAjaxSuccessFinish', [config]); 430 }); 431 } 432 433 try 434 { 435 if (!!config.jsonFailure) 436 { 437 throw {type: 'json_failure', data: config.jsonResponse, bProactive: config.jsonProactive}; 438 } 439 440 config.scripts = scripts; 441 442 BX.ajax.processScripts(config.scripts, true); 443 444 445 if (config.onsuccess) 446 { 447 config.onsuccess(result); 448 } 449 450 BX.onCustomEvent(config.xhr, 'onAjaxSuccess', [result, config]); 451 452 if(!config.processScriptsConsecutive) 453 { 454 BX.ajax.processScripts(config.scripts, false, cb); 455 } 456 else 457 { 458 BX.ajax.processScriptsConsecutive(config.scripts, false); 459 cb(); 460 } 461 } 462 catch (e) 463 { 464 if (config.onfailure) 465 config.onfailure("processing", e); 466 BX.onCustomEvent(config.xhr, 'onAjaxFailure', ['processing', e, config]); 467 } 468}; 469 470BX.ajax.processScripts = function(scripts, bRunFirst, cb) 471{ 472 var scriptsExt = [], scriptsInt = ''; 473 474 cb = cb || BX.DoNothing; 475 476 for (var i = 0, length = scripts.length; i < length; i++) 477 { 478 if (typeof bRunFirst != 'undefined' && bRunFirst != !!scripts[i].bRunFirst) 479 continue; 480 481 if (scripts[i].isInternal) 482 scriptsInt += ';' + scripts[i].JS; 483 else 484 scriptsExt.push(scripts[i].JS); 485 } 486 487 scriptsExt = BX.util.array_unique(scriptsExt); 488 489 var l = scriptsExt.length; 490 var l1 = l; 491 var f = scriptsInt.length > 0 ? function() { BX.evalGlobal(scriptsInt); } : BX.DoNothing; 492 493 if (l > 0) 494 { 495 var c = function() { 496 if (--l1 <= 0) 497 { 498 f(); 499 cb(); 500 f = BX.DoNothing; 501 } 502 }; 503 504 for (i=0; i < l; i++) 505 { 506 BX.loadScript(scriptsExt[i], c); 507 } 508 } 509 else 510 { 511 //f();BX.defer(cb)(); 512 f(); 513 cb(); 514 } 515}; 516 517BX.ajax.processScriptsConsecutive = function(scripts, bRunFirst) 518{ 519 for (var i = 0, length = scripts.length; i < length; i++) 520 { 521 if (null != bRunFirst && bRunFirst != !!scripts[i].bRunFirst) 522 continue; 523 524 if (scripts[i].isInternal) 525 { 526 BX.evalGlobal(scripts[i].JS); 527 } 528 else 529 { 530 BX.ajax.loadScriptAjax([scripts[i].JS]); 531 } 532 } 533}; 534 535// TODO: extend this function to use with any data objects or forms 536BX.ajax.prepareData = function(arData, prefix) 537{ 538 var data = ''; 539 if (BX.type.isString(arData)) 540 data = arData; 541 else if (null != arData) 542 { 543 for(var i in arData) 544 { 545 if (arData.hasOwnProperty(i)) 546 { 547 if (data.length > 0) 548 data += '&'; 549 var name = BX.util.urlencode(i); 550 if(prefix)
551 name = prefix + '[' + name + ']'; 552 if(typeof arData[i] == 'object') 553 data += BX.ajax.prepareData(arData[i], name); 554 else 555 data += name + '=' + BX.util.urlencode(arData[i]); 556 } 557 } 558 } 559 return data; 560}; 561 562BX.ajax.xhrSuccess = function(xhr) 563{ 564 return (xhr.status >= 200 && xhr.status < 300) || xhr.status === 304 || xhr.status === 1223 || xhr.status === 0; 565}; 566 567BX.ajax.Setup = function(config, bTemp) 568{ 569 bTemp = !!bTemp; 570 571 for (var i in config) 572 { 573 if (bTemp) 574 tempDefaultConfig[i] = config[i]; 575 else 576 defaultConfig[i] = config[i]; 577 } 578}; 579 580BX.ajax.replaceLocalStorageValue = function(lsId, data, ttl) 581{ 582 if (!!BX.localStorage) 583 BX.localStorage.set('ajax-' + lsId, data, ttl); 584}; 585 586 587BX.ajax._uncache = function(url) 588{ 589 return url + ((url.indexOf('?') !== -1 ? "&" : "?") + '_=' + (new Date()).getTime()); 590}; 591 592/* simple interface */ 593BX.ajax.get = function(url, data, callback) 594{ 595 if (BX.type.isFunction(data)) 596 { 597 callback = data; 598 data = ''; 599 } 600 601 data = BX.ajax.prepareData(data); 602 603 if (data) 604 { 605 url += (url.indexOf('?') !== -1 ? "&" : "?") + data; 606 data = ''; 607 } 608 609 return BX.ajax({ 610 'method': 'GET', 611 'dataType': 'html', 612 'url': url, 613 'data': '', 614 'onsuccess': callback 615 }); 616}; 617 618BX.ajax.getCaptcha = function(callback) 619{ 620 return BX.ajax.loadJSON('/bitrix/tools/ajax_captcha.php', callback); 621}; 622 623BX.ajax.insertToNode = function(url, node) 624{ 625 node = BX(node); 626 if (!!node) 627 { 628 var eventArgs = { cancel: false }; 629 BX.onCustomEvent('onAjaxInsertToNode', [{ url: url, node: node, eventArgs: eventArgs }]); 630 if(eventArgs.cancel === true) 631 { 632 return; 633 } 634 635 var show = null; 636 if (!tempDefaultConfig.denyShowWait) 637 { 638 show = BX.showWait(node); 639 delete tempDefaultConfig.denyShowWait; 640 } 641 642 return BX.ajax.get(url, function(data) { 643 node.innerHTML = data; 644 BX.closeWait(node, show); 645 }); 646 } 647}; 648 649BX.ajax.post = function(url, data, callback) 650{ 651 data = BX.ajax.prepareData(data); 652 653 return BX.ajax({ 654 'method': 'POST', 655 'dataType': 'html', 656 'url': url, 657 'data': data, 658 'onsuccess': callback 659 }); 660}; 661 662/* load and execute external file script with onload emulation */ 663BX.ajax.loadScriptAjax = function(script_src, callback, bPreload) 664{ 665 if (BX.type.isArray(script_src)) 666 { 667 for (var i=0,len=script_src.length;i<len;i++) 668 { 669 BX.ajax.loadScriptAjax(script_src[i], callback, bPreload); 670 } 671 } 672 else 673 { 674 var script_src_test = script_src.replace(/\.js\?.*/, '.js'); 675 676 if (r.script_self.test(script_src_test)) return; 677 if (r.script_self_window.test(script_src_test) && BX.CWindow) return; 678 if (r.script_self_admin.test(script_src_test) && BX.admin) return; 679 680 if (typeof loadedScripts[script_src_test] == 'undefined') 681 { 682 if (!!bPreload) 683 { 684 loadedScripts[script_src_test] = ''; 685 return BX.loadScript(script_src); 686 } 687 else 688 { 689 return BX.ajax({ 690 url: script_src, 691 method: 'GET', 692 dataType: 'script', 693 processData: true, 694 emulateOnload: false, 695 scriptsRunFirst: true, 696 async: false, 697 start: true, 698 onsuccess: function(result) { 699 loadedScripts[script_src_test] = result; 700 if (callback) 701 callback(result); 702 } 703 }); 704 } 705 } 706 else if (callback) 707 { 708 callback(loadedScripts[script_src_test]); 709 } 710 } 711}; 712 713/* non-xhr loadings */ 714BX.ajax.loadJSON = function(url, data, callback, callback_failure) 715{ 716 if (BX.type.isFunction(data)) 717 { 718 callback_failure = callback; 719 callback = data; 720 data = ''; 721 } 722 723 data = BX.ajax.prepareData(data); 724 725 if (data) 726 { 727 url += (url.indexOf('?') !== -1 ? "&" : "?") + data; 728 data = ''; 729 } 730 731 return BX.ajax({ 732 'method': 'GET', 733 'dataType': 'json', 734 'url': url, 735 'onsuccess': callback, 736 'onfailure': callback_failure 737 }); 738}; 739 740/* 741arObs = [{ 742 url: url, 743 type: html|script|json|css, 744 callback: function 745}] 746*/ 747BX.ajax.load = function(arObs, callback) 748{ 749 if (!BX.type.isArray(arObs)) 750 arObs = [arObs]; 751 752 var cnt = 0; 753 754 if (!BX.type.isFunction(callback)) 755 callback = BX.DoNothing; 756 757 var handler = function(data) 758 { 759 if (BX.type.isFunction(this.callback)) 760 this.callback(data); 761 762 if (++cnt >= len) 763 callback(); 764 }; 765 766 for (var i = 0, len = arObs.length; i<len; i++) 767 { 768 switch(arObs[i].type.toUpperCase()) 769 { 770 case 'SCRIPT': 771 BX.loadScript([arObs[i].url], BX.proxy(handler, arObs[i])); 772 break; 773 case 'CSS': 774 BX.loadCSS([arObs[i].url]); 775 776 if (++cnt >= len) 777 callback(); 778 break; 779 case 'JSON': 780 BX.ajax.loadJSON(arObs[i].url, BX.proxy(handler, arObs[i])); 781 break; 782 783 default: 784 BX.ajax.get(arObs[i].url, '', BX.proxy(handler, arObs[i])); 785 break; 786 } 787 } 788}; 789 790/* ajax form sending */ 791BX.ajax.submit = function(obForm, callback) 792{ 793 if (!obForm.target) 794 { 795 if (null == obForm.BXFormTarget) 796 { 797 var frame_name = 'formTarget_' + Math.random(); 798 obForm.BXFormTarget = document.body.appendChild(BX.create('IFRAME', { 799 props: { 800 name: frame_name, 801 id: frame_name, 802 src: 'javascript:void(0)' 803 }, 804 style: { 805 display: 'none' 806 } 807 })); 808 } 809 810 obForm.target = obForm.BXFormTarget.name; 811 } 812 813 obForm.BXFormCallback = callback; 814 BX.bind(obForm.BXFormTarget, 'load', BX.proxy(BX.ajax._submit_callback, obForm)); 815 816 BX.submit(obForm); 817 818 return false;
819}; 820 821BX.ajax.submitComponentForm = function(obForm, container, bWait) 822{ 823 if (!obForm.target) 824 { 825 if (null == obForm.BXFormTarget) 826 { 827 var frame_name = 'formTarget_' + Math.random(); 828 obForm.BXFormTarget = document.body.appendChild(BX.create('IFRAME', { 829 props: { 830 name: frame_name, 831 id: frame_name, 832 src: 'javascript:void(0)' 833 }, 834 style: { 835 display: 'none' 836 } 837 })); 838 } 839 840 obForm.target = obForm.BXFormTarget.name; 841 } 842 843 if (!!bWait) 844 var w = BX.showWait(container); 845 846 obForm.BXFormCallback = function(d) { 847 if (!!bWait) 848 BX.closeWait(w); 849 850 var callOnload = function(){ 851 if(!!window.bxcompajaxframeonload) 852 { 853 setTimeout(function(){window.bxcompajaxframeonload();window.bxcompajaxframeonload=null;}, 10); 854 } 855 }; 856 857 BX(container).innerHTML = d; 858 BX.onCustomEvent('onAjaxSuccess', [null,null,callOnload]); 859 }; 860 861 BX.bind(obForm.BXFormTarget, 'load', BX.proxy(BX.ajax._submit_callback, obForm)); 862 863 return true; 864}; 865 866// func will be executed in form context 867BX.ajax._submit_callback = function() 868{ 869 //opera and IE8 triggers onload event even on empty iframe 870 try 871 { 872 if(this.BXFormTarget.contentWindow.location.href.indexOf('http') != 0) 873 return; 874 } catch (e) { 875 return; 876 } 877 878 if (this.BXFormCallback) 879 this.BXFormCallback.apply(this, [this.BXFormTarget.contentWindow.document.body.innerHTML]); 880 881 BX.unbindAll(this.BXFormTarget); 882}; 883 884BX.ajax.prepareForm = function(obForm, data) 885{ 886 data = (!!data ? data : {}); 887 var i, ii, el, 888 _data = [], 889 n = obForm.elements.length, 890 files = 0, length = 0; 891 if(!!obForm) 892 { 893 for (i = 0; i < n; i++) 894 { 895 el = obForm.elements[i]; 896 if (el.disabled) 897 continue; 898 switch(el.type.toLowerCase()) 899 { 900 case 'text': 901 case 'textarea': 902 case 'password': 903 case 'hidden': 904 case 'select-one': 905 _data.push({name: el.name, value: el.value}); 906 length += (el.name.length + el.value.length); 907 break; 908 case 'file': 909 if (!!el.files) 910 { 911 for (ii = 0; ii < el.files.length; ii++) 912 { 913 files++; 914 _data.push({name: el.name, value: el.files[ii], file : true}); 915 length += el.files[ii].size; 916 } 917 } 918 break; 919 case 'radio': 920 case 'checkbox': 921 if(el.checked) 922 { 923 _data.push({name: el.name, value: el.value}); 924 length += (el.name.length + el.value.length); 925 } 926 break; 927 case 'select-multiple': 928 for (var j = 0; j < el.options.length; j++) 929 { 930 if (el.options[j].selected) 931 { 932 _data.push({name : el.name, value : el.options[j].value}); 933 length += (el.name.length + el.options[j].length); 934 } 935 } 936 break; 937 default: 938 break; 939 } 940 } 941 942 i = 0; length = 0; 943 var current = data; 944 945 while(i < _data.length) 946 { 947 var p = _data[i].name.indexOf('['); 948 if (p == -1) { 949 current[_data[i].name] = _data[i].value; 950 current = data; 951 i++; 952 } 953 else 954 { 955 var name = _data[i].name.substring(0, p); 956 var rest = _data[i].name.substring(p+1); 957 if(!current[name]) 958 current[name] = []; 959 960 var pp = rest.indexOf(']'); 961 if(pp == -1) 962 { 963 current = data; 964 i++; 965 } 966 else if(pp == 0) 967 { 968 //No index specified - so take the next integer 969 current = current[name]; 970 _data[i].name = '' + current.length; 971 } 972 else 973 { 974 //Now index name becomes and name and we go deeper into the array 975 current = current[name]; 976 _data[i].name = rest.substring(0, pp) + rest.substring(pp+1); 977 } 978 } 979 } 980 } 981 return {data : data, filesCount : files, roughSize : length}; 982}; 983BX.ajax.submitAjax = function(obForm, config) 984{ 985 config = (!!config && typeof config == "object" ? config : {}); 986 config.url = (config["url"] || obForm.getAttribute("action")); 987 config.data = BX.ajax.prepareForm(obForm).data; 988 989 if (!window["FormData"]) 990 { 991 BX.ajax(config); 992 } 993 else 994 { 995 var isFile = function(item) 996 { 997 var res = Object.prototype.toString.call(item); 998 return (res == '[object File]' || res == '[object Blob]'); 999 }, 1000 appendToForm = function(fd, key, val) 1001 { 1002 if (!!val && typeof val == "object" && !isFile(val)) 1003 { 1004 for (var ii in val) 1005 { 1006 if (val.hasOwnProperty(ii)) 1007 { 1008 appendToForm(fd, (key == '' ? ii : key + '[' + ii + ']'), val[ii]); 1009 } 1010 } 1011 } 1012 else 1013 fd.append(key, (!!val ? val : '')); 1014 }, 1015 prepareData = function(arData) 1016 { 1017 var data = {}; 1018 if (null != arData) 1019 { 1020 if(typeof arData == 'object') 1021 { 1022 for(var i in arData) 1023 { 1024 if (arData.hasOwnProperty(i)) 1025 { 1026 var name = BX.util.urlencode(i); 1027 if(typeof arData[i] == 'object' && arData[i]["file"] !== true) 1028 data[name] = prepareData(arData[i]); 1029 else if (arData[i]["file"] === true) 1030 data[name] = arData[i]["value"]; 1031 else 1032 data[name] = BX.util.urlencode(arData[i]); 1033 } 1034 } 1035 } 1036 else 1037 data = BX.util.urlencode(arData); 1038 } 1039 return data; 1040 }, 1041 fd = new window.FormData(); 1042 1043 if (config.method !== 'POST') 1044 {
1045 config.data = BX.ajax.prepareData(config.data); 1046 if (config.data) 1047 { 1048 config.url += (config.url.indexOf('?') !== -1 ? "&" : "?") + config.data; 1049 config.data = ''; 1050 } 1051 } 1052 else 1053 { 1054 if (config.preparePost === true) 1055 config.data = prepareData(config.data); 1056 appendToForm(fd, '', config.data); 1057 config.data = fd; 1058 } 1059 1060 config.preparePost = false; 1061 config.start = false; 1062 1063 var xhr = BX.ajax(config); 1064 if (!!config["onprogress"]) 1065 xhr.upload.addEventListener( 1066 'progress', 1067 function(e){ 1068 var percent = null; 1069 if(e.lengthComputable && (e.total || e["totalSize"])) { 1070 percent = e.loaded * 100 / (e.total || e["totalSize"]); 1071 } 1072 config["onprogress"](e, percent); 1073 } 1074 ); 1075 xhr.send(fd); 1076 } 1077}; 1078 1079BX.ajax.UpdatePageData = function (arData) 1080{ 1081 if (arData.TITLE) 1082 BX.ajax.UpdatePageTitle(arData.TITLE); 1083 if (arData.WINDOW_TITLE || arData.TITLE) 1084 BX.ajax.UpdateWindowTitle(arData.WINDOW_TITLE || arData.TITLE); 1085 if (arData.NAV_CHAIN) 1086 BX.ajax.UpdatePageNavChain(arData.NAV_CHAIN); 1087 if (arData.CSS && arData.CSS.length > 0) 1088 BX.loadCSS(arData.CSS); 1089 if (arData.SCRIPTS && arData.SCRIPTS.length > 0) 1090 { 1091 var f = function(result,config,cb){ 1092 1093 if(!!config && BX.type.isArray(config.scripts)) 1094 { 1095 for(var i=0,l=arData.SCRIPTS.length;i<l;i++) 1096 { 1097 config.scripts.push({isInternal:false,JS:arData.SCRIPTS[i]}); 1098 } 1099 } 1100 else 1101 { 1102 BX.loadScript(arData.SCRIPTS,cb); 1103 } 1104 1105 BX.removeCustomEvent('onAjaxSuccess',f); 1106 }; 1107 BX.addCustomEvent('onAjaxSuccess',f); 1108 } 1109 else 1110 { 1111 var f1 = function(result,config,cb){ 1112 if(BX.type.isFunction(cb)) 1113 { 1114 cb(); 1115 } 1116 BX.removeCustomEvent('onAjaxSuccess',f1); 1117 }; 1118 BX.addCustomEvent('onAjaxSuccess', f1); 1119 } 1120}; 1121 1122BX.ajax.UpdatePageTitle = function(title) 1123{ 1124 var obTitle = BX('pagetitle'); 1125 if (obTitle) 1126 { 1127 obTitle.removeChild(obTitle.firstChild); 1128 if (!obTitle.firstChild) 1129 obTitle.appendChild(document.createTextNode(title)); 1130 else 1131 obTitle.insertBefore(document.createTextNode(title), obTitle.firstChild); 1132 } 1133}; 1134 1135BX.ajax.UpdateWindowTitle = function(title) 1136{ 1137 document.title = title; 1138}; 1139 1140BX.ajax.UpdatePageNavChain = function(nav_chain) 1141{ 1142 var obNavChain = BX('navigation'); 1143 if (obNavChain) 1144 { 1145 obNavChain.innerHTML = nav_chain; 1146 } 1147}; 1148 1149/* user options handling */ 1150BX.userOptions = { 1151 options: null, 1152 bSend: false, 1153 delay: 5000, 1154 path: '/bitrix/admin/user_options.php?' 1155}; 1156 1157BX.userOptions.setAjaxPath = function(url) 1158{ 1159 BX.userOptions.path = url.indexOf('?') == -1? url+'?': url+'&'; 1160} 1161BX.userOptions.save = function(sCategory, sName, sValName, sVal, bCommon) 1162{ 1163 if (null == BX.userOptions.options) 1164 BX.userOptions.options = {}; 1165 1166 bCommon = !!bCommon; 1167 BX.userOptions.options[sCategory+'.'+sName+'.'+sValName] = [sCategory, sName, sValName, sVal, bCommon]; 1168 1169 var sParam = BX.userOptions.__get(); 1170 if (sParam != '') 1171 document.cookie = BX.message('COOKIE_PREFIX')+"_LAST_SETTINGS=" + sParam + "&sessid="+BX.bitrix_sessid()+"; expires=Thu, 31 Dec 2020 23:59:59 GMT; path=/;"; 1172 1173 if(!BX.userOptions.bSend) 1174 { 1175 BX.userOptions.bSend = true; 1176 setTimeout(function(){BX.userOptions.send(null)}, BX.userOptions.delay); 1177 } 1178}; 1179 1180BX.userOptions.send = function(callback) 1181{ 1182 var sParam = BX.userOptions.__get(); 1183 BX.userOptions.options = null; 1184 BX.userOptions.bSend = false; 1185 1186 if (sParam != '') 1187 { 1188 document.cookie = BX.message('COOKIE_PREFIX') + "_LAST_SETTINGS=; path=/;"; 1189 BX.ajax({ 1190 'method': 'GET', 1191 'dataType': 'html', 1192 'processData': false, 1193 'cache': false, 1194 'url': BX.userOptions.path+sParam+'&sessid='+BX.bitrix_sessid(), 1195 'onsuccess': callback 1196 }); 1197 } 1198}; 1199 1200BX.userOptions.del = function(sCategory, sName, bCommon, callback) 1201{ 1202 BX.ajax.get(BX.userOptions.path+'action=delete&c='+sCategory+'&n='+sName+(bCommon == true? '&common=Y':'')+'&sessid='+BX.bitrix_sessid(), callback); 1203}; 1204 1205BX.userOptions.__get = function() 1206{ 1207 if (!BX.userOptions.options) return ''; 1208 1209 var sParam = '', n = -1, prevParam = '', aOpt, i; 1210 1211 for (i in BX.userOptions.options) 1212 { 1213 if(BX.userOptions.options.hasOwnProperty(i)) 1214 { 1215 aOpt = BX.userOptions.options[i]; 1216 1217 if (prevParam != aOpt[0]+'.'+aOpt[1]) 1218 { 1219 n++; 1220 sParam += '&p['+n+'][c]='+BX.util.urlencode(aOpt[0]); 1221 sParam += '&p['+n+'][n]='+BX.util.urlencode(aOpt[1]); 1222 if (aOpt[4] == true) 1223 sParam += '&p['+n+'][d]=Y'; 1224 prevParam = aOpt[0]+'.'+aOpt[1]; 1225 } 1226 1227 sParam += '&p['+n+'][v]['+BX.util.urlencode(aOpt[2])+']='+BX.util.urlencode(aOpt[3]); 1228 } 1229 } 1230 1231 return sParam.substr(1); 1232}; 1233 1234BX.ajax.history = { 1235 expected_hash: '', 1236 1237 obParams: null, 1238 1239 obFrame: null, 1240 obImage: null, 1241 1242 obTimer: null, 1243 1244 bInited: false, 1245 bHashCollision: false, 1246 bPushState: !!(history.pushState && BX.type.isFunction(history.pushState)), 1247 1248 startState: null, 1249 1250 init: function(obParams) 1251 { 1252 if (BX.ajax.history.bInited) 1253 return; 1254 1255 this.obParams = obParams; 1256 var obCurrentState = this.obParams.getState(); 1257 1258 if (BX.ajax.history.bPushState) 1259 { 1260 BX.ajax.history.expected_hash = window.location.pathname; 1261 if (window.location.search) 1262 BX.ajax.history.expected_hash += window.location.search; 1263 1264 BX.ajax.history.put(obCurrentState, BX.ajax.history.expected_hash, '', true); 1265 // due to some strange thing, chrome calls popstate event on page start. so we should delay it
1266 setTimeout(function(){BX.bind(window, 'popstate', BX.ajax.history.__hashListener);}, 500); 1267 } 1268 else 1269 { 1270 BX.ajax.history.expected_hash = window.location.hash; 1271 1272 if (!BX.ajax.history.expected_hash || BX.ajax.history.expected_hash == '#') 1273 BX.ajax.history.expected_hash = '__bx_no_hash__'; 1274 1275 jsAjaxHistoryContainer.put(BX.ajax.history.expected_hash, obCurrentState); 1276 BX.ajax.history.obTimer = setTimeout(BX.ajax.history.__hashListener, 500); 1277 1278 if (BX.browser.IsIE()) 1279 { 1280 BX.ajax.history.obFrame = document.createElement('IFRAME'); 1281 BX.hide_object(BX.ajax.history.obFrame); 1282 1283 document.body.appendChild(BX.ajax.history.obFrame); 1284 1285 BX.ajax.history.obFrame.contentWindow.document.open(); 1286 BX.ajax.history.obFrame.contentWindow.document.write(BX.ajax.history.expected_hash); 1287 BX.ajax.history.obFrame.contentWindow.document.close(); 1288 } 1289 else if (BX.browser.IsOpera()) 1290 { 1291 BX.ajax.history.obImage = document.createElement('IMG'); 1292 BX.hide_object(BX.ajax.history.obImage); 1293 1294 document.body.appendChild(BX.ajax.history.obImage); 1295 1296 BX.ajax.history.obImage.setAttribute('src', 'javascript:location.href = \'javascript:BX.ajax.history.__hashListener();\';'); 1297 } 1298 } 1299 1300 BX.ajax.history.bInited = true; 1301 }, 1302 1303 __hashListener: function(e) 1304 { 1305 e = e || window.event || {state:false}; 1306 1307 if (BX.ajax.history.bPushState) 1308 { 1309 BX.ajax.history.obParams.setState(e.state||BX.ajax.history.startState); 1310 } 1311 else 1312 { 1313 if (BX.ajax.history.obTimer) 1314 { 1315 window.clearTimeout(BX.ajax.history.obTimer); 1316 BX.ajax.history.obTimer = null; 1317 } 1318 1319 var current_hash; 1320 if (null != BX.ajax.history.obFrame) 1321 current_hash = BX.ajax.history.obFrame.contentWindow.document.body.innerText; 1322 else 1323 current_hash = window.location.hash; 1324 1325 if (!current_hash || current_hash == '#') 1326 current_hash = '__bx_no_hash__'; 1327 1328 if (current_hash.indexOf('#') == 0) 1329 current_hash = current_hash.substring(1); 1330 1331 if (current_hash != BX.ajax.history.expected_hash) 1332 { 1333 var state = jsAjaxHistoryContainer.get(current_hash); 1334 if (state) 1335 { 1336 BX.ajax.history.obParams.setState(state); 1337 1338 BX.ajax.history.expected_hash = current_hash; 1339 if (null != BX.ajax.history.obFrame) 1340 { 1341 var __hash = current_hash == '__bx_no_hash__' ? '' : current_hash; 1342 if (window.location.hash != __hash && window.location.hash != '#' + __hash) 1343 window.location.hash = __hash; 1344 } 1345 } 1346 } 1347 1348 BX.ajax.history.obTimer = setTimeout(BX.ajax.history.__hashListener, 500); 1349 } 1350 }, 1351 1352 put: function(state, new_hash, new_hash1, bStartState) 1353 { 1354 if (this.bPushState) 1355 { 1356 if(!bStartState) 1357 { 1358 history.pushState(state, '', new_hash); 1359 } 1360 else 1361 { 1362 BX.ajax.history.startState = state; 1363 } 1364 } 1365 else 1366 { 1367 if (typeof new_hash1 != 'undefined') 1368 new_hash = new_hash1; 1369 else 1370 new_hash = 'view' + new_hash; 1371 1372 jsAjaxHistoryContainer.put(new_hash, state); 1373 BX.ajax.history.expected_hash = new_hash; 1374 1375 window.location.hash = BX.util.urlencode(new_hash); 1376 1377 if (null != BX.ajax.history.obFrame) 1378 { 1379 BX.ajax.history.obFrame.contentWindow.document.open(); 1380 BX.ajax.history.obFrame.contentWindow.document.write(new_hash); 1381 BX.ajax.history.obFrame.contentWindow.document.close(); 1382 } 1383 } 1384 }, 1385 1386 checkRedirectStart: function(param_name, param_value) 1387 { 1388 var current_hash = window.location.hash; 1389 if (current_hash.substring(0, 1) == '#') current_hash = current_hash.substring(1); 1390 1391 var test = current_hash.substring(0, 5); 1392 if (test == 'view/' || test == 'view%') 1393 { 1394 BX.ajax.history.bHashCollision = true;
1395 document.write('<' + 'div id="__ajax_hash_collision_' + param_value + '" style="display: none;">'); 1396 } 1397 }, 1398 1399 checkRedirectFinish: function(param_name, param_value) 1400 { 1401 document.write('</div>'); 1402 1403 var current_hash = window.location.hash; 1404 if (current_hash.substring(0, 1) == '#') current_hash = current_hash.substring(1); 1405 1406 BX.ready(function () 1407 { 1408 var test = current_hash.substring(0, 5); 1409 if (test == 'view/' || test == 'view%') 1410 { 1411 var obColNode = BX('__ajax_hash_collision_' + param_value); 1412 var obNode = obColNode.firstChild; 1413 BX.cleanNode(obNode); 1414 obColNode.style.display = 'block'; 1415 1416 // IE, Opera and Chrome automatically modifies hash with urlencode, but FF doesn't ;-( 1417 if (test != 'view%') 1418 current_hash = BX.util.urlencode(current_hash); 1419 1420 current_hash += (current_hash.indexOf('%3F') == -1 ? '%3F' : '%26') + param_name + '=' + param_value; 1421 1422 var url = '/bitrix/tools/ajax_redirector.php?hash=' + current_hash; 1423 1424 BX.ajax.insertToNode(url, obNode); 1425 } 1426 }); 1427 } 1428}; 1429 1430BX.ajax.component = function(node) 1431{ 1432 this.node = node; 1433}; 1434 1435BX.ajax.component.prototype.getState = function() 1436{ 1437 var state = { 1438 'node': this.node, 1439 'title': window.document.title, 1440 'data': BX(this.node).innerHTML 1441 }; 1442 1443 var obNavChain = BX('navigation'); 1444 if (null != obNavChain) 1445 state.nav_chain = obNavChain.innerHTML; 1446 1447 return state; 1448}; 1449 1450BX.ajax.component.prototype.setState = function(state) 1451{ 1452 BX(state.node).innerHTML = state.data; 1453 BX.ajax.UpdatePageTitle(state.title); 1454 1455 if (state.nav_chain) 1456 BX.ajax.UpdatePageNavChain(state.nav_chain); 1457}; 1458 1459var jsAjaxHistoryContainer = { 1460 arHistory: {}, 1461 1462 put: function(hash, state) 1463 { 1464 this.arHistory[hash] = state; 1465 }, 1466 1467 get: function(hash) 1468 { 1469 return this.arHistory[hash]; 1470 } 1471}; 1472 1473 1474BX.ajax.FormData = function() 1475{ 1476 this.elements = []; 1477 this.files = []; 1478 this.features = {}; 1479 this.isSupported(); 1480 this.log('BX FormData init'); 1481}; 1482 1483BX.ajax.FormData.isSupported = function() 1484{ 1485 var f = new BX.ajax.FormData(); 1486 var result = f.features.supported; 1487 f = null; 1488 return result; 1489}; 1490 1491BX.ajax.FormData.prototype.log = function(o) 1492{ 1493 if (false) { 1494 try { 1495 if (BX.browser.IsIE()) o = JSON.stringify(o); 1496 console.log(o); 1497 } catch(e) {} 1498 } 1499}; 1500 1501BX.ajax.FormData.prototype.isSupported = function() 1502{ 1503 var f = {}; 1504 f.fileReader = (window.FileReader && window.FileReader.prototype.readAsBinaryString); 1505 f.readFormData = f.sendFormData = !!(window.FormData); 1506 f.supported = !!(f.readFormData && f.sendFormData); 1507 this.features = f; 1508 this.log('features:'); 1509 this.log(f); 1510 1511 return f.supported; 1512}; 1513 1514BX.ajax.FormData.prototype.append = function(name, value) 1515{ 1516 if (typeof(value) === 'object') { // seems to be files element 1517 this.files.push({'name': name, 'value':value}); 1518 } else { 1519 this.elements.push({'name': name, 'value':value}); 1520 } 1521}; 1522 1523BX.ajax.FormData.prototype.send = function(url, callbackOk, callbackProgress, callbackError) 1524{ 1525 this.log('FD send'); 1526 this.xhr = BX.ajax({ 1527 'method': 'POST', 1528 'dataType': 'html', 1529 'url': url, 1530 'onsuccess': callbackOk, 1531 'onfailure': callbackError, 1532 'start': false, 1533 'preparePost':false 1534 }); 1535 1536 if (callbackProgress) 1537 { 1538 this.xhr.upload.addEventListener( 1539 'progress', 1540 function(e) { 1541 if (e.lengthComputable) 1542 callbackProgress(e.loaded / (e.total || e.totalSize)); 1543 }, 1544 false 1545 ); 1546 } 1547 1548 if (this.features.readFormData && this.features.sendFormData) 1549 { 1550 var fd = new FormData(); 1551 this.log('use browser formdata'); 1552 for (var i in this.elements) 1553 { 1554 if(this.elements.hasOwnProperty(i)) 1555 fd.append(this.elements[i].name,this.elements[i].value); 1556 } 1557 for (i in this.files) 1558 { 1559 if(this.files.hasOwnProperty(i)) 1560 fd.append(this.files[i].name, this.files[i].value); 1561 } 1562 this.xhr.send(fd); 1563 } 1564 1565 return this.xhr; 1566}; 1567 1568BX.addCustomEvent('onAjaxFailure', BX.debug); 1569})(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.