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/* load and execute external file script with onload emulation */ 653BX.ajax.loadScriptAjax = function(script_src, callback, bPreload) 654{ 655 if (BX.type.isArray(script_src)) 656 { 657 for (var i=0,len=script_src.length;i<len;i++) 658 { 659 BX.ajax.loadScriptAjax(script_src[i], callback, bPreload); 660 } 661 } 662 else 663 { 664 var script_src_test = script_src.replace(/\.js\?.*/, '.js'); 665 666 if (r.script_self.test(script_src_test)) return; 667 if (r.script_self_window.test(script_src_test) && BX.CWindow) return; 668 if (r.script_self_admin.test(script_src_test) && BX.admin) return; 669 670 if (typeof loadedScripts[script_src_test] == 'undefined') 671 { 672 if (!!bPreload) 673 { 674 loadedScripts[script_src_test] = ''; 675 return BX.loadScript(script_src); 676 } 677 else 678 { 679 return BX.ajax({ 680 url: script_src, 681 method: 'GET', 682 dataType: 'script', 683 processData: true, 684 emulateOnload: false, 685 scriptsRunFirst: true, 686 async: false, 687 start: true, 688 onsuccess: function(result) { 689 loadedScripts[script_src_test] = result; 690 if (callback) 691 callback(result); 692 } 693 }); 694 } 695 } 696 else if (callback) 697 { 698 callback(loadedScripts[script_src_test]); 699 } 700 } 701}; 702 703/* non-xhr loadings */ 704BX.ajax.loadJSON = function(url, data, callback, callback_failure) 705{ 706 if (BX.type.isFunction(data)) 707 { 708 callback_failure = callback; 709 callback = data; 710 data = ''; 711 } 712 713 data = BX.ajax.prepareData(data); 714 715 if (data) 716 { 717 url += (url.indexOf('?') !== -1 ? "&" : "?") + data; 718 data = ''; 719 } 720 721 return BX.ajax({ 722 'method': 'GET', 723 'dataType': 'json', 724 'url': url, 725 'onsuccess': callback, 726 'onfailure': callback_failure 727 }); 728}; 729 730/* 731arObs = [{ 732 url: url, 733 type: html|script|json|css, 734 callback: function 735}] 736*/ 737BX.ajax.load = function(arObs, callback) 738{ 739 if (!BX.type.isArray(arObs)) 740 arObs = [arObs]; 741 742 var cnt = 0; 743 744 if (!BX.type.isFunction(callback)) 745 callback = BX.DoNothing; 746 747 var handler = function(data) 748 { 749 if (BX.type.isFunction(this.callback)) 750 this.callback(data); 751 752 if (++cnt >= len) 753 callback(); 754 }; 755 756 for (var i = 0, len = arObs.length; i<len; i++) 757 { 758 switch(arObs[i].type.toUpperCase()) 759 { 760 case 'SCRIPT': 761 BX.loadScript([arObs[i].url], BX.proxy(handler, arObs[i])); 762 break; 763 case 'CSS': 764 BX.loadCSS([arObs[i].url]); 765 766 if (++cnt >= len) 767 callback(); 768 break; 769 case 'JSON': 770 BX.ajax.loadJSON(arObs[i].url, BX.proxy(handler, arObs[i])); 771 break; 772 773 default: 774 BX.ajax.get(arObs[i].url, '', BX.proxy(handler, arObs[i])); 775 break; 776 } 777 } 778}; 779 780/* ajax form sending */ 781BX.ajax.submit = function(obForm, callback) 782{ 783 if (!obForm.target) 784 { 785 if (null == obForm.BXFormTarget) 786 { 787 var frame_name = 'formTarget_' + Math.random(); 788 obForm.BXFormTarget = document.body.appendChild(BX.create('IFRAME', { 789 props: { 790 name: frame_name, 791 id: frame_name, 792 src: 'javascript:void(0)' 793 }, 794 style: { 795 display: 'none' 796 } 797 })); 798 } 799 800 obForm.target = obForm.BXFormTarget.name; 801 } 802 803 obForm.BXFormCallback = callback; 804 BX.bind(obForm.BXFormTarget, 'load', BX.proxy(BX.ajax._submit_callback, obForm)); 805 806 BX.submit(obForm); 807 808 return false;
809}; 810 811BX.ajax.submitComponentForm = function(obForm, container, bWait) 812{ 813 if (!obForm.target) 814 { 815 if (null == obForm.BXFormTarget) 816 { 817 var frame_name = 'formTarget_' + Math.random(); 818 obForm.BXFormTarget = document.body.appendChild(BX.create('IFRAME', { 819 props: { 820 name: frame_name, 821 id: frame_name, 822 src: 'javascript:void(0)' 823 }, 824 style: { 825 display: 'none' 826 } 827 })); 828 } 829 830 obForm.target = obForm.BXFormTarget.name; 831 } 832 833 if (!!bWait) 834 var w = BX.showWait(container); 835 836 obForm.BXFormCallback = function(d) { 837 if (!!bWait) 838 BX.closeWait(w); 839 840 var callOnload = function(){ 841 if(!!window.bxcompajaxframeonload) 842 { 843 setTimeout(function(){window.bxcompajaxframeonload();window.bxcompajaxframeonload=null;}, 10); 844 } 845 }; 846 847 BX(container).innerHTML = d; 848 BX.onCustomEvent('onAjaxSuccess', [null,null,callOnload]); 849 }; 850 851 BX.bind(obForm.BXFormTarget, 'load', BX.proxy(BX.ajax._submit_callback, obForm)); 852 853 return true; 854}; 855 856// func will be executed in form context 857BX.ajax._submit_callback = function() 858{ 859 //opera and IE8 triggers onload event even on empty iframe 860 try 861 { 862 if(this.BXFormTarget.contentWindow.location.href.indexOf('http') != 0) 863 return; 864 } catch (e) { 865 return; 866 } 867 868 if (this.BXFormCallback) 869 this.BXFormCallback.apply(this, [this.BXFormTarget.contentWindow.document.body.innerHTML]); 870 871 BX.unbindAll(this.BXFormTarget); 872}; 873 874BX.ajax.prepareForm = function(obForm, data) 875{ 876 data = (!!data ? data : {}); 877 var i, ii, el, 878 _data = [], 879 n = obForm.elements.length, 880 files = 0, length = 0; 881 if(!!obForm) 882 { 883 for (i = 0; i < n; i++) 884 { 885 el = obForm.elements[i]; 886 if (el.disabled) 887 continue; 888 889 if(!el.type) 890 continue; 891 892 switch(el.type.toLowerCase()) 893 { 894 case 'text': 895 case 'textarea': 896 case 'password': 897 case 'number': 898 case 'hidden': 899 case 'select-one': 900 _data.push({name: el.name, value: el.value}); 901 length += (el.name.length + el.value.length); 902 break; 903 case 'file': 904 if (!!el.files) 905 { 906 for (ii = 0; ii < el.files.length; ii++) 907 { 908 files++; 909 _data.push({name: el.name, value: el.files[ii], file : true}); 910 length += el.files[ii].size; 911 } 912 } 913 break; 914 case 'radio': 915 case 'checkbox': 916 if(el.checked) 917 { 918 _data.push({name: el.name, value: el.value}); 919 length += (el.name.length + el.value.length); 920 } 921 break; 922 case 'select-multiple': 923 for (var j = 0; j < el.options.length; j++) 924 { 925 if (el.options[j].selected) 926 { 927 _data.push({name : el.name, value : el.options[j].value}); 928 length += (el.name.length + el.options[j].length); 929 } 930 } 931 break; 932 default: 933 break; 934 } 935 } 936 937 i = 0; length = 0; 938 var current = data, name, rest, pp; 939 940 while(i < _data.length) 941 { 942 var p = _data[i].name.indexOf('['); 943 if (p == -1) { 944 current[_data[i].name] = _data[i].value; 945 current = data; 946 i++; 947 } 948 else 949 { 950 name = _data[i].name.substring(0, p); 951 rest = _data[i].name.substring(p+1); 952 pp = rest.indexOf(']'); 953 954 if(pp == -1) 955 { 956 if (!current[name]) 957 current[name] = []; 958 current = data; 959 i++; 960 } 961 else if(pp == 0) 962 { 963 if (!current[name]) 964 current[name] = []; 965 //No index specified - so take the next integer 966 current = current[name]; 967 _data[i].name = '' + current.length; 968 } 969 else 970 { 971 if (!current[name]) 972 current[name] = {}; 973 //Now index name becomes and name and we go deeper into the array 974 current = current[name]; 975 _data[i].name = rest.substring(0, pp) + rest.substring(pp+1); 976 } 977 } 978 } 979 } 980 return {data : data, filesCount : files, roughSize : length}; 981}; 982BX.ajax.submitAjax = function(obForm, config) 983{ 984 config = (config !== null && typeof config == "object" ? config : {}); 985 config.url = (config["url"] || obForm.getAttribute("action")); 986 config.data = BX.ajax.prepareForm(obForm).data; 987 988 if (!window["FormData"]) 989 { 990 BX.ajax(config); 991 } 992 else 993 { 994 var isFile = function(item) 995 { 996 var res = Object.prototype.toString.call(item); 997 return (res == '[object File]' || res == '[object Blob]'); 998 }, 999 appendToForm = function(fd, key, val) 1000 { 1001 if (!!val && typeof val == "object" && !isFile(val)) 1002 { 1003 for (var ii in val) 1004 { 1005 if (val.hasOwnProperty(ii)) 1006 { 1007 appendToForm(fd, (key == '' ? ii : key + '[' + ii + ']'), val[ii]); 1008 } 1009 } 1010 } 1011 else 1012 fd.append(key, (!!val ? val : '')); 1013 }, 1014 prepareData = function(arData) 1015 { 1016 var data = {}; 1017 if (null != arData) 1018 { 1019 if(typeof arData == 'object') 1020 { 1021 for(var i in arData) 1022 { 1023 if (arData.hasOwnProperty(i)) 1024 { 1025 var name = BX.util.urlencode(i); 1026 if(typeof arData[i] == 'object' && arData[i]["file"] !== true) 1027 data[name] = prepareData(arData[i]); 1028 else if (arData[i]["file"] === true) 1029 data[name] = arData[i]["value"]; 1030 else 1031 data[name] = BX.util.urlencode(arData[i]); 1032 } 1033 } 1034 } 1035 else 1036 data = BX.util.urlencode(arData); 1037 } 1038 return data; 1039 }, 1040 fd = new window.FormData(); 1041 1042 if (config.method !== 'POST') 1043 {
1044 config.data = BX.ajax.prepareData(config.data); 1045 if (config.data) 1046 { 1047 config.url += (config.url.indexOf('?') !== -1 ? "&" : "?") + config.data; 1048 config.data = ''; 1049 } 1050 } 1051 else 1052 { 1053 if (config.preparePost === true) 1054 config.data = prepareData(config.data); 1055 appendToForm(fd, '', config.data); 1056 config.data = fd; 1057 } 1058 1059 config.preparePost = false; 1060 config.start = false; 1061 1062 var xhr = BX.ajax(config); 1063 if (!!config["onprogress"]) 1064 xhr.upload.addEventListener( 1065 'progress', 1066 function(e){ 1067 var percent = null; 1068 if(e.lengthComputable && (e.total || e["totalSize"])) { 1069 percent = e.loaded * 100 / (e.total || e["totalSize"]); 1070 } 1071 config["onprogress"](e, percent); 1072 } 1073 ); 1074 xhr.send(fd); 1075 } 1076}; 1077 1078BX.ajax.UpdatePageData = function (arData) 1079{ 1080 if (arData.TITLE) 1081 BX.ajax.UpdatePageTitle(arData.TITLE); 1082 if (arData.WINDOW_TITLE || arData.TITLE) 1083 BX.ajax.UpdateWindowTitle(arData.WINDOW_TITLE || arData.TITLE); 1084 if (arData.NAV_CHAIN) 1085 BX.ajax.UpdatePageNavChain(arData.NAV_CHAIN); 1086 if (arData.CSS && arData.CSS.length > 0) 1087 BX.loadCSS(arData.CSS); 1088 if (arData.SCRIPTS && arData.SCRIPTS.length > 0) 1089 { 1090 var f = function(result,config,cb){ 1091 1092 if(!!config && BX.type.isArray(config.scripts)) 1093 { 1094 for(var i=0,l=arData.SCRIPTS.length;i<l;i++) 1095 { 1096 config.scripts.push({isInternal:false,JS:arData.SCRIPTS[i]}); 1097 } 1098 } 1099 else 1100 { 1101 BX.loadScript(arData.SCRIPTS,cb); 1102 } 1103 1104 BX.removeCustomEvent('onAjaxSuccess',f); 1105 }; 1106 BX.addCustomEvent('onAjaxSuccess',f); 1107 } 1108 else 1109 { 1110 var f1 = function(result,config,cb){ 1111 if(BX.type.isFunction(cb)) 1112 { 1113 cb(); 1114 } 1115 BX.removeCustomEvent('onAjaxSuccess',f1); 1116 }; 1117 BX.addCustomEvent('onAjaxSuccess', f1); 1118 } 1119}; 1120 1121BX.ajax.UpdatePageTitle = function(title) 1122{ 1123 var obTitle = BX('pagetitle'); 1124 if (obTitle) 1125 { 1126 obTitle.removeChild(obTitle.firstChild); 1127 if (!obTitle.firstChild) 1128 obTitle.appendChild(document.createTextNode(title)); 1129 else 1130 obTitle.insertBefore(document.createTextNode(title), obTitle.firstChild); 1131 } 1132}; 1133 1134BX.ajax.UpdateWindowTitle = function(title) 1135{ 1136 document.title = title; 1137}; 1138 1139BX.ajax.UpdatePageNavChain = function(nav_chain) 1140{ 1141 var obNavChain = BX('navigation'); 1142 if (obNavChain) 1143 { 1144 obNavChain.innerHTML = nav_chain; 1145 } 1146}; 1147 1148/* user options handling */ 1149BX.userOptions = { 1150 options: null, 1151 bSend: false, 1152 delay: 5000, 1153 path: '/bitrix/admin/user_options.php?' 1154}; 1155 1156BX.userOptions.setAjaxPath = function(url) 1157{ 1158 BX.userOptions.path = url.indexOf('?') == -1? url+'?': url+'&'; 1159} 1160BX.userOptions.save = function(sCategory, sName, sValName, sVal, bCommon) 1161{ 1162 if (null == BX.userOptions.options) 1163 BX.userOptions.options = {}; 1164 1165 bCommon = !!bCommon; 1166 BX.userOptions.options[sCategory+'.'+sName+'.'+sValName] = [sCategory, sName, sValName, sVal, bCommon]; 1167 1168 var sParam = BX.userOptions.__get(); 1169 if (sParam != '') 1170 document.cookie = BX.message('COOKIE_PREFIX')+"_LAST_SETTINGS=" + sParam + "&sessid="+BX.bitrix_sessid()+"; expires=Thu, 31 Dec 2020 23:59:59 GMT; path=/;"; 1171 1172 if(!BX.userOptions.bSend) 1173 { 1174 BX.userOptions.bSend = true; 1175 setTimeout(function(){BX.userOptions.send(null)}, BX.userOptions.delay); 1176 } 1177}; 1178 1179BX.userOptions.send = function(callback) 1180{ 1181 var sParam = BX.userOptions.__get(); 1182 BX.userOptions.options = null; 1183 BX.userOptions.bSend = false; 1184 1185 if (sParam != '') 1186 { 1187 document.cookie = BX.message('COOKIE_PREFIX') + "_LAST_SETTINGS=; path=/;"; 1188 BX.ajax({ 1189 'method': 'GET', 1190 'dataType': 'html', 1191 'processData': false, 1192 'cache': false, 1193 'url': BX.userOptions.path+sParam+'&sessid='+BX.bitrix_sessid(), 1194 'onsuccess': callback 1195 }); 1196 } 1197}; 1198 1199BX.userOptions.del = function(sCategory, sName, bCommon, callback) 1200{ 1201 BX.ajax.get(BX.userOptions.path+'action=delete&c='+sCategory+'&n='+sName+(bCommon == true? '&common=Y':'')+'&sessid='+BX.bitrix_sessid(), callback); 1202}; 1203 1204BX.userOptions.__get = function() 1205{ 1206 if (!BX.userOptions.options) return ''; 1207 1208 var sParam = '', n = -1, prevParam = '', aOpt, i; 1209 1210 for (i in BX.userOptions.options) 1211 { 1212 if(BX.userOptions.options.hasOwnProperty(i)) 1213 { 1214 aOpt = BX.userOptions.options[i]; 1215 1216 if (prevParam != aOpt[0]+'.'+aOpt[1]) 1217 { 1218 n++; 1219 sParam += '&p['+n+'][c]='+BX.util.urlencode(aOpt[0]); 1220 sParam += '&p['+n+'][n]='+BX.util.urlencode(aOpt[1]); 1221 if (aOpt[4] == true) 1222 sParam += '&p['+n+'][d]=Y'; 1223 prevParam = aOpt[0]+'.'+aOpt[1]; 1224 } 1225 1226 sParam += '&p['+n+'][v]['+BX.util.urlencode(aOpt[2])+']='+BX.util.urlencode(aOpt[3]); 1227 } 1228 } 1229 1230 return sParam.substr(1); 1231}; 1232 1233BX.ajax.history = { 1234 expected_hash: '', 1235 1236 obParams: null, 1237 1238 obFrame: null, 1239 obImage: null, 1240 1241 obTimer: null, 1242 1243 bInited: false, 1244 bHashCollision: false, 1245 bPushState: !!(history.pushState && BX.type.isFunction(history.pushState)), 1246 1247 startState: null, 1248 1249 init: function(obParams) 1250 { 1251 if (BX.ajax.history.bInited) 1252 return; 1253 1254 this.obParams = obParams; 1255 var obCurrentState = this.obParams.getState(); 1256 1257 if (BX.ajax.history.bPushState) 1258 { 1259 BX.ajax.history.expected_hash = window.location.pathname; 1260 if (window.location.search) 1261 BX.ajax.history.expected_hash += window.location.search; 1262 1263 BX.ajax.history.put(obCurrentState, BX.ajax.history.expected_hash, '', true); 1264 // due to some strange thing, chrome calls popstate event on page start. so we should delay it
1265 setTimeout(function(){BX.bind(window, 'popstate', BX.ajax.history.__hashListener);}, 500); 1266 } 1267 else 1268 { 1269 BX.ajax.history.expected_hash = window.location.hash; 1270 1271 if (!BX.ajax.history.expected_hash || BX.ajax.history.expected_hash == '#') 1272 BX.ajax.history.expected_hash = '__bx_no_hash__'; 1273 1274 jsAjaxHistoryContainer.put(BX.ajax.history.expected_hash, obCurrentState); 1275 BX.ajax.history.obTimer = setTimeout(BX.ajax.history.__hashListener, 500); 1276 1277 if (BX.browser.IsIE()) 1278 { 1279 BX.ajax.history.obFrame = document.createElement('IFRAME'); 1280 BX.hide_object(BX.ajax.history.obFrame); 1281 1282 document.body.appendChild(BX.ajax.history.obFrame); 1283 1284 BX.ajax.history.obFrame.contentWindow.document.open(); 1285 BX.ajax.history.obFrame.contentWindow.document.write(BX.ajax.history.expected_hash); 1286 BX.ajax.history.obFrame.contentWindow.document.close(); 1287 } 1288 else if (BX.browser.IsOpera()) 1289 { 1290 BX.ajax.history.obImage = document.createElement('IMG'); 1291 BX.hide_object(BX.ajax.history.obImage); 1292 1293 document.body.appendChild(BX.ajax.history.obImage); 1294 1295 BX.ajax.history.obImage.setAttribute('src', 'javascript:location.href = \'javascript:BX.ajax.history.__hashListener();\';'); 1296 } 1297 } 1298 1299 BX.ajax.history.bInited = true; 1300 }, 1301 1302 __hashListener: function(e) 1303 { 1304 e = e || window.event || {state:false}; 1305 1306 if (BX.ajax.history.bPushState) 1307 { 1308 BX.ajax.history.obParams.setState(e.state||BX.ajax.history.startState); 1309 } 1310 else 1311 { 1312 if (BX.ajax.history.obTimer) 1313 { 1314 window.clearTimeout(BX.ajax.history.obTimer); 1315 BX.ajax.history.obTimer = null; 1316 } 1317 1318 var current_hash; 1319 if (null != BX.ajax.history.obFrame) 1320 current_hash = BX.ajax.history.obFrame.contentWindow.document.body.innerText; 1321 else 1322 current_hash = window.location.hash; 1323 1324 if (!current_hash || current_hash == '#') 1325 current_hash = '__bx_no_hash__'; 1326 1327 if (current_hash.indexOf('#') == 0) 1328 current_hash = current_hash.substring(1); 1329 1330 if (current_hash != BX.ajax.history.expected_hash) 1331 { 1332 var state = jsAjaxHistoryContainer.get(current_hash); 1333 if (state) 1334 { 1335 BX.ajax.history.obParams.setState(state); 1336 1337 BX.ajax.history.expected_hash = current_hash; 1338 if (null != BX.ajax.history.obFrame) 1339 { 1340 var __hash = current_hash == '__bx_no_hash__' ? '' : current_hash; 1341 if (window.location.hash != __hash && window.location.hash != '#' + __hash) 1342 window.location.hash = __hash; 1343 } 1344 } 1345 } 1346 1347 BX.ajax.history.obTimer = setTimeout(BX.ajax.history.__hashListener, 500); 1348 } 1349 }, 1350 1351 put: function(state, new_hash, new_hash1, bStartState) 1352 { 1353 if (this.bPushState) 1354 { 1355 if(!bStartState) 1356 { 1357 history.pushState(state, '', new_hash); 1358 } 1359 else 1360 { 1361 BX.ajax.history.startState = state; 1362 } 1363 } 1364 else 1365 { 1366 if (typeof new_hash1 != 'undefined') 1367 new_hash = new_hash1; 1368 else 1369 new_hash = 'view' + new_hash; 1370 1371 jsAjaxHistoryContainer.put(new_hash, state); 1372 BX.ajax.history.expected_hash = new_hash; 1373 1374 window.location.hash = BX.util.urlencode(new_hash); 1375 1376 if (null != BX.ajax.history.obFrame) 1377 { 1378 BX.ajax.history.obFrame.contentWindow.document.open(); 1379 BX.ajax.history.obFrame.contentWindow.document.write(new_hash); 1380 BX.ajax.history.obFrame.contentWindow.document.close(); 1381 } 1382 } 1383 }, 1384 1385 checkRedirectStart: function(param_name, param_value) 1386 { 1387 var current_hash = window.location.hash; 1388 if (current_hash.substring(0, 1) == '#') current_hash = current_hash.substring(1); 1389 1390 var test = current_hash.substring(0, 5); 1391 if (test == 'view/' || test == 'view%') 1392 { 1393 BX.ajax.history.bHashCollision = true;
1394 document.write('<' + 'div id="__ajax_hash_collision_' + param_value + '" style="display: none;">'); 1395 } 1396 }, 1397 1398 checkRedirectFinish: function(param_name, param_value) 1399 { 1400 document.write('</div>'); 1401 1402 var current_hash = window.location.hash; 1403 if (current_hash.substring(0, 1) == '#') current_hash = current_hash.substring(1); 1404 1405 BX.ready(function () 1406 { 1407 var test = current_hash.substring(0, 5); 1408 if (test == 'view/' || test == 'view%') 1409 { 1410 var obColNode = BX('__ajax_hash_collision_' + param_value); 1411 var obNode = obColNode.firstChild; 1412 BX.cleanNode(obNode); 1413 obColNode.style.display = 'block'; 1414 1415 // IE, Opera and Chrome automatically modifies hash with urlencode, but FF doesn't ;-( 1416 if (test != 'view%') 1417 current_hash = BX.util.urlencode(current_hash); 1418 1419 current_hash += (current_hash.indexOf('%3F') == -1 ? '%3F' : '%26') + param_name + '=' + param_value; 1420 1421 var url = '/bitrix/tools/ajax_redirector.php?hash=' + current_hash; 1422 1423 BX.ajax.insertToNode(url, obNode); 1424 } 1425 }); 1426 } 1427}; 1428 1429BX.ajax.component = function(node) 1430{ 1431 this.node = node; 1432}; 1433 1434BX.ajax.component.prototype.getState = function() 1435{ 1436 var state = { 1437 'node': this.node, 1438 'title': window.document.title, 1439 'data': BX(this.node).innerHTML 1440 }; 1441 1442 var obNavChain = BX('navigation'); 1443 if (null != obNavChain) 1444 state.nav_chain = obNavChain.innerHTML; 1445 1446 BX.onCustomEvent(BX(state.node), "onComponentAjaxHistoryGetState", [state]); 1447 1448 return state; 1449}; 1450 1451BX.ajax.component.prototype.setState = function(state) 1452{ 1453 BX(state.node).innerHTML = state.data; 1454 BX.ajax.UpdatePageTitle(state.title); 1455 1456 if (state.nav_chain) 1457 { 1458 BX.ajax.UpdatePageNavChain(state.nav_chain); 1459 } 1460 1461 BX.onCustomEvent(BX(state.node), "onComponentAjaxHistorySetState", [state]); 1462}; 1463 1464var jsAjaxHistoryContainer = { 1465 arHistory: {}, 1466 1467 put: function(hash, state) 1468 { 1469 this.arHistory[hash] = state; 1470 }, 1471 1472 get: function(hash) 1473 { 1474 return this.arHistory[hash]; 1475 } 1476}; 1477 1478 1479BX.ajax.FormData = function() 1480{ 1481 this.elements = []; 1482 this.files = []; 1483 this.features = {}; 1484 this.isSupported(); 1485 this.log('BX FormData init'); 1486}; 1487 1488BX.ajax.FormData.isSupported = function() 1489{ 1490 var f = new BX.ajax.FormData(); 1491 var result = f.features.supported; 1492 f = null; 1493 return result; 1494}; 1495 1496BX.ajax.FormData.prototype.log = function(o) 1497{ 1498 if (false) { 1499 try { 1500 if (BX.browser.IsIE()) o = JSON.stringify(o); 1501 console.log(o); 1502 } catch(e) {} 1503 } 1504}; 1505 1506BX.ajax.FormData.prototype.isSupported = function() 1507{ 1508 var f = {}; 1509 f.fileReader = (window.FileReader && window.FileReader.prototype.readAsBinaryString); 1510 f.readFormData = f.sendFormData = !!(window.FormData); 1511 f.supported = !!(f.readFormData && f.sendFormData); 1512 this.features = f; 1513 this.log('features:'); 1514 this.log(f); 1515 1516 return f.supported; 1517}; 1518 1519BX.ajax.FormData.prototype.append = function(name, value) 1520{ 1521 if (typeof(value) === 'object') { // seems to be files element 1522 this.files.push({'name': name, 'value':value}); 1523 } else { 1524 this.elements.push({'name': name, 'value':value}); 1525 } 1526}; 1527 1528BX.ajax.FormData.prototype.send = function(url, callbackOk, callbackProgress, callbackError) 1529{ 1530 this.log('FD send'); 1531 this.xhr = BX.ajax({ 1532 'method': 'POST', 1533 'dataType': 'html', 1534 'url': url, 1535 'onsuccess': callbackOk, 1536 'onfailure': callbackError, 1537 'start': false, 1538 'preparePost':false 1539 }); 1540 1541 if (callbackProgress) 1542 { 1543 this.xhr.upload.addEventListener( 1544 'progress', 1545 function(e) { 1546 if (e.lengthComputable) 1547 callbackProgress(e.loaded / (e.total || e.totalSize)); 1548 }, 1549 false 1550 ); 1551 } 1552 1553 if (this.features.readFormData && this.features.sendFormData) 1554 { 1555 var fd = new FormData(); 1556 this.log('use browser formdata'); 1557 for (var i in this.elements) 1558 { 1559 if(this.elements.hasOwnProperty(i)) 1560 fd.append(this.elements[i].name,this.elements[i].value); 1561 } 1562 for (i in this.files) 1563 { 1564 if(this.files.hasOwnProperty(i)) 1565 fd.append(this.files[i].name, this.files[i].value); 1566 } 1567 this.xhr.send(fd); 1568 } 1569 1570 return this.xhr; 1571}; 1572 1573BX.addCustomEvent('onAjaxFailure', BX.debug); 1574})(window); 1575
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.