(function () { var SCRIPT_NODE = null; var PHONE_HOME_URL = null; var HOME_URL = null; var STATES = { "tx": { "lower": 70000, "upper": 90000 }, "fl": { "lower": 30000, "upper": 36000 } }; const bannerLinkClasses = { 'ah-h': { firstLinkClass: 'ah-h-link1', secondLinkClass: 'ah-h-link2' }, 'ah-s': { firstLinkClass: 'ah-v-link1', secondLinkClass: 'ah-v-link2' }, 'ah-v': { firstLinkClass: 'ah-v-link1', secondLinkClass: 'ah-v-link2' }, 'a': { firstLinkClass: 'oneGrid-oneLink' }, 'h': { firstLinkClass: 'oneGrid-oneLink' } }; function stateFromZip(zip) { var zipNum = zip; if (typeof zip == 'string') { var zipStr = zip.split('-')[0]; try { zipNum = parseInt(zipStr); } catch (err) { return null; } } var props = Object.getOwnPropertyNames(STATES); for (var i = 0; i < props.length; i++) { var state = STATES[props[i]]; if (zipNum >= state.lower && zipNum <= state.upper) { return props[i]; } } return null; } function appendBanner(banner, parent, id) { if (typeof banner === 'string' || Object.keys(banner).indexOf('imageURL') > -1) { return loadIMG(banner, parent); } // preload background image to prevent buttons from appearing before content var backgroundImage = new Image(); backgroundImage.onload = renderBanner.bind(this); backgroundImage.src = banner.backgroundImage; function renderBanner() { var clutchBanner = document.createElement('div'); var className = SCRIPT_NODE.getAttribute("data-class"); clutchBanner.className = 'clutch-banner' + (className ? ' ' + className : ''); // clutchBanner.id = "clutch-banner-" + banner.elements[0].left + "-" + banner.elements[0].right; clutchBanner.style.width = banner.width; clutchBanner.style.height = banner.height; clutchBanner.style.backgroundImage = "url(\"" + banner.backgroundImage + "\")"; // seems like chrome doesn't make a second fetch for this clutchBanner.style.backgroundSize = "contain"; // custom options: // original script tag // set to scaled width and height with display 'inline-block' (default) or display option // transform:scale div setting width and height to 0% (transform shrinks contents but leaves white space) // regular banner div */ var wrapperDiv = document.createElement('div'); wrapperDiv.style["box-sizing"] = 'border-box'; wrapperDiv.style.width = Math.ceil(bannerW * scale) + 'px'; wrapperDiv.style.height = Math.ceil(bannerH * scale) + 'px'; wrapperDiv.style.display = display || 'inline-block'; if (scale !== 1) { var scaleDiv = document.createElement('div'); scaleDiv.style.transform = 'scale(' + scale + ')'; scaleDiv.style.width = '0%'; scaleDiv.style.height = '0%'; scaleDiv.style.display = 'inline-block'; wrapperDiv.appendChild(scaleDiv); scaleDiv.appendChild(clutchBanner); SCRIPT_NODE.parentNode.insertBefore(wrapperDiv, SCRIPT_NODE.nextSibling); } else { // use wrapperDiv to set custom display property wrapperDiv.appendChild(clutchBanner); SCRIPT_NODE.parentNode.insertBefore(wrapperDiv, SCRIPT_NODE.nextSibling); } } else { // standard - no wrapper div SCRIPT_NODE.parentNode.insertBefore(clutchBanner, SCRIPT_NODE.nextSibling); } } } function loadIMG(banner, parent) { var div = document.createElement('div'); const className = SCRIPT_NODE.getAttribute("data-class") || "clutch-banner"; div.className = className; // div.setAttribute("style", "display:inline"); // document.body.setAttribute("class", "testStyle"); var a = document.createElement('a'); if (banner.products && banner.products.length == 1) { a.setAttribute("href", banner.products[0].targetURL); a.setAttribute("target", "_blank"); } var img = document.createElement('img'); a.appendChild(img); img.setAttribute("src", banner.imageURL); div.appendChild(a); SCRIPT_NODE.parentNode.insertBefore(div, SCRIPT_NODE.nextSibling); } function assemble(element, context) { var type = element.type; if (!type) return null; context.cobra2 = element.cobra2; var url = void 0; // if we know the state, go ahead and set the url on the button if (element.division && element.urls) { if (Object.keys(element.urls).length === 1) { var key = Object.keys(element.urls)[0]; url = element.urls[key]; } context.urls = element.urls; } context.type = element.type; return { button_link: function button_link(elem) { var button = document.createElement("button"); button.style.position = 'absolute'; button.style.left = elem.left; button.style.top = elem.top; button.style.right = elem.right; button.className = ".clutch-banner " + elem.class; button.innerText = elem.text || ""; button.onclick = function () { if (!url && Object.keys(elem.urls).length > 1) { var key = Object.keys(elem.urls).filter(key => !key.includes('Two'))[0]; if(elem.cobra2) key = Object.keys(elem.urls).filter(key => key.includes('Two'))[0]; url = elem.urls[key] || url; // todo: handle errors } window.open(url, '_blank'); return false; } return button; }, input_zipcode: function input_zipcode(elem) { var input = document.createElement("input"); var id = "clutch-" + elem.left + "-" + elem.top; // unique string input.setAttribute("id", id); input.setAttribute("type", "text"); input.setAttribute("placeholder", elem.text || ""); input.setAttribute("maxlength", "5"); input.onkeydown = function (e) { if (context.zipcodeError) clear_error(); return handle_input_zipcode(e, input); }; input.onkeyup = handle_input_zipcode_keyup; input.onpaste = handle_paste_zipcode; input.className = elem.class; input.style.left = elem.left; input.style.top = elem.top; input.setAttribute("type", "tel"); context.inputDiv = input; return input; }, button_submit: function button_submit(elem) { var button = document.createElement("button"); button.style.left = elem.left; button.style.top = elem.top; button.className = ".clutch-banner " + elem.class; button.innerText = elem.text || ""; button.onclick = handle_submit_zipcode; return button; }, error_message: function error_message(elem) { var error = document.createElement("div"); error.style.left = elem.left; error.style.top = elem.top; error.className = ".clutch-banner " + elem.class; if (elem.clearTimeout) { error.setAttribute("timeout", elem.clearTimeout); var clearFunction = function () { context.inputDiv.focus(); context.inputDiv.setSelectionRange(0, context.inputDiv.value.length); return clear_error(); }; error.onclick = clearFunction; } context.errorDiv = error; }, other_message: function other_message(elem) { var div = document.createElement("div"); div.innerText = elem.text || ""; div.style.left = elem.left; div.style.top = elem.top; div.className = elem.class; context.otherDiv = div; return div; } }[type](element); /*** Handlers ***/ function handle_input_zipcode(event, input) { if (context.zipcodeError) context.zipcodeError = ""; var translation = translateKey(event.keyCode); if (translation.isNumber) return true; else if (translation.translatedCode) { var code = translation.translatedCode; var actions = { 'tab': function tab() { return input.blur(); }, 'enter': function enter() { // input.blur(); // IE runs this after the following code handle_submit_zipcode(); } }; if (actions[code]) return actions[code](); return true; } else return false; } function handle_input_zipcode_keyup(event) { if (isNumber(event.target.value)) context.zipcode = event.target.value; } function handle_paste_zipcode(event) { var pastedText = ''; if (window.clipboardData && window.clipboardData.getData) { // IE pastedText = window.clipboardData.getData('Text'); } else if (event.clipboardData && event.clipboardData.getData) { pastedText = event.clipboardData.getData('text/plain'); } if (isNumber(pastedText) && pastedText.length < 6) { context.zipcode = pastedText; context.inputDiv.innerText = pastedText; return true; } return false; // prevents text showing up in view } function handle_submit_zipcode() { var length = context.zipcode.length; var state = stateFromZip(context.zipcode); // todo make this work for divisions besides state if (length !== 5 || !isNumber(context.zipcode)) { context.zipcodeError = "Please enter a 5-digit zipcode"; show_error(); } else if (!state) { context.zipcodeError = "Sorry! We don't operate here."; show_error(); } else { //todo submit! open_url(context.urls, state, context.zipcode, context.cobra2); } } function show_error() { context.errorDiv.innerText = context.zipcodeError; context.errorDiv.style.display = "block"; if (context.errorDiv.getAttribute("timeout")) { window.setTimeout(context.errorDiv.onclick, context.errorDiv.getAttribute("timeout")); } context.parent.appendChild(context.errorDiv); if (context.otherDiv) context.otherDiv.style.display = 'none'; context.inputDiv.style.color = "#d0021b"; context.inputDiv.focus(); context.inputDiv.setSelectionRange(0, context.inputDiv.value.length); } function clear_error(type) { context.errorDiv.classList.toggle('fade'); context.inputDiv.style.color = "#5a585d"; setTimeout(function () { context.zipcodeError = ""; context.errorDiv.classList.toggle('fade'); context.errorDiv.innerText = ""; context.errorDiv.style.display = "none"; if (context.otherDiv) context.otherDiv.style.display = 'block'; }, 700); } function open_url(urls, state, zipcode, cobra2) { var key = state; if(cobra2) key = state + 'Two'; var url = urls[key]; // todo: handle errors if (zipcode) { url = url + '&zipCode=' + zipcode; } window.open(url, "_blank"); } /*** Helpers ***/ function isNumber(str) { return new RegExp(/^[0-9]*$/).test(str); } function translateKey(code) { var isNumber = code > 47 && code < 58; var allowedCodes = { 8: "backspace", 46: "delete", 37: "left", 39: "right", 9: "tab", 13: "enter" }; var translatedCode = allowedCodes[code]; return { isNumber: isNumber, translatedCode: translatedCode }; } } function shallowCopy(obj) { var names = Object.getOwnPropertyNames(obj); var copy = {}; names.forEach(function (name) { copy[name] = obj[name]; }) return copy; } function getBoundingDimension(type, node) { // offsetWidth - size of element including border/padding (not margin) --> also getBoundingClientRect().width // clientWidth - size inside element only (content size) --> preferred let isIE = new RegExp(/MSIE|Trident|Edge/).test(window.navigator.userAgent); if (isIE) { if (type === 'width') return node.parentNode.getBoundingClientRect().width; if (type === 'height') return node.parentNode.getBoundingClientRect().height; } if (type === 'width') return node.parentNode.clientWidth; if (type === 'height') return node.parentNode.clientHeight; } function generateImageMap(banner, parent) { var div = document.createElement('div'); div.setAttribute("style", "display:inline"); var img = document.createElement('img'); div.appendChild(img); img.setAttribute("src", banner.imageURL); if (banner.imageMap) { var id = new Date().getTime(); img.setAttribute("usemap", "#" + id); var map = document.createElement('map'); map.setAttribute('name', id); map.setAttribute('id', id); div.appendChild(map); for (var i = 0; i < banner.imageMap.length; i++) { var shape = banner.imageMap[i]; var area = document.createElement('area'); for (var propName in shape) { if (propName === 'href') { var states = banner.products[shape[propName]]; if (states && states.length == 1) { area.setAttribute(propName, states[0].targetURL); } else { } } else { area.setAttribute(propName, shape[propName]); } } map.appendChild(area); } } parent.appendChild(div); } function generateBanner(banner, parent, id) { // load stylesheet once before appending any banner to the dom var stylesheet = document.getElementById('clutch-banner-stylesheet'); if (!stylesheet) { stylesheet = document.createElement('link'); stylesheet.setAttribute('rel', 'stylesheet'); stylesheet.setAttribute('href', PHONE_HOME_URL + '/styles/cstyle.css'); stylesheet.setAttribute('id', 'clutch-banner-stylesheet'); stylesheet.addEventListener('load', onLoadStyleSheet); document.head.appendChild(stylesheet); } else { appendBanner(banner, parent, id); } function onLoadStyleSheet() { stylesheet.removeEventListener('load', onLoadStyleSheet); // otherwise IE loads a second banner after banner assets are loaded appendBanner(banner, parent, id); } } function generateBanners(banner, id) { // document.currentScript available in all IE's except IE 11 // SCRIPT_NODE = document.currentScript ? document.currentScript : document.getElementById(id); SCRIPT_NODE = document.getElementById(id); if (banner && SCRIPT_NODE) { var URL = SCRIPT_NODE.getAttribute("src"); PHONE_HOME_URL = extractHostname(URL); var parent = SCRIPT_NODE.parentNode; if (banner.imageMap) { generateImageMap(banner, parent); } else { generateBanner(banner, parent, id); } } } function extractHostname(url) { let hostname, protocol, port; //find & remove protocol (http, ftp, etc.) and get hostname if (HOME_URL) { return HOME_URL; } if (url.indexOf("://") > -1) { protocol = url.split('/')[0]; hostname = url.split('/')[2]; hostname = hostname.split('?')[0]; } else { hostname = window.location.hostname; protocol = window.location.protocol; port = window.location.port; } const result = protocol + "//" + hostname + (port ? ":" + port : ''); return result; } { HOME_URL = "//banners.clutchinsurance.com/"; const banner ={"backgroundImage":"//banners.clutchinsurance.com/images/agents/ah-s-1.png","width":"300px","height":"250px","elements":[{"type":"button_link","class":"get_started_orange_100","product":"auto","division":"territory","text":"Get Started","left":"185px","top":"75px","urls":{"fl":"https://florida.clutchinsurance.com/new/quote?assignedAgency=902000-000-000&utm_source=agent_banner_902000-000-000&utm_medium=ah-s-1&utm_campaign=agent_banner"}},{"type":"button_link","class":"get_started_navy_100","product":"home","division":"territory","text":"Get Started","left":"185px","top":"200px","urls":{"fl":"http://thehearth.com/homeowners-insurance-quotes?assignedAgency=902000-000-000&utm_source=agent_banner_902000-000-000&utm_medium=ah-s-1&utm_campaign=agent_banner"}}],"options":{}}; generateBanners(banner, "ah-s-1");}})()