PluginProbe
Boxzilla – WordPress Popup Builder / 3.2
Boxzilla – WordPress Popup Builder v3.2
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 +1002 -544 3.03.2 View file →
@@ -1,592 +1,144 @@
1 -(function () { var require = 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){
1 +(function () { var require = undefined; var module = undefined; var exports = undefined; var define = undefined; (function(){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}return e})()({1:[function(require,module,exports){
2 2 'use strict';
3 3
4 -var Boxzilla = require('boxzilla');
5 -var options = window.boxzilla_options;
6 -var isLoggedIn = document.body.className.indexOf('logged-in') > -1;
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; };
7 5
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 -}
6 +(function () {
7 + 'use strict';
12 8
13 -// init boxzilla
14 -Boxzilla.init();
9 + var Boxzilla = require('boxzilla');
10 + var options = window.boxzilla_options;
15 11
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;
12 + // expose Boxzilla object to window
13 + window.Boxzilla = Boxzilla;
21 14
22 - // create box
23 - var box = Boxzilla.create( boxOpts.id, boxOpts);
24 -
25 - // add custom css to box
26 - css(box.element, boxOpts.css);
27 -}
15 + // helper function for setting CSS styles
16 + function css(element, styles) {
17 + if (styles.background_color) {
18 + element.style.background = styles.background_color;
19 + }
28 20
29 -function css(element, styles) {
30 - if( styles.background_color ) {
31 - element.style.background = styles.background_color;
32 - }
21 + if (styles.color) {
22 + element.style.color = styles.color;
23 + }
33 24
34 - if( styles.color ) {
35 - element.style.color = styles.color;
36 - }
25 + if (styles.border_color) {
26 + element.style.borderColor = styles.border_color;
27 + }
37 28
38 - if( styles.border_color ) {
39 - element.style.borderColor = styles.border_color;
40 - }
29 + if (styles.border_width) {
30 + element.style.borderWidth = parseInt(styles.border_width) + "px";
31 + }
41 32
42 - if( styles.border_width ) {
43 - element.style.borderWidth = parseInt(styles.border_width) + "px";
44 - }
33 + if (styles.border_style) {
34 + element.style.borderStyle = styles.border_style;
35 + }
45 36
46 - if( styles.border_style ) {
47 - element.style.borderStyle = styles.border_style;
37 + if (styles.width) {
38 + element.style.maxWidth = parseInt(styles.width) + "px";
39 + }
48 40 }
49 41
50 - if( styles.width ) {
51 - element.style.maxWidth = parseInt(styles.width) + "px";
52 - }
53 -}
42 + function createBoxesFromConfig() {
54 43
55 -window.Boxzilla = Boxzilla;
56 -},{"boxzilla":3}],2:[function(require,module,exports){
57 -'use strict';
44 + // failsafe against including script twice.
45 + if (options.inited) {
46 + return;
47 + }
58 48
59 -var $ = window.jQuery,
60 - defaults = {
61 - 'animation': 'fade',
62 - 'rehide': false,
63 - 'content': '',
64 - 'cookieTime': 0,
65 - 'icon': '&times',
66 - 'minimumScreenWidth': 0,
67 - 'position': 'center',
68 - 'testMode': false,
69 - 'trigger': false,
70 - 'closable': true
71 - }, Boxzilla;
49 + // create boxes from options
50 + for (var i = 0; i < options.boxes.length; i++) {
51 + // get opts
52 + var boxOpts = options.boxes[i];
53 + boxOpts.testMode = isLoggedIn && options.testMode;
72 54
73 -/**
74 - * Merge 2 objects, values of the latter overwriting the former.
75 - *
76 - * @param obj1
77 - * @param obj2
78 - * @returns {*}
79 - */
80 -function merge( obj1, obj2 ) {
81 - var obj3 = {};
82 - for (var attrname in obj1) { obj3[attrname] = obj1[attrname]; }
83 - for (var attrname in obj2) { obj3[attrname] = obj2[attrname]; }
84 - return obj3;
85 -}
55 + // set box content element
56 + boxOpts.content = document.getElementById('boxzilla-box-' + boxOpts.id + '-content');
86 57
87 -// Box Object
88 -var Box = function( id, config ) {
89 - this.id = id;
58 + // create box
59 + var box = Boxzilla.create(boxOpts.id, boxOpts);
90 60
91 - // store config values
92 - this.config = merge(defaults, config);
61 + // add box slug to box element as classname
62 + box.element.className = box.element.className + ' boxzilla-' + boxOpts.post.slug;
93 63
94 - // store ref to overlay
95 - this.overlay = document.getElementById('boxzilla-overlay');
64 + // add custom css to box
65 + css(box.element, boxOpts.css);
96 66
97 - // state
98 - this.visible = false;
99 - this.closed = false;
100 - this.triggered = false;
101 - this.triggerHeight = 0;
102 - this.cookieSet = false;
67 + box.element.firstChild.firstChild.className += " first-child";
68 + box.element.firstChild.lastChild.className += " last-child";
103 69
104 - // if a trigger was given, calculate values once and store
105 - if( this.config.trigger ) {
106 - if( this.config.trigger.method === 'percentage' || this.config.trigger.method === 'element' ) {
107 - this.triggerHeight = this.calculateTriggerHeight();
70 + // maybe show box right away
71 + if (box.fits() && locationHashRefersBox(box)) {
72 + box.show();
73 + }
108 74 }
109 75
110 - this.cookieSet = this.isCookieSet();
111 - }
76 + // set flag to prevent initialising twice
77 + options.inited = true;
112 78
113 - // create dom element for this box
114 - this.element = this.dom();
115 - this.$element = $(this.element);
79 + // trigger "done" event.
80 + Boxzilla.trigger('done');
116 81
117 - // further initialise the box
118 - this.events();
119 -};
120 -
121 -// initialise the box
122 -Box.prototype.events = function() {
123 - var box = this;
124 -
125 - // attach event to "close" icon inside box
126 - this.$element.find('.boxzilla-close-icon').click(box.dismiss.bind(this));
127 -
128 - this.$element.on('click', 'a', function(e) {
129 - Boxzilla.trigger('box.interactions.link', [ box, e.target ] );
130 - });
131 -
132 - this.$element.on('submit', 'form', function(e) {
133 - box.setCookie();
134 - Boxzilla.trigger('box.interactions.form', [ box, e.target ]);
135 - });
136 -
137 - // attach event to all links referring #boxzilla-{box_id}
138 - $(document.body).on('click', 'a[href="#boxzilla-' + box.id + '"]', function() {
139 - box.toggle();
140 - return false;
141 - });
142 -
143 - // maybe show box right away
144 - if( this.config.trigger.method === "time_on_page" && this.mayAutoShow() ) {
145 - window.setTimeout(this.trigger.bind(this), this.config.trigger.value * 1000 );
146 - // auto-show the box if box is referenced from URL
147 - } else if( this.fits() && this.locationHashRefersBox() ) {
148 - $(window).load(this.show.bind(this));
82 + // maybe open box with MC4WP form in it
83 + maybeOpenMailChimpForWordPressBox();
149 84 }
150 85
151 -};
152 -
153 -// generate dom elements for this box
154 -Box.prototype.dom = function() {
155 -
156 - var wrapper = document.createElement('div');
157 - wrapper.className = 'boxzilla-container boxzilla-' + this.config.position + '-container';
158 -
159 - var box = document.createElement('div');
160 - box.className = 'boxzilla boxzilla-' + this.id + ' boxzilla-' + this.config.position;
161 - box.style.display = 'none';
162 - wrapper.appendChild(box);
163 -
164 - var content = document.createElement('div');
165 - content.className = 'boxzilla-content';
166 - content.innerHTML = this.config.content;
167 - box.appendChild(content);
168 -
169 - if( this.config.closable && this.config.icon ) {
170 - var icon = document.createElement('span');
171 - icon.className = "boxzilla-close-icon";
172 - icon.innerHTML = this.config.icon;
173 - box.appendChild(icon);
174 - }
175 -
176 - document.body.appendChild(wrapper);
177 -
178 - return box;
179 -};
180 -
181 -// set (calculate) custom box styling depending on box options
182 -Box.prototype.setCustomBoxStyling = function() {
183 -
184 - // reset element to its initial state
185 - this.element.style.overflowY = 'auto';
186 - this.element.style.maxHeight = 'none';
187 -
188 - // get new dimensions
189 - var windowHeight = window.innerHeight;
190 - var boxHeight = this.$element.outerHeight();
191 -
192 - // add scrollbar to box and limit height
193 - if( boxHeight > windowHeight ) {
194 - this.element.style.maxHeight = windowHeight + "px";
195 - this.element.style.overflowY = 'scroll';
196 - }
197 -
198 - // set new top margin for boxes which are centered
199 - if( this.config.position === 'center' ) {
200 - var newTopMargin = ( ( windowHeight - boxHeight ) / 2 );
201 - newTopMargin = newTopMargin >= 0 ? newTopMargin : 0;
202 - this.element.style.marginTop = newTopMargin + "px";
203 - }
204 -
205 -};
206 -
207 -// toggle visibility of the box
208 -Box.prototype.toggle = function(show) {
209 -
210 - // revert visibility if no explicit argument is given
211 - if( typeof( show ) === "undefined" ) {
212 - show = ! this.visible;
213 - }
214 -
215 - // do nothing if element is being animated
216 - if( this.$element.is(':animated') ) {
217 - return false;
218 - }
219 -
220 - // is box already at desired visibility?
221 - if( show === this.visible ) {
222 - return false;
223 - }
224 -
225 - // if box should be hidden but is not closable, bail.
226 - if( ! show && ! this.config.closable ) {
227 - return false;
228 - }
229 -
230 - // set new visibility status
231 - this.visible = show;
232 -
233 - // calculate custom styling for which CSS is "too stupid"
234 - this.setCustomBoxStyling();
235 -
236 - // fadein / fadeout the overlay if position is "center"
237 - if( this.config.position === 'center' ) {
238 - $(this.overlay).fadeToggle('slow');
239 - }
240 -
241 - // trigger event
242 - Boxzilla.trigger('box.' + ( show ? 'show' : 'hide' ), [ this ] );
243 -
244 - // show or hide box using selected animation
245 - if( this.config.animation === 'fade' ) {
246 - this.$element.fadeToggle( 'slow' );
247 - } else {
248 - this.$element.slideToggle( 'slow' );
249 - }
250 -
251 - // // focus on first input field in box
252 - // this.$element.find('input').first().focus();
253 -
254 - return true;
255 -};
256 -
257 -// show the box
258 -Box.prototype.show = function() {
259 - return this.toggle(true);
260 -};
261 -
262 -// hide the box
263 -Box.prototype.hide = function() {
264 - return this.toggle(false);
265 -};
266 -
267 -// calculate trigger height
268 -Box.prototype.calculateTriggerHeight = function() {
269 - var triggerHeight = 0;
270 -
271 - if( this.config.trigger.method === 'element' ) {
272 - var $triggerElement = $(this.config.trigger.value).first();
273 - triggerHeight = ( $triggerElement.length > 0 ) ? $triggerElement.offset().top : 0;
274 - } else if( this.config.trigger.method === 'percentage' ) {
275 - triggerHeight = ( this.config.trigger.value / 100 * $(document).height() );
276 - }
277 -
278 - return triggerHeight;
279 -};
280 -
281 -// set cookie that disables automatically showing the box
282 -Box.prototype.setCookie = function() {
283 - // do nothing if cookieTime evaluates to false
284 - if(! this.config.cookieTime) {
285 - return;
286 - }
287 -
288 - var expiryDate = new Date();
289 - expiryDate.setDate( expiryDate.getDate() + this.config.cookieTime );
290 - document.cookie = 'boxzilla_box_'+ this.id + '=true; expires='+ expiryDate.toUTCString() +'; path=/';
291 -};
292 -
293 -// checks whether window.location.hash equals the box element ID or that of any element inside the box
294 -Box.prototype.locationHashRefersBox = function() {
295 -
296 - if( ! window.location.hash || 0 === window.location.hash.length ) {
297 - return false;
298 - }
299 -
300 - var elementId = window.location.hash.substring(1);
301 - if( elementId === this.element.id ) {
302 - return true;
303 - } else if( this.element.querySelector('#' + elementId) ) {
304 - return true;
305 - }
306 -
307 - return false;
308 -};
309 -
310 -Box.prototype.fits = function() {
311 - if( this.config.minimumScreenWidth <= 0 ) {
312 - return true;
313 - }
314 -
315 - return window.innerWidth > this.config.minimumScreenWidth
316 -};
317 -
318 -// is this box enabled?
319 -Box.prototype.mayAutoShow = function() {
320 -
321 - // don't show if box was closed (dismissed) before
322 - if( this.closed ) {
323 - return false;
324 - }
325 -
326 - // check if box fits on given minimum screen width
327 - if( ! this.fits() ) {
328 - return false;
329 - }
330 -
331 - // if trigger empty or error in calculating triggerHeight, return false
332 - if( ! this.config.trigger ) {
333 - return false;
334 - }
335 -
336 - // rely on cookie value (show if not set, don't show if set)
337 - return ! this.cookieSet;
338 -};
339 -
340 -Box.prototype.mayRehide = function() {
341 - return this.config.rehide && this.triggered;
342 -};
343 -
344 -Box.prototype.isCookieSet = function() {
345 - // always show on test mode
346 - if( this.config.testMode ) {
347 - return false;
348 - }
349 -
350 - // check for cookie
351 - if( ! this.config.cookieTime ) {
352 - return false;
353 - }
354 -
355 - var cookieSet = document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + 'boxzilla_box_' + this.id + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1") === "true";
356 - return cookieSet;
357 -
358 -};
359 -
360 -Box.prototype.trigger = function() {
361 - var shown = this.show();
362 - if( shown ) {
363 - this.triggered = true;
364 - }
365 -};
366 -
367 -Box.prototype.dismiss = function() {
368 - this.hide();
369 - this.setCookie();
370 - this.closed = true;
371 - Boxzilla.trigger('box.dismiss', [ this ]);
372 -};
373 -
374 -module.exports = function(_Boxzilla) {
375 - Boxzilla = _Boxzilla;
376 - return Box;
377 -};
378 -},{}],3:[function(require,module,exports){
379 -'use strict';
380 -
381 -var $ = window.jQuery,
382 - EventEmitter = require('wolfy87-eventemitter'),
383 - Boxzilla = Object.create(EventEmitter.prototype),
384 - Box = require('./Box.js')(Boxzilla),
385 - boxes = {},
386 - windowHeight = window.innerHeight,
387 - overlay = document.createElement('div'),
388 - exitIntentDelayTimer,
389 - exitIntentTriggered;
390 -
391 -function each( obj, callback ) {
392 - for( var key in obj ) {
393 - if(! obj.hasOwnProperty(key)) continue;
394 - callback(obj[key]);
395 - }
396 -}
397 -
398 -function throttle(fn, threshhold, scope) {
399 - threshhold || (threshhold = 250);
400 - var last,
401 - deferTimer;
402 - return function () {
403 - var context = scope || this;
404 -
405 - var now = +new Date,
406 - args = arguments;
407 - if (last && now < last + threshhold) {
408 - // hold on to it
409 - clearTimeout(deferTimer);
410 - deferTimer = setTimeout(function () {
411 - last = now;
412 - fn.apply(context, args);
413 - }, threshhold);
414 - } else {
415 - last = now;
416 - fn.apply(context, args);
86 + function locationHashRefersBox(box) {
87 + if (!window.location.hash || 0 === window.location.hash.length) {
88 + return false;
417 89 }
418 - };
419 -}
420 90
421 -// "keyup" listener
422 -function onKeyUp(e) {
423 - if (e.keyCode == 27) {
424 - Boxzilla.dismiss();
425 - }
426 -}
91 + var elementId = window.location.hash.substring(1);
427 92
428 -function checkTimeCriteria() {
429 - var start = sessionStorage.getItem('boxzilla_start_time');
430 - var now = Date.now();
431 - var timeOnSite = ( now - start ) / 1000;
432 -
433 - each(boxes, function(box) {
434 - if( ! box.mayAutoShow() || box.config.trigger.method !== 'time_on_site' ) {
435 - return;
93 + // only attempt on strings looking like an ID
94 + var regex = /^[a-zA-Z\-\_0-9]+$/;
95 + if (!regex.test(elementId)) {
96 + return false;
436 97 }
437 98
438 - if( timeOnSite > box.config.trigger.value ) {
439 - box.trigger();
99 + if (elementId === box.element.id) {
100 + return true;
101 + } else if (box.element.querySelector('#' + elementId)) {
102 + return true;
440 103 }
441 - });
442 -}
443 104
444 -// check triggerHeight criteria for all boxes
445 -function checkHeightCriteria() {
446 - var scrollY = window.scrollY;
447 - var scrollHeight = scrollY + ( windowHeight * 0.9 );
105 + return false;
106 + }
448 107
449 - each(boxes, function(box) {
450 - if( ! box.mayAutoShow() || box.triggerHeight <= 0 ) {
108 + function maybeOpenMailChimpForWordPressBox() {
109 + if (_typeof(window.mc4wp_forms_config) !== "object" || !window.mc4wp_forms_config.submitted_form) {
451 110 return;
452 111 }
453 112
454 - if( scrollHeight > box.triggerHeight ) {
455 - box.trigger();
456 - } else if( box.mayRehide() ) {
457 - box.hide();
113 + var selector = '#' + window.mc4wp_forms_config.submitted_form.element_id;
114 + var boxes = Boxzilla.boxes;
115 + for (var boxId in boxes) {
116 + if (!boxes.hasOwnProperty(boxId)) {
117 + continue;
118 + }
119 + var box = boxes[boxId];
120 + if (box.element.querySelector(selector)) {
121 + box.show();
122 + return;
123 + }
458 124 }
459 - });
460 -}
461 -
462 -// recalculate heights and variables based on height
463 -function recalculateHeights() {
464 - windowHeight = window.innerHeight;
465 -
466 - each(boxes, function(box) {
467 - box.setCustomBoxStyling();
468 - });
469 -}
470 -
471 -function onOverlayClick(e) {
472 - var x = e.offsetX;
473 - var y = e.offsetY;
474 -
475 - // calculate if click was near a box to avoid closing it (click error margin)
476 - each(boxes, function(box) {
477 - var rect = box.element.getBoundingClientRect();
478 - var margin = 100 + ( window.innerWidth * 0.05 );
479 -
480 - // if click was not anywhere near box, dismiss it.
481 - if( x < ( rect.left - margin ) || x > ( rect.right + margin ) || y < ( rect.top - margin ) || y > ( rect.bottom + margin ) ) {
482 - box.dismiss();
483 - }
484 - });
485 -}
486 -
487 -function triggerExitIntent() {
488 - if(exitIntentTriggered) return;
489 -
490 - each(boxes, function(box) {
491 - if(box.mayAutoShow() && box.config.trigger.method === 'exit_intent' ) {
492 - box.trigger();
493 - }
494 - });
495 -
496 - exitIntentTriggered = true;
497 -}
498 -
499 -function onMouseLeave(e) {
500 - // did mouse leave at top of window?
501 - if( e.clientY < 0 ) {
502 - exitIntentDelayTimer = window.setTimeout(triggerExitIntent, 1000);
503 125 }
504 -}
505 126
506 -function onMouseEnter() {
507 - if( exitIntentDelayTimer ) {
508 - window.clearInterval(exitIntentDelayTimer);
509 - exitIntentDelayTimer = null;
127 + // print message when test mode is enabled
128 + var isLoggedIn = document.body.className.indexOf('logged-in') > -1;
129 + if (isLoggedIn && options.testMode) {
130 + console.log('Boxzilla: Test mode is enabled. Please disable test mode if you\'re done testing.');
510 131 }
511 -}
512 132
513 -// initialise & add event listeners
514 -Boxzilla.init = function() {
515 - // add overlay element to dom
516 - overlay.id = 'boxzilla-overlay';
517 - document.body.appendChild(overlay);
133 + // init boxzilla
134 + Boxzilla.init();
518 135
519 - // event binds
520 - $(window).on('scroll', throttle(checkHeightCriteria));
521 - $(window).on('resize', throttle(recalculateHeights));
522 - $(window).on('load', recalculateHeights );
523 - $(document).on('mouseleave', onMouseLeave);
524 - $(document).on('mouseenter', onMouseEnter);
525 - $(document).on('keyup', onKeyUp);
526 - $(overlay).click(onOverlayClick);
527 - window.setInterval(checkTimeCriteria, 1000);
136 + // on window.load, create DOM elements for boxes
137 + window.addEventListener('load', createBoxesFromConfig);
138 +})();
528 139
529 - if(! sessionStorage.getItem('boxzilla_start_time')) {
530 - sessionStorage.setItem('boxzilla_start_time', Date.now());
531 - }
532 -
533 - Boxzilla.trigger('ready');
534 -};
535 -
536 -/**
537 - * Create a new Box
538 - *
539 - * @param string id
540 - * @param object opts
541 - *
542 - * @returns Box
543 - */
544 -Boxzilla.create = function(id, opts) {
545 - boxes[id] = new Box(id, opts);
546 - return boxes[id];
547 -};
548 -
549 -// dismiss a single box (or all by omitting id param)
550 -Boxzilla.dismiss = function(id) {
551 - // if no id given, dismiss all current open boxes
552 - if( typeof(id) === "undefined" ) {
553 - each(boxes, function(box) { box.dismiss(); });
554 - } else if( typeof( boxes[id] ) === "object" ) {
555 - boxes[id].dismiss();
556 - }
557 -};
558 -
559 -Boxzilla.hide = function(id) {
560 - if( typeof(id) === "undefined" ) {
561 - each(boxes, function(box) { box.hide(); });
562 - } else if( typeof( boxes[id] ) === "object" ) {
563 - boxes[id].hide();
564 - }
565 -};
566 -
567 -Boxzilla.show = function(id) {
568 - if( typeof(id) === "undefined" ) {
569 - each(boxes, function(box) { box.show(); });
570 - } else if( typeof( boxes[id] ) === "object" ) {
571 - boxes[id].show();
572 - }
573 -};
574 -
575 -Boxzilla.toggle = function(id) {
576 - if( typeof(id) === "undefined" ) {
577 - each(boxes, function(box) { box.toggle(); });
578 - } else if( typeof( boxes[id] ) === "object" ) {
579 - boxes[id].toggle();
580 - }
581 -};
582 -
583 -if ( typeof module !== 'undefined' && module.exports ) {
584 - module.exports = Boxzilla;
585 -} else {
586 - this.Boxzilla = Boxzilla;
587 -}
588 -},{"./Box.js":2,"wolfy87-eventemitter":4}],4:[function(require,module,exports){
140 +},{"boxzilla":5}],2:[function(require,module,exports){
589 141 /*!
590 142 * EventEmitter v4.2.11 - git.io/ee
591 143 * Unlicense - http://unlicense.org/
592 144 * Oliver Caldwell - http://oli.me.uk/
@@ -1060,6 +612,912 @@
1060 612 exports.EventEmitter = EventEmitter;
1061 613 }
1062 614 }.call(this));
1063 615
616 +},{}],3:[function(require,module,exports){
617 +'use strict';
618 +
619 +var duration = 320;
620 +
621 +function css(element, styles) {
622 + for (var property in styles) {
623 + element.style[property] = styles[property];
624 + }
625 +}
626 +
627 +function initObjectProperties(properties, value) {
628 + var newObject = {};
629 + for (var i = 0; i < properties.length; i++) {
630 + newObject[properties[i]] = value;
631 + }
632 + return newObject;
633 +}
634 +
635 +function copyObjectProperties(properties, object) {
636 + var newObject = {};
637 + for (var i = 0; i < properties.length; i++) {
638 + newObject[properties[i]] = object[properties[i]];
639 + }
640 + return newObject;
641 +}
642 +
643 +/**
644 + * Checks if the given element is currently being animated.
645 + *
646 + * @param element
647 + * @returns {boolean}
648 + */
649 +function animated(element) {
650 + return !!element.getAttribute('data-animated');
651 +}
652 +
653 +/**
654 + * Toggles the element using the given animation.
655 + *
656 + * @param element
657 + * @param animation Either "fade" or "slide"
658 + */
659 +function toggle(element, animation, callbackFn) {
660 + var nowVisible = element.style.display != 'none' || element.offsetLeft > 0;
661 +
662 + // create clone for reference
663 + var clone = element.cloneNode(true);
664 + var cleanup = function cleanup() {
665 + element.removeAttribute('data-animated');
666 + element.setAttribute('style', clone.getAttribute('style'));
667 + element.style.display = nowVisible ? 'none' : '';
668 + if (callbackFn) {
669 + callbackFn();
670 + }
671 + };
672 +
673 + // store attribute so everyone knows we're animating this element
674 + element.setAttribute('data-animated', "true");
675 +
676 + // toggle element visiblity right away if we're making something visible
677 + if (!nowVisible) {
678 + element.style.display = '';
679 + }
680 +
681 + var hiddenStyles, visibleStyles;
682 +
683 + // animate properties
684 + if (animation === 'slide') {
685 + hiddenStyles = initObjectProperties(["height", "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom"], 0);
686 + visibleStyles = {};
687 +
688 + if (!nowVisible) {
689 + var computedStyles = window.getComputedStyle(element);
690 + visibleStyles = copyObjectProperties(["height", "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom"], computedStyles);
691 +
692 + // in some browsers, getComputedStyle returns "auto" value. this falls back to getBoundingClientRect() in those browsers since we need an actual height.
693 + if (!isFinite(visibleStyles.height)) {
694 + var clientRect = element.getBoundingClientRect();
695 + visibleStyles.height = clientRect.height;
696 + }
697 + css(element, hiddenStyles);
698 + }
699 +
700 + // don't show a scrollbar during animation
701 + element.style.overflowY = 'hidden';
702 + animate(element, nowVisible ? hiddenStyles : visibleStyles, cleanup);
703 + } else {
704 + hiddenStyles = { opacity: 0 };
705 + visibleStyles = { opacity: 1 };
706 + if (!nowVisible) {
707 + css(element, hiddenStyles);
708 + }
709 +
710 + animate(element, nowVisible ? hiddenStyles : visibleStyles, cleanup);
711 + }
712 +}
713 +
714 +function animate(element, targetStyles, fn) {
715 + var last = +new Date();
716 + var initialStyles = window.getComputedStyle(element);
717 + var currentStyles = {};
718 + var propSteps = {};
719 +
720 + for (var property in targetStyles) {
721 + // make sure we have an object filled with floats
722 + targetStyles[property] = parseFloat(targetStyles[property]);
723 +
724 + // calculate step size & current value
725 + var to = targetStyles[property];
726 + var current = parseFloat(initialStyles[property]);
727 +
728 + // is there something to do?
729 + if (current == to) {
730 + delete targetStyles[property];
731 + continue;
732 + }
733 +
734 + propSteps[property] = (to - current) / duration; // points per second
735 + currentStyles[property] = current;
736 + }
737 +
738 + var tick = function tick() {
739 + var now = +new Date();
740 + var timeSinceLastTick = now - last;
741 + var done = true;
742 +
743 + var step, to, increment, newValue;
744 + for (var property in targetStyles) {
745 + step = propSteps[property];
746 + to = targetStyles[property];
747 + increment = step * timeSinceLastTick;
748 + newValue = currentStyles[property] + increment;
749 +
750 + if (step > 0 && newValue >= to || step < 0 && newValue <= to) {
751 + newValue = to;
752 + } else {
753 + done = false;
754 + }
755 +
756 + // store new value
757 + currentStyles[property] = newValue;
758 +
759 + var suffix = property !== "opacity" ? "px" : "";
760 + element.style[property] = newValue + suffix;
761 + }
762 +
763 + last = +new Date();
764 +
765 + // keep going until we're done for all props
766 + if (!done) {
767 + window.requestAnimationFrame && requestAnimationFrame(tick) || setTimeout(tick, 32);
768 + } else {
769 + // call callback
770 + fn && fn();
771 + }
772 + };
773 +
774 + tick();
775 +}
776 +
777 +module.exports = {
778 + 'toggle': toggle,
779 + 'animate': animate,
780 + 'animated': animated
781 +};
782 +
783 +},{}],4:[function(require,module,exports){
784 +'use strict';
785 +
786 +var defaults = {
787 + 'animation': 'fade',
788 + 'rehide': false,
789 + 'content': '',
790 + 'cookie': null,
791 + 'icon': '&times',
792 + 'screenWidthCondition': null,
793 + 'position': 'center',
794 + 'testMode': false,
795 + 'trigger': false,
796 + 'closable': true
797 +},
798 + Boxzilla,
799 + Animator = require('./animator.js');
800 +
801 +/**
802 +* Merge 2 objects, values of the latter overwriting the former.
803 +*
804 +* @param obj1
805 +* @param obj2
806 +* @returns {*}
807 +*/
808 +function merge(obj1, obj2) {
809 + var obj3 = {};
810 + for (var attrname in obj1) {
811 + obj3[attrname] = obj1[attrname];
812 + }
813 + for (var attrname in obj2) {
814 + obj3[attrname] = obj2[attrname];
815 + }
816 + return obj3;
817 +}
818 +
819 +/**
820 +* Get the real height of entire document.
821 +* @returns {number}
822 +*/
823 +function getDocumentHeight() {
824 + var body = document.body,
825 + html = document.documentElement;
826 +
827 + var height = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight);
828 +
829 + return height;
830 +}
831 +
832 +// Box Object
833 +var Box = function Box(id, config) {
834 + this.id = id;
835 +
836 + // store config values
837 + this.config = merge(defaults, config);
838 +
839 + // store ref to overlay
840 + this.overlay = document.getElementById('boxzilla-overlay');
841 +
842 + // state
843 + this.visible = false;
844 + this.dismissed = false;
845 + this.triggered = false;
846 + this.triggerHeight = this.calculateTriggerHeight();
847 + this.cookieSet = this.isCookieSet();
848 + this.element = null;
849 + this.contentElement = null;
850 + this.closeIcon = null;
851 +
852 + // create dom elements for this box
853 + this.dom();
854 +
855 + // further initialise the box
856 + this.events();
857 +};
858 +
859 +// initialise the box
860 +Box.prototype.events = function () {
861 + var box = this;
862 +
863 + // attach event to "close" icon inside box
864 + if (this.closeIcon) {
865 + this.closeIcon.addEventListener('click', this.dismiss.bind(this));
866 + }
867 +
868 + this.element.addEventListener('click', function (e) {
869 + if (e.target.tagName === 'A') {
870 + Boxzilla.trigger('box.interactions.link', [box, e.target]);
871 + }
872 + }, false);
873 +
874 + this.element.addEventListener('submit', function (e) {
875 + box.setCookie();
876 + Boxzilla.trigger('box.interactions.form', [box, e.target]);
877 + }, false);
878 +};
879 +
880 +// generate dom elements for this box
881 +Box.prototype.dom = function () {
882 + var wrapper = document.createElement('div');
883 + wrapper.className = 'boxzilla-container boxzilla-' + this.config.position + '-container';
884 +
885 + var box = document.createElement('div');
886 + box.setAttribute('id', 'boxzilla-' + this.id);
887 + box.className = 'boxzilla boxzilla-' + this.id + ' boxzilla-' + this.config.position;
888 + box.style.display = 'none';
889 + wrapper.appendChild(box);
890 +
891 + var content;
892 + if (typeof this.config.content === "string") {
893 + content = document.createElement('div');
894 + content.innerHTML = this.config.content;
895 + } else {
896 + content = this.config.content;
897 +
898 + // make sure element is visible
899 + content.style.display = '';
900 + }
901 + content.className = 'boxzilla-content';
902 + box.appendChild(content);
903 +
904 + if (this.config.closable && this.config.icon) {
905 + var closeIcon = document.createElement('span');
906 + closeIcon.className = "boxzilla-close-icon";
907 + closeIcon.innerHTML = this.config.icon;
908 + box.appendChild(closeIcon);
909 + this.closeIcon = closeIcon;
910 + }
911 +
912 + document.body.appendChild(wrapper);
913 + this.contentElement = content;
914 + this.element = box;
915 +};
916 +
917 +// set (calculate) custom box styling depending on box options
918 +Box.prototype.setCustomBoxStyling = function () {
919 +
920 + // reset element to its initial state
921 + var origDisplay = this.element.style.display;
922 + this.element.style.display = '';
923 + this.element.style.overflowY = 'auto';
924 + this.element.style.maxHeight = 'none';
925 +
926 + // get new dimensions
927 + var windowHeight = window.innerHeight;
928 + var boxHeight = this.element.clientHeight;
929 +
930 + // add scrollbar to box and limit height
931 + if (boxHeight > windowHeight) {
932 + this.element.style.maxHeight = windowHeight + "px";
933 + this.element.style.overflowY = 'scroll';
934 + }
935 +
936 + // set new top margin for boxes which are centered
937 + if (this.config.position === 'center') {
938 + var newTopMargin = (windowHeight - boxHeight) / 2;
939 + newTopMargin = newTopMargin >= 0 ? newTopMargin : 0;
940 + this.element.style.marginTop = newTopMargin + "px";
941 + }
942 +
943 + this.element.style.display = origDisplay;
944 +};
945 +
946 +// toggle visibility of the box
947 +Box.prototype.toggle = function (show) {
948 +
949 + // revert visibility if no explicit argument is given
950 + if (typeof show === "undefined") {
951 + show = !this.visible;
952 + }
953 +
954 + // is box already at desired visibility?
955 + if (show === this.visible) {
956 + return false;
957 + }
958 +
959 + // is box being animated?
960 + if (Animator.animated(this.element)) {
961 + return false;
962 + }
963 +
964 + // if box should be hidden but is not closable, bail.
965 + if (!show && !this.config.closable) {
966 + return false;
967 + }
968 +
969 + // set new visibility status
970 + this.visible = show;
971 +
972 + // calculate new styling rules
973 + this.setCustomBoxStyling();
974 +
975 + // trigger event
976 + Boxzilla.trigger('box.' + (show ? 'show' : 'hide'), [this]);
977 +
978 + // show or hide box using selected animation
979 + if (this.config.position === 'center') {
980 + this.overlay.classList.toggle('boxzilla-' + this.id + '-overlay');
981 + Animator.toggle(this.overlay, "fade");
982 + }
983 +
984 + Animator.toggle(this.element, this.config.animation, function () {
985 + if (this.visible) {
986 + return;
987 + }
988 + this.contentElement.innerHTML = this.contentElement.innerHTML;
989 + }.bind(this));
990 +
991 + return true;
992 +};
993 +
994 +// show the box
995 +Box.prototype.show = function () {
996 + return this.toggle(true);
997 +};
998 +
999 +// hide the box
1000 +Box.prototype.hide = function () {
1001 + return this.toggle(false);
1002 +};
1003 +
1004 +// calculate trigger height
1005 +Box.prototype.calculateTriggerHeight = function () {
1006 + var triggerHeight = 0;
1007 +
1008 + if (this.config.trigger) {
1009 + if (this.config.trigger.method === 'element') {
1010 + var triggerElement = document.body.querySelector(this.config.trigger.value);
1011 + if (triggerElement) {
1012 + var offset = triggerElement.getBoundingClientRect();
1013 + triggerHeight = offset.top;
1014 + }
1015 + } else if (this.config.trigger.method === 'percentage') {
1016 + triggerHeight = this.config.trigger.value / 100 * getDocumentHeight();
1017 + }
1018 + }
1019 +
1020 + return triggerHeight;
1021 +};
1022 +
1023 +Box.prototype.fits = function () {
1024 + if (!this.config.screenWidthCondition || !this.config.screenWidthCondition.value) {
1025 + return true;
1026 + }
1027 +
1028 + switch (this.config.screenWidthCondition.condition) {
1029 + case "larger":
1030 + return window.innerWidth > this.config.screenWidthCondition.value;
1031 + case "smaller":
1032 + return window.innerWidth < this.config.screenWidthCondition.value;
1033 + }
1034 +
1035 + // meh.. condition should be "smaller" or "larger", just return true.
1036 + return true;
1037 +};
1038 +
1039 +Box.prototype.onResize = function () {
1040 + this.triggerHeight = this.calculateTriggerHeight();
1041 + this.setCustomBoxStyling();
1042 +};
1043 +
1044 +// is this box enabled?
1045 +Box.prototype.mayAutoShow = function () {
1046 +
1047 + if (this.dismissed) {
1048 + return false;
1049 + }
1050 +
1051 + // check if box fits on given minimum screen width
1052 + if (!this.fits()) {
1053 + return false;
1054 + }
1055 +
1056 + // if trigger empty or error in calculating triggerHeight, return false
1057 + if (!this.config.trigger) {
1058 + return false;
1059 + }
1060 +
1061 + // rely on cookie value (show if not set, don't show if set)
1062 + return !this.cookieSet;
1063 +};
1064 +
1065 +Box.prototype.mayRehide = function () {
1066 + return this.config.rehide && this.triggered;
1067 +};
1068 +
1069 +Box.prototype.isCookieSet = function () {
1070 + // always show on test mode or when no auto-trigger is configured
1071 + if (this.config.testMode || !this.config.trigger) {
1072 + return false;
1073 + }
1074 +
1075 + // if either cookie is null or trigger & dismiss are both falsey, don't bother checking.
1076 + if (!this.config.cookie || !this.config.cookie.triggered && !this.config.cookie.dismissed) {
1077 + return false;
1078 + }
1079 +
1080 + var cookieSet = document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + 'boxzilla_box_' + this.id + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1") === "true";
1081 + return cookieSet;
1082 +};
1083 +
1084 +// set cookie that disables automatically showing the box
1085 +Box.prototype.setCookie = function (hours) {
1086 + var expiryDate = new Date();
1087 + expiryDate.setHours(expiryDate.getHours() + hours);
1088 + document.cookie = 'boxzilla_box_' + this.id + '=true; expires=' + expiryDate.toUTCString() + '; path=/';
1089 +};
1090 +
1091 +Box.prototype.trigger = function () {
1092 + var shown = this.show();
1093 + if (!shown) {
1094 + return;
1095 + }
1096 +
1097 + this.triggered = true;
1098 + if (this.config.cookie && this.config.cookie.triggered) {
1099 + this.setCookie(this.config.cookie.triggered);
1100 + }
1101 +};
1102 +
1103 +/**
1104 +* Dismisses the box and optionally sets a cookie.
1105 +*
1106 +* @param e The event that triggered this dismissal.
1107 +* @returns {boolean}
1108 +*/
1109 +Box.prototype.dismiss = function (e) {
1110 + // prevent default action
1111 + e && e.preventDefault();
1112 +
1113 + // only dismiss box if it's currently open.
1114 + if (!this.visible) {
1115 + return false;
1116 + }
1117 +
1118 + // hide box element
1119 + this.hide();
1120 +
1121 + // set cookie
1122 + if (this.config.cookie && this.config.cookie.dismissed) {
1123 + this.setCookie(this.config.cookie.dismissed);
1124 + }
1125 +
1126 + this.dismissed = true;
1127 + Boxzilla.trigger('box.dismiss', [this]);
1128 + return true;
1129 +};
1130 +
1131 +module.exports = function (_Boxzilla) {
1132 + Boxzilla = _Boxzilla;
1133 + return Box;
1134 +};
1135 +
1136 +},{"./animator.js":3}],5:[function(require,module,exports){
1137 +'use strict';
1138 +
1139 +var EventEmitter = require('wolfy87-eventemitter'),
1140 + Boxzilla = Object.create(EventEmitter.prototype),
1141 + Box = require('./box.js')(Boxzilla),
1142 + Timer = require('./timer.js'),
1143 + boxes = [],
1144 + overlay,
1145 + scrollElement = window,
1146 + exitIntentDelayTimer,
1147 + exitIntentTriggered,
1148 + siteTimer,
1149 + pageTimer,
1150 + pageViews;
1151 +
1152 +function throttle(fn, threshhold, scope) {
1153 + threshhold || (threshhold = 250);
1154 + var last, deferTimer;
1155 + return function () {
1156 + var context = scope || this;
1157 +
1158 + var now = +new Date(),
1159 + args = arguments;
1160 + if (last && now < last + threshhold) {
1161 + // hold on to it
1162 + clearTimeout(deferTimer);
1163 + deferTimer = setTimeout(function () {
1164 + last = now;
1165 + fn.apply(context, args);
1166 + }, threshhold);
1167 + } else {
1168 + last = now;
1169 + fn.apply(context, args);
1170 + }
1171 + };
1172 +}
1173 +
1174 +// "keyup" listener
1175 +function onKeyUp(e) {
1176 + if (e.keyCode == 27) {
1177 + Boxzilla.dismiss();
1178 + }
1179 +}
1180 +
1181 +// check "pageviews" criteria for each box
1182 +function checkPageViewsCriteria() {
1183 +
1184 + // don't bother if another box is currently open
1185 + if (isAnyBoxVisible()) {
1186 + return;
1187 + }
1188 +
1189 + boxes.forEach(function (box) {
1190 + if (!box.mayAutoShow()) {
1191 + return;
1192 + }
1193 +
1194 + if (box.config.trigger.method === 'pageviews' && pageViews >= box.config.trigger.value) {
1195 + box.trigger();
1196 + }
1197 + });
1198 +}
1199 +
1200 +// check time trigger criteria for each box
1201 +function checkTimeCriteria() {
1202 + // don't bother if another box is currently open
1203 + if (isAnyBoxVisible()) {
1204 + return;
1205 + }
1206 +
1207 + boxes.forEach(function (box) {
1208 + if (!box.mayAutoShow()) {
1209 + return;
1210 + }
1211 +
1212 + // check "time on site" trigger
1213 + if (box.config.trigger.method === 'time_on_site' && siteTimer.time >= box.config.trigger.value) {
1214 + box.trigger();
1215 + }
1216 +
1217 + // check "time on page" trigger
1218 + if (box.config.trigger.method === 'time_on_page' && pageTimer.time >= box.config.trigger.value) {
1219 + box.trigger();
1220 + }
1221 + });
1222 +}
1223 +
1224 +// check triggerHeight criteria for all boxes
1225 +function checkHeightCriteria() {
1226 +
1227 + var scrollY = scrollElement.hasOwnProperty('pageYOffset') ? scrollElement.pageYOffset : scrollElement.scrollTop;
1228 + scrollY = scrollY + window.innerHeight * 0.9;
1229 +
1230 + boxes.forEach(function (box) {
1231 + if (!box.mayAutoShow() || box.triggerHeight <= 0) {
1232 + return;
1233 + }
1234 +
1235 + if (scrollY > box.triggerHeight) {
1236 + // don't bother if another box is currently open
1237 + if (isAnyBoxVisible()) {
1238 + return;
1239 + }
1240 +
1241 + // trigger box
1242 + box.trigger();
1243 + } else if (box.mayRehide()) {
1244 + box.hide();
1245 + }
1246 + });
1247 +}
1248 +
1249 +// recalculate heights and variables based on height
1250 +function recalculateHeights() {
1251 + boxes.forEach(function (box) {
1252 + box.onResize();
1253 + });
1254 +}
1255 +
1256 +function onOverlayClick(e) {
1257 + var x = e.offsetX;
1258 + var y = e.offsetY;
1259 +
1260 + // calculate if click was less than 40px outside box to avoid closing it by accident
1261 + boxes.forEach(function (box) {
1262 + var rect = box.element.getBoundingClientRect();
1263 + var margin = 40;
1264 +
1265 + // if click was not anywhere near box, dismiss it.
1266 + if (x < rect.left - margin || x > rect.right + margin || y < rect.top - margin || y > rect.bottom + margin) {
1267 + box.dismiss();
1268 + }
1269 + });
1270 +}
1271 +
1272 +function triggerExitIntent() {
1273 + // do nothing if already triggered OR another box is visible.
1274 + if (exitIntentTriggered || isAnyBoxVisible()) {
1275 + return;
1276 + }
1277 +
1278 + boxes.forEach(function (box) {
1279 + if (box.mayAutoShow() && box.config.trigger.method === 'exit_intent') {
1280 + box.trigger();
1281 + }
1282 + });
1283 +
1284 + exitIntentTriggered = true;
1285 +}
1286 +
1287 +function onMouseLeave(e) {
1288 + var delay = 400;
1289 +
1290 + // did mouse leave at top of window?
1291 + if (e.clientY <= 0) {
1292 + exitIntentDelayTimer = window.setTimeout(triggerExitIntent, delay);
1293 + }
1294 +}
1295 +
1296 +function isAnyBoxVisible() {
1297 +
1298 + for (var i = 0; i < boxes.length; i++) {
1299 + var box = boxes[i];
1300 +
1301 + if (box.visible) {
1302 + return true;
1303 + }
1304 + }
1305 +
1306 + return false;
1307 +}
1308 +
1309 +function onMouseEnter() {
1310 + if (exitIntentDelayTimer) {
1311 + window.clearInterval(exitIntentDelayTimer);
1312 + exitIntentDelayTimer = null;
1313 + }
1314 +}
1315 +
1316 +function onElementClick(e) {
1317 + // find <a> element in up to 3 parent elements
1318 + var el = e.target || e.srcElement;
1319 + var depth = 3;
1320 + for (var i = 0; i <= depth; i++) {
1321 + if (!el || el.tagName === 'A') {
1322 + break;
1323 + }
1324 +
1325 + el = el.parentElement;
1326 + }
1327 +
1328 + if (!el || el.tagName !== 'A' || !el.getAttribute('href')) {
1329 + return;
1330 + }
1331 +
1332 + if (el.getAttribute('href').toLowerCase().indexOf('#boxzilla-') === 0) {
1333 + var boxId = el.getAttribute('href').toLowerCase().substring("#boxzilla-".length);
1334 + Boxzilla.toggle(boxId);
1335 + }
1336 +}
1337 +
1338 +var timers = {
1339 + start: function start() {
1340 + try {
1341 + var sessionTime = sessionStorage.getItem('boxzilla_timer');
1342 + if (sessionTime) siteTimer.time = sessionTime;
1343 + } catch (e) {}
1344 + siteTimer.start();
1345 + pageTimer.start();
1346 + },
1347 + stop: function stop() {
1348 + sessionStorage.setItem('boxzilla_timer', siteTimer.time);
1349 + siteTimer.stop();
1350 + pageTimer.stop();
1351 + }
1352 +};
1353 +
1354 +// initialise & add event listeners
1355 +Boxzilla.init = function () {
1356 + document.body.addEventListener('click', onElementClick, true);
1357 +
1358 + try {
1359 + pageViews = sessionStorage.getItem('boxzilla_pageviews') || 0;
1360 + } catch (e) {
1361 + pageViews = 0;
1362 + }
1363 +
1364 + siteTimer = new Timer(0);
1365 + pageTimer = new Timer(0);
1366 +
1367 + // insert styles into DOM
1368 + var styles = require('./styles.js');
1369 + var styleElement = document.createElement('style');
1370 + styleElement.setAttribute("type", "text/css");
1371 + styleElement.innerHTML = styles;
1372 + document.head.appendChild(styleElement);
1373 +
1374 + // add overlay element to dom
1375 + overlay = document.createElement('div');
1376 + overlay.style.display = 'none';
1377 + overlay.id = 'boxzilla-overlay';
1378 + document.body.appendChild(overlay);
1379 +
1380 + // event binds
1381 + scrollElement.addEventListener('touchstart', throttle(checkHeightCriteria), true);
1382 + scrollElement.addEventListener('scroll', throttle(checkHeightCriteria), true);
1383 + window.addEventListener('resize', throttle(recalculateHeights));
1384 + window.addEventListener('load', recalculateHeights);
1385 + overlay.addEventListener('click', onOverlayClick);
1386 + window.setInterval(checkTimeCriteria, 1000);
1387 + window.setTimeout(checkPageViewsCriteria, 1000);
1388 + document.documentElement.addEventListener('mouseleave', onMouseLeave);
1389 + document.documentElement.addEventListener('mouseenter', onMouseEnter);
1390 + document.addEventListener('keyup', onKeyUp);
1391 +
1392 + timers.start();
1393 + window.addEventListener('focus', timers.start);
1394 + window.addEventListener('beforeunload', function () {
1395 + timers.stop();
1396 + sessionStorage.setItem('boxzilla_pageviews', ++pageViews);
1397 + });
1398 + window.addEventListener('blur', timers.stop);
1399 +
1400 + Boxzilla.trigger('ready');
1401 +};
1402 +
1403 +/**
1404 + * Create a new Box
1405 + *
1406 + * @param string id
1407 + * @param object opts
1408 + *
1409 + * @returns Box
1410 + */
1411 +Boxzilla.create = function (id, opts) {
1412 +
1413 + // preserve backwards compat for minimumScreenWidth option
1414 + if (typeof opts.minimumScreenWidth !== "undefined") {
1415 + opts.screenWidthCondition = {
1416 + condition: "larger",
1417 + value: opts.minimumScreenWidth
1418 + };
1419 + }
1420 +
1421 + var box = new Box(id, opts);
1422 + boxes.push(box);
1423 + return box;
1424 +};
1425 +
1426 +Boxzilla.get = function (id) {
1427 + for (var i = 0; i < boxes.length; i++) {
1428 + var box = boxes[i];
1429 + if (box.id == id) {
1430 + return box;
1431 + }
1432 + }
1433 +
1434 + throw new Error("No box exists with ID " + id);
1435 +};
1436 +
1437 +// dismiss a single box (or all by omitting id param)
1438 +Boxzilla.dismiss = function (id) {
1439 + // if no id given, dismiss all current open boxes
1440 + if (typeof id === "undefined") {
1441 + boxes.forEach(function (box) {
1442 + box.dismiss();
1443 + });
1444 + } else {
1445 + Boxzilla.get(id).dismiss();
1446 + }
1447 +};
1448 +
1449 +Boxzilla.hide = function (id) {
1450 + if (typeof id === "undefined") {
1451 + boxes.forEach(function (box) {
1452 + box.hide();
1453 + });
1454 + } else {
1455 + Boxzilla.get(id).hide();
1456 + }
1457 +};
1458 +
1459 +Boxzilla.show = function (id) {
1460 + if (typeof id === "undefined") {
1461 + boxes.forEach(function (box) {
1462 + box.show();
1463 + });
1464 + } else {
1465 + Boxzilla.get(id).show();
1466 + }
1467 +};
1468 +
1469 +Boxzilla.toggle = function (id) {
1470 + if (typeof id === "undefined") {
1471 + boxes.forEach(function (box) {
1472 + box.toggle();
1473 + });
1474 + } else {
1475 + Boxzilla.get(id).toggle();
1476 + }
1477 +};
1478 +
1479 +// expose each individual box.
1480 +Boxzilla.boxes = boxes;
1481 +
1482 +// expose boxzilla object
1483 +window.Boxzilla = Boxzilla;
1484 +
1485 +if (typeof module !== 'undefined' && module.exports) {
1486 + module.exports = Boxzilla;
1487 +}
1488 +
1489 +},{"./box.js":4,"./styles.js":6,"./timer.js":7,"wolfy87-eventemitter":2}],6:[function(require,module,exports){
1490 +"use strict";
1491 +
1492 +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}";
1493 +module.exports = styles;
1494 +
1495 +},{}],7:[function(require,module,exports){
1496 +'use strict';
1497 +
1498 +var Timer = function Timer(start) {
1499 + this.time = start;
1500 + this.interval = 0;
1501 +};
1502 +
1503 +Timer.prototype.tick = function () {
1504 + this.time++;
1505 +};
1506 +
1507 +Timer.prototype.start = function () {
1508 + if (!this.interval) {
1509 + this.interval = window.setInterval(this.tick.bind(this), 1000);
1510 + }
1511 +};
1512 +
1513 +Timer.prototype.stop = function () {
1514 + if (this.interval) {
1515 + window.clearInterval(this.interval);
1516 + this.interval = 0;
1517 + }
1518 +};
1519 +
1520 +module.exports = Timer;
1521 +
1064 1522 },{}]},{},[1]);
1065 - })();
1523 +; })();