/** * Внешний скрипт для взаимодействия ифрейма формы поиска и ифрейма выдачи */ var sm2_sly_FjlSq = { /** * Суффикс нашего модуля * @public * @constant * @name sm2_sly_FjlSq.SUFFIX * @type {String} */ SUFFIX: '_FjlSq', /** * Идентификатор setInterval, который проверяет обновление хэша * @public * @name sm2_sly_FjlSq.interval_id * @type {Number|null} */ interval_id: null, /** * last hash; used to identify whether the current one has changed or not * @public * @name sm2_sly_FjlSq.last_hash * @type {String|null} */ last_hash: null, /** * eliminate * @public * @name sm2_sly_FjlSq.cache_bust * @type {Number} */ cache_bust: 1, /** * domain validator callback * @public * @name sm2_sly_FjlSq.rm_callback * @type {Function|null} */ rm_callback: null, /** * Id запроса, уникальный для каждой выдачи * @public * @name sm2_sly_FjlSq.request_id * @type {Number} */ request_id: 0, /** * Если оба iframe находятся на одной странице * @public * @name sm2_sly_FjlSq.isCombo * @type {Boolean} */ isCombo: false, /** * URL of a dialog box with responcing part of a frame * @public * @name sm2_sly_FjlSq.resultURL * @type {String} */ resultURL: '', /** * URLs of page, frame 1, frame 2; all URLs are saved without params * Массив url: страницы, в котрую встроен модуль; окно формы поиска; окно формы выдачи * @public * @name sm2_sly_FjlSq.GET * @type {Array} */ GET: ['', '', ''], /** * @public * @constant * @name sm2_sly_FjlSq.noScroll * @type {Number} */ noScroll: '0', /** * current working domain * Домен, к которому мы будем обращаться за выдачей и всем остальным * @public * @constant * @name sm2_sly_FjlSq.domain * @type {String} */ domain: 'ui.sletat.ru', /** * settings param from URL * Параметры из урла linker.js * @public * @name sm2_sly_FjlSq.settings * @type {Object|null} */ settings: null, /** * view mode for a frame; applied to container.style.display * @public * @name sm2_sly_FjlSq.formViewMode * @type {String} */ formViewMode: 'inline', /** * true in the case of an added payment form * @name sm2_sly_FjlSq.payFormAdded * @type {Boolean} */ payFormAdded: false, /** * Объект window окна с выдачей в случае, если выдача открывается в отдельном окне * @name sm2_sly_FjlSq.receiverHandler * @type {Object|null} */ receiverHandler: null, /** * Метод отправки сообщений в iframe * @public * @function * @name sm_sly_FjlSq.postMessage * @param {String} message * @param {String} target_url * @param target * @returns {undefined} */ postMessage: function (message, target_url, target) { if (typeof target !== 'string') { return; } if (!target_url) { target_url = '*'; } if (document.getElementById(target) !== null) { var targetFrame = document.getElementById(target).contentWindow; } else { return; } targetFrame.postMessage(message, target_url); }, /** * Метод полученяи сообщений из iframe * @public * @function * @name sm_sly_FjlSq.receiveMessage * @param {Function} callback * @returns {undefined} */ receiveMessage: function (callback) { if (typeof window.addEventListener === 'function') { window.addEventListener('message', function (event) { callback(event); }, false); } else { window.attachEvent('onmessage', function (event) { callback(event); }); } }, /** * Метод инициализирующий основные методы и переменные * @public * @function * @name sm2_sly_FjlSq.init * @returns {undefined} */ init: function () { if (this.init.initialized) { return; } else{ this.init.initialized = true; } var frameSearch = document.getElementById('sm2_slySearch_FjlSq'), frameResult = document.getElementById('sm2_slyResult_FjlSq'); this.noScroll = parseInt(this.noScroll, 10); this.GET[0] = window.location.href.slice(window.location.href.indexOf('?') + 1); if (frameSearch) { this.GET[1] = frameSearch.src; } if (frameResult) { this.GET[2] = frameResult.src; } if (this.GET[1] != '' && this.GET[1].indexOf('sletat.ru') == -1) { this.domain = 'search.' + document.domain; if (console) { console.log('Mimicried to: ' + this.domain); } } if (frameResult) { this.isCombo = true; } this.request_id = 0; this.addListeners(); if (window.location.href.indexOf('claimid') != -1 && !this.payFormAdded && this.isFirstWithPlugin('card_payment')) { //Показываем карточку оплаты при получении claimId в урле и если наш модуль первый среди модулей с нужным плагином var D = document, x = null, height = Math.max(Math.max(D.body.scrollHeight, D.documentElement.scrollHeight), Math.max(D.body.offsetHeight, D.documentElement.offsetHeight), Math.max(D.body.clientHeight, D.documentElement.clientHeight)), width = Math.max(Math.max(D.body.scrollWidth, D.documentElement.scrollWidth), Math.max(D.body.offsetWidth, D.documentElement.offsetWidth), Math.max(D.body.clientWidth, D.documentElement.clientWidth)); frameSearch.style.height = '0'; frameResult.style.display = this.formViewMode; frameResult.style.width = '858px'; frameResult.style.zIndex = 1000; frameResult.style.position = 'relative'; var B = document.getElementsByTagName('input'); for (var i = 0; i < B.length; i++) { B[i].style.display = 'none'; } B = document.getElementsByTagName('body')[0]; B.style.overflowX = 'hidden'; x = document.createElement('div'); x.innerHTML = '
' + '
' + '
' + '
'; B.appendChild(x); document.getElementById('sm2_slyPayForm' + this.SUFFIX).appendChild(frameResult); this.payFormAdded = true; } else { this.api.timemachine.init(); // no necessity to control this while showing claims } try { //Запоминаем параметры, которые у нас были переданы в урле для linker.js, в глобальную переменную this.settings = {formViewMode:'block'}; if (this.settings.formViewMode) { this.formViewMode = this.settings.formViewMode; } } catch (e) { this.settings = null; } if (frameSearch) { frameSearch.style.backgroundImage = ''; } }, /** * Добавляем слушатели * @public * @function * @name sm2_sly_FjlSq.addListeners * @returns {undefined} */ addListeners: function () { var _this = this; //Принмаем сообщения из ифреймов this.receiveMessage(function (e) { var sendMessage, targetUrl, params = _this.getHashParams(e.data), frameSearch = document.getElementById('sm2_slySearch' + _this.SUFFIX), frameResult = document.getElementById('sm2_slyResult' + _this.SUFFIX); if (typeof params['linkerLoaded' + _this.SUFFIX] !== 'undefined') { sendMessage = 'linkerLoaded'; targetUrl = 'http://' + _this.domain + '/HotForm.html'; _this.postMessage(sendMessage, targetUrl, 'sm2_slySearch' + _this.SUFFIX); //Если есть iframe выдачи if (_this.isCombo) { targetUrl = 'http://' + _this.domain + '/HotResult.html'; _this.postMessage(sendMessage, targetUrl, 'sm2_slyResult' + _this.SUFFIX); } } if (typeof params['searchResultInit' + _this.SUFFIX] !== 'undefined') { var STAAndCountry = _this.settings && _this.settings.setup && typeof _this.settings.setup.STA !== 'undefined' && typeof _this.settings.setup.country !== 'undefined'; //Если у нас в параметрах для linker.js передан параметр STA с номером страны для автозапуска if (STAAndCountry) { sendMessage = 'country=' + _this.settings.setup.country; targetUrl = 'http://' + _this.domain + '/HotResult.html'; _this.postMessage(sendMessage, targetUrl, 'sm2_slyResult' + _this.SUFFIX); frameResult.style.display = _this.formViewMode; if (!_this.noScroll) { frameResult.scrollIntoView(); } if (_this.api.onSelectCountry) { _this.api.onSelectCountry(_this.settings.setup.country); } } } //Устанавливаем высотыу выдачи if (typeof params['h3' + _this.SUFFIX] !== 'undefined') { var h = params['h3' + _this.SUFFIX] - 0; if (h > 0 && frameResult) { frameResult.height = h; } } //Устанавливаем высотыу поисковой формы if (typeof params['h0' + _this.SUFFIX] !== 'undefined') { if (params['h0' + _this.SUFFIX] != 0 && frameSearch) { frameSearch.style.display = _this.formViewMode; frameSearch.height = params['h0' + _this.SUFFIX]; if (frameSearch.height == -1) { frameSearch.parentNode.removeChild(frameSearch); } } } if (typeof params['h' + _this.SUFFIX] !== 'undefined') { if (params['h' + _this.SUFFIX] != 0 && frameResult) { frameResult.style.display = _this.formViewMode; frameResult.height = params['h' + _this.SUFFIX]; } } if (typeof params['country' + _this.SUFFIX] !== 'undefined') { sendMessage = 'country=' + params['country' + _this.SUFFIX]; targetUrl = 'http://' + _this.domain + '/HotResult.html'; _this.postMessage(sendMessage, targetUrl, 'sm2_slyResult' + _this.SUFFIX); frameResult.style.display = _this.formViewMode; if (!_this.noScroll) { frameResult.scrollIntoView(); } if (_this.api.onSelectCountry) { _this.api.onSelectCountry(params['country' + _this.SUFFIX]); } } if (typeof params['openhotel' + _this.SUFFIX] !== 'undefined') { sendMessage = 'openhotel=' + params['openhotel' + _this.SUFFIX]; targetUrl = 'http://' + _this.domain + '/HotResult.html'; _this.postMessage(sendMessage, targetUrl, 'sm2_slyResult' + _this.SUFFIX); setTimeout(function () { _this.postMessage(sendMessage, targetUrl, 'sm2_slyResult' + _this.SUFFIX); }, 100); } //Это первый рабочий запрос приходищий из main //Если пришел запрос на получение параметров get запроса из урла, //то отправляем их в iframe выдачи if (typeof params['fetchget'] !== 'undefined') { if (window.location.href.indexOf('?') == -1) { return; } sendMessage = window.location.href.slice(window.location.href.indexOf('?') + 1); targetUrl = 'http://' + _this.domain + '/HotForm.html'; //Ограничение на показ карточки в том случае, если у нас несколько модулей и данный не является первым с //установленным плагином карт онлайн-оплаты var notShowPaymentFormCard = window.location.href.indexOf('claimid') !== -1 && !_this.isFirstWithPlugin('card_payment'); //Если у нас не (автозапуск и нет результирующего фрейма) и у нас нет ограничения на показ формы оплаты, то мы отправляем данные из урла if (!(/country/.test(window.location.href) && !_this.isCombo) && !notShowPaymentFormCard) { _this.postMessage(sendMessage, targetUrl, 'sm2_slyResult' + _this.SUFFIX); if (!_this.noScroll) { //Даем время загрузиться форме выдачи setTimeout(function () { frameResult.scrollIntoView(); }, 1000); } } } if (typeof params['goHome'] !== 'undefined') { window.open(window.location.href.slice(0, window.location.href.indexOf('?')), '_self'); } if (typeof params['timemachine' + _this.SUFFIX] !== 'undefined') { var m = params['timemachine' + _this.SUFFIX].split('|'); _this.api.timemachine[m[0]](); } if (typeof params['goPage'] !== 'undefined') { window.open(( //for cyrillic domains at firefox function (params) { var url = params['goPage'], key = ''; for (key in params) { if (params.hasOwnProperty(key)) { if (key === 'goPage') { continue; } url += '&' + key + '=' + params[key]; } } return url; })(params), '_self'); } if (window.location.hostname.replace(/^www\./, '') === 'sletat.ru') { targetUrl = 'http://' + _this.domain + '/HotResult.html'; _this.postMessage('isSletatSite=1', targetUrl, 'sm2_slyResult' + _this.SUFFIX); } if (typeof params['showcaseTemplates' + _this.SUFFIX] !== 'undefined') { targetUrl = 'http://' + _this.domain + '/HotResult.html'; sendMessage = 'showcaseTemplates=' + params['showcaseTemplates' + _this.SUFFIX]; _this.postMessage(sendMessage, targetUrl, 'sm2_slyResult' + _this.SUFFIX); } }); }, /** * @public * @function * @name sm_sly_FjlSq.getHashParams * @param hash * @returns {Object} */ getHashParams: function (hash) { var e, a = /\+/g, r = /([^&;=]+)=?([^&;]*)/g, hashParams = {}, d = function (s) { try { return decodeURIComponent(s.replace(a, ' ')); } catch (e) { } }; while (e = r.exec(hash)) { hashParams[d(e[1])] = d(e[2]); } return hashParams; }, /** * Проверяем является ли наш модуль первым с плагином * @public * @function * @name sm_sly_FjlSq.isFirstWithPlugin * @returns {Boolean} */ isFirstWithPlugin: function (pluginName) { var ourModuleNumber = this.countModules(), globalTourModules = window.globalTourModules, modulesLength = globalTourModules.length, firstModuleWithPlugin = 0; for (; firstModuleWithPlugin < modulesLength; firstModuleWithPlugin++) { if (globalTourModules[firstModuleWithPlugin].frameSearchUrl.indexOf(pluginName) !== -1 || globalTourModules[firstModuleWithPlugin].frameResultUrl.indexOf(pluginName) !== -1) { //Если модуль содержит искомое слово в src фрейма поиска или выдачи break; } } return (ourModuleNumber === firstModuleWithPlugin); }, /** * Узнаем каким по счету уставлен наш модуль * и ставим наш модуль на учет в общую глобальную переменную * для всех модулей * @public * @function * @name sm2_sly_FjlSq.countModules * @returns {Number} */ countModules: function () { var moduleName = 'module' + this.SUFFIX, moduleParams = { name: moduleName, frameSearchUrl: this.GET[1], frameResultUrl: this.GET[2] }; if (typeof window.globalTourModules === 'undefined') { //Если ещё не существует глобальная переменная для учета установленных модулей window.globalTourModules = [moduleParams]; return 0; } var globalTourModules = window.globalTourModules, modulesLength = globalTourModules.length, moduleNumber = 0; for (; moduleNumber < modulesLength; moduleNumber++) { if (globalTourModules[moduleNumber].name === moduleName) { //Если наш модуль уже зарегистрирован, то возвращем его индекс return moduleNumber; } } //Если наш модуль ещё не зарегистрирован globalTourModules.push(moduleParams); return modulesLength; }, // API used for external interactions. Can be equally used for internal purposes too. api: { onSelectCountry: null, // Really, gents, eliminate this shit. I'm fed up! godSaveMeFromIE: false, forceResyncHeight: function (what) // 1 - top form; 2 - bottom form; 0/null - both { if (!what || what == 1) { sm2_sly_FjlSq.postMessage('api_forceResyncHeight=1', 'http://' + sm2_sly_FjlSq.domain + '/HotForm.html', 'sm2_slySearch_FjlSq'); } if (what != 1) { sm2_sly_FjlSq.postMessage('api_forceResyncHeight=1', 'http://' + sm2_sly_FjlSq.domain + '/HotResult.html', 'sm2_slyResult_FjlSq'); } if (sm2_sly_FjlSq.api.godSaveMeFromIE) { setTimeout(function () { sm2_sly_FjlSq.postMessage('clickCountry=1', 'http://' + sm2_sly_FjlSq.domain + '/HotForm.html', 'sm2_slySearch_FjlSq'); }, 250); } }, timemachine: { fuel: false, currentMS: null, init: function () { if (!window.history) { window.onbeforeunload = function () { var sendMessage = 'warningMessage=Не используйте кнопку "назад" для навигации во время поиска', targetUrl = 'http://' + main.domain + '/SearchForm.html'; main.postMessage(sendMessage, targetUrl, 'sm_slySearch' + 'sm2_slySearch_FjlSq'); return false; }; return false; } else { this.fuel = true; } if (typeof window.addEventListener === 'function') { window.addEventListener('popstate', function (e) { if (!e.state) { return false; } sm2_sly_FjlSq.postMessage('timemachine=showTours', 'http://' + sm2_sly_FjlSq.domain + '/HotResult.html', 'sm2_slyResult_FjlSq'); return true; }, false); } else { if (typeof window.attachEvent === 'object') { window.attachEvent('popstate', function (e) { sm2_sly_FjlSq.postMessage('timemachine=showTours', 'http://' + sm2_sly_FjlSq.domain + '/HotResult.html', 'sm2_slyResult_FjlSq'); return true; }); } } return true; }, showTour: function () { this.currentMS = 'tour'; this.mark({milestone: 'tour'}, 0, window.location.href); }, resetTours: function () { this.currentMS = 'tours'; this.mark({milestone: 'tours'}, 0, window.location.href); }, showHotel: function () { this.currentMS = 'hotel'; this.mark({milestone: 'hotel'}, 0, window.location.href); }, /** * Метод добавления новых записей в историю * @function * @param data * @param title * @param url * @returns {boolean} */ mark: function (data, title, url) { if (!this.fuel) { return false; } if (!data) { data = null; } if (sly_ieVersion() > 9) { for (var i = 5; i--;) { if (typeof history === 'object' && typeof history.pushState === 'function') { history.pushState(data, title ? title : 'Поиск туров', url); } } } } } } }; /** * TODO: Избавиться от этого метода!!! * Возвращает версию ie или 1000, если браизер не ie * @public * @function * @name sly_ieVersion * @returns {number} */ function sly_ieVersion() { var rv = 1000; if (navigator.appName == 'Microsoft Internet Explorer') { var ua = navigator.userAgent, re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})"); if (re.exec(ua) != null) { rv = parseInt(RegExp.$1); } } return rv; } //Инициализируем linker (function(){ var readyStateCheckInterval = setInterval(function() { if (document.readyState === "complete") { sm2_sly_FjlSq.init(); clearInterval(readyStateCheckInterval); } }, 10); })();