;(function(window){ if (window.BX.ajax) return; var BX = window.BX, tempDefaultConfig = {}, defaultConfig = { method: 'GET', // request method: GET|POST dataType: 'html', // type of data loading: html|json|script timeout: 0, // request timeout in seconds. 0 for browser-default async: true, // whether request is asynchronous or not processData: true, // any data processing is disabled if false, only callback call 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 emulateOnload: true, start: true, // send request immediately (if false, request can be started manually via XMLHttpRequest object returned) cache: true, // whether NOT to add random addition to URL preparePost: true, // whether set Content-Type x-www-form-urlencoded in POST 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'}] lsTimeout: 30, //local storage data TTL. useless without lsId. lsForce: false //wheter to force query instead of using localStorage data. useless without lsId. /* other parameters: url: url to get/post data: data to post onsuccess: successful request callback. BX.proxy may be used. onfailure: request failure callback. BX.proxy may be used. lsId: local storage id - for constantly updating queries which can communicate via localStorage. core_ls.js needed any of the default parameters can be overridden. defaults can be changed by BX.ajax.Setup() - for all further requests! */ }, ajax_session = null, loadedScripts = {}, loadedScriptsQueue = [], r = { 'url_utf': /[^\034-\254]+/g, 'script_self': /\/bitrix\/js\/main\/core\/core(_ajax)*.js$/i, 'script_self_window': /\/bitrix\/js\/main\/core\/core_window.js$/i, 'script_self_admin': /\/bitrix\/js\/main\/core\/core_admin.js$/i, 'script_onload': /window.onload/g }; // low-level method BX.ajax = function(config) { var status, data; if (!config || !config.url || !BX.type.isString(config.url)) { return false; } for (var i in tempDefaultConfig) if (typeof (config[i]) == "undefined") config[i] = tempDefaultConfig[i]; tempDefaultConfig = {}; for (i in defaultConfig) if (typeof (config[i]) == "undefined") config[i] = defaultConfig[i]; config.method = config.method.toUpperCase(); if (!BX.localStorage) config.lsId = null; if (BX.browser.IsIE()) { var result = r.url_utf.exec(config.url); if (result) { do { config.url = config.url.replace(result, BX.util.urlencode(result)); result = r.url_utf.exec(config.url); } while (result); } } if(config.dataType == 'json') config.emulateOnload = false; if (!config.cache && config.method == 'GET') config.url = BX.ajax._uncache(config.url); if (config.method == 'POST' && config.preparePost) { config.data = BX.ajax.prepareData(config.data); } var bXHR = true; if (config.lsId && !config.lsForce) { var v = BX.localStorage.get('ajax-' + config.lsId); if (v !== null) { bXHR = false; var lsHandler = function(lsData) { if (lsData.key == 'ajax-' + config.lsId && lsData.value != 'BXAJAXWAIT') { var data = lsData.value, bRemove = !!lsData.oldValue && data == null; if (!bRemove) BX.ajax.__run(config, data); else if (config.onfailure) config.onfailure("timeout"); BX.removeCustomEvent('onLocalStorageChange', lsHandler); } }; if (v == 'BXAJAXWAIT') { BX.addCustomEvent('onLocalStorageChange', lsHandler); } else { setTimeout(function() {lsHandler({key: 'ajax-' + config.lsId, value: v})}, 10); } } } if (bXHR) { config.xhr = BX.ajax.xhr(); if (!config.xhr) return; if (config.lsId) { BX.localStorage.set('ajax-' + config.lsId, 'BXAJAXWAIT', config.lsTimeout); } config.xhr.open(config.method, config.url, config.async); if (config.method == 'POST' && config.preparePost) { config.xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); } if (typeof(config.headers) == "object") { for (i = 0; i < config.headers.length; i++) config.xhr.setRequestHeader(config.headers[i].name, config.headers[i].value); } var bRequestCompleted = false; var onreadystatechange = config.xhr.onreadystatechange = function(additional) { if (bRequestCompleted) return; if (additional === 'timeout') { if (config.onfailure) config.onfailure("timeout"); BX.onCustomEvent(config.xhr, 'onAjaxFailure', ['timeout', '', config]); config.xhr.onreadystatechange = BX.DoNothing; config.xhr.abort(); if (config.async) { config.xhr = null; } } else { if (config.xhr.readyState == 4 || additional == 'run') { status = BX.ajax.xhrSuccess(config.xhr) ? "success" : "error"; bRequestCompleted = true; config.xhr.onreadystatechange = BX.DoNothing; // var status = oAjax.arThreads[TID].httpRequest.getResponseHeader('X-Bitrix-Ajax-Status'); // var bRedirect = (status == 'Redirect'); if (status == 'success') { var data = config.xhr.responseText; if (config.lsId) { BX.localStorage.set('ajax-' + config.lsId, data, config.lsTimeout); } BX.ajax.__run(config, data); } else if (config.onfailure) { config.onfailure("status", config.xhr.status); BX.onCustomEvent(config.xhr, 'onAjaxFailure', ['status', config.xhr.status, config]); } if (config.async) { config.xhr = null; } } } }; if (config.async && config.timeout > 0) { setTimeout(function() { if (config.xhr && !bRequestCompleted) { onreadystatechange("timeout"); } }, config.timeout * 1000); } if (config.start) { config.xhr.send(config.data); if (!config.async) { onreadystatechange('run'); } } return config.xhr; } }; BX.ajax.xhr = function() { if (window.XMLHttpRequest) { try {return new XMLHttpRequest();} catch(e){} } else if (window.ActiveXObject) { try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch(e) {} try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch(e) {} try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) {} try { return new ActiveXObject("Microsoft.XMLHTTP"); } catch(e) {} throw new Error("This browser does not support XMLHttpRequest."); } return null; }; BX.ajax.__prepareOnload = function(scripts) { if (scripts.length > 0) { BX.ajax['onload_' + ajax_session] = null; for (var i=0,len=scripts.length;i 0) BX.loadCSS(styles); if (config.emulateOnload) BX.ajax.__prepareOnload(scripts); var cb = BX.DoNothing; if(config.emulateOnload || bSessionCreated) { cb = BX.defer(function() { if (config.emulateOnload) BX.ajax.__runOnload(); if (bSessionCreated) ajax_session = null; BX.onCustomEvent(config.xhr, 'onAjaxSuccessFinish', [config]); }); } try { if (!!config.jsonFailure) { throw {type: 'json_failure', data: config.jsonResponse, bProactive: config.jsonProactive}; } config.scripts = scripts; BX.ajax.processScripts(config.scripts, true); if (config.onsuccess) { config.onsuccess(result); } BX.onCustomEvent(config.xhr, 'onAjaxSuccess', [result, config]); if(!config.processScriptsConsecutive) { BX.ajax.processScripts(config.scripts, false, cb); } else { BX.ajax.processScriptsConsecutive(config.scripts, false); cb(); } } catch (e) { if (config.onfailure) config.onfailure("processing", e); BX.onCustomEvent(config.xhr, 'onAjaxFailure', ['processing', e, config]); } }; BX.ajax.processScripts = function(scripts, bRunFirst, cb) { var scriptsExt = [], scriptsInt = ''; cb = cb || BX.DoNothing; for (var i = 0, length = scripts.length; i < length; i++) { if (typeof bRunFirst != 'undefined' && bRunFirst != !!scripts[i].bRunFirst) continue; if (scripts[i].isInternal) scriptsInt += ';' + scripts[i].JS; else scriptsExt.push(scripts[i].JS); } scriptsExt = BX.util.array_unique(scriptsExt); var l = scriptsExt.length; var l1 = l; var f = scriptsInt.length > 0 ? function() { BX.evalGlobal(scriptsInt); } : BX.DoNothing; if (l > 0) { var c = function() { if (--l1 <= 0) { f(); cb(); f = BX.DoNothing; } }; for (i=0; i < l; i++) { BX.loadScript(scriptsExt[i], c); } } else { //f();BX.defer(cb)(); f(); cb(); } }; BX.ajax.processScriptsConsecutive = function(scripts, bRunFirst) { for (var i = 0, length = scripts.length; i < length; i++) { if (null != bRunFirst && bRunFirst != !!scripts[i].bRunFirst) continue; if (scripts[i].isInternal) { BX.evalGlobal(scripts[i].JS); } else { BX.ajax.loadScriptAjax([scripts[i].JS]); } } }; // TODO: extend this function to use with any data objects or forms BX.ajax.prepareData = function(arData, prefix) { var data = ''; if (BX.type.isString(arData)) data = arData; else if (null != arData) { for(var i in arData) { if (!arData.hasOwnProperty(i)) continue; if (data.length > 0) data += '&'; var name = BX.util.urlencode(i); if(prefix) name = prefix + '[' + name + ']'; if(typeof arData[i] == 'object') data += BX.ajax.prepareData(arData[i], name); else data += name + '=' + BX.util.urlencode(arData[i]); } } return data; }; BX.ajax.xhrSuccess = function(xhr) { return (xhr.status >= 200 && xhr.status < 300) || xhr.status === 304 || xhr.status === 1223 || xhr.status === 0; }; BX.ajax.Setup = function(config, bTemp) { bTemp = !!bTemp; for (var i in config) { if (bTemp) tempDefaultConfig[i] = config[i]; else defaultConfig[i] = config[i]; } }; BX.ajax.replaceLocalStorageValue = function(lsId, data, ttl) { if (!!BX.localStorage) BX.localStorage.set('ajax-' + lsId, data, ttl); }; BX.ajax._uncache = function(url) { return url + ((url.indexOf('?') !== -1 ? "&" : "?") + '_=' + (new Date).getTime()); }; /* simple interface */ BX.ajax.get = function(url, data, callback) { if (BX.type.isFunction(data)) { callback = data; data = ''; } data = BX.ajax.prepareData(data); if (data) { url += (url.indexOf('?') !== -1 ? "&" : "?") + data; data = ''; } return BX.ajax({ 'method': 'GET', 'dataType': 'html', 'url': url, 'data': '', 'onsuccess': callback }); }; BX.ajax.getCaptcha = function(callback) { return BX.ajax.loadJSON('/bitrix/tools/ajax_captcha.php', callback); }; BX.ajax.insertToNode = function(url, node) { if (node = BX(node)) { BX.onCustomEvent('onAjaxInsertToNode', [{url: url, node: node}]); var show = null; if (!tempDefaultConfig.denyShowWait) { show = BX.showWait(node); delete tempDefaultConfig.denyShowWait; } return BX.ajax.get(url, function(data) { node.innerHTML = data; BX.closeWait(node, show); }); } }; BX.ajax.post = function(url, data, callback) { data = BX.ajax.prepareData(data); return BX.ajax({ 'method': 'POST', 'dataType': 'html', 'url': url, 'data': data, 'onsuccess': callback }); }; /* load and execute external file script with onload emulation */ BX.ajax.loadScriptAjax = function(script_src, callback, bPreload) { if (BX.type.isArray(script_src)) { for (var i=0,len=script_src.length;i= len) callback(); }; for (var i = 0, len = arObs.length; i= len) callback(); break; case 'JSON': BX.ajax.loadJSON(arObs.url, jsBX.proxy(handler, arObs[i])); break; default: BX.ajax.get(arObs.url, '', jsBX.proxy(handler, arObs[i])); break; } } }; /* ajax form sending */ BX.ajax.submit = function(obForm, callback) { if (!obForm.target) { if (null == obForm.BXFormTarget) { var frame_name = 'formTarget_' + Math.random(); obForm.BXFormTarget = document.body.appendChild(BX.create('IFRAME', { props: { name: frame_name, id: frame_name, src: 'javascript:void(0)' }, style: { display: 'none' } })); } obForm.target = obForm.BXFormTarget.name; } obForm.BXFormCallback = callback; BX.bind(obForm.BXFormTarget, 'load', BX.proxy(BX.ajax._submit_callback, obForm)); BX.submit(obForm); return false; }; BX.ajax.submitComponentForm = function(obForm, container, bWait) { if (!obForm.target) { if (null == obForm.BXFormTarget) { var frame_name = 'formTarget_' + Math.random(); obForm.BXFormTarget = document.body.appendChild(BX.create('IFRAME', { props: { name: frame_name, id: frame_name, src: 'javascript:void(0)' }, style: { display: 'none' } })); } obForm.target = obForm.BXFormTarget.name; } if (!!bWait) var w = BX.showWait(container); obForm.BXFormCallback = function(d) { if (!!bWait) BX.closeWait(w); BX(container).innerHTML = d; if (window.bxcompajaxframeonload){ setTimeout("window.bxcompajaxframeonload();window.bxcompajaxframeonload=null;", 10); } BX.onCustomEvent('onAjaxSuccess', []); }; BX.bind(obForm.BXFormTarget, 'load', BX.proxy(BX.ajax._submit_callback, obForm)); return true; }; // func will be executed in form context BX.ajax._submit_callback = function() { //opera and IE8 triggers onload event even on empty iframe try { if(this.BXFormTarget.contentWindow.location.href.indexOf('http') != 0) return; } catch (e) { return; } if (this.BXFormCallback) this.BXFormCallback.apply(this, [this.BXFormTarget.contentWindow.document.body.innerHTML]); BX.unbindAll(this.BXFormTarget); }; // TODO: currently in window extension. move it here. BX.ajax.submitAjax = function(obForm, callback) { }; BX.ajax.UpdatePageData = function (arData) { if (arData.TITLE) BX.ajax.UpdatePageTitle(arData.TITLE); if (arData.NAV_CHAIN) BX.ajax.UpdatePageNavChain(arData.NAV_CHAIN); if (arData.CSS && arData.CSS.length > 0) BX.loadCSS(arData.CSS); if (arData.SCRIPTS && arData.SCRIPTS.length > 0) { var f = function(result,config){ if(!!config && BX.type.isArray(config.scripts)) { for(var i=0,l=arData.SCRIPTS.length;i