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