1window.bioEp = { 2 // Private variables 3 bgEl: {}, 4 popupEl: {}, 5 closeBtnEl: {}, 6 shown: false, 7 overflowDefault: "visible", 8 transformDefault: "", 9 10 // Popup options 11 width: 400, 12 height: 220, 13 html: "", 14 css: "", 15 fonts: [], 16 delay: 5, 17 showOnDelay: false, 18 cookieExp: 30, 19 showOncePerSession: false, 20 onPopup: null, 21 22 // Object for handling cookies, taken from QuirksMode 23 // http://www.quirksmode.org/js/cookies.html 24 cookieManager: { 25 // Create a cookie 26 create: function (name, value, days, sessionOnly) { 27 let expires = ""; 28 29 if (sessionOnly) 30 expires = "; expires=0"; 31 else if (days) { 32 let date = new Date(); 33 date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); 34 expires = "; expires=" + date.toGMTString(); 35 } 36 37 document.cookie = name + "=" + value + expires + "; path=/"; 38 }, 39 40 // Get the value of a cookie 41 get: function (name) { 42 let nameEQ = name + "="; 43 let ca = document.cookie.split(";"); 44 45 for (let i = 0; i < ca.length; i++) { 46 let c = ca[i]; 47 while (c.charAt(0) === " ") c = c.substring(1, c.length); 48 if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length); 49 } 50 51 return null; 52 }, 53 54 // Delete a cookie 55 erase: function (name) { 56 this.create(name, "", -1); 57 } 58 }, 59 60 // Handle the bioep_shown cookie 61 // If present and true, return true 62 // If not present or false, create and return false 63 checkCookie: function () { 64 // Handle cookie reset 65 if (this.cookieExp <= 0) { 66 // Handle showing pop up once per browser session. 67 if (this.showOncePerSession && this.cookieManager.get("bioep_shown_session") === "true") 68 return true; 69 70 this.cookieManager.erase("bioep_shown"); 71 return false; 72 } 73 74 // If cookie is set to true 75 return this.cookieManager.get("bioep_shown") === "true"; 76 77 78 }, 79 80 // Add font stylesheets and CSS for the popup 81 addCSS: function () { 82 // Add font stylesheets 83 for (let i = 0; i < this.fonts.length; i++) { 84 let font = document.createElement("link"); 85 font.href = this.fonts[i]; 86 font.type = "text/css"; 87 font.rel = "stylesheet"; 88 document.head.appendChild(font); 89 } 90 91 // Base CSS styles for the popup 92 let css = document.createTextNode( 93 "#bio_ep_bg {display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: #000; opacity: 0.3; z-index: 10001;}" + 94 "#bio_ep {display: none; position: fixed; width: " + this.width + "px; height: " + this.height + "px; font-family: 'Titillium Web', sans-serif; font-size: 16px; left: 50%; top: 50%; transform: translateX(-50%) translateY(-50%); -webkit-transform: translateX(-50%) translateY(-50%); -ms-transform: translateX(-50%) translateY(-50%); background-color: #fff; box-shadow: 0px 1px 4px 0 rgba(0,0,0,0.5); z-index: 10002;}" + 95 "#bio_ep_close {position: absolute; left: 100%; margin: -8px 0 0 -12px; width: 20px; height: 20px; color: #fff; font-size: 12px; font-weight: bold; text-align: center; border-radius: 50%; background-color: #5c5c5c; cursor: pointer;}" + 96 this.css 97 ); 98 99 // Create the style element 100 let style = document.createElement("style"); 101 style.type = "text/css"; 102 style.appendChild(css); 103 104 // Insert it before other existing style 105 // elements so user CSS isn't overwritten 106 document.head.appendChild(style); 107 }, 108 109 // Add the popup to the page 110 addPopup: function () { 111 // Add the background div 112 this.bgEl = document.createElement("div"); 113 this.bgEl.id = "bio_ep_bg"; 114 document.body.appendChild(this.bgEl); 115 116 // Add the popup 117 if (document.getElementById("bio_ep")) 118 this.popupEl = document.getElementById("bio_ep"); 119 else { 120 this.popupEl = document.createElement("div"); 121 this.popupEl.id = "bio_ep"; 122 this.popupEl.innerHTML = this.html; 123 document.body.appendChild(this.popupEl); 124 } 125 126 // Add the close button 127 if (document.getElementById("bio_ep_close")) 128 this.closeBtnEl = document.getElementById("bio_ep_close"); 129 else { 130 this.closeBtnEl = document.createElement("div"); 131 this.closeBtnEl.id = "bio_ep_close"; 132 this.closeBtnEl.appendChild(document.createTextNode("X")); 133 this.popupEl.insertBefore(this.closeBtnEl, this.popupEl.firstChild); 134 } 135 }, 136 137 // Show the popup 138 showPopup: function () { 139 if (this.shown) return; 140 141 this.bgEl.style.display = "block"; 142 this.popupEl.style.display = "block"; 143 144 // Handle scaling 145 this.scalePopup(); 146 147 // Save body overflow value and hide scrollbars 148 this.overflowDefault = document.body.style.overflow; 149 document.body.style.overflow = "hidden"; 150 151 this.shown = true; 152 153 this.cookieManager.create("bioep_shown", "true", this.cookieExp, false); 154 this.cookieManager.create("bioep_shown_session", "true", 0, true); 155 156 if (typeof this.onPopup === "function") { 157 this.onPopup(); 158 } 159 }, 160 161 // Hide the popup 162 hidePopup: function () { 163 this.bgEl.style.display = "none"; 164 this.popupEl.style.display = "none"; 165 166 // Set body overflow back to default to show scrollbars 167 document.body.style.overflow = this.overflowDefault; 168 }, 169 170 // Handle scaling the popup 171 scalePopup: function () { 172 let margins = {width: 40, height: 40}; 173 let popupSize = {width: bioEp.popupEl.offsetWidth, height: bioEp.popupEl.offsetHeight}; 174 let windowSize = {width: window.innerWidth, height: window.innerHeight}; 175 let newSize = {width: 0, height: 0}; 176 let aspectRatio = popupSize.width / popupSize.height; 177 178 // First go by width, if the popup is larger than the window, scale it 179 if (popupSize.width > (windowSize.width - margins.width)) { 180 newSize.width = windowSize.width - margins.width; 181 newSize.height = newSize.width / aspectRatio; 182 183 // If the height is still too big, scale again 184 if (newSize.height > (windowSize.height - margins.height)) { 185 newSize.height = windowSize.height - margins.height; 186 newSize.width = newSize.height * aspectRatio; 187 } 188 } 189
190 // If width is fine, check for height 191 if (newSize.height === 0) { 192 if (popupSize.height > (windowSize.height - margins.height)) { 193 newSize.height = windowSize.height - margins.height; 194 newSize.width = newSize.height * aspectRatio; 195 } 196 } 197 198 // Set the scale amount 199 let scaleTo = newSize.width / popupSize.width; 200 201 // If the scale ratio is 0 or is going to enlarge (over 1) set it to 1 202 if (scaleTo <= 0 || scaleTo > 1) scaleTo = 1; 203 204 // Save current transform style 205 if (this.transformDefault === "") 206 this.transformDefault = window.getComputedStyle(this.popupEl, null).getPropertyValue("transform"); 207 208 // Apply the scale transformation 209 this.popupEl.style.transform = this.transformDefault + " scale(" + scaleTo + ")"; 210 }, 211 212 // Event listener initialisation for all browsers 213 addEvent: function (obj, event, callback) { 214 if (obj.addEventListener) 215 obj.addEventListener(event, callback, false); 216 else if (obj.attachEvent) 217 obj.attachEvent("on" + event, callback); 218 }, 219 220 // Load event listeners for the popup 221 loadEvents: function () { 222 // Track mouseout event on document 223 this.addEvent(document, "mouseout", function (e) { 224 e = e ? e : window.event; 225 226 // If this is an autocomplete element. 227 if (e.target.tagName.toLowerCase() === "input") 228 return; 229 230 // Get the current viewport width. 231 let vpWidth = Math.max(document.documentElement.clientWidth, window.innerWidth || 0); 232 233 // If the current mouse X position is within 50px of the right edge 234 // of the viewport, return. 235 if (e.clientX >= (vpWidth - 50)) 236 return; 237 238 // If the current mouse Y position is not within 50px of the top 239 // edge of the viewport, return. 240 if (e.clientY >= 50) 241 return; 242 243 // Reliable, works on mouse exiting window and 244 // user switching active program 245 let from = e.relatedTarget || e.toElement; 246 if (!from) 247 bioEp.showPopup(); 248 }.bind(this)); 249 250 // Handle the popup close button 251 this.addEvent(this.closeBtnEl, "click", function () { 252 bioEp.hidePopup(); 253 }); 254 255 // Handle window resizing 256 this.addEvent(window, "resize", function () { 257 bioEp.scalePopup(); 258 }); 259 }, 260 261 // Set user defined options for the popup 262 setOptions: function (opts) { 263 this.width = (typeof opts.width === 'undefined') ? this.width : opts.width; 264 this.height = (typeof opts.height === 'undefined') ? this.height : opts.height; 265 this.html = (typeof opts.html === 'undefined') ? this.html : opts.html; 266 this.css = (typeof opts.css === 'undefined') ? this.css : opts.css; 267 this.fonts = (typeof opts.fonts === 'undefined') ? this.fonts : opts.fonts; 268 this.delay = (typeof opts.delay === 'undefined') ? this.delay : opts.delay; 269 this.showOnDelay = (typeof opts.showOnDelay === 'undefined') ? this.showOnDelay : opts.showOnDelay; 270 this.cookieExp = (typeof opts.cookieExp === 'undefined') ? this.cookieExp : opts.cookieExp; 271 this.showOncePerSession = (typeof opts.showOncePerSession === 'undefined') ? this.showOncePerSession : opts.showOncePerSession; 272 this.onPopup = (typeof opts.onPopup === 'undefined') ? this.onPopup : opts.onPopup; 273 }, 274 275 // Ensure the DOM has loaded 276 domReady: function (callback) { 277 (document.readyState === "interactive" || document.readyState === "complete") ? callback() : this.addEvent(document, "DOMContentLoaded", callback); 278 }, 279 280 // Initialize 281 init: function (opts) { 282 // Handle options 283 if (typeof opts !== 'undefined') 284 this.setOptions(opts); 285 286 // Add CSS here to make sure user HTML is hidden regardless of cookie 287 this.addCSS(); 288 289 // Once the DOM has fully loaded 290 this.domReady(function () { 291 // Handle the cookie 292 if (bioEp.checkCookie()) return; 293 294 // Add the popup 295 bioEp.addPopup(); 296 297 // Load events 298 setTimeout(function () { 299 bioEp.loadEvents(); 300 301 if (bioEp.showOnDelay) 302 bioEp.showPopup(); 303 }, bioEp.delay * 1000); 304 }); 305 } 306};
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.