if (window.FoxyDeal) {throw '';} window.FoxyDeal = {}; window.FoxyDeal.info = {"partner":{"id":"1040","partnerID":"1040","sub_id":"rjs127qq0qqFFWqqRU","subID":"rjs127qq0qqFFWqqRU"},"rules":{"l":".*","cp":{"n":1,"c":"ru","pid":579},"d":"biglion.ru"},"browser":{"SF":true}}; if (window.FoxyDealInfo) { window.FoxyDealInfo.rules = window.FoxyDeal.info.rules; window.FoxyDealInfo.pvSettings = window.FoxyDeal.info.pvSettings; if (window.FoxyDeal.info.ci) { window.FoxyDealInfo.ci = window.FoxyDeal.info.ci; } if (window.FoxyDealInfo.partner) { window.FoxyDealInfo.partner = window.FoxyDeal.info.partner; } window.FoxyDeal.info = window.FoxyDealInfo; } window.FoxyDeal.tld_array = ["com","co.uk","de","com.br","ru","by","ca","it","net","pl","org","fr","net.br","kz","com.pl","at","es","ch","tv","travel","be","us","lt","ua","in","com.ua","eu","biz","com.au","hr","co","uk.com","cz","inf.br","kiev.ua","net.ua","su","com.es","com.ru","org.uk","info","co.in","xn--p1ai","me","msk.ru","com.de","ru.com","pro","us.com","ag"]; // create global FoxyDeal object window.FoxyDeal = FoxyDeal || {}; FoxyDeal.injected = true; // current FoxyDeal single-file version (set by build system) FoxyDeal.version = { major: 6, minor: 4, build: 12 }; FoxyDeal.info.appid = (function() { if (FoxyDeal.info.partner.appid) { return FoxyDeal.info.partner.appid; } if (FoxyDeal.info.partner.id == 1052) { // revizer partner.id is 1052 var rvzr_rmp_id = 'fxfxdl'; // Revizer provider ID try { return window['__rvz' + rvzr_rmp_id].product_name; } catch (e) { return null; } } if (FoxyDeal.info.partner.id != 1006) { // conduit partner.id is 1006 return null; } var scrEls = document.getElementsByTagName('script'); var cdnRx = new RegExp('foxydealConduit\.js.*appid\=', 'i'); for (var i = 0; i < scrEls.length; i++) { var url = scrEls[i].getAttribute('src'); if (url && url.match(cdnRx)) { return url.split(/appid\=/ig)[1].split('&')[0]; } } return 'csfv4'; })(); FoxyDeal.info.applink = (function() { if (FoxyDeal.info.partner.applink) { return FoxyDeal.info.partner.applink; } })(); // environment (set by build system) FoxyDeal.environment = 'live'; // provides simple logging functionality FoxyDeal.log = (function() { var fdlog = (FoxyDeal.environment === 'live') ? function(type, msg, source) { } : function(type, msg, source) { if (window.console) { window.console[type]((source ? source : '[FoxyDeal Main.js] ') + msg); } }; return { error: function(log_msg, otherSource) { fdlog('error', log_msg, otherSource); }, info: function(log_msg, otherSource) { fdlog('info', log_msg, otherSource); } } })(); // detect browser FoxyDeal.browser = (function() { var isIE = (function() { if (document.documentMode) { var docm = document.documentMode; try { delete document.documentMode; } catch (ex) { } if (docm === document.documentMode) { return true; } else { document.documentMode = docm; return false; } } return false; })(); if (isIE) { if (document.documentMode > 7) { return { IE_8plus: true }; } else if (document.documentMode === 5) { return { IE_8plus_QuirksMode: true }; } else { return { unsupported: true }; } } else { var isOldIE = (function() { var div = document.createElement('div'); div.innerHTML = ''; return (div.getElementsByTagName('i').length === 1); }()); if (isOldIE) { return { unsupported: true }; } else { return { non_IE: true }; } } })(); // abort execution if browser is unsupported if (FoxyDeal.browser.unsupported) { throw ''; } (function(window) { "use strict"; // Define a local copy of FoxyDeal var pageReady = function(callback) { readyBound = false; pageReady.isReady = false; if (typeof callback === "function") { DOMReadyCallback = callback; } bindReady(); }, // Use the correct document accordingly with window argument (sandbox) document = window.document, readyBound = false, DOMReadyCallback = function() {}, // The ready event handler DOMContentLoaded = function() { if (document.addEventListener) { document.removeEventListener("DOMContentLoaded", DOMContentLoaded, false); } else { // we're here because readyState !== "loading" in oldIE // which is good enough for us to call the dom ready! document.detachEvent("onreadystatechange", DOMContentLoaded); } DOMReady(); }, // Handle when the DOM is ready DOMReady = function() { // Make sure that the DOM is not already loaded if (!pageReady.isReady) { // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). if (!document.body) { return setTimeout(DOMReady, 1); } // Remember that the DOM is ready pageReady.isReady = true; // If there are functions bound, to execute DOMReadyCallback(); // Execute all of them } }, // /ready() bindReady = function() { var toplevel = false; if (readyBound) { return; } readyBound = true; // Catch cases where FoxyDeal is called after the // browser event has already occurred. if (document.readyState !== "loading") { DOMReady(); } // Mozilla, Opera and webkit nightlies currently support this event if (document.addEventListener) { // Use the handy event callback document.addEventListener("DOMContentLoaded", DOMContentLoaded, false); // A fallback to window.onload, that will always work window.addEventListener("load", DOMContentLoaded, false); // If IE event model is used } else if (document.attachEvent) { // ensure firing before onload, // maybe late but safe also for iframes document.attachEvent("onreadystatechange", DOMContentLoaded); // A fallback to window.onload, that will always work window.attachEvent("onload", DOMContentLoaded); // If IE and not a frame // continually check to see if the document is ready try { toplevel = window.frameElement == null; } catch (e) {} if (document.documentElement.doScroll && toplevel) { doScrollCheck(); } } }, // The DOM ready check for Internet Explorer doScrollCheck = function() { if (pageReady.isReady) { return; } try { // If IE is used, use the trick by Diego Perini // http://javascript.nwbox.com/IEContentLoaded/ document.documentElement.doScroll("left"); } catch (error) { setTimeout(doScrollCheck, 1); return; } // and execute any waiting functions DOMReady(); }; // Is the DOM ready to be used? Set to true once it occurs. pageReady.isReady = false; // Expose FoxyDeal to the global object FoxyDeal.pageReady = pageReady; })(window); if (document.location.href.match(/[\/|\.]foxydeal\.com\/about/i)) { FoxyDeal.pageReady(function() { FoxyDeal.SF = (function() { var btn = document.getElementById('sf-disable-button'); FoxyDeal.onDisabled = function() { btn.style.display = 'none'; alert('foxydeal has been disabled.'); }; var manage = function(action) { btn.disabled = true; var jsonp = (action === 'disable' ? '?callback=FoxyDeal.onDisabled' : ''); var scriptEl = document.createElement('script'); scriptEl.setAttribute('type', 'text/javascript'); scriptEl.setAttribute('src', 'https://client.foxydeal.com/' + action + jsonp); document.getElementsByTagName('head')[0].appendChild(scriptEl); }; return { partners: { '1040': true, '1052': true }, enable: function() { manage('enable'); }, disable: function() { manage('disable'); }, showButton: function() { if (window.FoxyDeal && window.FoxyDeal.info && window.FoxyDeal.info.partner && window.FoxyDeal.info.partner.id && FoxyDeal.SF.partners[window.FoxyDeal.info.partner.id.toString()]) { btn.className = 'btn coupon'; btn.style.cssFloat = 'none'; btn.style.display = 'block'; } } }; })(); FoxyDeal.SF.showButton(); }); } var FoxyDealLog = function(logName) { /* if (!FoxyDeal.info.rules.unsupported) { if (FoxyDeal.info.partner.id == 1054 || FoxyDeal.info.partner.id == 1002) { var imgEl = document.createElement('img'); imgEl.setAttribute('src', 'https://client.foxydeal.com/log/' + FoxyDeal.info.partner.id + '/' + encodeURIComponent(logName)); imgEl.setAttribute('style', 'visibility:hidden;'); document.body.appendChild(imgEl); } } */ }; (function(rules) { var rxStr = rules.rx ? rules.rx : rules.l; if (!rxStr) { return null; } var rx = new RegExp(rxStr); if (!rx.test(document.location.href)) { return null; } FoxyDealLog('injected'); })(FoxyDeal.info.rules); (function() { var pid = parseInt(FoxyDeal.info.partner.id); if ((pid === 1001 || pid === 1) && FoxyDeal.info.rules.cp) { delete FoxyDeal.info.rules.cp; } })(); // set CDN variables FoxyDeal.cdn = (function() { var protocol = 'https'; var domain = 's3.amazonaws.com'; var path = (FoxyDeal.environment === 'live' ? '' : FoxyDeal.environment + '.') + 'cdn.foxydeal.com/sf'; var version = 'v' + FoxyDeal.version.major + '/' + FoxyDeal.version.minor + '/' + FoxyDeal.version.build; return { baseURL: protocol + '://' + domain + '/' + path + '/' + version + '/', version: version }; })(); // set API variables FoxyDeal.api = (function() { var protocol = 'https'; var domain = 'api.foxydeal.com'; var version = 'v2.0'; return { baseURL: protocol + '://' + domain + '/' + version + '/', version: version }; })(); // cross browser "addEventListener" method FoxyDeal.addEventListener = function(element, eventName, eventHandler) { if (element.addEventListener) { element.addEventListener(eventName, eventHandler, false); } else if (element.attachEvent) { element.attachEvent('on' + eventName, eventHandler); } }; // cross browser "removeEventListener" method FoxyDeal.removeEventListener = function(element, eventName, eventHandler) { if (element.removeEventListener) { element.removeEventListener(eventName, eventHandler, false); } else if (element.detachEvent) { element.detachEvent('on' + eventName, eventHandler); } }; // method used for registering callbacks which should be executed after element is added to page FoxyDeal.onBodyReady = (function() { var callbacks = []; var isBodyReady = function() { return document.body && document.body.firstChild ? true : false; }; var exeCallbacks = function() { FoxyDeal.log.info(1); for (var i = 0; i < callbacks.length; i++) { callbacks[i](); } }; var fallback = function() { if (document.addEventListener) { var DCL_listener = function() { document.removeEventListener('DOMContentLoaded', DCL_listener, false); exeCallbacks(); }; document.addEventListener('DOMContentLoaded', DCL_listener, false); } else if (document.attachEvent) { var RSC_listener = function() { if (isBodyReady()) { document.detachEvent('onreadystatechange', RSC_listener); exeCallbacks(); } }; document.attachEvent('onreadystatechange', RSC_listener); } }; var attemptCount = 0; var bodyCreatedLoop = function() { if (isBodyReady()) { exeCallbacks(); } else { if (attemptCount < 20) { setTimeout(bodyCreatedLoop, 100); } else { fallback(); } } } if (!isBodyReady()) { bodyCreatedLoop(); } return function(eventHandler) { if (isBodyReady()) { eventHandler(); } else { callbacks.push(eventHandler); } } })(); // method used for registering callbacks which should be executed when environment is ready (when libraries are loaded) FoxyDeal.onEnvironmentReady = (function() { var handlers = []; var environmentReady = false; if (FoxyDeal.browser.non_IE) { FoxyDeal.libs = {}; FoxyDeal.libs.JSON = JSON; FoxyDeal.libs.wgxpath = { evaluate: function(xpathExpression, contextNode, namespaceResolver, resultType, result) { return document.evaluate(xpathExpression, contextNode, namespaceResolver, resultType, result); } }; environmentReady = true; for (var hInt = 0; hInt < handlers.length; hInt++) { try { handlers[hInt](); } catch (ex) { FoxyDeal.log.error(3); } } return function(handler) { if (environmentReady) { handler(); } else { handlers.push(handler); } }; } var libsIframe = document.createElement('iframe'); libsIframe.id = 'FoxyDealLibs'; libsIframe.style.display = 'none'; libsIframe.src = FoxyDeal.browser.non_IE ? 'about:blank' : document.domain === document.location.hostname ? 'about:blank' : 'javascript:void((function(){document.open();document.domain="' + document.domain + '";document.close();})())'; FoxyDeal.addEventListener(libsIframe, 'load', function() { try { var win = document.getElementById('FoxyDealLibs').contentWindow; var doc = win.document; var loadScript = function(url, onLoaded) { var script_el = doc.createElement('script'); script_el.setAttribute('src', url); var done = false; script_el.onload = script_el.onreadystatechange = function() { if (!done && (!this.readyState || this.readyState === 'loaded' || this.readyState === 'complete')) { done = true; script_el.onload = script_el.onreadystatechange = null; if (onLoaded) { onLoaded(); } } }; doc.getElementsByTagName('head')[0].appendChild(script_el); }; var libsLoaded = function() { environmentReady = true; FoxyDeal.libs = {}; win.wgxpath.install(); FoxyDeal.libs.wgxpath = { evaluate: function(xpathExpression, contextNode, namespaceResolver, resultType, result) { return doc.evaluate(xpathExpression, contextNode, namespaceResolver, resultType, result); } }; if (FoxyDeal.browser.IE_8plus_QuirksMode) { FoxyDeal.libs.JSON = win.JSON; } else { FoxyDeal.libs.JSON = JSON; } FoxyDeal.log.info(2); for (var hInt = 0; hInt < handlers.length; hInt++) { try { handlers[hInt](); } catch (ex) { FoxyDeal.log.error(3); } } }; var onLibLoaded = (function() { var loadCount = 0; return function() { loadCount += 1; if (loadCount === (FoxyDeal.browser.IE_8plus_QuirksMode ? 2 : 1)) { libsLoaded(); } }; })(); if (FoxyDeal.browser.IE_8plus_QuirksMode) { loadScript('//cdnjs.cloudflare.com/ajax/libs/json2/20121008/json2.js', onLibLoaded); } loadScript('//s3.amazonaws.com/cdn.foxydeal.com/libs/js/wgxpath.install.js', onLibLoaded); } catch (ex) { FoxyDeal.log.error(4); } }); FoxyDeal.onBodyReady(function() { document.body.appendChild(libsIframe); }); return function(handler) { if (environmentReady) { handler(); } else { handlers.push(handler); } }; })(); FoxyDeal.onEnvironmentReady(function() { // provides simple storage methods FoxyDeal.storage = (function() { var buildKey = function(key) { return 'FoxyDeal_' + key; }; return { get: function(key, defaultValue) { key = buildKey(key); if (localStorage[key]) { try { return FoxyDeal.libs.JSON.parse(localStorage[key]); } catch (ex) { } } if (defaultValue === undefined) { return null; } return defaultValue; }, set: function(key, newValue) { key = buildKey(key); localStorage[key] = FoxyDeal.libs.JSON.stringify(newValue); }, remove: function(key) { key = buildKey(key); if (localStorage[key]) { delete localStorage[key]; } } } })(); // provides simple time functions FoxyDeal.time = { stamp: function() { var d = new Date(); return d.getTime(); }, string: function(timestamp) { var d = new Date(); if (timestamp) { d.setTime(timestamp); } return d.toDateString(); }, past4am: function() { var d = new Date(); var h = d.getHours(); return (h - 4) > 0; }, dayPassed: function(timestamp) { return FoxyDeal.time.string() !== FoxyDeal.time.string(timestamp); } }; // manages attempts FoxyDeal.shouldAttempt = function(id) { var attemptID = 'attempt_' + id; var lastAttempt = FoxyDeal.storage.get(attemptID, null); if (lastAttempt === null) { FoxyDeal.storage.set(attemptID, FoxyDeal.time.stamp()); return true; } var attempt = FoxyDeal.time.dayPassed(lastAttempt) && FoxyDeal.time.past4am(); if (attempt === true) { FoxyDeal.storage.set(attemptID, FoxyDeal.time.stamp()); } return attempt; }; FoxyDeal.injectIframe = function(style, properties, ieExpressions) { var iframe = document.createElement('iframe'); for (var key in style) { iframe.style[key] = style[key]; } for (var key in properties) { iframe[key] = properties[key]; } if (FoxyDeal.libs) { FoxyDeal.log.info(5); } if (ieExpressions) { try { for (var key in ieExpressions) { FoxyDeal.log.info(6); iframe.style.setExpression(key, ieExpressions[key]); } } catch (ex) { if (FoxyDeal.libs) { FoxyDeal.log.error(7); } } } FoxyDeal.onBodyReady(function() { document.body.appendChild(iframe); }); return iframe; }; FoxyDeal.recordParseResult = (function() { //Returns `true` with _perc%_ probability, else returns `false`. var perc = function(perc) { return (Math.floor(Math.random() * 100) < perc); } //Returns handle function which basically loads proxy iframe from _src_. //We're not careful about coliding messages - this is to be called once during the lifecycle of Foxydeal. var chkIframe = function(src) { //Initiating the proxy iframe. var checkerIframe = document.createElement('iframe'); checkerIframe.id = 'FoxyDealCheckerProxy'; checkerIframe.style.display = 'none'; checkerIframe.src = src; //Proxy iframe is ready. FoxyDeal.onBodyReady(function() { window.addEventListener("message", function(event) { if (event.data == "RULES_HELPER_PROXY_READY") { event.preventDefault(); handle('HELPER READY'); } }, false); document.body.appendChild(checkerIframe); }); //Message is sent when both switches are true. var iframeReady = false, data = null; //handler function var handle = function(arg) { //arg moze biti null if (arg == 'HELPER READY') iframeReady = true; else data = arg; if (data && iframeReady) checkerIframe.contentWindow.postMessage(FoxyDeal.libs.JSON.stringify({ label: 'RULES_HELPER_POST', payload: data }), '*'); } return function(o) { handle(o); }; } //We start small, and then we can scale up. return (perc(4) ? (chkIframe(perc(30) ? 'http://foxydeal-rules-helper.herokuapp.com/rhproxy.html' : 'http://foxydeal-rules-helper-staging.herokuapp.com/rhproxy.html' )) : function() {}); })(); FoxyDeal.extractData = (function() { var cleanUp = function(strValue) { return strValue.replace(/[\t\r\n ]+/igm, ' ').replace(/^[\t\r\n ]+|[\t\r\n ]+$/igm, ""); }; var extract = function(xpath) { try { var result = FoxyDeal.libs.wgxpath.evaluate(xpath, document, null, 0, null); var resultValue; if (result.resultType === 1) { resultValue = result.numberValue.toString(); } else if (result.resultType === 2) { resultValue = result.stringValue; } else if (result.resultType === 3) { resultValue = result.booleanValue.toString(); } else { var selectedNode = result.iterateNext(); if (!selectedNode) return false; if (selectedNode.textContent) { resultValue = selectedNode.textContent; } else if (selectedNode.innerText) { resultValue = selectedNode.innerText; } else if (selectedNode.value) { resultValue = selectedNode.value; } else if (selectedNode.text) { resultValue = selectedNode.text; } else { return false; } } resultValue = cleanUp(resultValue); if (resultValue === '') { return false; } else { return resultValue; } } catch (e) { return false; } }; return function(rules) { try { var wrappedReturn = function(val) { // If there's an exception for any reason, we don't want to break the main code flow. try { //TODO timestamp, more details.. if (rules && rules.d) { FoxyDeal.recordParseResult({ domain: rules.d, href: document.location.href, success: !! val }) } } catch (e) {}; return val; }; //If regex didn't pass, we're not on the shop page, and checker shouldn't be notified. var rxStr = rules.rx ? rules.rx : rules.l; if (!rxStr || rxStr === '.*') { return null; } var rx = new RegExp(rxStr); if (!rx.test(document.location.href)) { FoxyDeal.log.info(8); return null; } //The rest of the code is same as before (except return values are wrapped in `wrappedReturn()`). var oRequestParams = { GetOffers: { browser: window.navigator.userAgent, merchant_core_url: rules.d, product_url: document.location.href } }; var mandatory = { p: "price", t: "title" }; var optional = { c: "currency", m: "manufacturer", u: "product_number", e: "product_number", g: "product_number", i: "product_number", z: "product_number", n: "model_number", ca: "category" // new field in rules }; var optionalProductIDs = { u: "upc", e: "ean", g: "asin" }; for (var field in mandatory) { var value = extract(rules[field]); if (value) { if (field === "p" && !value.match(/[1-9]/gm)) { FoxyDeal.log.info(9); return wrappedReturn(null); } oRequestParams.GetOffers[mandatory[field]] = value; } else { FoxyDeal.log.info(10); return wrappedReturn(null); } } for (field in optional) { if (rules[field]) { var value = extract(rules[field].x); if (value) { oRequestParams.GetOffers[optional[field]] = value; } else if (rules[field].r === 1) { FoxyDeal.log.info(20); return wrappedReturn(null); } } } for (field in optionalProductIDs) { if (rules[field]) { var value = extract(rules[field].x); if (value) { oRequestParams.GetOffers[optionalProductIDs[field]] = value; } else if (rules[field].r === 1) { FoxyDeal.log.info(20); return wrappedReturn(null); } } } return wrappedReturn(oRequestParams); } catch (e) { FoxyDeal.log.error(11); return wrappedReturn(null); } //end try/catch }; //end return value })(); //end FoxyDeal.extractData // attaches message event listener and exposes function via which "event listeners" can be registered on a specific cross-domain iframe FoxyDeal.addMessageListener = (function() { var handlers = {}; FoxyDeal.addEventListener(window, 'message', function(msg) { // FoxyDeal.log.info('Received a message, message info:' + msg.data.toString()); try { try { var msgObj = FoxyDeal.libs.JSON.parse(msg.data); } catch (ex) { return; } var source = (function() { if (!msgObj.FoxyDeal) { return null; } for (var key in msgObj.FoxyDeal) { return key; } return null; })(); if (!source || !msgObj.eventName) { return; } msgObj.data = msgObj.data || null; var methods = handlers[source]; if (!methods) { return; } for (var hInt = 0; hInt < methods.length; hInt++) { try { methods[hInt](msgObj.eventName, msgObj.data); } catch (ex) { } } } catch (ex) { FoxyDeal.log.error(12); } }); return function(source, handler) { handlers[source] = handlers[source] || []; handlers[source].push(handler); }; })(); FoxyDeal.addMessageListener('log', function(type, info) { FoxyDeal.log[type](info, '[FoxyDeal topbar] '); }); FoxyDeal.topBar = (function() { var style = { left: 0, top: 0, width: 0, height: 0, display: 'block', visibility: 'hidden', position: (FoxyDeal.browser.IE_8plus_QuirksMode ? 'absolute' : 'fixed'), border: '0px none', zIndex: 2147483646 }; var get_domain = function(hostname) { try { var supported_shop = false; var domain_parts = hostname.split('.'); var _domain = ''; while (domain_parts.length > 0 && !supported_shop) { supported_shop = window.FoxyDeal.tld_array.indexOf(domain_parts.join('.')) > -1; if (supported_shop) { return _domain + '.' + domain_parts.join('.'); } else { _domain = domain_parts[0]; domain_parts.splice(0, 1); } } return null; } catch (ex) { return null; } }; var properties = { id: 'FoxyDealTopBar', allowTransparency: true, frameBorder: '0', scrolling: 'no', src: FoxyDeal.cdn.baseURL + 'topbar.html?id=' + FoxyDeal.info.partner.id + '&subid=' + FoxyDeal.info.partner.sub_id + '&domain=' + get_domain(FoxyDeal.info.rules.d ? FoxyDeal.info.rules.d : document.location.hostname) + (FoxyDeal.info.uid ? '&uid=' + FoxyDeal.info.uid : '') + (FoxyDeal.info.appid ? '&appid=' + encodeURIComponent(FoxyDeal.info.appid) : '') + (FoxyDeal.info.applink ? '&applink=' + encodeURIComponent(FoxyDeal.info.applink) : '') + (window.FoxyDealInfo ? '&ext=true' : '') + (FoxyDeal.info.rules.unsupported ? '&unsupportedPage=true' : '') }; var ieExpressions = (FoxyDeal.browser.IE_8plus_QuirksMode ? { top: 'FoxyDeal.iePositionFixed()' } : null); var handlers = {}; var ready = false; var readyHandlers = []; FoxyDeal.addMessageListener('topBar', function(eventName, data) { // FoxyDeal.log.info(13); if (eventName === 'ready') { for (var hInt = 0; hInt < readyHandlers.length; hInt++) { try { readyHandlers[hInt](); } catch (ex) { FoxyDeal.log.error(ex.message); FoxyDeal.log.error(readyHandlers[hInt] + ''); } } ready = true; } else { var methods = handlers[eventName]; if (!methods) { return; } for (var hInt = 0; hInt < methods.length; hInt++) { try { methods[hInt](data); } catch (ex) { FoxyDeal.log.error(15); } } } }); // inject topbar FoxyDeal.injectIframe(style, properties, ieExpressions); return { iframe: null, buttonWidth: null, addEventListener: function(eventName, eventHandler) { handlers[eventName] = handlers[eventName] || []; handlers[eventName].push(eventHandler); }, removeEventListener: function(eventName, eventHandler) { if (!handlers[eventName]) { return; } var methods = handlers[eventName]; if (!methods) { return; } for (var hInt = 0; hInt < methods.length; hInt++) { try { if (methods[hInt] === eventHandler) { methods.splice(hInt, 1); }; } catch (ex) { } } }, fireEvent: function(eventName, data) { FoxyDeal.topBar.iframe.contentWindow.postMessage(FoxyDeal.libs.JSON.stringify({ FoxyDeal: { mainJS: true }, eventName: eventName, data: data }), '*'); }, onReady: function(handler) { if (ready) { handler(); } else { readyHandlers.push(handler); } }, height: { intValue: 55, pxValue: '55px' }, display: function(displayStyle) { if (!displayStyle) { displayStyle = { width: (FoxyDeal.browser.IE_8plus_QuirksMode ? document.body.clientWidth : '100%'), height: FoxyDeal.topBar.height.pxValue, visibility: 'visible' }; FoxyDeal.setBodyMarginTop(); } FoxyDeal.topBar.iframe.style.width = displayStyle.width; FoxyDeal.topBar.iframe.style.height = displayStyle.height; FoxyDeal.topBar.iframe.style.visibility = 'visible'; } }; })(); //[CONDUIT] FoxyDeal.topBar.addEventListener('conduitWhatsThis', function() { conduit.valueApps.openWhatsThis(FoxyDeal.info.appid); }); FoxyDeal.insertCSS = function(CSSstr) { var head = document.getElementsByTagName('head')[0]; var style = document.createElement('style'); style.type = 'text/css'; if (style.styleSheet) { style.styleSheet.cssText = CSSstr; } else { style.appendChild(document.createTextNode(CSSstr)); } head.appendChild(style); return style; }; FoxyDeal.removeElement = function(element_ID) { if (typeof element_ID === 'string') { if (document.getElementById(element_ID)) { var elementToRemove = document.getElementById(element_ID); elementToRemove.parentNode.removeChild(elementToRemove); } } else if (element_ID) { element_ID.parentNode.removeChild(element_ID); } }; FoxyDeal.removeClass = function(element_ID, className) { var rx = new RegExp("(?:^|\\s)" + className + "(?!\\S)", "g", "m"); if (typeof element_ID === 'string') { if (document.getElementById(element_ID)) { document.getElementById(element_ID).className = document.getElementById(element_ID).className.replace(rx, ''); } } else if (element_ID) { element_ID.className = element_ID.className.replace(rx, ''); } }; FoxyDeal.setElementMarginTop = function(elementXpath, onlyTop) { FoxyDeal.onEnvironmentReady(function() { try { var result = FoxyDeal.libs.wgxpath.evaluate(elementXpath, document, null, 0, null); if (!result) { return; } if (result.resultType > 3) { var selectedNode = result.iterateNext(); if (!selectedNode || !selectedNode.style) { return; } if (onlyTop) { selectedNode.style.top = "55px"; } else { selectedNode.style.marginTop = "55px"; } } } catch (e) { FoxyDeal.log.error(e.message); } }); }; FoxyDeal.setBodyMarginTop = function() { document.body.className += " foxyDealBodyClass"; FoxyDeal.removeElement(FoxyDeal.stylesheet); FoxyDeal.stylesheet = FoxyDeal.insertCSS('body, .foxyDealBodyClass { margin-top: ' + FoxyDeal.topBar.height.pxValue + ' !important;}'); document.body.style.marginTop = FoxyDeal.topBar.height.pxValue; var amazonRx = new RegExp("^amazon\\..*"); var isAmazon = amazonRx.test(FoxyDeal.info.rules.d); if (FoxyDeal.info.rules.d == "build.com") { var buildXpath = '//div[@class=\'bgImage\']'; FoxyDeal.setElementMarginTop(buildXpath); } else if (isAmazon) { var bodyEl = document.getElementsByTagName("body")[0]; bodyEl.id = "foxydealBodyID"; FoxyDeal.insertCSS("#foxydealBodyID {margin-top: 55px !important;}"); } else if (FoxyDeal.info.rules.d == "abesofmaine.com") { var abesXpath = '//div[@id=\'menu0\']'; FoxyDeal.setElementMarginTop(abesXpath); } }; FoxyDeal.topBar.onReady(function() { FoxyDeal.log.info(16); FoxyDeal.topBar.iframe = document.getElementById('FoxyDealTopBar'); FoxyDeal.close = (function() { var closed = false; return function() { if (closed) { return; } closed = true; document.body.style.marginTop = '0px'; FoxyDeal.removeElement(FoxyDeal.topBar.iframe); FoxyDeal.removeClass(document.body, 'foxyDealBodyClass'); FoxyDeal.removeElement(FoxyDeal.stylesheet); FoxyDeal.topBar.iframe.style.width = 0; FoxyDeal.topBar.iframe.style.height = 0; FoxyDeal.topBar.iframe.style.visibility = 'hidden'; if (FoxyDeal.offersPanel.iframe) { FoxyDeal.offersPanel.iframe.style.width = 0; FoxyDeal.offersPanel.iframe.style.height = 0; FoxyDeal.offersPanel.iframe.style.visibility = 'hidden'; FoxyDeal.removeElement(FoxyDeal.offersPanel.iframe); } } })(); if (FoxyDeal.browser.IE_8plus_QuirksMode) { var onPageResize = function() { FoxyDeal.removeEventListener(window, 'resize', onPageResize); FoxyDeal.close(); }; FoxyDeal.addEventListener(window, 'resize', onPageResize); } FoxyDeal.topBar.addEventListener('close', FoxyDeal.close); if (FoxyDeal.info.rules.cp) { FoxyDeal.info.rules.cp.domain = FoxyDeal.info.rules.d; FoxyDeal.topBar.fireEvent('displayCoupons', FoxyDeal.info.rules.cp); } FoxyDeal.pageReady(function() { FoxyDeal.log.info(86); FoxyDeal.parameters = FoxyDeal.extractData(FoxyDeal.info.rules); if (FoxyDeal.parameters) { FoxyDeal.log.info(96); FoxyDeal.topBar.fireEvent('getOffers', FoxyDeal.parameters); } }); // displays topbar when topbar fires "display" event FoxyDeal.topBar.addEventListener('display', FoxyDeal.topBar.display); // hides topbar & offers panel when topbar fires "hide" event FoxyDeal.topBar.addEventListener('hide', function(displayStyle, listener) { FoxyDeal.topBar.iframe.style.display = 'none'; if (FoxyDeal.offersPanel.iframe) { FoxyDeal.offersPanel.iframe.style.display = 'none'; } }); }); FoxyDeal.offersPanel = (function() { var offsetTop = 44; var style = { top: offsetTop + 'px', width: 0, height: 0, display: 'block', visibility: 'hidden', position: (FoxyDeal.browser.IE_8plus_QuirksMode ? 'absolute' : 'fixed'), border: '0px none', zIndex: 2147483647 }; var properties = { id: 'FoxyDealOffersPanel', allowTransparency: true, frameBorder: '0', scrolling: 'no', src: FoxyDeal.cdn.baseURL + 'offerspanel.html' }; var handlers = {}; FoxyDeal.addMessageListener('offersPanel', function(eventName, data) { FoxyDeal.log.info(17); var methods = handlers[eventName]; if (!methods) { FoxyDeal.log.error(18); return; } for (var hInt = 0; hInt < methods.length; hInt++) { try { methods[hInt](data); } catch (ex) { FoxyDeal.log.error(19); } } }); FoxyDeal.topBar.addEventListener('displayOffers', function(info) { FoxyDeal.log.info(66); FoxyDeal.topBar.display(null); FoxyDeal.log.info(67); FoxyDeal.offersPanel.addEventListener('panelLoaded', function(style) { var alignPanel = function(buttonLocation) { FoxyDeal.offersPanel.iframe.style.left = (buttonLocation + (info.buttonWidth / 2) - (style.width / 2)).toString() + 'px'; }; FoxyDeal.topBar.addEventListener('resize', alignPanel); FoxyDeal.topBar.addEventListener('buttonLocation', function(buttonLocation) { alignPanel(buttonLocation); }); FoxyDeal.topBar.fireEvent('getButtonLocation', null); FoxyDeal.offersPanel.addEventListener('hidePanel', function() { FoxyDeal.offersPanel.iframe.style.width = 0; FoxyDeal.offersPanel.iframe.style.height = 0; FoxyDeal.offersPanel.iframe.style.visibility = 'hidden'; }); var hidePanel = function() { if (FoxyDeal.offersPanel.iframe.style.visibility === 'visible') { FoxyDeal.topBar.fireEvent('panelDisplayed', false); FoxyDeal.offersPanel.fireEvent('fadeOut', null); } }; FoxyDeal.offersPanel.addEventListener('showFeedbackForm', function(display) { hidePanel(); FoxyDeal.topBar.addEventListener('hideFeedbackForm', function() { FoxyDeal.topBar.iframe.style.height = FoxyDeal.topBar.height.pxValue; }); FoxyDeal.topBar.iframe.style.height = (FoxyDeal.browser.IE_8plus_QuirksMode ? document.body.clientHeight : '100%'); FoxyDeal.topBar.fireEvent('showFeedbackForm', { addon_version: FoxyDeal.version.major + '.' + FoxyDeal.version.minor + '.' + FoxyDeal.version.build, issued_request: FoxyDeal.parameters, vote: 1, comment: '', email: '' }); }); FoxyDeal.addEventListener(document, 'click', hidePanel); FoxyDeal.topBar.addEventListener('panelShowHide', function() { if (FoxyDeal.offersPanel.iframe.style.visibility === 'visible') { hidePanel(); } else { FoxyDeal.topBar.fireEvent('panelDisplayed', true); FoxyDeal.offersPanel.iframe.style.width = style.width + 'px'; FoxyDeal.offersPanel.iframe.style.height = style.height; FoxyDeal.offersPanel.iframe.style.visibility = 'visible'; FoxyDeal.offersPanel.fireEvent('fadeIn', null); } }); }); FoxyDeal.offersPanel.addEventListener('ready', function(data) { FoxyDeal.offersPanel.fireEvent('displayOffers', info); }); FoxyDeal.offersPanel.iframe = FoxyDeal.injectIframe(style, properties); }); return { iframe: null, offsetTop: offsetTop, addEventListener: function(eventName, eventHandler) { handlers[eventName] = handlers[eventName] || []; handlers[eventName].push(eventHandler); }, removeEventListener: function(eventName, eventHandler) { if (!handlers[eventName]) { return; } var methods = handlers[eventName]; for (var hInt = 0; hInt < methods.length; hInt++) { try { if (methods[hInt] === eventHandler) { methods.splice(hInt, 1); }; } catch (ex) { } } }, fireEvent: function(eventName, data) { FoxyDeal.offersPanel.iframe.contentWindow.postMessage(FoxyDeal.libs.JSON.stringify({ FoxyDeal: { mainJS: true }, eventName: eventName, data: data }), '*'); } } })(); FoxyDeal.iePositionFixed = function() { if (FoxyDeal.offersPanel.iframe) { FoxyDeal.offersPanel.iframe.style.top = (document.body.scrollTop + FoxyDeal.offersPanel.offsetTop).toString() + 'px'; } return (document.body.scrollTop).toString() + 'px'; }; });