PluginProbe
Boxzilla – WordPress Popup Builder / 3.1.3
Boxzilla – WordPress Popup Builder v3.1.3
3.4.11 3.4.10 3.4.9 3.4.3 3.4.4 3.4.5 3.4.6 3.4.7 3.4.8 trunk 3.0 3.0.1 3.0.2 3.0.3 3.1 3.1.1 3.1.10 3.1.11 3.1.12 3.1.13 3.1.14 3.1.15 3.1.16 3.1.17 3.1.18 All 72 releases
← All changes | assets/js/script.js +247 -345 3.1.103.1.3 View file →
@@ -1,136 +1,90 @@
1 1 (function () { var require = undefined; var module = undefined; var exports = undefined; var define = undefined; (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
2 2 'use strict';
3 3
4 -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
4 +var Boxzilla = require('boxzilla');
5 +var options = window.boxzilla_options;
6 +var isLoggedIn = document.body.className.indexOf('logged-in') > -1;
5 7
6 -(function () {
7 - 'use strict';
8 +// print message when test mode is enabled
9 +if( isLoggedIn && options.testMode ) {
10 + console.log( 'Boxzilla: Test mode is enabled. Please disable test mode if you\'re done testing.' );
11 +}
8 12
9 - var Boxzilla = require('boxzilla');
10 - var options = window.boxzilla_options;
13 +// init boxzilla
14 +Boxzilla.init();
11 15
12 - // expose Boxzilla object to window
13 - window.Boxzilla = Boxzilla;
16 +// create boxes from options
17 +for( var i=0; i < options.boxes.length; i++ ) {
18 + // get opts
19 + var boxOpts = options.boxes[i];
20 + boxOpts.testMode = isLoggedIn && options.testMode;
14 21
15 - function ready(fn) {
16 - if (document.readyState != 'loading') {
17 - fn();
18 - } else {
19 - document.addEventListener('DOMContentLoaded', fn);
20 - }
22 + // fix http:// links in box content....
23 + if( window.location.origin.substring(0, 5) === "https" ) {
24 + boxOpts.content = boxOpts.content.replace(window.location.origin.replace("https", "http"), window.location.origin);
21 25 }
22 26
23 - // helper function for setting CSS styles
24 - function css(element, styles) {
25 - if (styles.background_color) {
26 - element.style.background = styles.background_color;
27 - }
27 + // create box
28 + var box = Boxzilla.create( boxOpts.id, boxOpts);
29 +
30 + // add custom css to box
31 + css(box.element, boxOpts.css);
32 +}
28 33
29 - if (styles.color) {
30 - element.style.color = styles.color;
31 - }
34 +// helper function for setting CSS styles
35 +function css(element, styles) {
36 + if( styles.background_color ) {
37 + element.style.background = styles.background_color;
38 + }
32 39
33 - if (styles.border_color) {
34 - element.style.borderColor = styles.border_color;
35 - }
40 + if( styles.color ) {
41 + element.style.color = styles.color;
42 + }
36 43
37 - if (styles.border_width) {
38 - element.style.borderWidth = parseInt(styles.border_width) + "px";
39 - }
44 + if( styles.border_color ) {
45 + element.style.borderColor = styles.border_color;
46 + }
40 47
41 - if (styles.border_style) {
42 - element.style.borderStyle = styles.border_style;
43 - }
48 + if( styles.border_width ) {
49 + element.style.borderWidth = parseInt(styles.border_width) + "px";
50 + }
44 51
45 - if (styles.width) {
46 - element.style.maxWidth = parseInt(styles.width) + "px";
47 - }
52 + if( styles.border_style ) {
53 + element.style.borderStyle = styles.border_style;
48 54 }
49 55
50 - function createBoxesFromConfig() {
51 - var isLoggedIn = document.body.className.indexOf('logged-in') > -1;
52 -
53 - // failsafe against including script twice.
54 - if (options.inited) {
55 - return;
56 - }
57 -
58 - // print message when test mode is enabled
59 - if (isLoggedIn && options.testMode) {
60 - console.log('Boxzilla: Test mode is enabled. Please disable test mode if you\'re done testing.');
61 - }
62 -
63 - // init boxzilla
64 - Boxzilla.init();
65 -
66 - // create boxes from options
67 - for (var i = 0; i < options.boxes.length; i++) {
68 - // get opts
69 - var boxOpts = options.boxes[i];
70 - boxOpts.testMode = isLoggedIn && options.testMode;
71 -
72 - // fix http:// links in box content....
73 - if (window.location.protocol === "https:" && window.location.host) {
74 - var o = "http://" + window.location.host;
75 - var n = o.replace('http://', 'https://');
76 - boxOpts.content = boxOpts.content.replace(o, n);
77 - }
78 -
79 - // create box
80 - var box = Boxzilla.create(boxOpts.id, boxOpts);
81 -
82 - // add box slug to box element as classname
83 - box.element.className = box.element.className + ' boxzilla-' + boxOpts.post.slug;
84 -
85 - // add custom css to box
86 - css(box.element, boxOpts.css);
87 -
88 - box.element.firstChild.firstChild.className += " first-child";
89 - box.element.firstChild.lastChild.className += " last-child";
90 - }
91 -
92 - /**
93 - * If a MailChimp for WordPress form was submitted, open the box containing that form (if any)
94 - *
95 - * TODO: Just set location hash from MailChimp for WP?
96 - */
97 - window.addEventListener('load', openMailChimpForWordPressBox);
98 -
99 - options.inited = true;
100 -
101 - // trigger "done" event.
102 - Boxzilla.trigger('done');
56 + if( styles.width ) {
57 + element.style.maxWidth = parseInt(styles.width) + "px";
103 58 }
59 +}
104 60
105 - function openMailChimpForWordPressBox() {
106 - if (_typeof(window.mc4wp_forms_config) === "object" && window.mc4wp_forms_config.submitted_form) {
107 - var selector = '#' + window.mc4wp_forms_config.submitted_form.element_id;
108 - var boxes = Boxzilla.boxes;
109 - for (var boxId in boxes) {
110 - if (!boxes.hasOwnProperty(boxId)) {
111 - continue;
112 - }
113 - var box = boxes[boxId];
114 - if (box.element.querySelector(selector)) {
115 - box.show();
116 - return;
117 - }
61 +/**
62 + * If a MailChimp for WordPress form was submitted, open the box containing that form (if any)
63 + *
64 + * TODO: Just set location hash from MailChimp for WP?
65 + */
66 +window.addEventListener('load', function() {
67 + if( typeof(window.mc4wp_forms_config) === "object" && window.mc4wp_forms_config.submitted_form ) {
68 + var selector = '#' + window.mc4wp_forms_config.submitted_form.element_id;
69 + var boxes = Boxzilla.boxes;
70 + for( var boxId in boxes ) {
71 + if(!boxes.hasOwnProperty(boxId)) { continue; }
72 + var box = boxes[boxId];
73 + if( box.element.querySelector(selector)) {
74 + box.show();
75 + return;
118 76 }
119 77 }
120 78 }
79 +});
121 80
122 - // create boxes as soon as document.ready fires
123 - ready(createBoxesFromConfig);
124 -})();
125 -
81 +window.Boxzilla = Boxzilla;
126 82 },{"boxzilla":4}],2:[function(require,module,exports){
127 -'use strict';
128 -
129 83 var duration = 320;
130 84
131 85 function css(element, styles) {
132 - for (var property in styles) {
86 + for(var property in styles) {
133 87 element.style[property] = styles[property];
134 88 }
135 89 }
136 90
@@ -135,9 +89,9 @@
135 89 }
136 90
137 91 function initObjectProperties(properties, value) {
138 92 var newObject = {};
139 - for (var i = 0; i < properties.length; i++) {
93 + for(var i=0; i<properties.length; i++) {
140 94 newObject[properties[i]] = value;
141 95 }
142 96 return newObject;
143 97 }
@@ -142,10 +96,10 @@
142 96 return newObject;
143 97 }
144 98
145 99 function copyObjectProperties(properties, object) {
146 - var newObject = {};
147 - for (var i = 0; i < properties.length; i++) {
100 + var newObject = {}
101 + for(var i=0; i<properties.length; i++) {
148 102 newObject[properties[i]] = object[properties[i]];
149 103 }
150 104 return newObject;
151 105 }
@@ -156,9 +110,9 @@
156 110 * @param element
157 111 * @returns {boolean}
158 112 */
159 113 function animated(element) {
160 - return !!element.getAttribute('data-animated');
114 + return !! element.getAttribute('data-animated');
161 115 }
162 116
163 117 /**
164 118 * Toggles the element using the given animation.
@@ -170,9 +124,9 @@
170 124 var nowVisible = element.style.display != 'none' || element.offsetLeft > 0;
171 125
172 126 // create clone for reference
173 127 var clone = element.cloneNode(true);
174 - var cleanup = function cleanup() {
128 + var cleanup = function() {
175 129 element.removeAttribute('data-animated');
176 130 element.setAttribute('style', clone.getAttribute('style'));
177 131 element.style.display = nowVisible ? 'none' : '';
178 132 };
@@ -180,9 +134,9 @@
180 134 // store attribute so everyone knows we're animating this element
181 135 element.setAttribute('data-animated', "true");
182 136
183 137 // toggle element visiblity right away if we're making something visible
184 - if (!nowVisible) {
138 + if( ! nowVisible ) {
185 139 element.style.display = '';
186 140 }
187 141
188 142 var hiddenStyles, visibleStyles;
@@ -187,13 +141,13 @@
187 141
188 142 var hiddenStyles, visibleStyles;
189 143
190 144 // animate properties
191 - if (animation === 'slide') {
145 + if( animation === 'slide' ) {
192 146 hiddenStyles = initObjectProperties(["height", "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom"], 0);
193 147 visibleStyles = {};
194 148
195 - if (!nowVisible) {
149 + if( ! nowVisible ) {
196 150 var computedStyles = window.getComputedStyle(element);
197 151 visibleStyles = copyObjectProperties(["height", "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom"], computedStyles);
198 152 css(element, hiddenStyles);
199 153 }
@@ -203,9 +157,9 @@
203 157 animate(element, nowVisible ? hiddenStyles : visibleStyles, cleanup);
204 158 } else {
205 159 hiddenStyles = { opacity: 0 };
206 160 visibleStyles = { opacity: 1 };
207 - if (!nowVisible) {
161 + if( ! nowVisible ) {
208 162 css(element, hiddenStyles);
209 163 }
210 164
211 165 animate(element, nowVisible ? hiddenStyles : visibleStyles, cleanup);
@@ -217,9 +171,9 @@
217 171 var initialStyles = window.getComputedStyle(element);
218 172 var currentStyles = {};
219 173 var propSteps = {};
220 174
221 - for (var property in targetStyles) {
175 + for(var property in targetStyles) {
222 176 // make sure we have an object filled with floats
223 177 targetStyles[property] = parseFloat(targetStyles[property]);
224 178
225 179 // calculate step size & current value
@@ -226,30 +180,30 @@
226 180 var to = targetStyles[property];
227 181 var current = parseFloat(initialStyles[property]);
228 182
229 183 // is there something to do?
230 - if (current == to) {
184 + if( current == to ) {
231 185 delete targetStyles[property];
232 186 continue;
233 187 }
234 188
235 - propSteps[property] = (to - current) / duration; // points per second
189 + propSteps[property] = ( to - current ) / duration; // points per second
236 190 currentStyles[property] = current;
237 191 }
238 192
239 - var tick = function tick() {
193 + var tick = function() {
240 194 var now = +new Date();
241 195 var timeSinceLastTick = now - last;
242 196 var done = true;
243 197
244 198 var step, to, increment, newValue;
245 - for (var property in targetStyles) {
199 + for(var property in targetStyles ) {
246 200 step = propSteps[property];
247 201 to = targetStyles[property];
248 - increment = step * timeSinceLastTick;
202 + increment = step * timeSinceLastTick;
249 203 newValue = currentStyles[property] + increment;
250 204
251 - if (step > 0 && newValue >= to || step < 0 && newValue <= to) {
205 + if( step > 0 && newValue >= to || step < 0 && newValue <= to ) {
252 206 newValue = to;
253 207 } else {
254 208 done = false;
255 209 }
@@ -263,10 +217,10 @@
263 217
264 218 last = +new Date();
265 219
266 220 // keep going until we're done for all props
267 - if (!done) {
268 - window.requestAnimationFrame && requestAnimationFrame(tick) || setTimeout(tick, 32);
221 + if(!done) {
222 + (window.requestAnimationFrame && requestAnimationFrame(tick)) || setTimeout(tick, 32);
269 223 } else {
270 224 // call callback
271 225 fn && fn();
272 226 }
@@ -274,29 +228,29 @@
274 228
275 229 tick();
276 230 }
277 231
232 +
278 233 module.exports = {
279 234 'toggle': toggle,
280 235 'animate': animate,
281 236 'animated': animated
282 237 };
283 -
284 238 },{}],3:[function(require,module,exports){
285 239 'use strict';
286 240
287 241 var defaults = {
288 - 'animation': 'fade',
289 - 'rehide': false,
290 - 'content': '',
291 - 'cookie': null,
292 - 'icon': '&times',
293 - 'minimumScreenWidth': 0,
294 - 'position': 'center',
295 - 'testMode': false,
296 - 'trigger': false,
297 - 'closable': true
298 -},
242 + 'animation': 'fade',
243 + 'rehide': false,
244 + 'content': '',
245 + 'cookie': null,
246 + 'icon': '&times',
247 + 'minimumScreenWidth': 0,
248 + 'position': 'center',
249 + 'testMode': false,
250 + 'trigger': false,
251 + 'closable': true
252 + },
299 253 Boxzilla,
300 254 Animator = require('./animator.js');
301 255
302 256 /**
@@ -305,16 +259,12 @@
305 259 * @param obj1
306 260 * @param obj2
307 261 * @returns {*}
308 262 */
309 -function merge(obj1, obj2) {
263 +function merge( obj1, obj2 ) {
310 264 var obj3 = {};
311 - for (var attrname in obj1) {
312 - obj3[attrname] = obj1[attrname];
313 - }
314 - for (var attrname in obj2) {
315 - obj3[attrname] = obj2[attrname];
316 - }
265 + for (var attrname in obj1) { obj3[attrname] = obj1[attrname]; }
266 + for (var attrname in obj2) { obj3[attrname] = obj2[attrname]; }
317 267 return obj3;
318 268 }
319 269
320 270 /**
@@ -324,16 +274,17 @@
324 274 function getDocumentHeight() {
325 275 var body = document.body,
326 276 html = document.documentElement;
327 277
328 - var height = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight);
278 + var height = Math.max( body.scrollHeight, body.offsetHeight,
279 + html.clientHeight, html.scrollHeight, html.offsetHeight );
329 280
330 281 return height;
331 282 }
332 283
333 284 // Box Object
334 -var Box = function Box(id, config) {
335 - this.id = id;
285 +var Box = function( id, config ) {
286 + this.id = id;
336 287
337 288 // store config values
338 289 this.config = merge(defaults, config);
339 290
@@ -340,11 +291,11 @@
340 291 // store ref to overlay
341 292 this.overlay = document.getElementById('boxzilla-overlay');
342 293
343 294 // state
344 - this.visible = false;
345 - this.dismissed = false;
346 - this.triggered = false;
295 + this.visible = false;
296 + this.dismissed = false;
297 + this.triggered = false;
347 298 this.triggerHeight = 0;
348 299 this.cookieSet = false;
349 300 this.element = null;
350 301 this.closeIcon = null;
@@ -349,10 +300,10 @@
349 300 this.element = null;
350 301 this.closeIcon = null;
351 302
352 303 // if a trigger was given, calculate values once and store
353 - if (this.config.trigger) {
354 - if (this.config.trigger.method === 'percentage' || this.config.trigger.method === 'element') {
304 + if( this.config.trigger ) {
305 + if( this.config.trigger.method === 'percentage' || this.config.trigger.method === 'element' ) {
355 306 this.triggerHeight = this.calculateTriggerHeight();
356 307 }
357 308
358 309 this.cookieSet = this.isCookieSet();
@@ -365,35 +316,41 @@
365 316 this.events();
366 317 };
367 318
368 319 // initialise the box
369 -Box.prototype.events = function () {
320 +Box.prototype.events = function() {
370 321 var box = this;
371 322
372 323 // attach event to "close" icon inside box
373 - if (this.closeIcon) {
374 - this.closeIcon.addEventListener('click', this.dismiss.bind(this));
375 - }
324 + this.closeIcon && this.closeIcon.addEventListener('click', box.dismiss.bind(this));
376 325
377 - this.element.addEventListener('click', function (e) {
378 - if (e.target.tagName === 'A') {
379 - Boxzilla.trigger('box.interactions.link', [box, e.target]);
326 + this.element.addEventListener('click', function(e) {
327 + if( e.target.tagName === 'A' ) {
328 + Boxzilla.trigger('box.interactions.link', [ box, e.target ] );
380 329 }
381 330 }, false);
382 331
383 - this.element.addEventListener('submit', function (e) {
332 + this.element.addEventListener('submit', function(e) {
384 333 box.setCookie();
385 - Boxzilla.trigger('box.interactions.form', [box, e.target]);
334 + Boxzilla.trigger('box.interactions.form', [ box, e.target ]);
386 335 }, false);
336 +
337 + window.addEventListener("hashchange", function() {
338 + var needle = "#boxzilla-" + box.id;
339 + if( location.hash === needle ) {
340 + box.toggle();
341 + }
342 + });
387 343
388 344 // maybe show box right away
389 - if (this.fits() && this.locationHashRefersBox()) {
345 + if( this.fits() && this.locationHashRefersBox() ) {
390 346 window.addEventListener('load', this.show.bind(this));
391 347 }
348 +
392 349 };
393 350
394 351 // generate dom elements for this box
395 -Box.prototype.dom = function () {
352 +Box.prototype.dom = function() {
396 353 var wrapper = document.createElement('div');
397 354 wrapper.className = 'boxzilla-container boxzilla-' + this.config.position + '-container';
398 355
399 356 var box = document.createElement('div');
@@ -408,18 +365,18 @@
408 365 box.appendChild(content);
409 366
410 367 // remove <script> from box content and append them to the document body
411 368 var scripts = content.querySelectorAll('script');
412 - if (scripts.length) {
369 + if(scripts.length) {
413 370 var script = document.createElement('script');
414 - for (var i = 0; i < scripts.length; i++) {
371 + for( var i=0; i<scripts.length; i++ ) {
415 372 script.appendChild(document.createTextNode(scripts[i].text));
416 373 scripts[i].parentNode.removeChild(scripts[i]);
417 374 }
418 375 document.body.appendChild(script);
419 376 }
420 -
421 - if (this.config.closable && this.config.icon) {
377 +
378 + if( this.config.closable && this.config.icon ) {
422 379 var closeIcon = document.createElement('span');
423 380 closeIcon.className = "boxzilla-close-icon";
424 381 closeIcon.innerHTML = this.config.icon;
425 382 box.appendChild(closeIcon);
@@ -430,9 +387,9 @@
430 387 this.element = box;
431 388 };
432 389
433 390 // set (calculate) custom box styling depending on box options
434 -Box.prototype.setCustomBoxStyling = function () {
391 +Box.prototype.setCustomBoxStyling = function() {
435 392
436 393 // reset element to its initial state
437 394 var origDisplay = this.element.style.display;
438 395 this.element.style.display = '';
@@ -443,16 +400,16 @@
443 400 var windowHeight = window.innerHeight;
444 401 var boxHeight = this.element.clientHeight;
445 402
446 403 // add scrollbar to box and limit height
447 - if (boxHeight > windowHeight) {
404 + if( boxHeight > windowHeight ) {
448 405 this.element.style.maxHeight = windowHeight + "px";
449 406 this.element.style.overflowY = 'scroll';
450 407 }
451 408
452 409 // set new top margin for boxes which are centered
453 - if (this.config.position === 'center') {
454 - var newTopMargin = (windowHeight - boxHeight) / 2;
410 + if( this.config.position === 'center' ) {
411 + var newTopMargin = ( ( windowHeight - boxHeight ) / 2 );
455 412 newTopMargin = newTopMargin >= 0 ? newTopMargin : 0;
456 413 this.element.style.marginTop = newTopMargin + "px";
457 414 }
458 415
@@ -459,27 +416,27 @@
459 416 this.element.style.display = origDisplay;
460 417 };
461 418
462 419 // toggle visibility of the box
463 -Box.prototype.toggle = function (show) {
420 +Box.prototype.toggle = function(show) {
464 421
465 422 // revert visibility if no explicit argument is given
466 - if (typeof show === "undefined") {
467 - show = !this.visible;
423 + if( typeof( show ) === "undefined" ) {
424 + show = ! this.visible;
468 425 }
469 426
470 427 // is box already at desired visibility?
471 - if (show === this.visible) {
428 + if( show === this.visible ) {
472 429 return false;
473 430 }
474 431
475 432 // is box being animated?
476 - if (Animator.animated(this.element)) {
433 + if( Animator.animated(this.element) ) {
477 434 return false;
478 435 }
479 436
480 437 // if box should be hidden but is not closable, bail.
481 - if (!show && !this.config.closable) {
438 + if( ! show && ! this.config.closable ) {
482 439 return false;
483 440 }
484 441
485 442 // set new visibility status
@@ -488,43 +445,48 @@
488 445 // calculate new styling rules
489 446 this.setCustomBoxStyling();
490 447
491 448 // trigger event
492 - Boxzilla.trigger('box.' + (show ? 'show' : 'hide'), [this]);
449 + Boxzilla.trigger('box.' + ( show ? 'show' : 'hide' ), [ this ] );
493 450
494 451 // show or hide box using selected animation
495 - if (this.config.position === 'center') {
496 - this.overlay.classList.toggle('boxzilla-' + this.id + '-overlay');
452 + if( this.config.position === 'center' ) {
497 453 Animator.toggle(this.overlay, "fade");
498 454 }
499 455
500 456 Animator.toggle(this.element, this.config.animation);
501 457
458 + // focus on first input field in box
459 + var firstInput = this.element.querySelector('input, textarea');
460 + if(firstInput) {
461 + firstInput.focus();
462 + }
463 +
502 464 return true;
503 465 };
504 466
505 467 // show the box
506 -Box.prototype.show = function () {
468 +Box.prototype.show = function() {
507 469 return this.toggle(true);
508 470 };
509 471
510 472 // hide the box
511 -Box.prototype.hide = function () {
473 +Box.prototype.hide = function() {
512 474 return this.toggle(false);
513 475 };
514 476
515 477 // calculate trigger height
516 -Box.prototype.calculateTriggerHeight = function () {
478 +Box.prototype.calculateTriggerHeight = function() {
517 479 var triggerHeight = 0;
518 480
519 - if (this.config.trigger.method === 'element') {
481 + if( this.config.trigger.method === 'element' ) {
520 482 var triggerElement = document.body.querySelector(this.config.trigger.value);
521 - if (triggerElement) {
483 + if( triggerElement ) {
522 484 var offset = triggerElement.getBoundingClientRect();
523 485 triggerHeight = offset.top;
524 486 }
525 - } else if (this.config.trigger.method === 'percentage') {
526 - triggerHeight = this.config.trigger.value / 100 * getDocumentHeight();
487 + } else if( this.config.trigger.method === 'percentage' ) {
488 + triggerHeight = ( this.config.trigger.value / 100 * getDocumentHeight() );
527 489 }
528 490
529 491 return triggerHeight;
530 492 };
@@ -529,18 +491,18 @@
529 491 return triggerHeight;
530 492 };
531 493
532 494 // checks whether window.location.hash equals the box element ID or that of any element inside the box
533 -Box.prototype.locationHashRefersBox = function () {
495 +Box.prototype.locationHashRefersBox = function() {
534 496
535 - if (!window.location.hash || 0 === window.location.hash.length) {
497 + if( ! window.location.hash || 0 === window.location.hash.length ) {
536 498 return false;
537 499 }
538 500
539 501 var elementId = window.location.hash.substring(1);
540 - if (elementId === this.element.id) {
502 + if( elementId === this.element.id ) {
541 503 return true;
542 - } else if (this.element.querySelector('#' + elementId)) {
504 + } else if( this.element.querySelector('#' + elementId) ) {
543 505 return true;
544 506 }
545 507
546 508 return false;
@@ -545,49 +507,49 @@
545 507
546 508 return false;
547 509 };
548 510
549 -Box.prototype.fits = function () {
550 - if (this.config.minimumScreenWidth <= 0) {
511 +Box.prototype.fits = function() {
512 + if( this.config.minimumScreenWidth <= 0 ) {
551 513 return true;
552 514 }
553 515
554 - return window.innerWidth > this.config.minimumScreenWidth;
516 + return window.innerWidth > this.config.minimumScreenWidth
555 517 };
556 518
557 519 // is this box enabled?
558 -Box.prototype.mayAutoShow = function () {
520 +Box.prototype.mayAutoShow = function() {
559 521
560 - if (this.dismissed) {
522 + if( this.dismissed ) {
561 523 return false;
562 524 }
563 525
564 526 // check if box fits on given minimum screen width
565 - if (!this.fits()) {
527 + if( ! this.fits() ) {
566 528 return false;
567 529 }
568 530
569 531 // if trigger empty or error in calculating triggerHeight, return false
570 - if (!this.config.trigger) {
532 + if( ! this.config.trigger ) {
571 533 return false;
572 534 }
573 535
574 536 // rely on cookie value (show if not set, don't show if set)
575 - return !this.cookieSet;
537 + return ! this.cookieSet;
576 538 };
577 539
578 -Box.prototype.mayRehide = function () {
540 +Box.prototype.mayRehide = function() {
579 541 return this.config.rehide && this.triggered;
580 542 };
581 543
582 -Box.prototype.isCookieSet = function () {
544 +Box.prototype.isCookieSet = function() {
583 545 // always show on test mode
584 - if (this.config.testMode) {
546 + if(this.config.testMode) {
585 547 return false;
586 548 }
587 549
588 550 // if either cookie is null or trigger & dismiss are both falsey, don't bother checking.
589 - if (!this.config.cookie || !this.config.cookie.triggered && !this.config.cookie.dismissed) {
551 + if(!this.config.cookie || ( ! this.config.cookie.triggered && ! this.config.cookie.dismissed ) ) {
590 552 return false;
591 553 }
592 554
593 555 var cookieSet = document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + 'boxzilla_box_' + this.id + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1") === "true";
@@ -594,64 +556,44 @@
594 556 return cookieSet;
595 557 };
596 558
597 559 // set cookie that disables automatically showing the box
598 -Box.prototype.setCookie = function (hours) {
560 +Box.prototype.setCookie = function(hours) {
599 561 var expiryDate = new Date();
600 - expiryDate.setHours(expiryDate.getHours() + hours);
601 - document.cookie = 'boxzilla_box_' + this.id + '=true; expires=' + expiryDate.toUTCString() + '; path=/';
562 + expiryDate.setHours( expiryDate.getHours() + hours);
563 + document.cookie = 'boxzilla_box_'+ this.id + '=true; expires='+ expiryDate.toUTCString() +'; path=/';
602 564 };
603 565
604 -Box.prototype.trigger = function () {
566 +Box.prototype.trigger = function() {
605 567 var shown = this.show();
606 - if (!shown) {
568 + if( ! shown ) {
607 569 return;
608 570 }
609 571
610 572 this.triggered = true;
611 - if (this.config.cookie && this.config.cookie.triggered) {
573 + if(this.config.cookie && this.config.cookie.triggered) {
612 574 this.setCookie(this.config.cookie.triggered);
613 575 }
614 576 };
615 577
616 -/**
617 - * Dismisses the box and optionally sets a cookie.
618 - *
619 - * @param e The event that triggered this dismissal.
620 - * @returns {boolean}
621 - */
622 -Box.prototype.dismiss = function (e) {
623 - // prevent default action
624 - e && e.preventDefault();
625 -
626 - // only dismiss box if it's currently open.
627 - if (!this.visible) {
628 - return false;
629 - }
630 -
631 - // hide box element
578 +Box.prototype.dismiss = function() {
632 579 this.hide();
633 580
634 - // set cookie
635 - if (this.config.cookie && this.config.cookie.dismissed) {
581 + if(this.config.cookie && this.config.cookie.dismissed) {
636 582 this.setCookie(this.config.cookie.dismissed);
637 583 }
638 584
639 585 this.dismissed = true;
640 - Boxzilla.trigger('box.dismiss', [this]);
641 - return true;
586 + Boxzilla.trigger('box.dismiss', [ this ]);
642 587 };
643 588
644 -module.exports = function (_Boxzilla) {
589 +module.exports = function(_Boxzilla) {
645 590 Boxzilla = _Boxzilla;
646 591 return Box;
647 592 };
648 -
649 593 },{"./animator.js":2}],4:[function(require,module,exports){
650 594 'use strict';
651 595
652 -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
653 -
654 596 var EventEmitter = require('wolfy87-eventemitter'),
655 597 Boxzilla = Object.create(EventEmitter.prototype),
656 598 Box = require('./box.js')(Boxzilla),
657 599 Timer = require('./timer.js'),
@@ -656,22 +598,19 @@
656 598 Box = require('./box.js')(Boxzilla),
657 599 Timer = require('./timer.js'),
658 600 boxes = [],
659 601 overlay,
660 - scrollElement = window,
661 - exitIntentDelayTimer,
662 - exitIntentTriggered,
663 - siteTimer,
664 - pageTimer,
665 - pageViews;
602 + exitIntentDelayTimer, exitIntentTriggered,
603 + siteTimer, pageTimer, pageViews;
666 604
667 605 function throttle(fn, threshhold, scope) {
668 606 threshhold || (threshhold = 250);
669 - var last, deferTimer;
607 + var last,
608 + deferTimer;
670 609 return function () {
671 610 var context = scope || this;
672 611
673 - var now = +new Date(),
612 + var now = +new Date,
674 613 args = arguments;
675 614 if (last && now < last + threshhold) {
676 615 // hold on to it
677 616 clearTimeout(deferTimer);
@@ -696,18 +635,18 @@
696 635 // check "pageviews" criteria for each box
697 636 function checkPageViewsCriteria() {
698 637
699 638 // don't bother if another box is currently open
700 - if (isAnyBoxVisible()) {
639 + if( isAnyBoxVisible() ) {
701 640 return;
702 641 }
703 642
704 - boxes.forEach(function (box) {
705 - if (!box.mayAutoShow()) {
643 + boxes.forEach(function(box) {
644 + if( ! box.mayAutoShow() ) {
706 645 return;
707 646 }
708 647
709 - if (box.config.trigger.method === 'pageviews' && pageViews >= box.config.trigger.value) {
648 + if( box.config.trigger.method === 'pageviews' && pageViews >= box.config.trigger.value ) {
710 649 box.trigger();
711 650 }
712 651 });
713 652 }
@@ -714,14 +653,14 @@
714 653
715 654 // check time trigger criteria for each box
716 655 function checkTimeCriteria() {
717 656 // don't bother if another box is currently open
718 - if (isAnyBoxVisible()) {
657 + if( isAnyBoxVisible() ) {
719 658 return;
720 659 }
721 660
722 - boxes.forEach(function (box) {
723 - if (!box.mayAutoShow()) {
661 + boxes.forEach(function(box) {
662 + if( ! box.mayAutoShow() ) {
724 663 return;
725 664 }
726 665
727 666 // check "time on site" trigger
@@ -737,26 +676,24 @@
737 676 }
738 677
739 678 // check triggerHeight criteria for all boxes
740 679 function checkHeightCriteria() {
680 + var scrollY = ( window.scrollY || window.pageYOffset ) + window.innerHeight * 0.75;
741 681
742 - var scrollY = scrollElement.hasOwnProperty('scrollY') ? scrollElement.scrollY : scrollElement.scrollTop;
743 - scrollY = scrollY + window.innerHeight * 0.75;
682 + // don't bother if another box is currently open
683 + if( isAnyBoxVisible() ) {
684 + return;
685 + }
744 686
745 - boxes.forEach(function (box) {
746 - if (!box.mayAutoShow() || box.triggerHeight <= 0) {
687 + boxes.forEach(function(box) {
688 +
689 + if( ! box.mayAutoShow() || box.triggerHeight <= 0 ) {
747 690 return;
748 691 }
749 692
750 - if (scrollY > box.triggerHeight) {
751 - // don't bother if another box is currently open
752 - if (isAnyBoxVisible()) {
753 - return;
754 - }
755 -
756 - // trigger box
693 + if( scrollY > box.triggerHeight ) {
757 694 box.trigger();
758 - } else if (box.mayRehide()) {
695 + } else if( box.mayRehide() ) {
759 696 box.hide();
760 697 }
761 698 });
762 699 }
@@ -762,9 +699,9 @@
762 699 }
763 700
764 701 // recalculate heights and variables based on height
765 702 function recalculateHeights() {
766 - boxes.forEach(function (box) {
703 + boxes.forEach(function(box) {
767 704 box.setCustomBoxStyling();
768 705 });
769 706 }
770 707
@@ -771,15 +708,15 @@
771 708 function onOverlayClick(e) {
772 709 var x = e.offsetX;
773 710 var y = e.offsetY;
774 711
775 - // calculate if click was less than 40px outside box to avoid closing it by accident
776 - boxes.forEach(function (box) {
712 + // calculate if click was near a box to avoid closing it (click error margin)
713 + boxes.forEach(function(box) {
777 714 var rect = box.element.getBoundingClientRect();
778 - var margin = 40;
715 + var margin = 100 + ( window.innerWidth * 0.05 );
779 716
780 717 // if click was not anywhere near box, dismiss it.
781 - if (x < rect.left - margin || x > rect.right + margin || y < rect.top - margin || y > rect.bottom + margin) {
718 + if( x < ( rect.left - margin ) || x > ( rect.right + margin ) || y < ( rect.top - margin ) || y > ( rect.bottom + margin ) ) {
782 719 box.dismiss();
783 720 }
784 721 });
785 722 }
@@ -785,14 +722,14 @@
785 722 }
786 723
787 724 function triggerExitIntent() {
788 725 // do nothing if already triggered OR another box is visible.
789 - if (exitIntentTriggered || isAnyBoxVisible()) {
726 + if(exitIntentTriggered || isAnyBoxVisible() ) {
790 727 return;
791 728 }
792 729
793 - boxes.forEach(function (box) {
794 - if (box.mayAutoShow() && box.config.trigger.method === 'exit_intent') {
730 + boxes.forEach(function(box) {
731 + if(box.mayAutoShow() && box.config.trigger.method === 'exit_intent' ) {
795 732 box.trigger();
796 733 }
797 734 });
798 735
@@ -802,9 +739,9 @@
802 739 function onMouseLeave(e) {
803 740 var delay = 400;
804 741
805 742 // did mouse leave at top of window?
806 - if (e.clientY <= 0) {
743 + if( e.clientY <= 0 ) {
807 744 exitIntentDelayTimer = window.setTimeout(triggerExitIntent, delay);
808 745 }
809 746 }
810 747
@@ -809,12 +746,12 @@
809 746 }
810 747
811 748 function isAnyBoxVisible() {
812 749
813 - for (var i = 0; i < boxes.length; i++) {
750 + for( var i=0; i<boxes.length; i++ ) {
814 751 var box = boxes[i];
815 752
816 - if (box.visible) {
753 + if( box.visible ) {
817 754 return true;
818 755 }
819 756 }
820 757
@@ -821,33 +758,22 @@
821 758 return false;
822 759 }
823 760
824 761 function onMouseEnter() {
825 - if (exitIntentDelayTimer) {
762 + if( exitIntentDelayTimer ) {
826 763 window.clearInterval(exitIntentDelayTimer);
827 764 exitIntentDelayTimer = null;
828 765 }
829 766 }
830 767
831 -function onElementClick(e) {
832 - var el = e.target || e.srcElement;
833 - if (el && el.tagName === 'A' && el.getAttribute('href').toLowerCase().indexOf('#boxzilla-') === 0) {
834 - window.a = el;
835 - var boxId = e.target.getAttribute('href').toLowerCase().substring("#boxzilla-".length);
836 - Boxzilla.toggle(boxId);
837 - }
838 -}
839 -
840 768 var timers = {
841 - start: function start() {
842 - try {
843 - var sessionTime = sessionStorage.getItem('boxzilla_timer');
844 - if (sessionTime) siteTimer.time = sessionTime;
845 - } catch (e) {}
769 + start: function() {
770 + var sessionTime = sessionStorage.getItem('boxzilla_timer');
771 + if( sessionTime ) siteTimer.time = sessionTime;
846 772 siteTimer.start();
847 773 pageTimer.start();
848 774 },
849 - stop: function stop() {
775 + stop: function() {
850 776 sessionStorage.setItem('boxzilla_timer', siteTimer.time);
851 777 siteTimer.stop();
852 778 pageTimer.stop();
853 779 }
@@ -853,19 +779,12 @@
853 779 }
854 780 };
855 781
856 782 // initialise & add event listeners
857 -Boxzilla.init = function () {
858 - document.body.addEventListener('click', onElementClick, false);
859 -
860 - try {
861 - pageViews = sessionStorage.getItem('boxzilla_pageviews') || 0;
862 - } catch (e) {
863 - pageViews = 0;
864 - }
865 -
866 - siteTimer = new Timer(0);
783 +Boxzilla.init = function() {
784 + siteTimer = new Timer(sessionStorage.getItem('boxzilla_timer') || 0);
867 785 pageTimer = new Timer(0);
786 + pageViews = sessionStorage.getItem('boxzilla_pageviews') || 0;
868 787
869 788 // insert styles into DOM
870 789 var styles = require('./styles.js');
871 790 var styleElement = document.createElement('style');
@@ -879,15 +798,14 @@
879 798 overlay.id = 'boxzilla-overlay';
880 799 document.body.appendChild(overlay);
881 800
882 801 // event binds
883 - scrollElement.addEventListener('touchstart', throttle(checkHeightCriteria), true);
884 - scrollElement.addEventListener('scroll', throttle(checkHeightCriteria), true);
802 + window.addEventListener('scroll', throttle(checkHeightCriteria));
885 803 window.addEventListener('resize', throttle(recalculateHeights));
886 - window.addEventListener('load', recalculateHeights);
804 + window.addEventListener('load', recalculateHeights );
887 805 overlay.addEventListener('click', onOverlayClick);
888 806 window.setInterval(checkTimeCriteria, 1000);
889 - window.setTimeout(checkPageViewsCriteria, 1000);
807 + window.setTimeout(checkPageViewsCriteria, 1000 );
890 808 document.documentElement.addEventListener('mouseleave', onMouseLeave);
891 809 document.documentElement.addEventListener('mouseenter', onMouseEnter);
892 810 document.addEventListener('keyup', onKeyUp);
893 811
@@ -892,9 +810,9 @@
892 810 document.addEventListener('keyup', onKeyUp);
893 811
894 812 timers.start();
895 813 window.addEventListener('focus', timers.start);
896 - window.addEventListener('beforeunload', function () {
814 + window.addEventListener('beforeunload', function() {
897 815 timers.stop();
898 816 sessionStorage.setItem('boxzilla_pageviews', ++pageViews);
899 817 });
900 818 window.addEventListener('blur', timers.stop);
@@ -909,63 +827,53 @@
909 827 * @param object opts
910 828 *
911 829 * @returns Box
912 830 */
913 -Boxzilla.create = function (id, opts) {
831 +Boxzilla.create = function(id, opts) {
914 832 var box = new Box(id, opts);
915 833 boxes.push(box);
916 834 return box;
917 835 };
918 836
919 -Boxzilla.get = function (id) {
920 - for (var i = 0; i < boxes.length; i++) {
837 +Boxzilla.get = function(id) {
838 + for( var i=0; i<boxes.length; i++) {
921 839 var box = boxes[i];
922 - if (box.id == id) {
840 + if( box.id == id ) {
923 841 return box;
924 842 }
925 843 }
844 +}
926 845
927 - throw new Error("No box exists with ID " + id);
928 -};
929 -
930 846 // dismiss a single box (or all by omitting id param)
931 -Boxzilla.dismiss = function (id) {
847 +Boxzilla.dismiss = function(id) {
932 848 // if no id given, dismiss all current open boxes
933 - if (typeof id === "undefined") {
934 - boxes.forEach(function (box) {
935 - box.dismiss();
936 - });
937 - } else if (_typeof(boxes[id]) === "object") {
849 + if( typeof(id) === "undefined" ) {
850 + boxes.forEach(function(box) { box.dismiss(); });
851 + } else if( typeof( boxes[id] ) === "object" ) {
938 852 Boxzilla.get(id).dismiss();
939 853 }
940 854 };
941 855
942 -Boxzilla.hide = function (id) {
943 - if (typeof id === "undefined") {
944 - boxes.forEach(function (box) {
945 - box.hide();
946 - });
856 +Boxzilla.hide = function(id) {
857 + if( typeof(id) === "undefined" ) {
858 + boxes.forEach(function(box) { box.hide(); });
947 859 } else {
948 860 Boxzilla.get(id).hide();
949 861 }
950 862 };
951 863
952 -Boxzilla.show = function (id) {
953 - if (typeof id === "undefined") {
954 - boxes.forEach(function (box) {
955 - box.show();
956 - });
957 - } else {
864 +Boxzilla.show = function(id) {
865 + if( typeof(id) === "undefined" ) {
866 + boxes.forEach(function(box) { box.show(); });
867 + } else if( typeof( boxes[id] ) === "object" ) {
958 868 Boxzilla.get(id).show();
959 869 }
960 870 };
961 871
962 -Boxzilla.toggle = function (id) {
963 - if (typeof id === "undefined") {
964 - boxes.forEach(function (box) {
965 - box.toggle();
966 - });
967 - } else {
872 +Boxzilla.toggle = function(id) {
873 + if( typeof(id) === "undefined" ) {
874 + boxes.forEach(function(box) { box.toggle(); });
875 + } else if( typeof( boxes[id] ) === "object" ) {
968 876 Boxzilla.get(id).toggle();
969 877 }
970 878 };
971 879
@@ -971,41 +879,36 @@
971 879
972 880 // expose each individual box.
973 881 Boxzilla.boxes = boxes;
974 882
975 -// expose boxzilla object
976 883 window.Boxzilla = Boxzilla;
977 884
978 -if (typeof module !== 'undefined' && module.exports) {
885 +if ( typeof module !== 'undefined' && module.exports ) {
979 886 module.exports = Boxzilla;
980 887 }
981 -
982 888 },{"./box.js":3,"./styles.js":5,"./timer.js":6,"wolfy87-eventemitter":7}],5:[function(require,module,exports){
983 -"use strict";
984 -
985 -var styles = "#boxzilla-overlay{position:fixed;background:rgba(0,0,0,.65);width:100%;height:100%;left:0;top:0;z-index:99999}.boxzilla-center-container{position:fixed;top:0;left:0;right:0;height:0;text-align:center;z-index:999999;line-height:0}.boxzilla-center-container .boxzilla{display:inline-block;text-align:left;position:relative;line-height:normal}.boxzilla{position:fixed;z-index:999999;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;background:#fff;padding:25px}.boxzilla.boxzilla-top-left{top:0;left:0}.boxzilla.boxzilla-top-right{top:0;right:0}.boxzilla.boxzilla-bottom-left{bottom:0;left:0}.boxzilla.boxzilla-bottom-right{bottom:0;right:0}.boxzilla-content>:first-child{margin-top:0;padding-top:0}.boxzilla-content>:last-child{margin-bottom:0;padding-bottom:0}.boxzilla-close-icon{position:absolute;right:0;top:0;text-align:center;padding:6px;cursor:pointer;-webkit-appearance:none;font-size:28px;font-weight:700;line-height:20px;color:#000;opacity:.5}.boxzilla-close-icon:focus,.boxzilla-close-icon:hover{opacity:.8}";
889 +const styles = `#boxzilla-overlay{position:fixed;background:rgba(0,0,0,.65);width:100%;height:100%;left:0;top:0;z-index:99999}.boxzilla-center-container{position:fixed;top:0;left:0;right:0;height:0;text-align:center;z-index:999999;line-height:0}.boxzilla-center-container .boxzilla{display:inline-block;text-align:left;position:relative;line-height:normal}.boxzilla{position:fixed;z-index:999999;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;background:#fff;padding:25px}.boxzilla.boxzilla-top-left{top:0;left:0}.boxzilla.boxzilla-top-right{top:0;right:0}.boxzilla.boxzilla-bottom-left{bottom:0;left:0}.boxzilla.boxzilla-bottom-right{bottom:0;right:0}.boxzilla-content>:first-child{margin-top:0;padding-top:0}.boxzilla-content>:last-child{margin-bottom:0;padding-bottom:0}.boxzilla-close-icon{position:absolute;right:0;top:0;text-align:center;padding:6px;cursor:pointer;-webkit-appearance:none;font-size:28px;font-weight:700;line-height:20px;color:#000;opacity:.5}.boxzilla-close-icon:focus,.boxzilla-close-icon:hover{opacity:.8}`;
986 890 module.exports = styles;
987 -
988 891 },{}],6:[function(require,module,exports){
989 892 'use strict';
990 893
991 -var Timer = function Timer(start) {
894 +var Timer = function(start) {
992 895 this.time = start;
993 896 this.interval = 0;
994 897 };
995 898
996 -Timer.prototype.tick = function () {
899 +Timer.prototype.tick = function() {
997 900 this.time++;
998 901 };
999 902
1000 -Timer.prototype.start = function () {
1001 - if (!this.interval) {
903 +Timer.prototype.start = function() {
904 + if( ! this.interval ) {
1002 905 this.interval = window.setInterval(this.tick.bind(this), 1000);
1003 906 }
1004 907 };
1005 908
1006 -Timer.prototype.stop = function () {
1007 - if (this.interval) {
909 +Timer.prototype.stop = function() {
910 + if( this.interval ) {
1008 911 window.clearInterval(this.interval);
1009 912 this.interval = 0;
1010 913 }
1011 914 };
@@ -1010,9 +913,8 @@
1010 913 }
1011 914 };
1012 915
1013 916 module.exports = Timer;
1014 -
1015 917 },{}],7:[function(require,module,exports){
1016 918 /*!
1017 919 * EventEmitter v4.2.11 - git.io/ee
1018 920 * Unlicense - http://unlicense.org/