1(function(w) { 2 "use strict"; 3 w.ysExit = function(o) { 4 5 var defaults = { 6 width: '100%', //popup width 7 height: 'auto', //popup height 8 target: '#ys-container', //popup selector 9 cookieValidity: 1, //days 10 closeOnOutsideClick: true, //close popup if user clicks outside 11 delay: 0, //delay in ms until the popup is registered 12 debug: false //if true, the cookie will not be set 13 }, 14 options = fixOptions(o), 15 element = document.querySelector(options.target), 16 layer = document.querySelector('.ys-layer'), 17 closeBt = document.querySelector(options.target + ' .ys-popup-close'), 18 inner = document.querySelector(options.target + ' .ys-box'), 19 //exitBt = document.querySelector(options.target + ' .ys-exit'), 20 21 //cookies management helper 22 cookies = { 23 set: function(name, value, days) { 24 var components = [name + '=' + value]; 25 26 if (days) { 27 var date = new Date(); 28 date.setTime(date.getTime() + (days * 24 * 3600 * 1000)); 29 components.push('expires=' + date.toGMTString()); 30 } 31 32 components.push('path=/'); 33 34 document.cookie = components.join('; '); 35 }, 36 get: function(name) { 37 var start = name + '=', 38 arr = document.cookie.split(';'), 39 i; 40 41 for(i = 0; i < arr.length; i++) { 42 var item = arr[i].trim(); 43 44 if (item.indexOf(start) === 0){ 45 return item.substring(start.length); 46 } 47 } 48 49 return null; 50 } 51 }, 52 //the popup object 53 pop = { 54 active: false, 55 mouseLeftWindow: function(e) { 56 var from, to; 57 58 e = e ? e : window.event; 59 from = e.relatedTarget || e.toElement; 60 61 if (!from || from.nodeName === "HTML") { 62 pop.open(); 63 } 64 }, 65 setDimension: function(dimension, value) { 66 if (value.toString().indexOf('%') === -1) { 67 value = value + 'px'; 68 } 69 70 inner.style[dimension] = value; 71 }, 72 attachEvents: function() { 73 function close(e) { 74 pop.destroy(); 75 e.preventDefault(); 76 } 77 78 document.addEventListener('mouseout', pop.mouseLeftWindow, false); 79 closeBt.addEventListener('click', close); 80 //exitBt.addEventListener('click', close); 81 82 if (options.closeOnOutsideClick) { 83 element.addEventListener('click', close); 84 inner.addEventListener('click', function(e) { 85 e.stopPropagation(); 86 }); 87 } 88 89 this.active = true; 90 }, 91 detachEvents: function() { 92 document.removeEventListener('mouseout', pop.mouseLeftWindow); 93 }, 94 open: function() { 95 var self = this; 96 97 element.classList.add('visible'); 98 layer.classList.add('visible'); 99 self.detachEvents(); 100 101 setTimeout(function() { 102 self.setDimension('width', options.width); 103 self.setDimension('height', options.height); 104 }, 20); 105 106 setTimeout(function() { 107 element.classList.add('finished'); 108 }, 200); 109 }, 110 destroy: function() { 111 if (this.active) { 112 pop.detachEvents(); 113 114 setTimeout(function () { 115 element.parentNode.removeChild(element); 116 layer.classList.remove('visible'); 117 }, 200); 118 119 if (!options.debug) { 120 cookies.set('ysExit', 1, options.cookieValidity); 121 } 122 } 123 } 124 }; 125 126 //helper functions 127 function fixOptions(options) { 128 var newOptions = {}; 129
130 Object.keys(defaults).forEach(function(key) { 131 newOptions[key] = options.hasOwnProperty(key) ? options[key] : defaults[key]; 132 }); 133 134 return newOptions; 135 } 136 137 function delegate(obj, func) { 138 return function() { 139 func.apply(obj, arguments); 140 }; 141 } 142 143 //start logic 144 if (!cookies.get(options.cookieIdentifier)) { 145 if (typeof options.delay !== 'number') { 146 throw new Error('options.delay must be a numeric value'); 147 } 148 149 if (!element) { 150 throw new Error('Could not find element with selector: ' + options.target); 151 } 152 153 if (element.parentNode !== document.body) { 154 throw new Error(options.target + ' element must be placed directly inside of the <body> element'); 155 } 156 157 setTimeout(delegate(pop, pop.attachEvents), options.delay); 158 } 159 160 //return object with public interface 161 return { 162 open: delegate(pop, pop.open), 163 destroy: delegate(pop, pop.destroy), 164 getElement: function() { 165 return element; 166 } 167 }; 168 }; 169})(window);
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.