PluginProbe
Boxzilla – WordPress Popup Builder / 3.2.18
Boxzilla – WordPress Popup Builder v3.2.18
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/admin-script.js +301 -228 3.0.3 → 3.2.18 View file →
@@ -1,305 +1,366 @@
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){
1 +(function () { var require = undefined; var module = undefined; var exports = undefined; var define = undefined; (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
2 +"use strict";
3 +
2 4 window.Boxzilla_Admin = require('./admin/_admin.js');
5 +
3 6 },{"./admin/_admin.js":2}],2:[function(require,module,exports){
4 -'use strict';
7 +"use strict";
5 8
6 -var $ = window.jQuery;
7 -var Option = require('./_option.js');
8 -var optionControls = document.getElementById('boxzilla-box-options-controls');
9 -var $optionControls = $(optionControls);
9 +(function () {
10 + 'use strict';
10 11
11 -// sanity check, are we on the correct page?
12 -if( $optionControls.length === 0 ) {
13 - return;
14 -}
12 + var $ = window.jQuery;
15 13
16 -var EventEmitter = require('wolfy87-eventemitter');
17 -var events = new EventEmitter();
18 -var Designer = require('./_designer.js')($, Option, events);
19 -var rowTemplate = wp.template('rule-row-template');
20 -var i18n = boxzilla_i18n;
14 + var Option = require('./_option.js');
21 15
22 -// events
23 -$optionControls.on('click', ".boxzilla-add-rule", addRuleFields);
24 -$optionControls.on('click', ".boxzilla-remove-rule", removeRule);
25 -$optionControls.on('change', ".boxzilla-rule-condition", setContextualHelpers);
26 -$optionControls.find('.boxzilla-auto-show-trigger').on('change', toggleTriggerOptions );
16 + var optionControls = document.getElementById('boxzilla-box-options-controls');
17 + var $optionControls = $(optionControls);
18 + var tnLoggedIn = document.createTextNode(' logged in'); // sanity check, are we on the correct page?
27 19
28 -$(window).load(function() {
29 - if( typeof(window.tinyMCE) === "undefined" ) {
30 - document.getElementById('notice-notinymce').style.display = '';
31 - }
32 -});
20 + if ($optionControls.length === 0) {
21 + return;
22 + }
33 23
34 -// call contextual helper method for each row
35 -$('.boxzilla-rule-row').each(setContextualHelpers);
24 + var EventEmitter = require('wolfy87-eventemitter');
36 25
37 -function toggleTriggerOptions() {
38 - $optionControls.find('.boxzilla-trigger-options').toggle( this.value !== '' );
39 -}
26 + var events = new EventEmitter();
40 27
41 -function removeRule() {
42 - $(this).parents('tr').remove();
43 -}
28 + var Designer = require('./_designer.js')($, Option, events);
44 29
45 -function setContextualHelpers() {
30 + var rowTemplate = wp.template('rule-row-template');
31 + var i18n = boxzilla_i18n;
32 + var ruleComparisonEl = document.getElementById('boxzilla-rule-comparison');
33 + var rulesContainerEl = document.getElementById('boxzilla-box-rules'); // events
46 34
47 - var context = ( this.tagName.toLowerCase() === "tr" ) ? this : $(this).parents('tr').get(0);
48 - var condition = context.querySelector('.boxzilla-rule-condition').value;
49 - var valueInput = context.querySelector('.boxzilla-rule-value');
50 - var qualifierInput = context.querySelector('.boxzilla-rule-qualifier');
51 - var betterInput = valueInput.cloneNode(true);
52 - var $betterInput = $(betterInput);
35 + $optionControls.on('click', ".boxzilla-add-rule", addRuleFields);
36 + $optionControls.on('click', ".boxzilla-remove-rule", removeRule);
37 + $optionControls.on('change', ".boxzilla-rule-condition", setContextualHelpers);
38 + $optionControls.find('.boxzilla-auto-show-trigger').on('change', toggleTriggerOptions);
39 + $(ruleComparisonEl).change(toggleAndOrTexts);
40 + $(window).load(function () {
41 + if (typeof window.tinyMCE === "undefined") {
42 + document.getElementById('notice-notinymce').style.display = '';
43 + }
44 + }); // call contextual helper method for each row
53 45
54 - // remove previously added helpers
55 - $(context.querySelectorAll('.boxzilla-helper')).remove();
46 + $('.boxzilla-rule-row').each(setContextualHelpers);
56 47
57 - // prepare better input
58 - betterInput.removeAttribute('name');
59 - betterInput.className = betterInput.className + ' boxzilla-helper';
60 - valueInput.parentNode.insertBefore(betterInput, valueInput.nextSibling);
61 - $betterInput.change(function() { valueInput.value = this.value; });
48 + function toggleAndOrTexts() {
49 + var newText = ruleComparisonEl.value === 'any' ? i18n.or : i18n.and;
50 + $('.boxzilla-andor').text(newText);
51 + }
62 52
63 - betterInput.style.display = '';
64 - valueInput.style.display = 'none';
65 - qualifierInput.style.display = '';
53 + function toggleTriggerOptions() {
54 + $optionControls.find('.boxzilla-trigger-options').toggle(this.value !== '');
55 + }
66 56
67 - // change placeholder for textual help
68 - switch(condition) {
69 - default:
70 - betterInput.placeholder = i18n.enterCommaSeparatedValues;
71 - break;
57 + function removeRule() {
58 + var row = $(this).parents('tr'); // delete andor row
72 59
73 - case '':
74 - case 'everywhere':
75 - qualifierInput.value = '1';
76 - valueInput.value = '';
77 - betterInput.style.display = 'none';
78 - qualifierInput.style.display = 'none';
79 - break;
60 + row.prev().remove(); // delete rule row
80 61
81 - case 'is_single':
82 - case 'is_post':
83 - betterInput.placeholder = i18n.enterCommaSeparatedPosts;
84 - $betterInput.suggest(ajaxurl + "?action=boxzilla_autocomplete&type=post", {multiple:true, multipleSep: ","});
85 - break;
62 + row.remove();
63 + }
86 64
87 - case 'is_page':
88 - betterInput.placeholder = i18n.enterCommaSeparatedPages;
89 - $betterInput.suggest(ajaxurl + "?action=boxzilla_autocomplete&type=page", {multiple:true, multipleSep: ","});
90 - break;
65 + function setContextualHelpers() {
66 + var context = this.tagName.toLowerCase() === "tr" ? this : $(this).parents('tr').get(0);
67 + var condition = context.querySelector('.boxzilla-rule-condition').value;
68 + var valueInput = context.querySelector('.boxzilla-rule-value');
69 + var qualifierInput = context.querySelector('.boxzilla-rule-qualifier');
70 + var betterInput = valueInput.cloneNode(true);
71 + var $betterInput = $(betterInput); // remove previously added helpers
91 72
92 - case 'is_post_type':
93 - betterInput.placeholder = i18n.enterCommaSeparatedPostTypes;
94 - $betterInput.suggest(ajaxurl + "?action=boxzilla_autocomplete&type=post_type", {multiple:true, multipleSep: ","});
95 - break;
73 + $(context.querySelectorAll('.boxzilla-helper')).remove(); // prepare better input
96 74
97 - case 'is_url':
98 - betterInput.placeholder = i18n.enterCommaSeparatedRelativeUrls;
99 - break;
75 + betterInput.removeAttribute('name');
76 + betterInput.className = betterInput.className + ' boxzilla-helper';
77 + valueInput.parentNode.insertBefore(betterInput, valueInput.nextSibling);
78 + $betterInput.change(function () {
79 + valueInput.value = this.value;
80 + });
81 + betterInput.style.display = '';
82 + valueInput.style.display = 'none';
83 + qualifierInput.style.display = '';
84 + qualifierInput.querySelector('option[value="not_contains"]').style.display = 'none';
85 + qualifierInput.querySelector('option[value="contains"]').style.display = 'none';
100 86
101 - case 'is_post_in_category':
102 - $betterInput.suggest(ajaxurl + "?action=boxzilla_autocomplete&type=category", {multiple:true, multipleSep: ","});
103 - break;
87 + if (tnLoggedIn.parentNode) {
88 + tnLoggedIn.parentNode.removeChild(tnLoggedIn);
89 + } // change placeholder for textual help
104 90
105 - case 'is_post_with_tag':
106 - $betterInput.suggest(ajaxurl + "?action=boxzilla_autocomplete&type=post_tag", {multiple:true, multipleSep: ","});
107 - break;
108 - }
109 -}
110 91
111 -function addRuleFields() {
112 - var data = {
113 - 'key': optionControls.querySelectorAll('.boxzilla-rule-row').length
114 - };
115 - var html = rowTemplate(data);
116 - $(document.getElementById('boxzilla-box-rules')).after(html);
117 - return false;
118 -}
92 + switch (condition) {
93 + default:
94 + betterInput.placeholder = i18n.enterCommaSeparatedValues;
95 + break;
119 96
120 -module.exports = {
121 - 'Designer': Designer,
122 - 'Option': Option,
123 - 'events': events
124 -};
97 + case '':
98 + case 'everywhere':
99 + qualifierInput.value = '1';
100 + valueInput.value = '';
101 + betterInput.style.display = 'none';
102 + qualifierInput.style.display = 'none';
103 + break;
125 104
105 + case 'is_single':
106 + case 'is_post':
107 + betterInput.placeholder = i18n.enterCommaSeparatedPosts;
108 + $betterInput.suggest(ajaxurl + "?action=boxzilla_autocomplete&type=post", {
109 + multiple: true,
110 + multipleSep: ","
111 + });
112 + break;
113 +
114 + case 'is_page':
115 + betterInput.placeholder = i18n.enterCommaSeparatedPages;
116 + $betterInput.suggest(ajaxurl + "?action=boxzilla_autocomplete&type=page", {
117 + multiple: true,
118 + multipleSep: ","
119 + });
120 + break;
121 +
122 + case 'is_post_type':
123 + betterInput.placeholder = i18n.enterCommaSeparatedPostTypes;
124 + $betterInput.suggest(ajaxurl + "?action=boxzilla_autocomplete&type=post_type", {
125 + multiple: true,
126 + multipleSep: ","
127 + });
128 + break;
129 +
130 + case 'is_url':
131 + qualifierInput.querySelector('option[value="contains"]').style.display = '';
132 + qualifierInput.querySelector('option[value="not_contains"]').style.display = '';
133 + betterInput.placeholder = i18n.enterCommaSeparatedRelativeUrls;
134 + break;
135 +
136 + case 'is_post_in_category':
137 + $betterInput.suggest(ajaxurl + "?action=boxzilla_autocomplete&type=category", {
138 + multiple: true,
139 + multipleSep: ","
140 + });
141 + break;
142 +
143 + case 'is_post_with_tag':
144 + $betterInput.suggest(ajaxurl + "?action=boxzilla_autocomplete&type=post_tag", {
145 + multiple: true,
146 + multipleSep: ","
147 + });
148 + break;
149 +
150 + case 'is_user_logged_in':
151 + betterInput.style.display = 'none';
152 + valueInput.parentNode.insertBefore(tnLoggedIn, valueInput.nextSibling);
153 + break;
154 +
155 + case 'is_referer':
156 + qualifierInput.querySelector('option[value="contains"]').style.display = '';
157 + qualifierInput.querySelector('option[value="not_contains"]').style.display = '';
158 + break;
159 + }
160 + }
161 +
162 + function addRuleFields() {
163 + var data = {
164 + 'key': optionControls.querySelectorAll('.boxzilla-rule-row').length,
165 + 'andor': ruleComparisonEl.value === 'any' ? i18n.or : i18n.and
166 + };
167 + var html = rowTemplate(data);
168 + $(rulesContainerEl).append(html);
169 + return false;
170 + }
171 +
172 + module.exports = {
173 + 'Designer': Designer,
174 + 'Option': Option,
175 + 'events': events
176 + };
177 +})();
178 +
126 179 },{"./_designer.js":3,"./_option.js":4,"wolfy87-eventemitter":5}],3:[function(require,module,exports){
127 -var Designer = function($, Option, events) {
180 +"use strict";
128 181
129 - // vars
130 - var boxId = document.getElementById('post_ID').value || 0,
131 - $editor, $editorFrame,
132 - $innerEditor,
133 - options = {},
134 - visualEditorInitialised = false;
182 +function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
135 183
136 - var $appearanceControls = $("#boxzilla-box-appearance-controls");
184 +var Designer = function Designer($, Option, events) {
185 + // vars
186 + var boxId = document.getElementById('post_ID').value || 0,
187 + $editor,
188 + $editorFrame,
189 + $innerEditor,
190 + options = {},
191 + visualEditorInitialised = false;
192 + var $appearanceControls = $("#boxzilla-box-appearance-controls"); // create Option objects
137 193
138 - // create Option objects
139 - options.borderColor = new Option('border-color');
140 - options.borderWidth = new Option('border-width');
141 - options.borderStyle = new Option('border-style');
142 - options.backgroundColor = new Option('background-color');
143 - options.width = new Option('width');
144 - options.color = new Option('color');
194 + options.borderColor = new Option('border-color');
195 + options.borderWidth = new Option('border-width');
196 + options.borderStyle = new Option('border-style');
197 + options.backgroundColor = new Option('background-color');
198 + options.width = new Option('width');
199 + options.color = new Option('color'); // functions
145 200
146 - // functions
147 - function init() {
201 + function init() {
202 + // Only run if TinyMCE has actually inited
203 + if (_typeof(window.tinyMCE) !== "object" || tinyMCE.get('content') === null) {
204 + return;
205 + } // add classes to TinyMCE <html>
148 206
149 - // Only run if TinyMCE has actually inited
150 - if( typeof( window.tinyMCE ) !== "object" || tinyMCE.get('content') === null ) {
151 - return;
152 - }
153 207
154 - // add classes to TinyMCE <html>
155 - $editorFrame = $("#content_ifr");
156 - $editor = $editorFrame.contents().find('html');
157 - $editor.css({
158 - 'background': 'white'
159 - });
208 + $editorFrame = $("#content_ifr");
209 + $editor = $editorFrame.contents().find('html');
210 + $editor.css({
211 + 'background': 'white'
212 + }); // add content class and padding to TinyMCE <body>
160 213
161 - // add content class and padding to TinyMCE <body>
162 - $innerEditor = $editor.find('#tinymce');
163 - $innerEditor.addClass('boxzilla boxzilla-' + boxId);
164 - $innerEditor.css({
165 - 'margin': 0,
166 - 'background': 'white',
167 - 'display': 'inline-block',
168 - 'width': 'auto',
169 - 'min-width': '240px',
170 - 'position': 'relative'
171 - });
172 - $innerEditor.get(0).style.cssText += ';padding: 25px !important;';
214 + $innerEditor = $editor.find('#tinymce');
215 + $innerEditor.addClass('boxzilla boxzilla-' + boxId);
216 + $innerEditor.css({
217 + 'margin': 0,
218 + 'background': 'white',
219 + 'display': 'inline-block',
220 + 'width': 'auto',
221 + 'min-width': '240px',
222 + 'position': 'relative'
223 + });
224 + $innerEditor.get(0).style.cssText += ';padding: 25px !important;';
225 + visualEditorInitialised = true;
226 + /* @since 2.0.3 */
173 227
174 - visualEditorInitialised = true;
228 + events.trigger('editor.init');
229 + }
230 + /**
231 + * Applies the styles from the options to the TinyMCE Editor
232 + *
233 + * @return bool
234 + */
175 235
176 - /* @since 2.0.3 */
177 - events.trigger('editor.init');
178 - }
179 236
180 - /**
181 - * Applies the styles from the options to the TinyMCE Editor
182 - *
183 - * @return bool
184 - */
185 - function applyStyles() {
237 + function applyStyles() {
238 + if (!visualEditorInitialised) {
239 + return false;
240 + } // Apply styles from CSS editor.
241 + // Use short timeout to make sure color values are updated.
186 242
187 - if( ! visualEditorInitialised ) {
188 - return false;
189 - }
190 243
191 - // apply styles from CSS editor
192 - $innerEditor.css({
193 - 'border-color': options.borderColor.getColorValue(), //getColorValue( 'borderColor', '' ),
194 - 'border-width': options.borderWidth.getPxValue(), //getPxValue( 'borderWidth', '' ),
195 - 'border-style': options.borderStyle.getValue(), //getValue('borderStyle', '' ),
196 - 'background-color': options.backgroundColor.getColorValue(), //getColorValue( 'backgroundColor', ''),
197 - 'width': options.width.getPxValue(), //getPxValue( 'width', 'auto' ),
198 - 'color': options.color.getColorValue() // getColorValue( 'color', '' )
199 - });
244 + window.setTimeout(function () {
245 + $innerEditor.css({
246 + 'border-color': options.borderColor.getColorValue(),
247 + //getColorValue( 'borderColor', '' ),
248 + 'border-width': options.borderWidth.getPxValue(),
249 + //getPxValue( 'borderWidth', '' ),
250 + 'border-style': options.borderStyle.getValue(),
251 + //getValue('borderStyle', '' ),
252 + 'background-color': options.backgroundColor.getColorValue(),
253 + //getColorValue( 'backgroundColor', ''),
254 + 'width': options.width.getPxValue(),
255 + //getPxValue( 'width', 'auto' ),
256 + 'color': options.color.getColorValue() // getColorValue( 'color', '' )
200 257
201 - /* @since 2.0.3 */
202 - events.trigger('editor.styles.apply');
258 + });
259 + /* @since 2.0.3 */
203 260
204 - return true;
205 - }
261 + events.trigger('editor.styles.apply');
262 + }, 10);
263 + return true;
264 + }
206 265
207 - function resetStyles() {
208 - for( var key in options ) {
209 - if( key.substring(0,5) === 'theme' ) {
210 - continue;
211 - }
266 + function resetStyles() {
267 + for (var key in options) {
268 + if (key.substring(0, 5) === 'theme') {
269 + continue;
270 + }
212 271
213 - options[key].clear();
214 - }
215 - applyStyles();
272 + options[key].clear();
273 + }
216 274
217 - /* @since 2.0.3 */
218 - events.trigger('editor.styles.reset');
219 - }
275 + applyStyles();
276 + /* @since 2.0.3 */
220 277
221 - // event binders
222 - $appearanceControls.find('input.boxzilla-color-field').wpColorPicker({ change: applyStyles, clear: applyStyles });
223 - $appearanceControls.find(":input").not(".boxzilla-color-field").change(applyStyles);
224 - events.on('editor.init', applyStyles);
278 + events.trigger('editor.styles.reset');
279 + } // event binders
225 280
226 - // public methods
227 - return {
228 - 'init': init,
229 - 'resetStyles': resetStyles,
230 - 'options': options
231 - };
232 281
282 + $appearanceControls.find('input.boxzilla-color-field').wpColorPicker({
283 + change: applyStyles,
284 + clear: applyStyles
285 + });
286 + $appearanceControls.find(":input").not(".boxzilla-color-field").change(applyStyles);
287 + events.on('editor.init', applyStyles); // public methods
288 +
289 + return {
290 + 'init': init,
291 + 'resetStyles': resetStyles,
292 + 'options': options
293 + };
233 294 };
234 295
235 296 module.exports = Designer;
297 +
236 298 },{}],4:[function(require,module,exports){
237 299 'use strict';
238 300
239 301 var $ = window.jQuery;
240 302
241 -var Option = function( element ) {
303 +var Option = function Option(element) {
304 + // find corresponding element
305 + if (typeof element == "string") {
306 + element = document.getElementById('boxzilla-' + element);
307 + }
242 308
243 - // find corresponding element
244 - if( typeof(element) == "string" ) {
245 - element = document.getElementById('boxzilla-' + element);
246 - }
309 + if (!element) {
310 + console.error("Unable to find option element.");
311 + }
247 312
248 - if( ! element ) {
249 - console.error("Unable to find option element.");
250 - }
251 -
252 - this.element = element;
313 + this.element = element;
253 314 };
254 315
255 -Option.prototype.getColorValue = function() {
256 - if( this.element.value.length > 0 ) {
257 - if( $(this.element).hasClass('wp-color-field')) {
258 - return $(this.element).wpColorPicker('color');
259 - } else {
260 - return this.element.value;
261 - }
262 - }
316 +Option.prototype.getColorValue = function () {
317 + if (this.element.value.length > 0) {
318 + if ($(this.element).hasClass('wp-color-field')) {
319 + return $(this.element).wpColorPicker('color');
320 + } else {
321 + return this.element.value;
322 + }
323 + }
263 324
264 - return '';
325 + return '';
265 326 };
266 327
267 -Option.prototype.getPxValue = function( fallbackValue ) {
268 - if( this.element.value.length > 0 ) {
269 - return parseInt( this.element.value ) + "px";
270 - }
328 +Option.prototype.getPxValue = function (fallbackValue) {
329 + if (this.element.value.length > 0) {
330 + return parseInt(this.element.value) + "px";
331 + }
271 332
272 - return fallbackValue || '';
333 + return fallbackValue || '';
273 334 };
274 335
275 -Option.prototype.getValue = function( fallbackValue ) {
336 +Option.prototype.getValue = function (fallbackValue) {
337 + if (this.element.value.length > 0) {
338 + return this.element.value;
339 + }
276 340
277 - if( this.element.value.length > 0 ) {
278 - return this.element.value;
279 - }
280 -
281 - return fallbackValue || '';
341 + return fallbackValue || '';
282 342 };
283 343
284 -Option.prototype.clear = function() {
285 - this.element.value = '';
344 +Option.prototype.clear = function () {
345 + this.element.value = '';
286 346 };
287 347
288 -Option.prototype.setValue = function(value) {
289 - this.element.value = value;
348 +Option.prototype.setValue = function (value) {
349 + this.element.value = value;
290 350 };
291 351
292 352 module.exports = Option;
353 +
293 354 },{}],5:[function(require,module,exports){
294 355 /*!
295 - * EventEmitter v4.2.11 - git.io/ee
356 + * EventEmitter v5.2.8 - git.io/ee
296 357 * Unlicense - http://unlicense.org/
297 - * Oliver Caldwell - http://oli.me.uk/
358 + * Oliver Caldwell - https://oli.me.uk/
298 359 * @preserve
299 360 */
300 361
301 -;(function () {
362 +;(function (exports) {
302 363 'use strict';
303 364
304 365 /**
305 366 * Class for managing events.
@@ -310,9 +371,8 @@
310 371 function EventEmitter() {}
311 372
312 373 // Shortcuts to improve speed and size
313 374 var proto = EventEmitter.prototype;
314 - var exports = this;
315 375 var originalGlobalValue = exports.EventEmitter;
316 376
317 377 /**
318 378 * Finds the index of the listener for the event in its storage array.
@@ -411,8 +471,18 @@
411 471
412 472 return response || listeners;
413 473 };
414 474
475 + function isValidListener (listener) {
476 + if (typeof listener === 'function' || listener instanceof RegExp) {
477 + return true
478 + } else if (listener && typeof listener === 'object') {
479 + return isValidListener(listener.listener)
480 + } else {
481 + return false
482 + }
483 + }
484 +
415 485 /**
416 486 * Adds a listener function to the specified event.
417 487 * The listener will not be added if it is a duplicate.
418 488 * If the listener returns true then it will be removed after it is called.
@@ -422,8 +492,12 @@
422 492 * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
423 493 * @return {Object} Current instance of EventEmitter for chaining.
424 494 */
425 495 proto.addListener = function addListener(evt, listener) {
496 + if (!isValidListener(listener)) {
497 + throw new TypeError('listener must be a function');
498 + }
499 +
426 500 var listeners = this.getListenersAsObject(evt);
427 501 var listenerIsWrapped = typeof listener === 'object';
428 502 var key;
429 503
@@ -521,9 +595,9 @@
521 595 proto.off = alias('removeListener');
522 596
523 597 /**
524 598 * Adds listeners in bulk using the manipulateListeners method.
525 - * If you pass an object as the second argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added.
599 + * If you pass an object as the first argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added.
526 600 * You can also pass it a regular expression to add the array of listeners to all events that match it.
527 601 * Yeah, this function does quite a bit. That's probably a bad thing.
528 602 *
529 603 * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once.
@@ -536,9 +610,9 @@
536 610 };
537 611
538 612 /**
539 613 * Removes listeners in bulk using the manipulateListeners method.
540 - * If you pass an object as the second argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.
614 + * If you pass an object as the first argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.
541 615 * You can also pass it an event name and an array of listeners to be removed.
542 616 * You can also pass it a regular expression to remove the listeners from all events that match it.
543 617 *
544 618 * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once.
@@ -660,11 +734,10 @@
660 734
661 735 for (key in listenersMap) {
662 736 if (listenersMap.hasOwnProperty(key)) {
663 737 listeners = listenersMap[key].slice(0);
664 - i = listeners.length;
665 738
666 - while (i--) {
739 + for (i = 0; i < listeners.length; i++) {
667 740 // If the listener returns true then it shall be removed from the event
668 741 // The function is executed either with a basic call or an apply if there is an args array
669 742 listener = listeners[i];
670 743
@@ -763,8 +836,8 @@
763 836 }
764 837 else {
765 838 exports.EventEmitter = EventEmitter;
766 839 }
767 -}.call(this));
840 +}(typeof window !== 'undefined' ? window : this || {}));
768 841
769 842 },{}]},{},[1]);
770 843 ; })();