zeroclipboard-rails 0.0.13 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 42b0ab9281477489a2d8982c0433d1e88c4da338
4
- data.tar.gz: 446eb6619ca7521ade2a90a750f1ebda0731cf49
3
+ metadata.gz: 11106a7f252d9580af77ab54c7a979769824bf96
4
+ data.tar.gz: 1912126d137697e613bb206bec6f982893e09c5d
5
5
  SHA512:
6
- metadata.gz: af77e8addd3e54cb73ecd6d909299d09d96a68af01c3a820407461cfccaf93560cb2c88e35f78d3ff2e8db6133a932850b6963432dd58a29668679d71c74a42d
7
- data.tar.gz: 7c5fb22bcb434c425cf666f2ca9a57ad97140abee58af346a8fc13ac910ef761d8d6742aa662bb23b1093ea5f59b56d4255e311246cb26a2c0792a08e52cdd22
6
+ metadata.gz: 2ff318896ae59121daa0c07c972e03d99c22893ef3bcc6e4461c890c4eccbabe0ddf9121a48a419cbb05d8d409534a23deea09c735b2a2070e85740e6015b05a
7
+ data.tar.gz: 981fb0fc85d610ccaa3094482fd730ae76b45c46bd120770a0c2ae7ba53becf324fb7d38ace9b1dd818f56b04d470855929db14fd9c52a5f28fd83f5fe21538f
data/README.md CHANGED
@@ -103,6 +103,7 @@ This gem is merely a wrapper around [ZeroClipboard](https://github.com/zeroclipb
103
103
  |[`0.0.11`](https://rubygems.org/gems/zeroclipboard-rails/versions/0.0.11)|[`1.3.1`](https://github.com/zeroclipboard/ZeroClipboard/tree/v1.3.1)||
104
104
  |[`0.0.12`](https://rubygems.org/gems/zeroclipboard-rails/versions/0.0.12)|[`1.3.1`](https://github.com/zeroclipboard/ZeroClipboard/tree/v1.3.1)|[Fix deprecation warning](https://github.com/zeroclipboard/zeroclipboard-rails/pull/17) - [@markrickert](https://github.com/markrickert)|
105
105
  |[`0.0.13`](https://rubygems.org/gems/zeroclipboard-rails/versions/0.0.13)|[`1.3.5`](https://github.com/zeroclipboard/ZeroClipboard/tree/v1.3.5)||
106
+ |[`0.1.0`](https://rubygems.org/gems/zeroclipboard-rails/versions/0.1.0)|[`2.1.2`](https://github.com/zeroclipboard/ZeroClipboard/tree/v2.1.2)|Switch to new zeroclipboard.js major version, see their [releases](https://github.com/zeroclipboard/zeroclipboard/releases)|
106
107
 
107
108
 
108
109
 
@@ -1,39 +1,214 @@
1
1
  /*!
2
- * ZeroClipboard
3
- * The ZeroClipboard library provides an easy way to copy text to the clipboard using an invisible Adobe Flash movie and a JavaScript interface.
4
- * Copyright (c) 2014 Jon Rohan, James M. Greene
5
- * Licensed MIT
6
- * http://zeroclipboard.org/
7
- * v1.3.5
8
- */
9
- (function(window) {
2
+ * ZeroClipboard
3
+ * The ZeroClipboard library provides an easy way to copy text to the clipboard using an invisible Adobe Flash movie and a JavaScript interface.
4
+ * Copyright (c) 2014 Jon Rohan, James M. Greene
5
+ * Licensed MIT
6
+ * http://zeroclipboard.org/
7
+ * v2.1.2
8
+ */
9
+ (function(window, undefined) {
10
10
  "use strict";
11
- var currentElement;
12
- var flashState = {
11
+ /**
12
+ * Store references to critically important global functions that may be
13
+ * overridden on certain web pages.
14
+ */
15
+ var _window = window, _document = _window.document, _navigator = _window.navigator, _setTimeout = _window.setTimeout, _encodeURIComponent = _window.encodeURIComponent, _ActiveXObject = _window.ActiveXObject, _parseInt = _window.Number.parseInt || _window.parseInt, _parseFloat = _window.Number.parseFloat || _window.parseFloat, _isNaN = _window.Number.isNaN || _window.isNaN, _round = _window.Math.round, _now = _window.Date.now, _keys = _window.Object.keys, _defineProperty = _window.Object.defineProperty, _hasOwn = _window.Object.prototype.hasOwnProperty, _slice = _window.Array.prototype.slice;
16
+ /**
17
+ * Convert an `arguments` object into an Array.
18
+ *
19
+ * @returns The arguments as an Array
20
+ * @private
21
+ */
22
+ var _args = function(argumentsObj) {
23
+ return _slice.call(argumentsObj, 0);
24
+ };
25
+ /**
26
+ * Shallow-copy the owned, enumerable properties of one object over to another, similar to jQuery's `$.extend`.
27
+ *
28
+ * @returns The target object, augmented
29
+ * @private
30
+ */
31
+ var _extend = function() {
32
+ var i, len, arg, prop, src, copy, args = _args(arguments), target = args[0] || {};
33
+ for (i = 1, len = args.length; i < len; i++) {
34
+ if ((arg = args[i]) != null) {
35
+ for (prop in arg) {
36
+ if (_hasOwn.call(arg, prop)) {
37
+ src = target[prop];
38
+ copy = arg[prop];
39
+ if (target !== copy && copy !== undefined) {
40
+ target[prop] = copy;
41
+ }
42
+ }
43
+ }
44
+ }
45
+ }
46
+ return target;
47
+ };
48
+ /**
49
+ * Return a deep copy of the source object or array.
50
+ *
51
+ * @returns Object or Array
52
+ * @private
53
+ */
54
+ var _deepCopy = function(source) {
55
+ var copy, i, len, prop;
56
+ if (typeof source !== "object" || source == null) {
57
+ copy = source;
58
+ } else if (typeof source.length === "number") {
59
+ copy = [];
60
+ for (i = 0, len = source.length; i < len; i++) {
61
+ if (_hasOwn.call(source, i)) {
62
+ copy[i] = _deepCopy(source[i]);
63
+ }
64
+ }
65
+ } else {
66
+ copy = {};
67
+ for (prop in source) {
68
+ if (_hasOwn.call(source, prop)) {
69
+ copy[prop] = _deepCopy(source[prop]);
70
+ }
71
+ }
72
+ }
73
+ return copy;
74
+ };
75
+ /**
76
+ * Makes a shallow copy of `obj` (like `_extend`) but filters its properties based on a list of `keys` to keep.
77
+ * The inverse of `_omit`, mostly. The big difference is that these properties do NOT need to be enumerable to
78
+ * be kept.
79
+ *
80
+ * @returns A new filtered object.
81
+ * @private
82
+ */
83
+ var _pick = function(obj, keys) {
84
+ var newObj = {};
85
+ for (var i = 0, len = keys.length; i < len; i++) {
86
+ if (keys[i] in obj) {
87
+ newObj[keys[i]] = obj[keys[i]];
88
+ }
89
+ }
90
+ return newObj;
91
+ };
92
+ /**
93
+ * Makes a shallow copy of `obj` (like `_extend`) but filters its properties based on a list of `keys` to omit.
94
+ * The inverse of `_pick`.
95
+ *
96
+ * @returns A new filtered object.
97
+ * @private
98
+ */
99
+ var _omit = function(obj, keys) {
100
+ var newObj = {};
101
+ for (var prop in obj) {
102
+ if (keys.indexOf(prop) === -1) {
103
+ newObj[prop] = obj[prop];
104
+ }
105
+ }
106
+ return newObj;
107
+ };
108
+ /**
109
+ * Remove all owned, enumerable properties from an object.
110
+ *
111
+ * @returns The original object without its owned, enumerable properties.
112
+ * @private
113
+ */
114
+ var _deleteOwnProperties = function(obj) {
115
+ if (obj) {
116
+ for (var prop in obj) {
117
+ if (_hasOwn.call(obj, prop)) {
118
+ delete obj[prop];
119
+ }
120
+ }
121
+ }
122
+ return obj;
123
+ };
124
+ /**
125
+ * Determine if an element is contained within another element.
126
+ *
127
+ * @returns Boolean
128
+ * @private
129
+ */
130
+ var _containedBy = function(el, ancestorEl) {
131
+ if (el && el.nodeType === 1 && el.ownerDocument && ancestorEl && (ancestorEl.nodeType === 1 && ancestorEl.ownerDocument && ancestorEl.ownerDocument === el.ownerDocument || ancestorEl.nodeType === 9 && !ancestorEl.ownerDocument && ancestorEl === el.ownerDocument)) {
132
+ do {
133
+ if (el === ancestorEl) {
134
+ return true;
135
+ }
136
+ el = el.parentNode;
137
+ } while (el);
138
+ }
139
+ return false;
140
+ };
141
+ /**
142
+ * Keep track of the state of the Flash object.
143
+ * @private
144
+ */
145
+ var _flashState = {
13
146
  bridge: null,
14
147
  version: "0.0.0",
148
+ pluginType: "unknown",
15
149
  disabled: null,
16
150
  outdated: null,
151
+ unavailable: null,
152
+ deactivated: null,
153
+ overdue: null,
17
154
  ready: null
18
155
  };
156
+ /**
157
+ * The minimum Flash Player version required to use ZeroClipboard completely.
158
+ * @readonly
159
+ * @private
160
+ */
161
+ var _minimumFlashVersion = "11.0.0";
162
+ /**
163
+ * Keep track of all event listener registrations.
164
+ * @private
165
+ */
166
+ var _handlers = {};
167
+ /**
168
+ * Keep track of the currently activated element.
169
+ * @private
170
+ */
171
+ var _currentElement;
172
+ /**
173
+ * Keep track of data for the pending clipboard transaction.
174
+ * @private
175
+ */
19
176
  var _clipData = {};
20
- var clientIdCounter = 0;
21
- var _clientMeta = {};
22
- var elementIdCounter = 0;
23
- var _elementMeta = {};
24
- var _amdModuleId = null;
25
- var _cjsModuleId = null;
177
+ /**
178
+ * Keep track of data formats for the pending clipboard transaction.
179
+ * @private
180
+ */
181
+ var _clipDataFormatMap = null;
182
+ /**
183
+ * The `message` store for events
184
+ * @private
185
+ */
186
+ var _eventMessages = {
187
+ ready: "Flash communication is established",
188
+ error: {
189
+ "flash-disabled": "Flash is disabled or not installed",
190
+ "flash-outdated": "Flash is too outdated to support ZeroClipboard",
191
+ "flash-unavailable": "Flash is unable to communicate bidirectionally with JavaScript",
192
+ "flash-deactivated": "Flash is too outdated for your browser and/or is configured as click-to-activate",
193
+ "flash-overdue": "Flash communication was established but NOT within the acceptable time limit"
194
+ }
195
+ };
196
+ /**
197
+ * The presumed location of the "ZeroClipboard.swf" file, based on the location
198
+ * of the executing JavaScript file (e.g. "ZeroClipboard.js", etc.).
199
+ * @private
200
+ */
26
201
  var _swfPath = function() {
27
202
  var i, jsDir, tmpJsPath, jsPath, swfPath = "ZeroClipboard.swf";
28
- if (document.currentScript && (jsPath = document.currentScript.src)) {} else {
29
- var scripts = document.getElementsByTagName("script");
203
+ if (!(_document.currentScript && (jsPath = _document.currentScript.src))) {
204
+ var scripts = _document.getElementsByTagName("script");
30
205
  if ("readyState" in scripts[0]) {
31
206
  for (i = scripts.length; i--; ) {
32
207
  if (scripts[i].readyState === "interactive" && (jsPath = scripts[i].src)) {
33
208
  break;
34
209
  }
35
210
  }
36
- } else if (document.readyState === "loading") {
211
+ } else if (_document.readyState === "loading") {
37
212
  jsPath = scripts[scripts.length - 1].src;
38
213
  } else {
39
214
  for (i = scripts.length; i--; ) {
@@ -62,288 +237,919 @@
62
237
  }
63
238
  return swfPath;
64
239
  }();
65
- var _camelizeCssPropName = function() {
66
- var matcherRegex = /\-([a-z])/g, replacerFn = function(match, group) {
67
- return group.toUpperCase();
68
- };
69
- return function(prop) {
70
- return prop.replace(matcherRegex, replacerFn);
240
+ /**
241
+ * ZeroClipboard configuration defaults for the Core module.
242
+ * @private
243
+ */
244
+ var _globalConfig = {
245
+ swfPath: _swfPath,
246
+ trustedDomains: window.location.host ? [ window.location.host ] : [],
247
+ cacheBust: true,
248
+ forceEnhancedClipboard: false,
249
+ flashLoadTimeout: 3e4,
250
+ autoActivate: true,
251
+ bubbleEvents: true,
252
+ containerId: "global-zeroclipboard-html-bridge",
253
+ containerClass: "global-zeroclipboard-container",
254
+ swfObjectId: "global-zeroclipboard-flash-bridge",
255
+ hoverClass: "zeroclipboard-is-hover",
256
+ activeClass: "zeroclipboard-is-active",
257
+ forceHandCursor: false,
258
+ title: null,
259
+ zIndex: 999999999
260
+ };
261
+ /**
262
+ * The underlying implementation of `ZeroClipboard.config`.
263
+ * @private
264
+ */
265
+ var _config = function(options) {
266
+ if (typeof options === "object" && options !== null) {
267
+ for (var prop in options) {
268
+ if (_hasOwn.call(options, prop)) {
269
+ if (/^(?:forceHandCursor|title|zIndex|bubbleEvents)$/.test(prop)) {
270
+ _globalConfig[prop] = options[prop];
271
+ } else if (_flashState.bridge == null) {
272
+ if (prop === "containerId" || prop === "swfObjectId") {
273
+ if (_isValidHtml4Id(options[prop])) {
274
+ _globalConfig[prop] = options[prop];
275
+ } else {
276
+ throw new Error("The specified `" + prop + "` value is not valid as an HTML4 Element ID");
277
+ }
278
+ } else {
279
+ _globalConfig[prop] = options[prop];
280
+ }
281
+ }
282
+ }
283
+ }
284
+ }
285
+ if (typeof options === "string" && options) {
286
+ if (_hasOwn.call(_globalConfig, options)) {
287
+ return _globalConfig[options];
288
+ }
289
+ return;
290
+ }
291
+ return _deepCopy(_globalConfig);
292
+ };
293
+ /**
294
+ * The underlying implementation of `ZeroClipboard.state`.
295
+ * @private
296
+ */
297
+ var _state = function() {
298
+ return {
299
+ browser: _pick(_navigator, [ "userAgent", "platform", "appName" ]),
300
+ flash: _omit(_flashState, [ "bridge" ]),
301
+ zeroclipboard: {
302
+ version: ZeroClipboard.version,
303
+ config: ZeroClipboard.config()
304
+ }
71
305
  };
72
- }();
73
- var _getStyle = function(el, prop) {
74
- var value, camelProp, tagName, possiblePointers, i, len;
75
- if (window.getComputedStyle) {
76
- value = window.getComputedStyle(el, null).getPropertyValue(prop);
77
- } else {
78
- camelProp = _camelizeCssPropName(prop);
79
- if (el.currentStyle) {
80
- value = el.currentStyle[camelProp];
81
- } else {
82
- value = el.style[camelProp];
306
+ };
307
+ /**
308
+ * The underlying implementation of `ZeroClipboard.isFlashUnusable`.
309
+ * @private
310
+ */
311
+ var _isFlashUnusable = function() {
312
+ return !!(_flashState.disabled || _flashState.outdated || _flashState.unavailable || _flashState.deactivated);
313
+ };
314
+ /**
315
+ * The underlying implementation of `ZeroClipboard.on`.
316
+ * @private
317
+ */
318
+ var _on = function(eventType, listener) {
319
+ var i, len, events, added = {};
320
+ if (typeof eventType === "string" && eventType) {
321
+ events = eventType.toLowerCase().split(/\s+/);
322
+ } else if (typeof eventType === "object" && eventType && typeof listener === "undefined") {
323
+ for (i in eventType) {
324
+ if (_hasOwn.call(eventType, i) && typeof i === "string" && i && typeof eventType[i] === "function") {
325
+ ZeroClipboard.on(i, eventType[i]);
326
+ }
83
327
  }
84
328
  }
85
- if (prop === "cursor") {
86
- if (!value || value === "auto") {
87
- tagName = el.tagName.toLowerCase();
88
- if (tagName === "a") {
89
- return "pointer";
329
+ if (events && events.length) {
330
+ for (i = 0, len = events.length; i < len; i++) {
331
+ eventType = events[i].replace(/^on/, "");
332
+ added[eventType] = true;
333
+ if (!_handlers[eventType]) {
334
+ _handlers[eventType] = [];
335
+ }
336
+ _handlers[eventType].push(listener);
337
+ }
338
+ if (added.ready && _flashState.ready) {
339
+ ZeroClipboard.emit({
340
+ type: "ready"
341
+ });
342
+ }
343
+ if (added.error) {
344
+ var errorTypes = [ "disabled", "outdated", "unavailable", "deactivated", "overdue" ];
345
+ for (i = 0, len = errorTypes.length; i < len; i++) {
346
+ if (_flashState[errorTypes[i]] === true) {
347
+ ZeroClipboard.emit({
348
+ type: "error",
349
+ name: "flash-" + errorTypes[i]
350
+ });
351
+ break;
352
+ }
90
353
  }
91
354
  }
92
355
  }
93
- return value;
356
+ return ZeroClipboard;
94
357
  };
95
- var _elementMouseOver = function(event) {
358
+ /**
359
+ * The underlying implementation of `ZeroClipboard.off`.
360
+ * @private
361
+ */
362
+ var _off = function(eventType, listener) {
363
+ var i, len, foundIndex, events, perEventHandlers;
364
+ if (arguments.length === 0) {
365
+ events = _keys(_handlers);
366
+ } else if (typeof eventType === "string" && eventType) {
367
+ events = eventType.split(/\s+/);
368
+ } else if (typeof eventType === "object" && eventType && typeof listener === "undefined") {
369
+ for (i in eventType) {
370
+ if (_hasOwn.call(eventType, i) && typeof i === "string" && i && typeof eventType[i] === "function") {
371
+ ZeroClipboard.off(i, eventType[i]);
372
+ }
373
+ }
374
+ }
375
+ if (events && events.length) {
376
+ for (i = 0, len = events.length; i < len; i++) {
377
+ eventType = events[i].toLowerCase().replace(/^on/, "");
378
+ perEventHandlers = _handlers[eventType];
379
+ if (perEventHandlers && perEventHandlers.length) {
380
+ if (listener) {
381
+ foundIndex = perEventHandlers.indexOf(listener);
382
+ while (foundIndex !== -1) {
383
+ perEventHandlers.splice(foundIndex, 1);
384
+ foundIndex = perEventHandlers.indexOf(listener, foundIndex);
385
+ }
386
+ } else {
387
+ perEventHandlers.length = 0;
388
+ }
389
+ }
390
+ }
391
+ }
392
+ return ZeroClipboard;
393
+ };
394
+ /**
395
+ * The underlying implementation of `ZeroClipboard.handlers`.
396
+ * @private
397
+ */
398
+ var _listeners = function(eventType) {
399
+ var copy;
400
+ if (typeof eventType === "string" && eventType) {
401
+ copy = _deepCopy(_handlers[eventType]) || null;
402
+ } else {
403
+ copy = _deepCopy(_handlers);
404
+ }
405
+ return copy;
406
+ };
407
+ /**
408
+ * The underlying implementation of `ZeroClipboard.emit`.
409
+ * @private
410
+ */
411
+ var _emit = function(event) {
412
+ var eventCopy, returnVal, tmp;
413
+ event = _createEvent(event);
96
414
  if (!event) {
97
- event = window.event;
415
+ return;
416
+ }
417
+ if (_preprocessEvent(event)) {
418
+ return;
98
419
  }
99
- var target;
100
- if (this !== window) {
101
- target = this;
102
- } else if (event.target) {
103
- target = event.target;
104
- } else if (event.srcElement) {
105
- target = event.srcElement;
420
+ if (event.type === "ready" && _flashState.overdue === true) {
421
+ return ZeroClipboard.emit({
422
+ type: "error",
423
+ name: "flash-overdue"
424
+ });
106
425
  }
107
- ZeroClipboard.activate(target);
426
+ eventCopy = _extend({}, event);
427
+ _dispatchCallbacks.call(this, eventCopy);
428
+ if (event.type === "copy") {
429
+ tmp = _mapClipDataToFlash(_clipData);
430
+ returnVal = tmp.data;
431
+ _clipDataFormatMap = tmp.formatMap;
432
+ }
433
+ return returnVal;
108
434
  };
109
- var _addEventHandler = function(element, method, func) {
110
- if (!element || element.nodeType !== 1) {
435
+ /**
436
+ * The underlying implementation of `ZeroClipboard.create`.
437
+ * @private
438
+ */
439
+ var _create = function() {
440
+ if (typeof _flashState.ready !== "boolean") {
441
+ _flashState.ready = false;
442
+ }
443
+ if (!ZeroClipboard.isFlashUnusable() && _flashState.bridge === null) {
444
+ var maxWait = _globalConfig.flashLoadTimeout;
445
+ if (typeof maxWait === "number" && maxWait >= 0) {
446
+ _setTimeout(function() {
447
+ if (typeof _flashState.deactivated !== "boolean") {
448
+ _flashState.deactivated = true;
449
+ }
450
+ if (_flashState.deactivated === true) {
451
+ ZeroClipboard.emit({
452
+ type: "error",
453
+ name: "flash-deactivated"
454
+ });
455
+ }
456
+ }, maxWait);
457
+ }
458
+ _flashState.overdue = false;
459
+ _embedSwf();
460
+ }
461
+ };
462
+ /**
463
+ * The underlying implementation of `ZeroClipboard.destroy`.
464
+ * @private
465
+ */
466
+ var _destroy = function() {
467
+ ZeroClipboard.clearData();
468
+ ZeroClipboard.blur();
469
+ ZeroClipboard.emit("destroy");
470
+ _unembedSwf();
471
+ ZeroClipboard.off();
472
+ };
473
+ /**
474
+ * The underlying implementation of `ZeroClipboard.setData`.
475
+ * @private
476
+ */
477
+ var _setData = function(format, data) {
478
+ var dataObj;
479
+ if (typeof format === "object" && format && typeof data === "undefined") {
480
+ dataObj = format;
481
+ ZeroClipboard.clearData();
482
+ } else if (typeof format === "string" && format) {
483
+ dataObj = {};
484
+ dataObj[format] = data;
485
+ } else {
111
486
  return;
112
487
  }
113
- if (element.addEventListener) {
114
- element.addEventListener(method, func, false);
115
- } else if (element.attachEvent) {
116
- element.attachEvent("on" + method, func);
488
+ for (var dataFormat in dataObj) {
489
+ if (typeof dataFormat === "string" && dataFormat && _hasOwn.call(dataObj, dataFormat) && typeof dataObj[dataFormat] === "string" && dataObj[dataFormat]) {
490
+ _clipData[dataFormat] = dataObj[dataFormat];
491
+ }
117
492
  }
118
493
  };
119
- var _removeEventHandler = function(element, method, func) {
120
- if (!element || element.nodeType !== 1) {
494
+ /**
495
+ * The underlying implementation of `ZeroClipboard.clearData`.
496
+ * @private
497
+ */
498
+ var _clearData = function(format) {
499
+ if (typeof format === "undefined") {
500
+ _deleteOwnProperties(_clipData);
501
+ _clipDataFormatMap = null;
502
+ } else if (typeof format === "string" && _hasOwn.call(_clipData, format)) {
503
+ delete _clipData[format];
504
+ }
505
+ };
506
+ /**
507
+ * The underlying implementation of `ZeroClipboard.getData`.
508
+ * @private
509
+ */
510
+ var _getData = function(format) {
511
+ if (typeof format === "undefined") {
512
+ return _deepCopy(_clipData);
513
+ } else if (typeof format === "string" && _hasOwn.call(_clipData, format)) {
514
+ return _clipData[format];
515
+ }
516
+ };
517
+ /**
518
+ * The underlying implementation of `ZeroClipboard.focus`/`ZeroClipboard.activate`.
519
+ * @private
520
+ */
521
+ var _focus = function(element) {
522
+ if (!(element && element.nodeType === 1)) {
121
523
  return;
122
524
  }
123
- if (element.removeEventListener) {
124
- element.removeEventListener(method, func, false);
125
- } else if (element.detachEvent) {
126
- element.detachEvent("on" + method, func);
525
+ if (_currentElement) {
526
+ _removeClass(_currentElement, _globalConfig.activeClass);
527
+ if (_currentElement !== element) {
528
+ _removeClass(_currentElement, _globalConfig.hoverClass);
529
+ }
530
+ }
531
+ _currentElement = element;
532
+ _addClass(element, _globalConfig.hoverClass);
533
+ var newTitle = element.getAttribute("title") || _globalConfig.title;
534
+ if (typeof newTitle === "string" && newTitle) {
535
+ var htmlBridge = _getHtmlBridge(_flashState.bridge);
536
+ if (htmlBridge) {
537
+ htmlBridge.setAttribute("title", newTitle);
538
+ }
127
539
  }
540
+ var useHandCursor = _globalConfig.forceHandCursor === true || _getStyle(element, "cursor") === "pointer";
541
+ _setHandCursor(useHandCursor);
542
+ _reposition();
128
543
  };
129
- var _addClass = function(element, value) {
130
- if (!element || element.nodeType !== 1) {
131
- return element;
544
+ /**
545
+ * The underlying implementation of `ZeroClipboard.blur`/`ZeroClipboard.deactivate`.
546
+ * @private
547
+ */
548
+ var _blur = function() {
549
+ var htmlBridge = _getHtmlBridge(_flashState.bridge);
550
+ if (htmlBridge) {
551
+ htmlBridge.removeAttribute("title");
552
+ htmlBridge.style.left = "0px";
553
+ htmlBridge.style.top = "-9999px";
554
+ htmlBridge.style.width = "1px";
555
+ htmlBridge.style.top = "1px";
132
556
  }
133
- if (element.classList) {
134
- if (!element.classList.contains(value)) {
135
- element.classList.add(value);
557
+ if (_currentElement) {
558
+ _removeClass(_currentElement, _globalConfig.hoverClass);
559
+ _removeClass(_currentElement, _globalConfig.activeClass);
560
+ _currentElement = null;
561
+ }
562
+ };
563
+ /**
564
+ * The underlying implementation of `ZeroClipboard.activeElement`.
565
+ * @private
566
+ */
567
+ var _activeElement = function() {
568
+ return _currentElement || null;
569
+ };
570
+ /**
571
+ * Check if a value is a valid HTML4 `ID` or `Name` token.
572
+ * @private
573
+ */
574
+ var _isValidHtml4Id = function(id) {
575
+ return typeof id === "string" && id && /^[A-Za-z][A-Za-z0-9_:\-\.]*$/.test(id);
576
+ };
577
+ /**
578
+ * Create or update an `event` object, based on the `eventType`.
579
+ * @private
580
+ */
581
+ var _createEvent = function(event) {
582
+ var eventType;
583
+ if (typeof event === "string" && event) {
584
+ eventType = event;
585
+ event = {};
586
+ } else if (typeof event === "object" && event && typeof event.type === "string" && event.type) {
587
+ eventType = event.type;
588
+ }
589
+ if (!eventType) {
590
+ return;
591
+ }
592
+ _extend(event, {
593
+ type: eventType.toLowerCase(),
594
+ target: event.target || _currentElement || null,
595
+ relatedTarget: event.relatedTarget || null,
596
+ currentTarget: _flashState && _flashState.bridge || null,
597
+ timeStamp: event.timeStamp || _now() || null
598
+ });
599
+ var msg = _eventMessages[event.type];
600
+ if (event.type === "error" && event.name && msg) {
601
+ msg = msg[event.name];
602
+ }
603
+ if (msg) {
604
+ event.message = msg;
605
+ }
606
+ if (event.type === "ready") {
607
+ _extend(event, {
608
+ target: null,
609
+ version: _flashState.version
610
+ });
611
+ }
612
+ if (event.type === "error") {
613
+ if (/^flash-(disabled|outdated|unavailable|deactivated|overdue)$/.test(event.name)) {
614
+ _extend(event, {
615
+ target: null,
616
+ minimumVersion: _minimumFlashVersion
617
+ });
618
+ }
619
+ if (/^flash-(outdated|unavailable|deactivated|overdue)$/.test(event.name)) {
620
+ _extend(event, {
621
+ version: _flashState.version
622
+ });
136
623
  }
137
- return element;
138
624
  }
139
- if (value && typeof value === "string") {
140
- var classNames = (value || "").split(/\s+/);
141
- if (element.nodeType === 1) {
142
- if (!element.className) {
143
- element.className = value;
144
- } else {
145
- var className = " " + element.className + " ", setClass = element.className;
146
- for (var c = 0, cl = classNames.length; c < cl; c++) {
147
- if (className.indexOf(" " + classNames[c] + " ") < 0) {
148
- setClass += " " + classNames[c];
149
- }
150
- }
151
- element.className = setClass.replace(/^\s+|\s+$/g, "");
625
+ if (event.type === "copy") {
626
+ event.clipboardData = {
627
+ setData: ZeroClipboard.setData,
628
+ clearData: ZeroClipboard.clearData
629
+ };
630
+ }
631
+ if (event.type === "aftercopy") {
632
+ event = _mapClipResultsFromFlash(event, _clipDataFormatMap);
633
+ }
634
+ if (event.target && !event.relatedTarget) {
635
+ event.relatedTarget = _getRelatedTarget(event.target);
636
+ }
637
+ event = _addMouseData(event);
638
+ return event;
639
+ };
640
+ /**
641
+ * Get a relatedTarget from the target's `data-clipboard-target` attribute
642
+ * @private
643
+ */
644
+ var _getRelatedTarget = function(targetEl) {
645
+ var relatedTargetId = targetEl && targetEl.getAttribute && targetEl.getAttribute("data-clipboard-target");
646
+ return relatedTargetId ? _document.getElementById(relatedTargetId) : null;
647
+ };
648
+ /**
649
+ * Add element and position data to `MouseEvent` instances
650
+ * @private
651
+ */
652
+ var _addMouseData = function(event) {
653
+ if (event && /^_(?:click|mouse(?:over|out|down|up|move))$/.test(event.type)) {
654
+ var srcElement = event.target;
655
+ var fromElement = event.type === "_mouseover" && event.relatedTarget ? event.relatedTarget : undefined;
656
+ var toElement = event.type === "_mouseout" && event.relatedTarget ? event.relatedTarget : undefined;
657
+ var pos = _getDOMObjectPosition(srcElement);
658
+ var screenLeft = _window.screenLeft || _window.screenX || 0;
659
+ var screenTop = _window.screenTop || _window.screenY || 0;
660
+ var scrollLeft = _document.body.scrollLeft + _document.documentElement.scrollLeft;
661
+ var scrollTop = _document.body.scrollTop + _document.documentElement.scrollTop;
662
+ var pageX = pos.left + (typeof event._stageX === "number" ? event._stageX : 0);
663
+ var pageY = pos.top + (typeof event._stageY === "number" ? event._stageY : 0);
664
+ var clientX = pageX - scrollLeft;
665
+ var clientY = pageY - scrollTop;
666
+ var screenX = screenLeft + clientX;
667
+ var screenY = screenTop + clientY;
668
+ var moveX = typeof event.movementX === "number" ? event.movementX : 0;
669
+ var moveY = typeof event.movementY === "number" ? event.movementY : 0;
670
+ delete event._stageX;
671
+ delete event._stageY;
672
+ _extend(event, {
673
+ srcElement: srcElement,
674
+ fromElement: fromElement,
675
+ toElement: toElement,
676
+ screenX: screenX,
677
+ screenY: screenY,
678
+ pageX: pageX,
679
+ pageY: pageY,
680
+ clientX: clientX,
681
+ clientY: clientY,
682
+ x: clientX,
683
+ y: clientY,
684
+ movementX: moveX,
685
+ movementY: moveY,
686
+ offsetX: 0,
687
+ offsetY: 0,
688
+ layerX: 0,
689
+ layerY: 0
690
+ });
691
+ }
692
+ return event;
693
+ };
694
+ /**
695
+ * Determine if an event's registered handlers should be execute synchronously or asynchronously.
696
+ *
697
+ * @returns {boolean}
698
+ * @private
699
+ */
700
+ var _shouldPerformAsync = function(event) {
701
+ var eventType = event && typeof event.type === "string" && event.type || "";
702
+ return !/^(?:(?:before)?copy|destroy)$/.test(eventType);
703
+ };
704
+ /**
705
+ * Control if a callback should be executed asynchronously or not.
706
+ *
707
+ * @returns `undefined`
708
+ * @private
709
+ */
710
+ var _dispatchCallback = function(func, context, args, async) {
711
+ if (async) {
712
+ _setTimeout(function() {
713
+ func.apply(context, args);
714
+ }, 0);
715
+ } else {
716
+ func.apply(context, args);
717
+ }
718
+ };
719
+ /**
720
+ * Handle the actual dispatching of events to client instances.
721
+ *
722
+ * @returns `undefined`
723
+ * @private
724
+ */
725
+ var _dispatchCallbacks = function(event) {
726
+ if (!(typeof event === "object" && event && event.type)) {
727
+ return;
728
+ }
729
+ var async = _shouldPerformAsync(event);
730
+ var wildcardTypeHandlers = _handlers["*"] || [];
731
+ var specificTypeHandlers = _handlers[event.type] || [];
732
+ var handlers = wildcardTypeHandlers.concat(specificTypeHandlers);
733
+ if (handlers && handlers.length) {
734
+ var i, len, func, context, eventCopy, originalContext = this;
735
+ for (i = 0, len = handlers.length; i < len; i++) {
736
+ func = handlers[i];
737
+ context = originalContext;
738
+ if (typeof func === "string" && typeof _window[func] === "function") {
739
+ func = _window[func];
740
+ }
741
+ if (typeof func === "object" && func && typeof func.handleEvent === "function") {
742
+ context = func;
743
+ func = func.handleEvent;
744
+ }
745
+ if (typeof func === "function") {
746
+ eventCopy = _extend({}, event);
747
+ _dispatchCallback(func, context, [ eventCopy ], async);
152
748
  }
153
749
  }
154
750
  }
155
- return element;
751
+ return this;
156
752
  };
157
- var _removeClass = function(element, value) {
158
- if (!element || element.nodeType !== 1) {
159
- return element;
753
+ /**
754
+ * Preprocess any special behaviors, reactions, or state changes after receiving this event.
755
+ * Executes only once per event emitted, NOT once per client.
756
+ * @private
757
+ */
758
+ var _preprocessEvent = function(event) {
759
+ var element = event.target || _currentElement || null;
760
+ var sourceIsSwf = event._source === "swf";
761
+ delete event._source;
762
+ var flashErrorNames = [ "flash-disabled", "flash-outdated", "flash-unavailable", "flash-deactivated", "flash-overdue" ];
763
+ switch (event.type) {
764
+ case "error":
765
+ if (flashErrorNames.indexOf(event.name) !== -1) {
766
+ _extend(_flashState, {
767
+ disabled: event.name === "flash-disabled",
768
+ outdated: event.name === "flash-outdated",
769
+ unavailable: event.name === "flash-unavailable",
770
+ deactivated: event.name === "flash-deactivated",
771
+ overdue: event.name === "flash-overdue",
772
+ ready: false
773
+ });
774
+ }
775
+ break;
776
+
777
+ case "ready":
778
+ var wasDeactivated = _flashState.deactivated === true;
779
+ _extend(_flashState, {
780
+ disabled: false,
781
+ outdated: false,
782
+ unavailable: false,
783
+ deactivated: false,
784
+ overdue: wasDeactivated,
785
+ ready: !wasDeactivated
786
+ });
787
+ break;
788
+
789
+ case "copy":
790
+ var textContent, htmlContent, targetEl = event.relatedTarget;
791
+ if (!(_clipData["text/html"] || _clipData["text/plain"]) && targetEl && (htmlContent = targetEl.value || targetEl.outerHTML || targetEl.innerHTML) && (textContent = targetEl.value || targetEl.textContent || targetEl.innerText)) {
792
+ event.clipboardData.clearData();
793
+ event.clipboardData.setData("text/plain", textContent);
794
+ if (htmlContent !== textContent) {
795
+ event.clipboardData.setData("text/html", htmlContent);
796
+ }
797
+ } else if (!_clipData["text/plain"] && event.target && (textContent = event.target.getAttribute("data-clipboard-text"))) {
798
+ event.clipboardData.clearData();
799
+ event.clipboardData.setData("text/plain", textContent);
800
+ }
801
+ break;
802
+
803
+ case "aftercopy":
804
+ ZeroClipboard.clearData();
805
+ if (element && element !== _safeActiveElement() && element.focus) {
806
+ element.focus();
807
+ }
808
+ break;
809
+
810
+ case "_mouseover":
811
+ ZeroClipboard.focus(element);
812
+ if (_globalConfig.bubbleEvents === true && sourceIsSwf) {
813
+ if (element && element !== event.relatedTarget && !_containedBy(event.relatedTarget, element)) {
814
+ _fireMouseEvent(_extend({}, event, {
815
+ type: "mouseenter",
816
+ bubbles: false,
817
+ cancelable: false
818
+ }));
819
+ }
820
+ _fireMouseEvent(_extend({}, event, {
821
+ type: "mouseover"
822
+ }));
823
+ }
824
+ break;
825
+
826
+ case "_mouseout":
827
+ ZeroClipboard.blur();
828
+ if (_globalConfig.bubbleEvents === true && sourceIsSwf) {
829
+ if (element && element !== event.relatedTarget && !_containedBy(event.relatedTarget, element)) {
830
+ _fireMouseEvent(_extend({}, event, {
831
+ type: "mouseleave",
832
+ bubbles: false,
833
+ cancelable: false
834
+ }));
835
+ }
836
+ _fireMouseEvent(_extend({}, event, {
837
+ type: "mouseout"
838
+ }));
839
+ }
840
+ break;
841
+
842
+ case "_mousedown":
843
+ _addClass(element, _globalConfig.activeClass);
844
+ if (_globalConfig.bubbleEvents === true && sourceIsSwf) {
845
+ _fireMouseEvent(_extend({}, event, {
846
+ type: event.type.slice(1)
847
+ }));
848
+ }
849
+ break;
850
+
851
+ case "_mouseup":
852
+ _removeClass(element, _globalConfig.activeClass);
853
+ if (_globalConfig.bubbleEvents === true && sourceIsSwf) {
854
+ _fireMouseEvent(_extend({}, event, {
855
+ type: event.type.slice(1)
856
+ }));
857
+ }
858
+ break;
859
+
860
+ case "_click":
861
+ case "_mousemove":
862
+ if (_globalConfig.bubbleEvents === true && sourceIsSwf) {
863
+ _fireMouseEvent(_extend({}, event, {
864
+ type: event.type.slice(1)
865
+ }));
866
+ }
867
+ break;
160
868
  }
161
- if (element.classList) {
162
- if (element.classList.contains(value)) {
163
- element.classList.remove(value);
869
+ if (/^_(?:click|mouse(?:over|out|down|up|move))$/.test(event.type)) {
870
+ return true;
871
+ }
872
+ };
873
+ /**
874
+ * Dispatch a synthetic MouseEvent.
875
+ *
876
+ * @returns `undefined`
877
+ * @private
878
+ */
879
+ var _fireMouseEvent = function(event) {
880
+ if (!(event && typeof event.type === "string" && event)) {
881
+ return;
882
+ }
883
+ var e, target = event.target || null, doc = target && target.ownerDocument || _document, defaults = {
884
+ view: doc.defaultView || _window,
885
+ canBubble: true,
886
+ cancelable: true,
887
+ detail: event.type === "click" ? 1 : 0,
888
+ button: typeof event.which === "number" ? event.which - 1 : typeof event.button === "number" ? event.button : doc.createEvent ? 0 : 1
889
+ }, args = _extend(defaults, event);
890
+ if (!target) {
891
+ return;
892
+ }
893
+ if (doc.createEvent && target.dispatchEvent) {
894
+ args = [ args.type, args.canBubble, args.cancelable, args.view, args.detail, args.screenX, args.screenY, args.clientX, args.clientY, args.ctrlKey, args.altKey, args.shiftKey, args.metaKey, args.button, args.relatedTarget ];
895
+ e = doc.createEvent("MouseEvents");
896
+ if (e.initMouseEvent) {
897
+ e.initMouseEvent.apply(e, args);
898
+ e._source = "js";
899
+ target.dispatchEvent(e);
164
900
  }
165
- return element;
166
901
  }
167
- if (value && typeof value === "string" || value === undefined) {
168
- var classNames = (value || "").split(/\s+/);
169
- if (element.nodeType === 1 && element.className) {
170
- if (value) {
171
- var className = (" " + element.className + " ").replace(/[\n\t]/g, " ");
172
- for (var c = 0, cl = classNames.length; c < cl; c++) {
173
- className = className.replace(" " + classNames[c] + " ", " ");
174
- }
175
- element.className = className.replace(/^\s+|\s+$/g, "");
902
+ };
903
+ /**
904
+ * Create the HTML bridge element to embed the Flash object into.
905
+ * @private
906
+ */
907
+ var _createHtmlBridge = function() {
908
+ var container = _document.createElement("div");
909
+ container.id = _globalConfig.containerId;
910
+ container.className = _globalConfig.containerClass;
911
+ container.style.position = "absolute";
912
+ container.style.left = "0px";
913
+ container.style.top = "-9999px";
914
+ container.style.width = "1px";
915
+ container.style.height = "1px";
916
+ container.style.zIndex = "" + _getSafeZIndex(_globalConfig.zIndex);
917
+ return container;
918
+ };
919
+ /**
920
+ * Get the HTML element container that wraps the Flash bridge object/element.
921
+ * @private
922
+ */
923
+ var _getHtmlBridge = function(flashBridge) {
924
+ var htmlBridge = flashBridge && flashBridge.parentNode;
925
+ while (htmlBridge && htmlBridge.nodeName === "OBJECT" && htmlBridge.parentNode) {
926
+ htmlBridge = htmlBridge.parentNode;
927
+ }
928
+ return htmlBridge || null;
929
+ };
930
+ /**
931
+ * Create the SWF object.
932
+ *
933
+ * @returns The SWF object reference.
934
+ * @private
935
+ */
936
+ var _embedSwf = function() {
937
+ var len, flashBridge = _flashState.bridge, container = _getHtmlBridge(flashBridge);
938
+ if (!flashBridge) {
939
+ var allowScriptAccess = _determineScriptAccess(_window.location.host, _globalConfig);
940
+ var allowNetworking = allowScriptAccess === "never" ? "none" : "all";
941
+ var flashvars = _vars(_globalConfig);
942
+ var swfUrl = _globalConfig.swfPath + _cacheBust(_globalConfig.swfPath, _globalConfig);
943
+ container = _createHtmlBridge();
944
+ var divToBeReplaced = _document.createElement("div");
945
+ container.appendChild(divToBeReplaced);
946
+ _document.body.appendChild(container);
947
+ var tmpDiv = _document.createElement("div");
948
+ var oldIE = _flashState.pluginType === "activex";
949
+ tmpDiv.innerHTML = '<object id="' + _globalConfig.swfObjectId + '" name="' + _globalConfig.swfObjectId + '" ' + 'width="100%" height="100%" ' + (oldIE ? 'classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"' : 'type="application/x-shockwave-flash" data="' + swfUrl + '"') + ">" + (oldIE ? '<param name="movie" value="' + swfUrl + '"/>' : "") + '<param name="allowScriptAccess" value="' + allowScriptAccess + '"/>' + '<param name="allowNetworking" value="' + allowNetworking + '"/>' + '<param name="menu" value="false"/>' + '<param name="wmode" value="transparent"/>' + '<param name="flashvars" value="' + flashvars + '"/>' + "</object>";
950
+ flashBridge = tmpDiv.firstChild;
951
+ tmpDiv = null;
952
+ flashBridge.ZeroClipboard = ZeroClipboard;
953
+ container.replaceChild(flashBridge, divToBeReplaced);
954
+ }
955
+ if (!flashBridge) {
956
+ flashBridge = _document[_globalConfig.swfObjectId];
957
+ if (flashBridge && (len = flashBridge.length)) {
958
+ flashBridge = flashBridge[len - 1];
959
+ }
960
+ if (!flashBridge && container) {
961
+ flashBridge = container.firstChild;
962
+ }
963
+ }
964
+ _flashState.bridge = flashBridge || null;
965
+ return flashBridge;
966
+ };
967
+ /**
968
+ * Destroy the SWF object.
969
+ * @private
970
+ */
971
+ var _unembedSwf = function() {
972
+ var flashBridge = _flashState.bridge;
973
+ if (flashBridge) {
974
+ var htmlBridge = _getHtmlBridge(flashBridge);
975
+ if (htmlBridge) {
976
+ if (_flashState.pluginType === "activex" && "readyState" in flashBridge) {
977
+ flashBridge.style.display = "none";
978
+ (function removeSwfFromIE() {
979
+ if (flashBridge.readyState === 4) {
980
+ for (var prop in flashBridge) {
981
+ if (typeof flashBridge[prop] === "function") {
982
+ flashBridge[prop] = null;
983
+ }
984
+ }
985
+ if (flashBridge.parentNode) {
986
+ flashBridge.parentNode.removeChild(flashBridge);
987
+ }
988
+ if (htmlBridge.parentNode) {
989
+ htmlBridge.parentNode.removeChild(htmlBridge);
990
+ }
991
+ } else {
992
+ _setTimeout(removeSwfFromIE, 10);
993
+ }
994
+ })();
176
995
  } else {
177
- element.className = "";
996
+ if (flashBridge.parentNode) {
997
+ flashBridge.parentNode.removeChild(flashBridge);
998
+ }
999
+ if (htmlBridge.parentNode) {
1000
+ htmlBridge.parentNode.removeChild(htmlBridge);
1001
+ }
178
1002
  }
179
1003
  }
1004
+ _flashState.ready = null;
1005
+ _flashState.bridge = null;
1006
+ _flashState.deactivated = null;
180
1007
  }
181
- return element;
182
1008
  };
183
- var _getZoomFactor = function() {
184
- var rect, physicalWidth, logicalWidth, zoomFactor = 1;
185
- if (typeof document.body.getBoundingClientRect === "function") {
186
- rect = document.body.getBoundingClientRect();
187
- physicalWidth = rect.right - rect.left;
188
- logicalWidth = document.body.offsetWidth;
189
- zoomFactor = Math.round(physicalWidth / logicalWidth * 100) / 100;
1009
+ /**
1010
+ * Map the data format names of the "clipData" to Flash-friendly names.
1011
+ *
1012
+ * @returns A new transformed object.
1013
+ * @private
1014
+ */
1015
+ var _mapClipDataToFlash = function(clipData) {
1016
+ var newClipData = {}, formatMap = {};
1017
+ if (!(typeof clipData === "object" && clipData)) {
1018
+ return;
190
1019
  }
191
- return zoomFactor;
192
- };
193
- var _getDOMObjectPosition = function(obj, defaultZIndex) {
194
- var info = {
195
- left: 0,
196
- top: 0,
197
- width: 0,
198
- height: 0,
199
- zIndex: _getSafeZIndex(defaultZIndex) - 1
1020
+ for (var dataFormat in clipData) {
1021
+ if (dataFormat && _hasOwn.call(clipData, dataFormat) && typeof clipData[dataFormat] === "string" && clipData[dataFormat]) {
1022
+ switch (dataFormat.toLowerCase()) {
1023
+ case "text/plain":
1024
+ case "text":
1025
+ case "air:text":
1026
+ case "flash:text":
1027
+ newClipData.text = clipData[dataFormat];
1028
+ formatMap.text = dataFormat;
1029
+ break;
1030
+
1031
+ case "text/html":
1032
+ case "html":
1033
+ case "air:html":
1034
+ case "flash:html":
1035
+ newClipData.html = clipData[dataFormat];
1036
+ formatMap.html = dataFormat;
1037
+ break;
1038
+
1039
+ case "application/rtf":
1040
+ case "text/rtf":
1041
+ case "rtf":
1042
+ case "richtext":
1043
+ case "air:rtf":
1044
+ case "flash:rtf":
1045
+ newClipData.rtf = clipData[dataFormat];
1046
+ formatMap.rtf = dataFormat;
1047
+ break;
1048
+
1049
+ default:
1050
+ break;
1051
+ }
1052
+ }
1053
+ }
1054
+ return {
1055
+ data: newClipData,
1056
+ formatMap: formatMap
200
1057
  };
201
- if (obj.getBoundingClientRect) {
202
- var rect = obj.getBoundingClientRect();
203
- var pageXOffset, pageYOffset, zoomFactor;
204
- if ("pageXOffset" in window && "pageYOffset" in window) {
205
- pageXOffset = window.pageXOffset;
206
- pageYOffset = window.pageYOffset;
207
- } else {
208
- zoomFactor = _getZoomFactor();
209
- pageXOffset = Math.round(document.documentElement.scrollLeft / zoomFactor);
210
- pageYOffset = Math.round(document.documentElement.scrollTop / zoomFactor);
1058
+ };
1059
+ /**
1060
+ * Map the data format names from Flash-friendly names back to their original "clipData" names (via a format mapping).
1061
+ *
1062
+ * @returns A new transformed object.
1063
+ * @private
1064
+ */
1065
+ var _mapClipResultsFromFlash = function(clipResults, formatMap) {
1066
+ if (!(typeof clipResults === "object" && clipResults && typeof formatMap === "object" && formatMap)) {
1067
+ return clipResults;
1068
+ }
1069
+ var newResults = {};
1070
+ for (var prop in clipResults) {
1071
+ if (_hasOwn.call(clipResults, prop)) {
1072
+ if (prop !== "success" && prop !== "data") {
1073
+ newResults[prop] = clipResults[prop];
1074
+ continue;
1075
+ }
1076
+ newResults[prop] = {};
1077
+ var tmpHash = clipResults[prop];
1078
+ for (var dataFormat in tmpHash) {
1079
+ if (dataFormat && _hasOwn.call(tmpHash, dataFormat) && _hasOwn.call(formatMap, dataFormat)) {
1080
+ newResults[prop][formatMap[dataFormat]] = tmpHash[dataFormat];
1081
+ }
1082
+ }
211
1083
  }
212
- var leftBorderWidth = document.documentElement.clientLeft || 0;
213
- var topBorderWidth = document.documentElement.clientTop || 0;
214
- info.left = rect.left + pageXOffset - leftBorderWidth;
215
- info.top = rect.top + pageYOffset - topBorderWidth;
216
- info.width = "width" in rect ? rect.width : rect.right - rect.left;
217
- info.height = "height" in rect ? rect.height : rect.bottom - rect.top;
218
1084
  }
219
- return info;
1085
+ return newResults;
220
1086
  };
1087
+ /**
1088
+ * Will look at a path, and will create a "?noCache={time}" or "&noCache={time}"
1089
+ * query param string to return. Does NOT append that string to the original path.
1090
+ * This is useful because ExternalInterface often breaks when a Flash SWF is cached.
1091
+ *
1092
+ * @returns The `noCache` query param with necessary "?"/"&" prefix.
1093
+ * @private
1094
+ */
221
1095
  var _cacheBust = function(path, options) {
222
- var cacheBust = options == null || options && options.cacheBust === true && options.useNoCache === true;
1096
+ var cacheBust = options == null || options && options.cacheBust === true;
223
1097
  if (cacheBust) {
224
- return (path.indexOf("?") === -1 ? "?" : "&") + "noCache=" + new Date().getTime();
1098
+ return (path.indexOf("?") === -1 ? "?" : "&") + "noCache=" + _now();
225
1099
  } else {
226
1100
  return "";
227
1101
  }
228
1102
  };
1103
+ /**
1104
+ * Creates a query string for the FlashVars param.
1105
+ * Does NOT include the cache-busting query param.
1106
+ *
1107
+ * @returns FlashVars query string
1108
+ * @private
1109
+ */
229
1110
  var _vars = function(options) {
230
- var i, len, domain, str = [], domains = [], trustedOriginsExpanded = [];
231
- if (options.trustedOrigins) {
232
- if (typeof options.trustedOrigins === "string") {
233
- domains.push(options.trustedOrigins);
234
- } else if (typeof options.trustedOrigins === "object" && "length" in options.trustedOrigins) {
235
- domains = domains.concat(options.trustedOrigins);
236
- }
237
- }
1111
+ var i, len, domain, domains, str = "", trustedOriginsExpanded = [];
238
1112
  if (options.trustedDomains) {
239
1113
  if (typeof options.trustedDomains === "string") {
240
- domains.push(options.trustedDomains);
1114
+ domains = [ options.trustedDomains ];
241
1115
  } else if (typeof options.trustedDomains === "object" && "length" in options.trustedDomains) {
242
- domains = domains.concat(options.trustedDomains);
1116
+ domains = options.trustedDomains;
243
1117
  }
244
1118
  }
245
- if (domains.length) {
1119
+ if (domains && domains.length) {
246
1120
  for (i = 0, len = domains.length; i < len; i++) {
247
- if (domains.hasOwnProperty(i) && domains[i] && typeof domains[i] === "string") {
1121
+ if (_hasOwn.call(domains, i) && domains[i] && typeof domains[i] === "string") {
248
1122
  domain = _extractDomain(domains[i]);
249
1123
  if (!domain) {
250
1124
  continue;
251
1125
  }
252
1126
  if (domain === "*") {
253
- trustedOriginsExpanded = [ domain ];
1127
+ trustedOriginsExpanded.length = 0;
1128
+ trustedOriginsExpanded.push(domain);
254
1129
  break;
255
1130
  }
256
- trustedOriginsExpanded.push.apply(trustedOriginsExpanded, [ domain, "//" + domain, window.location.protocol + "//" + domain ]);
1131
+ trustedOriginsExpanded.push.apply(trustedOriginsExpanded, [ domain, "//" + domain, _window.location.protocol + "//" + domain ]);
257
1132
  }
258
1133
  }
259
1134
  }
260
1135
  if (trustedOriginsExpanded.length) {
261
- str.push("trustedOrigins=" + encodeURIComponent(trustedOriginsExpanded.join(",")));
262
- }
263
- if (typeof options.jsModuleId === "string" && options.jsModuleId) {
264
- str.push("jsModuleId=" + encodeURIComponent(options.jsModuleId));
265
- }
266
- return str.join("&");
267
- };
268
- var _inArray = function(elem, array, fromIndex) {
269
- if (typeof array.indexOf === "function") {
270
- return array.indexOf(elem, fromIndex);
271
- }
272
- var i, len = array.length;
273
- if (typeof fromIndex === "undefined") {
274
- fromIndex = 0;
275
- } else if (fromIndex < 0) {
276
- fromIndex = len + fromIndex;
277
- }
278
- for (i = fromIndex; i < len; i++) {
279
- if (array.hasOwnProperty(i) && array[i] === elem) {
280
- return i;
281
- }
282
- }
283
- return -1;
284
- };
285
- var _prepClip = function(elements) {
286
- if (typeof elements === "string") throw new TypeError("ZeroClipboard doesn't accept query strings.");
287
- if (!elements.length) return [ elements ];
288
- return elements;
289
- };
290
- var _dispatchCallback = function(func, context, args, async) {
291
- if (async) {
292
- window.setTimeout(function() {
293
- func.apply(context, args);
294
- }, 0);
295
- } else {
296
- func.apply(context, args);
297
- }
298
- };
299
- var _getSafeZIndex = function(val) {
300
- var zIndex, tmp;
301
- if (val) {
302
- if (typeof val === "number" && val > 0) {
303
- zIndex = val;
304
- } else if (typeof val === "string" && (tmp = parseInt(val, 10)) && !isNaN(tmp) && tmp > 0) {
305
- zIndex = tmp;
306
- }
1136
+ str += "trustedOrigins=" + _encodeURIComponent(trustedOriginsExpanded.join(","));
307
1137
  }
308
- if (!zIndex) {
309
- if (typeof _globalConfig.zIndex === "number" && _globalConfig.zIndex > 0) {
310
- zIndex = _globalConfig.zIndex;
311
- } else if (typeof _globalConfig.zIndex === "string" && (tmp = parseInt(_globalConfig.zIndex, 10)) && !isNaN(tmp) && tmp > 0) {
312
- zIndex = tmp;
313
- }
314
- }
315
- return zIndex || 0;
316
- };
317
- var _deprecationWarning = function(deprecatedApiName, debugEnabled) {
318
- if (deprecatedApiName && debugEnabled !== false && typeof console !== "undefined" && console && (console.warn || console.log)) {
319
- var deprecationWarning = "`" + deprecatedApiName + "` is deprecated. See docs for more info:\n" + " https://github.com/zeroclipboard/zeroclipboard/blob/master/docs/instructions.md#deprecations";
320
- if (console.warn) {
321
- console.warn(deprecationWarning);
322
- } else {
323
- console.log(deprecationWarning);
324
- }
1138
+ if (options.forceEnhancedClipboard === true) {
1139
+ str += (str ? "&" : "") + "forceEnhancedClipboard=true";
325
1140
  }
326
- };
327
- var _extend = function() {
328
- var i, len, arg, prop, src, copy, target = arguments[0] || {};
329
- for (i = 1, len = arguments.length; i < len; i++) {
330
- if ((arg = arguments[i]) != null) {
331
- for (prop in arg) {
332
- if (arg.hasOwnProperty(prop)) {
333
- src = target[prop];
334
- copy = arg[prop];
335
- if (target === copy) {
336
- continue;
337
- }
338
- if (copy !== undefined) {
339
- target[prop] = copy;
340
- }
341
- }
342
- }
343
- }
1141
+ if (typeof options.swfObjectId === "string" && options.swfObjectId) {
1142
+ str += (str ? "&" : "") + "swfObjectId=" + _encodeURIComponent(options.swfObjectId);
344
1143
  }
345
- return target;
1144
+ return str;
346
1145
  };
1146
+ /**
1147
+ * Extract the domain (e.g. "github.com") from an origin (e.g. "https://github.com") or
1148
+ * URL (e.g. "https://github.com/zeroclipboard/zeroclipboard/").
1149
+ *
1150
+ * @returns the domain
1151
+ * @private
1152
+ */
347
1153
  var _extractDomain = function(originOrUrl) {
348
1154
  if (originOrUrl == null || originOrUrl === "") {
349
1155
  return null;
@@ -361,55 +1167,47 @@
361
1167
  }
362
1168
  return originOrUrl || null;
363
1169
  };
1170
+ /**
1171
+ * Set `allowScriptAccess` based on `trustedDomains` and `window.location.host` vs. `swfPath`.
1172
+ *
1173
+ * @returns The appropriate script access level.
1174
+ * @private
1175
+ */
364
1176
  var _determineScriptAccess = function() {
365
- var _extractAllDomains = function(origins, resultsArray) {
366
- var i, len, tmp;
367
- if (origins != null && resultsArray[0] !== "*") {
368
- if (typeof origins === "string") {
369
- origins = [ origins ];
370
- }
371
- if (typeof origins === "object" && "length" in origins) {
372
- for (i = 0, len = origins.length; i < len; i++) {
373
- if (origins.hasOwnProperty(i)) {
374
- tmp = _extractDomain(origins[i]);
375
- if (tmp) {
376
- if (tmp === "*") {
377
- resultsArray.length = 0;
378
- resultsArray.push("*");
379
- break;
380
- }
381
- if (_inArray(tmp, resultsArray) === -1) {
382
- resultsArray.push(tmp);
383
- }
384
- }
385
- }
1177
+ var _extractAllDomains = function(origins) {
1178
+ var i, len, tmp, resultsArray = [];
1179
+ if (typeof origins === "string") {
1180
+ origins = [ origins ];
1181
+ }
1182
+ if (!(typeof origins === "object" && origins && typeof origins.length === "number")) {
1183
+ return resultsArray;
1184
+ }
1185
+ for (i = 0, len = origins.length; i < len; i++) {
1186
+ if (_hasOwn.call(origins, i) && (tmp = _extractDomain(origins[i]))) {
1187
+ if (tmp === "*") {
1188
+ resultsArray.length = 0;
1189
+ resultsArray.push("*");
1190
+ break;
1191
+ }
1192
+ if (resultsArray.indexOf(tmp) === -1) {
1193
+ resultsArray.push(tmp);
386
1194
  }
387
1195
  }
388
1196
  }
389
- };
390
- var _accessLevelLookup = {
391
- always: "always",
392
- samedomain: "sameDomain",
393
- never: "never"
1197
+ return resultsArray;
394
1198
  };
395
1199
  return function(currentDomain, configOptions) {
396
- var asaLower, allowScriptAccess = configOptions.allowScriptAccess;
397
- if (typeof allowScriptAccess === "string" && (asaLower = allowScriptAccess.toLowerCase()) && /^always|samedomain|never$/.test(asaLower)) {
398
- return _accessLevelLookup[asaLower];
399
- }
400
- var swfDomain = _extractDomain(configOptions.moviePath);
1200
+ var swfDomain = _extractDomain(configOptions.swfPath);
401
1201
  if (swfDomain === null) {
402
1202
  swfDomain = currentDomain;
403
1203
  }
404
- var trustedDomains = [];
405
- _extractAllDomains(configOptions.trustedOrigins, trustedDomains);
406
- _extractAllDomains(configOptions.trustedDomains, trustedDomains);
1204
+ var trustedDomains = _extractAllDomains(configOptions.trustedDomains);
407
1205
  var len = trustedDomains.length;
408
1206
  if (len > 0) {
409
1207
  if (len === 1 && trustedDomains[0] === "*") {
410
1208
  return "always";
411
1209
  }
412
- if (_inArray(currentDomain, trustedDomains) !== -1) {
1210
+ if (trustedDomains.indexOf(currentDomain) !== -1) {
413
1211
  if (len === 1 && currentDomain === swfDomain) {
414
1212
  return "sameDomain";
415
1213
  }
@@ -419,613 +1217,989 @@
419
1217
  return "never";
420
1218
  };
421
1219
  }();
422
- var _objectKeys = function(obj) {
423
- if (obj == null) {
424
- return [];
425
- }
426
- if (Object.keys) {
427
- return Object.keys(obj);
428
- }
429
- var keys = [];
430
- for (var prop in obj) {
431
- if (obj.hasOwnProperty(prop)) {
432
- keys.push(prop);
433
- }
1220
+ /**
1221
+ * Get the currently active/focused DOM element.
1222
+ *
1223
+ * @returns the currently active/focused element, or `null`
1224
+ * @private
1225
+ */
1226
+ var _safeActiveElement = function() {
1227
+ try {
1228
+ return _document.activeElement;
1229
+ } catch (err) {
1230
+ return null;
434
1231
  }
435
- return keys;
436
1232
  };
437
- var _deleteOwnProperties = function(obj) {
438
- if (obj) {
439
- for (var prop in obj) {
440
- if (obj.hasOwnProperty(prop)) {
441
- delete obj[prop];
442
- }
1233
+ /**
1234
+ * Add a class to an element, if it doesn't already have it.
1235
+ *
1236
+ * @returns The element, with its new class added.
1237
+ * @private
1238
+ */
1239
+ var _addClass = function(element, value) {
1240
+ if (!element || element.nodeType !== 1) {
1241
+ return element;
1242
+ }
1243
+ if (element.classList) {
1244
+ if (!element.classList.contains(value)) {
1245
+ element.classList.add(value);
443
1246
  }
1247
+ return element;
444
1248
  }
445
- return obj;
446
- };
447
- var _safeActiveElement = function() {
448
- try {
449
- return document.activeElement;
450
- } catch (err) {}
451
- return null;
452
- };
453
- var _detectFlashSupport = function() {
454
- var hasFlash = false;
455
- if (typeof flashState.disabled === "boolean") {
456
- hasFlash = flashState.disabled === false;
457
- } else {
458
- if (typeof ActiveXObject === "function") {
459
- try {
460
- if (new ActiveXObject("ShockwaveFlash.ShockwaveFlash")) {
461
- hasFlash = true;
1249
+ if (value && typeof value === "string") {
1250
+ var classNames = (value || "").split(/\s+/);
1251
+ if (element.nodeType === 1) {
1252
+ if (!element.className) {
1253
+ element.className = value;
1254
+ } else {
1255
+ var className = " " + element.className + " ", setClass = element.className;
1256
+ for (var c = 0, cl = classNames.length; c < cl; c++) {
1257
+ if (className.indexOf(" " + classNames[c] + " ") < 0) {
1258
+ setClass += " " + classNames[c];
1259
+ }
462
1260
  }
463
- } catch (error) {}
464
- }
465
- if (!hasFlash && navigator.mimeTypes["application/x-shockwave-flash"]) {
466
- hasFlash = true;
1261
+ element.className = setClass.replace(/^\s+|\s+$/g, "");
1262
+ }
467
1263
  }
468
1264
  }
469
- return hasFlash;
1265
+ return element;
470
1266
  };
471
- function _parseFlashVersion(flashVersion) {
472
- return flashVersion.replace(/,/g, ".").replace(/[^0-9\.]/g, "");
473
- }
474
- function _isFlashVersionSupported(flashVersion) {
475
- return parseFloat(_parseFlashVersion(flashVersion)) >= 10;
476
- }
477
- var ZeroClipboard = function(elements, options) {
478
- if (!(this instanceof ZeroClipboard)) {
479
- return new ZeroClipboard(elements, options);
480
- }
481
- this.id = "" + clientIdCounter++;
482
- _clientMeta[this.id] = {
483
- instance: this,
484
- elements: [],
485
- handlers: {}
486
- };
487
- if (elements) {
488
- this.clip(elements);
489
- }
490
- if (typeof options !== "undefined") {
491
- _deprecationWarning("new ZeroClipboard(elements, options)", _globalConfig.debug);
492
- ZeroClipboard.config(options);
1267
+ /**
1268
+ * Remove a class from an element, if it has it.
1269
+ *
1270
+ * @returns The element, with its class removed.
1271
+ * @private
1272
+ */
1273
+ var _removeClass = function(element, value) {
1274
+ if (!element || element.nodeType !== 1) {
1275
+ return element;
493
1276
  }
494
- this.options = ZeroClipboard.config();
495
- if (typeof flashState.disabled !== "boolean") {
496
- flashState.disabled = !_detectFlashSupport();
1277
+ if (element.classList) {
1278
+ if (element.classList.contains(value)) {
1279
+ element.classList.remove(value);
1280
+ }
1281
+ return element;
497
1282
  }
498
- if (flashState.disabled === false && flashState.outdated !== true) {
499
- if (flashState.bridge === null) {
500
- flashState.outdated = false;
501
- flashState.ready = false;
502
- _bridge();
1283
+ if (typeof value === "string" && value) {
1284
+ var classNames = value.split(/\s+/);
1285
+ if (element.nodeType === 1 && element.className) {
1286
+ var className = (" " + element.className + " ").replace(/[\n\t]/g, " ");
1287
+ for (var c = 0, cl = classNames.length; c < cl; c++) {
1288
+ className = className.replace(" " + classNames[c] + " ", " ");
1289
+ }
1290
+ element.className = className.replace(/^\s+|\s+$/g, "");
503
1291
  }
504
1292
  }
1293
+ return element;
505
1294
  };
506
- ZeroClipboard.prototype.setText = function(newText) {
507
- if (newText && newText !== "") {
508
- _clipData["text/plain"] = newText;
509
- if (flashState.ready === true && flashState.bridge && typeof flashState.bridge.setText === "function") {
510
- flashState.bridge.setText(newText);
511
- } else {
512
- flashState.ready = false;
1295
+ /**
1296
+ * Attempt to interpret the element's CSS styling. If `prop` is `"cursor"`,
1297
+ * then we assume that it should be a hand ("pointer") cursor if the element
1298
+ * is an anchor element ("a" tag).
1299
+ *
1300
+ * @returns The computed style property.
1301
+ * @private
1302
+ */
1303
+ var _getStyle = function(el, prop) {
1304
+ var value = _window.getComputedStyle(el, null).getPropertyValue(prop);
1305
+ if (prop === "cursor") {
1306
+ if (!value || value === "auto") {
1307
+ if (el.nodeName === "A") {
1308
+ return "pointer";
1309
+ }
513
1310
  }
514
1311
  }
515
- return this;
1312
+ return value;
516
1313
  };
517
- ZeroClipboard.prototype.setSize = function(width, height) {
518
- if (flashState.ready === true && flashState.bridge && typeof flashState.bridge.setSize === "function") {
519
- flashState.bridge.setSize(width, height);
520
- } else {
521
- flashState.ready = false;
1314
+ /**
1315
+ * Get the zoom factor of the browser. Always returns `1.0`, except at
1316
+ * non-default zoom levels in IE<8 and some older versions of WebKit.
1317
+ *
1318
+ * @returns Floating unit percentage of the zoom factor (e.g. 150% = `1.5`).
1319
+ * @private
1320
+ */
1321
+ var _getZoomFactor = function() {
1322
+ var rect, physicalWidth, logicalWidth, zoomFactor = 1;
1323
+ if (typeof _document.body.getBoundingClientRect === "function") {
1324
+ rect = _document.body.getBoundingClientRect();
1325
+ physicalWidth = rect.right - rect.left;
1326
+ logicalWidth = _document.body.offsetWidth;
1327
+ zoomFactor = _round(physicalWidth / logicalWidth * 100) / 100;
522
1328
  }
523
- return this;
1329
+ return zoomFactor;
524
1330
  };
525
- var _setHandCursor = function(enabled) {
526
- if (flashState.ready === true && flashState.bridge && typeof flashState.bridge.setHandCursor === "function") {
527
- flashState.bridge.setHandCursor(enabled);
528
- } else {
529
- flashState.ready = false;
1331
+ /**
1332
+ * Get the DOM positioning info of an element.
1333
+ *
1334
+ * @returns Object containing the element's position, width, and height.
1335
+ * @private
1336
+ */
1337
+ var _getDOMObjectPosition = function(obj) {
1338
+ var info = {
1339
+ left: 0,
1340
+ top: 0,
1341
+ width: 0,
1342
+ height: 0
1343
+ };
1344
+ if (obj.getBoundingClientRect) {
1345
+ var rect = obj.getBoundingClientRect();
1346
+ var pageXOffset, pageYOffset, zoomFactor;
1347
+ if ("pageXOffset" in _window && "pageYOffset" in _window) {
1348
+ pageXOffset = _window.pageXOffset;
1349
+ pageYOffset = _window.pageYOffset;
1350
+ } else {
1351
+ zoomFactor = _getZoomFactor();
1352
+ pageXOffset = _round(_document.documentElement.scrollLeft / zoomFactor);
1353
+ pageYOffset = _round(_document.documentElement.scrollTop / zoomFactor);
1354
+ }
1355
+ var leftBorderWidth = _document.documentElement.clientLeft || 0;
1356
+ var topBorderWidth = _document.documentElement.clientTop || 0;
1357
+ info.left = rect.left + pageXOffset - leftBorderWidth;
1358
+ info.top = rect.top + pageYOffset - topBorderWidth;
1359
+ info.width = "width" in rect ? rect.width : rect.right - rect.left;
1360
+ info.height = "height" in rect ? rect.height : rect.bottom - rect.top;
530
1361
  }
1362
+ return info;
531
1363
  };
532
- ZeroClipboard.prototype.destroy = function() {
533
- this.unclip();
534
- this.off();
535
- delete _clientMeta[this.id];
1364
+ /**
1365
+ * Reposition the Flash object to cover the currently activated element.
1366
+ *
1367
+ * @returns `undefined`
1368
+ * @private
1369
+ */
1370
+ var _reposition = function() {
1371
+ var htmlBridge;
1372
+ if (_currentElement && (htmlBridge = _getHtmlBridge(_flashState.bridge))) {
1373
+ var pos = _getDOMObjectPosition(_currentElement);
1374
+ _extend(htmlBridge.style, {
1375
+ width: pos.width + "px",
1376
+ height: pos.height + "px",
1377
+ top: pos.top + "px",
1378
+ left: pos.left + "px",
1379
+ zIndex: "" + _getSafeZIndex(_globalConfig.zIndex)
1380
+ });
1381
+ }
536
1382
  };
537
- var _getAllClients = function() {
538
- var i, len, client, clients = [], clientIds = _objectKeys(_clientMeta);
539
- for (i = 0, len = clientIds.length; i < len; i++) {
540
- client = _clientMeta[clientIds[i]].instance;
541
- if (client && client instanceof ZeroClipboard) {
542
- clients.push(client);
1383
+ /**
1384
+ * Sends a signal to the Flash object to display the hand cursor if `true`.
1385
+ *
1386
+ * @returns `undefined`
1387
+ * @private
1388
+ */
1389
+ var _setHandCursor = function(enabled) {
1390
+ if (_flashState.ready === true) {
1391
+ if (_flashState.bridge && typeof _flashState.bridge.setHandCursor === "function") {
1392
+ _flashState.bridge.setHandCursor(enabled);
1393
+ } else {
1394
+ _flashState.ready = false;
543
1395
  }
544
1396
  }
545
- return clients;
546
- };
547
- ZeroClipboard.version = "1.3.5";
548
- var _globalConfig = {
549
- swfPath: _swfPath,
550
- trustedDomains: window.location.host ? [ window.location.host ] : [],
551
- cacheBust: true,
552
- forceHandCursor: false,
553
- zIndex: 999999999,
554
- debug: true,
555
- title: null,
556
- autoActivate: true
557
1397
  };
558
- ZeroClipboard.config = function(options) {
559
- if (typeof options === "object" && options !== null) {
560
- _extend(_globalConfig, options);
1398
+ /**
1399
+ * Get a safe value for `zIndex`
1400
+ *
1401
+ * @returns an integer, or "auto"
1402
+ * @private
1403
+ */
1404
+ var _getSafeZIndex = function(val) {
1405
+ if (/^(?:auto|inherit)$/.test(val)) {
1406
+ return val;
561
1407
  }
562
- if (typeof options === "string" && options) {
563
- if (_globalConfig.hasOwnProperty(options)) {
564
- return _globalConfig[options];
565
- }
566
- return;
1408
+ var zIndex;
1409
+ if (typeof val === "number" && !_isNaN(val)) {
1410
+ zIndex = val;
1411
+ } else if (typeof val === "string") {
1412
+ zIndex = _getSafeZIndex(_parseInt(val, 10));
567
1413
  }
568
- var copy = {};
569
- for (var prop in _globalConfig) {
570
- if (_globalConfig.hasOwnProperty(prop)) {
571
- if (typeof _globalConfig[prop] === "object" && _globalConfig[prop] !== null) {
572
- if ("length" in _globalConfig[prop]) {
573
- copy[prop] = _globalConfig[prop].slice(0);
574
- } else {
575
- copy[prop] = _extend({}, _globalConfig[prop]);
576
- }
577
- } else {
578
- copy[prop] = _globalConfig[prop];
1414
+ return typeof zIndex === "number" ? zIndex : "auto";
1415
+ };
1416
+ /**
1417
+ * Detect the Flash Player status, version, and plugin type.
1418
+ *
1419
+ * @see {@link https://code.google.com/p/doctype-mirror/wiki/ArticleDetectFlash#The_code}
1420
+ * @see {@link http://stackoverflow.com/questions/12866060/detecting-pepper-ppapi-flash-with-javascript}
1421
+ *
1422
+ * @returns `undefined`
1423
+ * @private
1424
+ */
1425
+ var _detectFlashSupport = function(ActiveXObject) {
1426
+ var plugin, ax, mimeType, hasFlash = false, isActiveX = false, isPPAPI = false, flashVersion = "";
1427
+ /**
1428
+ * Derived from Apple's suggested sniffer.
1429
+ * @param {String} desc e.g. "Shockwave Flash 7.0 r61"
1430
+ * @returns {String} "7.0.61"
1431
+ * @private
1432
+ */
1433
+ function parseFlashVersion(desc) {
1434
+ var matches = desc.match(/[\d]+/g);
1435
+ matches.length = 3;
1436
+ return matches.join(".");
1437
+ }
1438
+ function isPepperFlash(flashPlayerFileName) {
1439
+ return !!flashPlayerFileName && (flashPlayerFileName = flashPlayerFileName.toLowerCase()) && (/^(pepflashplayer\.dll|libpepflashplayer\.so|pepperflashplayer\.plugin)$/.test(flashPlayerFileName) || flashPlayerFileName.slice(-13) === "chrome.plugin");
1440
+ }
1441
+ function inspectPlugin(plugin) {
1442
+ if (plugin) {
1443
+ hasFlash = true;
1444
+ if (plugin.version) {
1445
+ flashVersion = parseFlashVersion(plugin.version);
1446
+ }
1447
+ if (!flashVersion && plugin.description) {
1448
+ flashVersion = parseFlashVersion(plugin.description);
1449
+ }
1450
+ if (plugin.filename) {
1451
+ isPPAPI = isPepperFlash(plugin.filename);
579
1452
  }
580
1453
  }
581
1454
  }
582
- return copy;
583
- };
584
- ZeroClipboard.destroy = function() {
585
- ZeroClipboard.deactivate();
586
- for (var clientId in _clientMeta) {
587
- if (_clientMeta.hasOwnProperty(clientId) && _clientMeta[clientId]) {
588
- var client = _clientMeta[clientId].instance;
589
- if (client && typeof client.destroy === "function") {
590
- client.destroy();
1455
+ if (_navigator.plugins && _navigator.plugins.length) {
1456
+ plugin = _navigator.plugins["Shockwave Flash"];
1457
+ inspectPlugin(plugin);
1458
+ if (_navigator.plugins["Shockwave Flash 2.0"]) {
1459
+ hasFlash = true;
1460
+ flashVersion = "2.0.0.11";
1461
+ }
1462
+ } else if (_navigator.mimeTypes && _navigator.mimeTypes.length) {
1463
+ mimeType = _navigator.mimeTypes["application/x-shockwave-flash"];
1464
+ plugin = mimeType && mimeType.enabledPlugin;
1465
+ inspectPlugin(plugin);
1466
+ } else if (typeof ActiveXObject !== "undefined") {
1467
+ isActiveX = true;
1468
+ try {
1469
+ ax = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
1470
+ hasFlash = true;
1471
+ flashVersion = parseFlashVersion(ax.GetVariable("$version"));
1472
+ } catch (e1) {
1473
+ try {
1474
+ ax = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
1475
+ hasFlash = true;
1476
+ flashVersion = "6.0.21";
1477
+ } catch (e2) {
1478
+ try {
1479
+ ax = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
1480
+ hasFlash = true;
1481
+ flashVersion = parseFlashVersion(ax.GetVariable("$version"));
1482
+ } catch (e3) {
1483
+ isActiveX = false;
1484
+ }
591
1485
  }
592
1486
  }
593
1487
  }
594
- var htmlBridge = _getHtmlBridge(flashState.bridge);
595
- if (htmlBridge && htmlBridge.parentNode) {
596
- htmlBridge.parentNode.removeChild(htmlBridge);
597
- flashState.ready = null;
598
- flashState.bridge = null;
599
- }
1488
+ _flashState.disabled = hasFlash !== true;
1489
+ _flashState.outdated = flashVersion && _parseFloat(flashVersion) < _parseFloat(_minimumFlashVersion);
1490
+ _flashState.version = flashVersion || "0.0.0";
1491
+ _flashState.pluginType = isPPAPI ? "pepper" : isActiveX ? "activex" : hasFlash ? "netscape" : "unknown";
600
1492
  };
601
- ZeroClipboard.activate = function(element) {
602
- if (currentElement) {
603
- _removeClass(currentElement, _globalConfig.hoverClass);
604
- _removeClass(currentElement, _globalConfig.activeClass);
1493
+ /**
1494
+ * Invoke the Flash detection algorithms immediately upon inclusion so we're not waiting later.
1495
+ */
1496
+ _detectFlashSupport(_ActiveXObject);
1497
+ /**
1498
+ * A shell constructor for `ZeroClipboard` client instances.
1499
+ *
1500
+ * @constructor
1501
+ */
1502
+ var ZeroClipboard = function() {
1503
+ if (!(this instanceof ZeroClipboard)) {
1504
+ return new ZeroClipboard();
605
1505
  }
606
- currentElement = element;
607
- _addClass(element, _globalConfig.hoverClass);
608
- _reposition();
609
- var newTitle = _globalConfig.title || element.getAttribute("title");
610
- if (newTitle) {
611
- var htmlBridge = _getHtmlBridge(flashState.bridge);
612
- if (htmlBridge) {
613
- htmlBridge.setAttribute("title", newTitle);
614
- }
1506
+ if (typeof ZeroClipboard._createClient === "function") {
1507
+ ZeroClipboard._createClient.apply(this, _args(arguments));
615
1508
  }
616
- var useHandCursor = _globalConfig.forceHandCursor === true || _getStyle(element, "cursor") === "pointer";
617
- _setHandCursor(useHandCursor);
618
1509
  };
619
- ZeroClipboard.deactivate = function() {
620
- var htmlBridge = _getHtmlBridge(flashState.bridge);
621
- if (htmlBridge) {
622
- htmlBridge.style.left = "0px";
623
- htmlBridge.style.top = "-9999px";
624
- htmlBridge.removeAttribute("title");
625
- }
626
- if (currentElement) {
627
- _removeClass(currentElement, _globalConfig.hoverClass);
628
- _removeClass(currentElement, _globalConfig.activeClass);
629
- currentElement = null;
630
- }
631
- };
632
- var _bridge = function() {
633
- var flashBridge, len;
634
- var container = document.getElementById("global-zeroclipboard-html-bridge");
635
- if (!container) {
636
- var opts = ZeroClipboard.config();
637
- opts.jsModuleId = typeof _amdModuleId === "string" && _amdModuleId || typeof _cjsModuleId === "string" && _cjsModuleId || null;
638
- var allowScriptAccess = _determineScriptAccess(window.location.host, _globalConfig);
639
- var flashvars = _vars(opts);
640
- var swfUrl = _globalConfig.moviePath + _cacheBust(_globalConfig.moviePath, _globalConfig);
641
- var html = ' <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" id="global-zeroclipboard-flash-bridge" width="100%" height="100%"> <param name="movie" value="' + swfUrl + '"/> <param name="allowScriptAccess" value="' + allowScriptAccess + '"/> <param name="scale" value="exactfit"/> <param name="loop" value="false"/> <param name="menu" value="false"/> <param name="quality" value="best" /> <param name="bgcolor" value="#ffffff"/> <param name="wmode" value="transparent"/> <param name="flashvars" value="' + flashvars + '"/> <embed src="' + swfUrl + '" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="100%" height="100%" name="global-zeroclipboard-flash-bridge" allowScriptAccess="' + allowScriptAccess + '" allowFullScreen="false" type="application/x-shockwave-flash" wmode="transparent" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="' + flashvars + '" scale="exactfit"> </embed> </object>';
642
- container = document.createElement("div");
643
- container.id = "global-zeroclipboard-html-bridge";
644
- container.setAttribute("class", "global-zeroclipboard-container");
645
- container.style.position = "absolute";
646
- container.style.left = "0px";
647
- container.style.top = "-9999px";
648
- container.style.width = "15px";
649
- container.style.height = "15px";
650
- container.style.zIndex = "" + _getSafeZIndex(_globalConfig.zIndex);
651
- document.body.appendChild(container);
652
- container.innerHTML = html;
653
- }
654
- flashBridge = document["global-zeroclipboard-flash-bridge"];
655
- if (flashBridge && (len = flashBridge.length)) {
656
- flashBridge = flashBridge[len - 1];
657
- }
658
- flashState.bridge = flashBridge || container.children[0].lastElementChild;
1510
+ /**
1511
+ * The ZeroClipboard library's version number.
1512
+ *
1513
+ * @static
1514
+ * @readonly
1515
+ * @property {string}
1516
+ */
1517
+ _defineProperty(ZeroClipboard, "version", {
1518
+ value: "2.1.2",
1519
+ writable: false,
1520
+ configurable: true,
1521
+ enumerable: true
1522
+ });
1523
+ /**
1524
+ * Update or get a copy of the ZeroClipboard global configuration.
1525
+ * Returns a copy of the current/updated configuration.
1526
+ *
1527
+ * @returns Object
1528
+ * @static
1529
+ */
1530
+ ZeroClipboard.config = function() {
1531
+ return _config.apply(this, _args(arguments));
659
1532
  };
660
- var _getHtmlBridge = function(flashBridge) {
661
- var isFlashElement = /^OBJECT|EMBED$/;
662
- var htmlBridge = flashBridge && flashBridge.parentNode;
663
- while (htmlBridge && isFlashElement.test(htmlBridge.nodeName) && htmlBridge.parentNode) {
664
- htmlBridge = htmlBridge.parentNode;
665
- }
666
- return htmlBridge || null;
1533
+ /**
1534
+ * Diagnostic method that describes the state of the browser, Flash Player, and ZeroClipboard.
1535
+ *
1536
+ * @returns Object
1537
+ * @static
1538
+ */
1539
+ ZeroClipboard.state = function() {
1540
+ return _state.apply(this, _args(arguments));
667
1541
  };
668
- var _reposition = function() {
669
- if (currentElement) {
670
- var pos = _getDOMObjectPosition(currentElement, _globalConfig.zIndex);
671
- var htmlBridge = _getHtmlBridge(flashState.bridge);
672
- if (htmlBridge) {
673
- htmlBridge.style.top = pos.top + "px";
674
- htmlBridge.style.left = pos.left + "px";
675
- htmlBridge.style.width = pos.width + "px";
676
- htmlBridge.style.height = pos.height + "px";
677
- htmlBridge.style.zIndex = pos.zIndex + 1;
678
- }
679
- if (flashState.ready === true && flashState.bridge && typeof flashState.bridge.setSize === "function") {
680
- flashState.bridge.setSize(pos.width, pos.height);
681
- } else {
682
- flashState.ready = false;
683
- }
1542
+ /**
1543
+ * Check if Flash is unusable for any reason: disabled, outdated, deactivated, etc.
1544
+ *
1545
+ * @returns Boolean
1546
+ * @static
1547
+ */
1548
+ ZeroClipboard.isFlashUnusable = function() {
1549
+ return _isFlashUnusable.apply(this, _args(arguments));
1550
+ };
1551
+ /**
1552
+ * Register an event listener.
1553
+ *
1554
+ * @returns `ZeroClipboard`
1555
+ * @static
1556
+ */
1557
+ ZeroClipboard.on = function() {
1558
+ return _on.apply(this, _args(arguments));
1559
+ };
1560
+ /**
1561
+ * Unregister an event listener.
1562
+ * If no `listener` function/object is provided, it will unregister all listeners for the provided `eventType`.
1563
+ * If no `eventType` is provided, it will unregister all listeners for every event type.
1564
+ *
1565
+ * @returns `ZeroClipboard`
1566
+ * @static
1567
+ */
1568
+ ZeroClipboard.off = function() {
1569
+ return _off.apply(this, _args(arguments));
1570
+ };
1571
+ /**
1572
+ * Retrieve event listeners for an `eventType`.
1573
+ * If no `eventType` is provided, it will retrieve all listeners for every event type.
1574
+ *
1575
+ * @returns array of listeners for the `eventType`; if no `eventType`, then a map/hash object of listeners for all event types; or `null`
1576
+ */
1577
+ ZeroClipboard.handlers = function() {
1578
+ return _listeners.apply(this, _args(arguments));
1579
+ };
1580
+ /**
1581
+ * Event emission receiver from the Flash object, forwarding to any registered JavaScript event listeners.
1582
+ *
1583
+ * @returns For the "copy" event, returns the Flash-friendly "clipData" object; otherwise `undefined`.
1584
+ * @static
1585
+ */
1586
+ ZeroClipboard.emit = function() {
1587
+ return _emit.apply(this, _args(arguments));
1588
+ };
1589
+ /**
1590
+ * Create and embed the Flash object.
1591
+ *
1592
+ * @returns The Flash object
1593
+ * @static
1594
+ */
1595
+ ZeroClipboard.create = function() {
1596
+ return _create.apply(this, _args(arguments));
1597
+ };
1598
+ /**
1599
+ * Self-destruct and clean up everything, including the embedded Flash object.
1600
+ *
1601
+ * @returns `undefined`
1602
+ * @static
1603
+ */
1604
+ ZeroClipboard.destroy = function() {
1605
+ return _destroy.apply(this, _args(arguments));
1606
+ };
1607
+ /**
1608
+ * Set the pending data for clipboard injection.
1609
+ *
1610
+ * @returns `undefined`
1611
+ * @static
1612
+ */
1613
+ ZeroClipboard.setData = function() {
1614
+ return _setData.apply(this, _args(arguments));
1615
+ };
1616
+ /**
1617
+ * Clear the pending data for clipboard injection.
1618
+ * If no `format` is provided, all pending data formats will be cleared.
1619
+ *
1620
+ * @returns `undefined`
1621
+ * @static
1622
+ */
1623
+ ZeroClipboard.clearData = function() {
1624
+ return _clearData.apply(this, _args(arguments));
1625
+ };
1626
+ /**
1627
+ * Get a copy of the pending data for clipboard injection.
1628
+ * If no `format` is provided, a copy of ALL pending data formats will be returned.
1629
+ *
1630
+ * @returns `String` or `Object`
1631
+ * @static
1632
+ */
1633
+ ZeroClipboard.getData = function() {
1634
+ return _getData.apply(this, _args(arguments));
1635
+ };
1636
+ /**
1637
+ * Sets the current HTML object that the Flash object should overlay. This will put the global
1638
+ * Flash object on top of the current element; depending on the setup, this may also set the
1639
+ * pending clipboard text data as well as the Flash object's wrapping element's title attribute
1640
+ * based on the underlying HTML element and ZeroClipboard configuration.
1641
+ *
1642
+ * @returns `undefined`
1643
+ * @static
1644
+ */
1645
+ ZeroClipboard.focus = ZeroClipboard.activate = function() {
1646
+ return _focus.apply(this, _args(arguments));
1647
+ };
1648
+ /**
1649
+ * Un-overlays the Flash object. This will put the global Flash object off-screen; depending on
1650
+ * the setup, this may also unset the Flash object's wrapping element's title attribute based on
1651
+ * the underlying HTML element and ZeroClipboard configuration.
1652
+ *
1653
+ * @returns `undefined`
1654
+ * @static
1655
+ */
1656
+ ZeroClipboard.blur = ZeroClipboard.deactivate = function() {
1657
+ return _blur.apply(this, _args(arguments));
1658
+ };
1659
+ /**
1660
+ * Returns the currently focused/"activated" HTML element that the Flash object is wrapping.
1661
+ *
1662
+ * @returns `HTMLElement` or `null`
1663
+ * @static
1664
+ */
1665
+ ZeroClipboard.activeElement = function() {
1666
+ return _activeElement.apply(this, _args(arguments));
1667
+ };
1668
+ /**
1669
+ * Keep track of the ZeroClipboard client instance counter.
1670
+ */
1671
+ var _clientIdCounter = 0;
1672
+ /**
1673
+ * Keep track of the state of the client instances.
1674
+ *
1675
+ * Entry structure:
1676
+ * _clientMeta[client.id] = {
1677
+ * instance: client,
1678
+ * elements: [],
1679
+ * handlers: {}
1680
+ * };
1681
+ */
1682
+ var _clientMeta = {};
1683
+ /**
1684
+ * Keep track of the ZeroClipboard clipped elements counter.
1685
+ */
1686
+ var _elementIdCounter = 0;
1687
+ /**
1688
+ * Keep track of the state of the clipped element relationships to clients.
1689
+ *
1690
+ * Entry structure:
1691
+ * _elementMeta[element.zcClippingId] = [client1.id, client2.id];
1692
+ */
1693
+ var _elementMeta = {};
1694
+ /**
1695
+ * Keep track of the state of the mouse event handlers for clipped elements.
1696
+ *
1697
+ * Entry structure:
1698
+ * _mouseHandlers[element.zcClippingId] = {
1699
+ * mouseover: function(event) {},
1700
+ * mouseout: function(event) {},
1701
+ * mouseenter: function(event) {},
1702
+ * mouseleave: function(event) {},
1703
+ * mousemove: function(event) {}
1704
+ * };
1705
+ */
1706
+ var _mouseHandlers = {};
1707
+ /**
1708
+ * Extending the ZeroClipboard configuration defaults for the Client module.
1709
+ */
1710
+ _extend(_globalConfig, {
1711
+ autoActivate: true
1712
+ });
1713
+ /**
1714
+ * The real constructor for `ZeroClipboard` client instances.
1715
+ * @private
1716
+ */
1717
+ var _clientConstructor = function(elements) {
1718
+ var client = this;
1719
+ client.id = "" + _clientIdCounter++;
1720
+ _clientMeta[client.id] = {
1721
+ instance: client,
1722
+ elements: [],
1723
+ handlers: {}
1724
+ };
1725
+ if (elements) {
1726
+ client.clip(elements);
684
1727
  }
685
- return this;
1728
+ ZeroClipboard.on("*", function(event) {
1729
+ return client.emit(event);
1730
+ });
1731
+ ZeroClipboard.on("destroy", function() {
1732
+ client.destroy();
1733
+ });
1734
+ ZeroClipboard.create();
686
1735
  };
687
- ZeroClipboard.prototype.on = function(eventName, func) {
1736
+ /**
1737
+ * The underlying implementation of `ZeroClipboard.Client.prototype.on`.
1738
+ * @private
1739
+ */
1740
+ var _clientOn = function(eventType, listener) {
688
1741
  var i, len, events, added = {}, handlers = _clientMeta[this.id] && _clientMeta[this.id].handlers;
689
- if (typeof eventName === "string" && eventName) {
690
- events = eventName.toLowerCase().split(/\s+/);
691
- } else if (typeof eventName === "object" && eventName && typeof func === "undefined") {
692
- for (i in eventName) {
693
- if (eventName.hasOwnProperty(i) && typeof i === "string" && i && typeof eventName[i] === "function") {
694
- this.on(i, eventName[i]);
1742
+ if (typeof eventType === "string" && eventType) {
1743
+ events = eventType.toLowerCase().split(/\s+/);
1744
+ } else if (typeof eventType === "object" && eventType && typeof listener === "undefined") {
1745
+ for (i in eventType) {
1746
+ if (_hasOwn.call(eventType, i) && typeof i === "string" && i && typeof eventType[i] === "function") {
1747
+ this.on(i, eventType[i]);
695
1748
  }
696
1749
  }
697
1750
  }
698
1751
  if (events && events.length) {
699
1752
  for (i = 0, len = events.length; i < len; i++) {
700
- eventName = events[i].replace(/^on/, "");
701
- added[eventName] = true;
702
- if (!handlers[eventName]) {
703
- handlers[eventName] = [];
1753
+ eventType = events[i].replace(/^on/, "");
1754
+ added[eventType] = true;
1755
+ if (!handlers[eventType]) {
1756
+ handlers[eventType] = [];
704
1757
  }
705
- handlers[eventName].push(func);
1758
+ handlers[eventType].push(listener);
706
1759
  }
707
- if (added.noflash && flashState.disabled) {
708
- _receiveEvent.call(this, "noflash", {});
709
- }
710
- if (added.wrongflash && flashState.outdated) {
711
- _receiveEvent.call(this, "wrongflash", {
712
- flashVersion: flashState.version
1760
+ if (added.ready && _flashState.ready) {
1761
+ this.emit({
1762
+ type: "ready",
1763
+ client: this
713
1764
  });
714
1765
  }
715
- if (added.load && flashState.ready) {
716
- _receiveEvent.call(this, "load", {
717
- flashVersion: flashState.version
718
- });
1766
+ if (added.error) {
1767
+ var errorTypes = [ "disabled", "outdated", "unavailable", "deactivated", "overdue" ];
1768
+ for (i = 0, len = errorTypes.length; i < len; i++) {
1769
+ if (_flashState[errorTypes[i]]) {
1770
+ this.emit({
1771
+ type: "error",
1772
+ name: "flash-" + errorTypes[i],
1773
+ client: this
1774
+ });
1775
+ break;
1776
+ }
1777
+ }
719
1778
  }
720
1779
  }
721
1780
  return this;
722
1781
  };
723
- ZeroClipboard.prototype.off = function(eventName, func) {
1782
+ /**
1783
+ * The underlying implementation of `ZeroClipboard.Client.prototype.off`.
1784
+ * @private
1785
+ */
1786
+ var _clientOff = function(eventType, listener) {
724
1787
  var i, len, foundIndex, events, perEventHandlers, handlers = _clientMeta[this.id] && _clientMeta[this.id].handlers;
725
1788
  if (arguments.length === 0) {
726
- events = _objectKeys(handlers);
727
- } else if (typeof eventName === "string" && eventName) {
728
- events = eventName.split(/\s+/);
729
- } else if (typeof eventName === "object" && eventName && typeof func === "undefined") {
730
- for (i in eventName) {
731
- if (eventName.hasOwnProperty(i) && typeof i === "string" && i && typeof eventName[i] === "function") {
732
- this.off(i, eventName[i]);
1789
+ events = _keys(handlers);
1790
+ } else if (typeof eventType === "string" && eventType) {
1791
+ events = eventType.split(/\s+/);
1792
+ } else if (typeof eventType === "object" && eventType && typeof listener === "undefined") {
1793
+ for (i in eventType) {
1794
+ if (_hasOwn.call(eventType, i) && typeof i === "string" && i && typeof eventType[i] === "function") {
1795
+ this.off(i, eventType[i]);
733
1796
  }
734
1797
  }
735
1798
  }
736
1799
  if (events && events.length) {
737
1800
  for (i = 0, len = events.length; i < len; i++) {
738
- eventName = events[i].toLowerCase().replace(/^on/, "");
739
- perEventHandlers = handlers[eventName];
1801
+ eventType = events[i].toLowerCase().replace(/^on/, "");
1802
+ perEventHandlers = handlers[eventType];
740
1803
  if (perEventHandlers && perEventHandlers.length) {
741
- if (func) {
742
- foundIndex = _inArray(func, perEventHandlers);
1804
+ if (listener) {
1805
+ foundIndex = perEventHandlers.indexOf(listener);
743
1806
  while (foundIndex !== -1) {
744
1807
  perEventHandlers.splice(foundIndex, 1);
745
- foundIndex = _inArray(func, perEventHandlers, foundIndex);
1808
+ foundIndex = perEventHandlers.indexOf(listener, foundIndex);
746
1809
  }
747
1810
  } else {
748
- handlers[eventName].length = 0;
1811
+ perEventHandlers.length = 0;
749
1812
  }
750
1813
  }
751
1814
  }
752
1815
  }
753
1816
  return this;
754
1817
  };
755
- ZeroClipboard.prototype.handlers = function(eventName) {
756
- var prop, copy = null, handlers = _clientMeta[this.id] && _clientMeta[this.id].handlers;
1818
+ /**
1819
+ * The underlying implementation of `ZeroClipboard.Client.prototype.handlers`.
1820
+ * @private
1821
+ */
1822
+ var _clientListeners = function(eventType) {
1823
+ var copy = null, handlers = _clientMeta[this.id] && _clientMeta[this.id].handlers;
757
1824
  if (handlers) {
758
- if (typeof eventName === "string" && eventName) {
759
- return handlers[eventName] ? handlers[eventName].slice(0) : null;
760
- }
761
- copy = {};
762
- for (prop in handlers) {
763
- if (handlers.hasOwnProperty(prop) && handlers[prop]) {
764
- copy[prop] = handlers[prop].slice(0);
765
- }
1825
+ if (typeof eventType === "string" && eventType) {
1826
+ copy = handlers[eventType] ? handlers[eventType].slice(0) : [];
1827
+ } else {
1828
+ copy = _deepCopy(handlers);
766
1829
  }
767
1830
  }
768
1831
  return copy;
769
1832
  };
770
- var _dispatchClientCallbacks = function(eventName, context, args, async) {
771
- var handlers = _clientMeta[this.id] && _clientMeta[this.id].handlers[eventName];
772
- if (handlers && handlers.length) {
773
- var i, len, func, originalContext = context || this;
774
- for (i = 0, len = handlers.length; i < len; i++) {
775
- func = handlers[i];
776
- context = originalContext;
777
- if (typeof func === "string" && typeof window[func] === "function") {
778
- func = window[func];
779
- }
780
- if (typeof func === "object" && func && typeof func.handleEvent === "function") {
781
- context = func;
782
- func = func.handleEvent;
783
- }
784
- if (typeof func === "function") {
785
- _dispatchCallback(func, context, args, async);
786
- }
1833
+ /**
1834
+ * The underlying implementation of `ZeroClipboard.Client.prototype.emit`.
1835
+ * @private
1836
+ */
1837
+ var _clientEmit = function(event) {
1838
+ if (_clientShouldEmit.call(this, event)) {
1839
+ if (typeof event === "object" && event && typeof event.type === "string" && event.type) {
1840
+ event = _extend({}, event);
787
1841
  }
1842
+ var eventCopy = _extend({}, _createEvent(event), {
1843
+ client: this
1844
+ });
1845
+ _clientDispatchCallbacks.call(this, eventCopy);
788
1846
  }
789
1847
  return this;
790
1848
  };
791
- ZeroClipboard.prototype.clip = function(elements) {
1849
+ /**
1850
+ * The underlying implementation of `ZeroClipboard.Client.prototype.clip`.
1851
+ * @private
1852
+ */
1853
+ var _clientClip = function(elements) {
792
1854
  elements = _prepClip(elements);
793
1855
  for (var i = 0; i < elements.length; i++) {
794
- if (elements.hasOwnProperty(i) && elements[i] && elements[i].nodeType === 1) {
1856
+ if (_hasOwn.call(elements, i) && elements[i] && elements[i].nodeType === 1) {
795
1857
  if (!elements[i].zcClippingId) {
796
- elements[i].zcClippingId = "zcClippingId_" + elementIdCounter++;
1858
+ elements[i].zcClippingId = "zcClippingId_" + _elementIdCounter++;
797
1859
  _elementMeta[elements[i].zcClippingId] = [ this.id ];
798
1860
  if (_globalConfig.autoActivate === true) {
799
- _addEventHandler(elements[i], "mouseover", _elementMouseOver);
1861
+ _addMouseHandlers(elements[i]);
800
1862
  }
801
- } else if (_inArray(this.id, _elementMeta[elements[i].zcClippingId]) === -1) {
1863
+ } else if (_elementMeta[elements[i].zcClippingId].indexOf(this.id) === -1) {
802
1864
  _elementMeta[elements[i].zcClippingId].push(this.id);
803
1865
  }
804
- var clippedElements = _clientMeta[this.id].elements;
805
- if (_inArray(elements[i], clippedElements) === -1) {
1866
+ var clippedElements = _clientMeta[this.id] && _clientMeta[this.id].elements;
1867
+ if (clippedElements.indexOf(elements[i]) === -1) {
806
1868
  clippedElements.push(elements[i]);
807
1869
  }
808
1870
  }
809
1871
  }
810
1872
  return this;
811
1873
  };
812
- ZeroClipboard.prototype.unclip = function(elements) {
1874
+ /**
1875
+ * The underlying implementation of `ZeroClipboard.Client.prototype.unclip`.
1876
+ * @private
1877
+ */
1878
+ var _clientUnclip = function(elements) {
813
1879
  var meta = _clientMeta[this.id];
814
- if (meta) {
815
- var clippedElements = meta.elements;
816
- var arrayIndex;
817
- if (typeof elements === "undefined") {
818
- elements = clippedElements.slice(0);
819
- } else {
820
- elements = _prepClip(elements);
821
- }
822
- for (var i = elements.length; i--; ) {
823
- if (elements.hasOwnProperty(i) && elements[i] && elements[i].nodeType === 1) {
1880
+ if (!meta) {
1881
+ return this;
1882
+ }
1883
+ var clippedElements = meta.elements;
1884
+ var arrayIndex;
1885
+ if (typeof elements === "undefined") {
1886
+ elements = clippedElements.slice(0);
1887
+ } else {
1888
+ elements = _prepClip(elements);
1889
+ }
1890
+ for (var i = elements.length; i--; ) {
1891
+ if (_hasOwn.call(elements, i) && elements[i] && elements[i].nodeType === 1) {
1892
+ arrayIndex = 0;
1893
+ while ((arrayIndex = clippedElements.indexOf(elements[i], arrayIndex)) !== -1) {
1894
+ clippedElements.splice(arrayIndex, 1);
1895
+ }
1896
+ var clientIds = _elementMeta[elements[i].zcClippingId];
1897
+ if (clientIds) {
824
1898
  arrayIndex = 0;
825
- while ((arrayIndex = _inArray(elements[i], clippedElements, arrayIndex)) !== -1) {
826
- clippedElements.splice(arrayIndex, 1);
1899
+ while ((arrayIndex = clientIds.indexOf(this.id, arrayIndex)) !== -1) {
1900
+ clientIds.splice(arrayIndex, 1);
827
1901
  }
828
- var clientIds = _elementMeta[elements[i].zcClippingId];
829
- if (clientIds) {
830
- arrayIndex = 0;
831
- while ((arrayIndex = _inArray(this.id, clientIds, arrayIndex)) !== -1) {
832
- clientIds.splice(arrayIndex, 1);
833
- }
834
- if (clientIds.length === 0) {
835
- if (_globalConfig.autoActivate === true) {
836
- _removeEventHandler(elements[i], "mouseover", _elementMouseOver);
837
- }
838
- delete elements[i].zcClippingId;
1902
+ if (clientIds.length === 0) {
1903
+ if (_globalConfig.autoActivate === true) {
1904
+ _removeMouseHandlers(elements[i]);
839
1905
  }
1906
+ delete elements[i].zcClippingId;
840
1907
  }
841
1908
  }
842
1909
  }
843
1910
  }
844
1911
  return this;
845
1912
  };
846
- ZeroClipboard.prototype.elements = function() {
1913
+ /**
1914
+ * The underlying implementation of `ZeroClipboard.Client.prototype.elements`.
1915
+ * @private
1916
+ */
1917
+ var _clientElements = function() {
847
1918
  var meta = _clientMeta[this.id];
848
1919
  return meta && meta.elements ? meta.elements.slice(0) : [];
849
1920
  };
850
- var _getAllClientsClippedToElement = function(element) {
851
- var elementMetaId, clientIds, i, len, client, clients = [];
852
- if (element && element.nodeType === 1 && (elementMetaId = element.zcClippingId) && _elementMeta.hasOwnProperty(elementMetaId)) {
853
- clientIds = _elementMeta[elementMetaId];
854
- if (clientIds && clientIds.length) {
855
- for (i = 0, len = clientIds.length; i < len; i++) {
856
- client = _clientMeta[clientIds[i]].instance;
857
- if (client && client instanceof ZeroClipboard) {
858
- clients.push(client);
859
- }
860
- }
861
- }
1921
+ /**
1922
+ * The underlying implementation of `ZeroClipboard.Client.prototype.destroy`.
1923
+ * @private
1924
+ */
1925
+ var _clientDestroy = function() {
1926
+ this.unclip();
1927
+ this.off();
1928
+ delete _clientMeta[this.id];
1929
+ };
1930
+ /**
1931
+ * Inspect an Event to see if the Client (`this`) should honor it for emission.
1932
+ * @private
1933
+ */
1934
+ var _clientShouldEmit = function(event) {
1935
+ if (!(event && event.type)) {
1936
+ return false;
1937
+ }
1938
+ if (event.client && event.client !== this) {
1939
+ return false;
1940
+ }
1941
+ var clippedEls = _clientMeta[this.id] && _clientMeta[this.id].elements;
1942
+ var hasClippedEls = !!clippedEls && clippedEls.length > 0;
1943
+ var goodTarget = !event.target || hasClippedEls && clippedEls.indexOf(event.target) !== -1;
1944
+ var goodRelTarget = event.relatedTarget && hasClippedEls && clippedEls.indexOf(event.relatedTarget) !== -1;
1945
+ var goodClient = event.client && event.client === this;
1946
+ if (!(goodTarget || goodRelTarget || goodClient)) {
1947
+ return false;
1948
+ }
1949
+ return true;
1950
+ };
1951
+ /**
1952
+ * Handle the actual dispatching of events to a client instance.
1953
+ *
1954
+ * @returns `this`
1955
+ * @private
1956
+ */
1957
+ var _clientDispatchCallbacks = function(event) {
1958
+ if (!(typeof event === "object" && event && event.type)) {
1959
+ return;
862
1960
  }
863
- return clients;
864
- };
865
- _globalConfig.hoverClass = "zeroclipboard-is-hover";
866
- _globalConfig.activeClass = "zeroclipboard-is-active";
867
- _globalConfig.trustedOrigins = null;
868
- _globalConfig.allowScriptAccess = null;
869
- _globalConfig.useNoCache = true;
870
- _globalConfig.moviePath = "ZeroClipboard.swf";
871
- ZeroClipboard.detectFlashSupport = function() {
872
- _deprecationWarning("ZeroClipboard.detectFlashSupport", _globalConfig.debug);
873
- return _detectFlashSupport();
874
- };
875
- ZeroClipboard.dispatch = function(eventName, args) {
876
- if (typeof eventName === "string" && eventName) {
877
- var cleanEventName = eventName.toLowerCase().replace(/^on/, "");
878
- if (cleanEventName) {
879
- var clients = currentElement && _globalConfig.autoActivate === true ? _getAllClientsClippedToElement(currentElement) : _getAllClients();
880
- for (var i = 0, len = clients.length; i < len; i++) {
881
- _receiveEvent.call(clients[i], cleanEventName, args);
1961
+ var async = _shouldPerformAsync(event);
1962
+ var wildcardTypeHandlers = _clientMeta[this.id] && _clientMeta[this.id].handlers["*"] || [];
1963
+ var specificTypeHandlers = _clientMeta[this.id] && _clientMeta[this.id].handlers[event.type] || [];
1964
+ var handlers = wildcardTypeHandlers.concat(specificTypeHandlers);
1965
+ if (handlers && handlers.length) {
1966
+ var i, len, func, context, eventCopy, originalContext = this;
1967
+ for (i = 0, len = handlers.length; i < len; i++) {
1968
+ func = handlers[i];
1969
+ context = originalContext;
1970
+ if (typeof func === "string" && typeof _window[func] === "function") {
1971
+ func = _window[func];
1972
+ }
1973
+ if (typeof func === "object" && func && typeof func.handleEvent === "function") {
1974
+ context = func;
1975
+ func = func.handleEvent;
1976
+ }
1977
+ if (typeof func === "function") {
1978
+ eventCopy = _extend({}, event);
1979
+ _dispatchCallback(func, context, [ eventCopy ], async);
882
1980
  }
883
1981
  }
884
1982
  }
885
- };
886
- ZeroClipboard.prototype.setHandCursor = function(enabled) {
887
- _deprecationWarning("ZeroClipboard.prototype.setHandCursor", _globalConfig.debug);
888
- enabled = typeof enabled === "boolean" ? enabled : !!enabled;
889
- _setHandCursor(enabled);
890
- _globalConfig.forceHandCursor = enabled;
891
1983
  return this;
892
1984
  };
893
- ZeroClipboard.prototype.reposition = function() {
894
- _deprecationWarning("ZeroClipboard.prototype.reposition", _globalConfig.debug);
895
- return _reposition();
1985
+ /**
1986
+ * Prepares the elements for clipping/unclipping.
1987
+ *
1988
+ * @returns An Array of elements.
1989
+ * @private
1990
+ */
1991
+ var _prepClip = function(elements) {
1992
+ if (typeof elements === "string") {
1993
+ elements = [];
1994
+ }
1995
+ return typeof elements.length !== "number" ? [ elements ] : elements;
1996
+ };
1997
+ /**
1998
+ * Add a `mouseover` handler function for a clipped element.
1999
+ *
2000
+ * @returns `undefined`
2001
+ * @private
2002
+ */
2003
+ var _addMouseHandlers = function(element) {
2004
+ if (!(element && element.nodeType === 1)) {
2005
+ return;
2006
+ }
2007
+ var _suppressMouseEvents = function(event) {
2008
+ if (!(event || (event = _window.event))) {
2009
+ return;
2010
+ }
2011
+ if (event._source !== "js") {
2012
+ event.stopImmediatePropagation();
2013
+ event.preventDefault();
2014
+ }
2015
+ delete event._source;
2016
+ };
2017
+ var _elementMouseOver = function(event) {
2018
+ if (!(event || (event = _window.event))) {
2019
+ return;
2020
+ }
2021
+ _suppressMouseEvents(event);
2022
+ ZeroClipboard.focus(element);
2023
+ };
2024
+ element.addEventListener("mouseover", _elementMouseOver, false);
2025
+ element.addEventListener("mouseout", _suppressMouseEvents, false);
2026
+ element.addEventListener("mouseenter", _suppressMouseEvents, false);
2027
+ element.addEventListener("mouseleave", _suppressMouseEvents, false);
2028
+ element.addEventListener("mousemove", _suppressMouseEvents, false);
2029
+ _mouseHandlers[element.zcClippingId] = {
2030
+ mouseover: _elementMouseOver,
2031
+ mouseout: _suppressMouseEvents,
2032
+ mouseenter: _suppressMouseEvents,
2033
+ mouseleave: _suppressMouseEvents,
2034
+ mousemove: _suppressMouseEvents
2035
+ };
896
2036
  };
897
- ZeroClipboard.prototype.receiveEvent = function(eventName, args) {
898
- _deprecationWarning("ZeroClipboard.prototype.receiveEvent", _globalConfig.debug);
899
- if (typeof eventName === "string" && eventName) {
900
- var cleanEventName = eventName.toLowerCase().replace(/^on/, "");
901
- if (cleanEventName) {
902
- _receiveEvent.call(this, cleanEventName, args);
2037
+ /**
2038
+ * Remove a `mouseover` handler function for a clipped element.
2039
+ *
2040
+ * @returns `undefined`
2041
+ * @private
2042
+ */
2043
+ var _removeMouseHandlers = function(element) {
2044
+ if (!(element && element.nodeType === 1)) {
2045
+ return;
2046
+ }
2047
+ var mouseHandlers = _mouseHandlers[element.zcClippingId];
2048
+ if (!(typeof mouseHandlers === "object" && mouseHandlers)) {
2049
+ return;
2050
+ }
2051
+ var key, val, mouseEvents = [ "move", "leave", "enter", "out", "over" ];
2052
+ for (var i = 0, len = mouseEvents.length; i < len; i++) {
2053
+ key = "mouse" + mouseEvents[i];
2054
+ val = mouseHandlers[key];
2055
+ if (typeof val === "function") {
2056
+ element.removeEventListener(key, val, false);
903
2057
  }
904
2058
  }
2059
+ delete _mouseHandlers[element.zcClippingId];
2060
+ };
2061
+ /**
2062
+ * Creates a new ZeroClipboard client instance.
2063
+ * Optionally, auto-`clip` an element or collection of elements.
2064
+ *
2065
+ * @constructor
2066
+ */
2067
+ ZeroClipboard._createClient = function() {
2068
+ _clientConstructor.apply(this, _args(arguments));
2069
+ };
2070
+ /**
2071
+ * Register an event listener to the client.
2072
+ *
2073
+ * @returns `this`
2074
+ */
2075
+ ZeroClipboard.prototype.on = function() {
2076
+ return _clientOn.apply(this, _args(arguments));
905
2077
  };
906
- ZeroClipboard.prototype.setCurrent = function(element) {
907
- _deprecationWarning("ZeroClipboard.prototype.setCurrent", _globalConfig.debug);
908
- ZeroClipboard.activate(element);
2078
+ /**
2079
+ * Unregister an event handler from the client.
2080
+ * If no `listener` function/object is provided, it will unregister all handlers for the provided `eventType`.
2081
+ * If no `eventType` is provided, it will unregister all handlers for every event type.
2082
+ *
2083
+ * @returns `this`
2084
+ */
2085
+ ZeroClipboard.prototype.off = function() {
2086
+ return _clientOff.apply(this, _args(arguments));
2087
+ };
2088
+ /**
2089
+ * Retrieve event listeners for an `eventType` from the client.
2090
+ * If no `eventType` is provided, it will retrieve all listeners for every event type.
2091
+ *
2092
+ * @returns array of listeners for the `eventType`; if no `eventType`, then a map/hash object of listeners for all event types; or `null`
2093
+ */
2094
+ ZeroClipboard.prototype.handlers = function() {
2095
+ return _clientListeners.apply(this, _args(arguments));
2096
+ };
2097
+ /**
2098
+ * Event emission receiver from the Flash object for this client's registered JavaScript event listeners.
2099
+ *
2100
+ * @returns For the "copy" event, returns the Flash-friendly "clipData" object; otherwise `undefined`.
2101
+ */
2102
+ ZeroClipboard.prototype.emit = function() {
2103
+ return _clientEmit.apply(this, _args(arguments));
2104
+ };
2105
+ /**
2106
+ * Register clipboard actions for new element(s) to the client.
2107
+ *
2108
+ * @returns `this`
2109
+ */
2110
+ ZeroClipboard.prototype.clip = function() {
2111
+ return _clientClip.apply(this, _args(arguments));
2112
+ };
2113
+ /**
2114
+ * Unregister the clipboard actions of previously registered element(s) on the page.
2115
+ * If no elements are provided, ALL registered elements will be unregistered.
2116
+ *
2117
+ * @returns `this`
2118
+ */
2119
+ ZeroClipboard.prototype.unclip = function() {
2120
+ return _clientUnclip.apply(this, _args(arguments));
2121
+ };
2122
+ /**
2123
+ * Get all of the elements to which this client is clipped.
2124
+ *
2125
+ * @returns array of clipped elements
2126
+ */
2127
+ ZeroClipboard.prototype.elements = function() {
2128
+ return _clientElements.apply(this, _args(arguments));
2129
+ };
2130
+ /**
2131
+ * Self-destruct and clean up everything for a single client.
2132
+ * This will NOT destroy the embedded Flash object.
2133
+ *
2134
+ * @returns `undefined`
2135
+ */
2136
+ ZeroClipboard.prototype.destroy = function() {
2137
+ return _clientDestroy.apply(this, _args(arguments));
2138
+ };
2139
+ /**
2140
+ * Stores the pending plain text to inject into the clipboard.
2141
+ *
2142
+ * @returns `this`
2143
+ */
2144
+ ZeroClipboard.prototype.setText = function(text) {
2145
+ ZeroClipboard.setData("text/plain", text);
909
2146
  return this;
910
2147
  };
911
- ZeroClipboard.prototype.resetBridge = function() {
912
- _deprecationWarning("ZeroClipboard.prototype.resetBridge", _globalConfig.debug);
913
- ZeroClipboard.deactivate();
2148
+ /**
2149
+ * Stores the pending HTML text to inject into the clipboard.
2150
+ *
2151
+ * @returns `this`
2152
+ */
2153
+ ZeroClipboard.prototype.setHtml = function(html) {
2154
+ ZeroClipboard.setData("text/html", html);
914
2155
  return this;
915
2156
  };
916
- ZeroClipboard.prototype.setTitle = function(newTitle) {
917
- _deprecationWarning("ZeroClipboard.prototype.setTitle", _globalConfig.debug);
918
- newTitle = newTitle || _globalConfig.title || currentElement && currentElement.getAttribute("title");
919
- if (newTitle) {
920
- var htmlBridge = _getHtmlBridge(flashState.bridge);
921
- if (htmlBridge) {
922
- htmlBridge.setAttribute("title", newTitle);
923
- }
924
- }
2157
+ /**
2158
+ * Stores the pending rich text (RTF) to inject into the clipboard.
2159
+ *
2160
+ * @returns `this`
2161
+ */
2162
+ ZeroClipboard.prototype.setRichText = function(richText) {
2163
+ ZeroClipboard.setData("application/rtf", richText);
925
2164
  return this;
926
2165
  };
927
- ZeroClipboard.setDefaults = function(options) {
928
- _deprecationWarning("ZeroClipboard.setDefaults", _globalConfig.debug);
929
- ZeroClipboard.config(options);
930
- };
931
- ZeroClipboard.prototype.addEventListener = function(eventName, func) {
932
- _deprecationWarning("ZeroClipboard.prototype.addEventListener", _globalConfig.debug);
933
- return this.on(eventName, func);
934
- };
935
- ZeroClipboard.prototype.removeEventListener = function(eventName, func) {
936
- _deprecationWarning("ZeroClipboard.prototype.removeEventListener", _globalConfig.debug);
937
- return this.off(eventName, func);
938
- };
939
- ZeroClipboard.prototype.ready = function() {
940
- _deprecationWarning("ZeroClipboard.prototype.ready", _globalConfig.debug);
941
- return flashState.ready === true;
942
- };
943
- var _receiveEvent = function(eventName, args) {
944
- eventName = eventName.toLowerCase().replace(/^on/, "");
945
- var cleanVersion = args && args.flashVersion && _parseFlashVersion(args.flashVersion) || null;
946
- var element = currentElement;
947
- var performCallbackAsync = true;
948
- switch (eventName) {
949
- case "load":
950
- if (cleanVersion) {
951
- if (!_isFlashVersionSupported(cleanVersion)) {
952
- _receiveEvent.call(this, "onWrongFlash", {
953
- flashVersion: cleanVersion
954
- });
955
- return;
956
- }
957
- flashState.outdated = false;
958
- flashState.ready = true;
959
- flashState.version = cleanVersion;
960
- }
961
- break;
962
-
963
- case "wrongflash":
964
- if (cleanVersion && !_isFlashVersionSupported(cleanVersion)) {
965
- flashState.outdated = true;
966
- flashState.ready = false;
967
- flashState.version = cleanVersion;
968
- }
969
- break;
970
-
971
- case "mouseover":
972
- _addClass(element, _globalConfig.hoverClass);
973
- break;
974
-
975
- case "mouseout":
976
- if (_globalConfig.autoActivate === true) {
977
- ZeroClipboard.deactivate();
978
- }
979
- break;
980
-
981
- case "mousedown":
982
- _addClass(element, _globalConfig.activeClass);
983
- break;
984
-
985
- case "mouseup":
986
- _removeClass(element, _globalConfig.activeClass);
987
- break;
988
-
989
- case "datarequested":
990
- if (element) {
991
- var targetId = element.getAttribute("data-clipboard-target"), targetEl = !targetId ? null : document.getElementById(targetId);
992
- if (targetEl) {
993
- var textContent = targetEl.value || targetEl.textContent || targetEl.innerText;
994
- if (textContent) {
995
- this.setText(textContent);
996
- }
997
- } else {
998
- var defaultText = element.getAttribute("data-clipboard-text");
999
- if (defaultText) {
1000
- this.setText(defaultText);
1001
- }
1002
- }
1003
- }
1004
- performCallbackAsync = false;
1005
- break;
1006
-
1007
- case "complete":
1008
- _deleteOwnProperties(_clipData);
1009
- if (element && element !== _safeActiveElement() && element.focus) {
1010
- element.focus();
1011
- }
1012
- break;
1013
- }
1014
- var context = element;
1015
- var eventArgs = [ this, args ];
1016
- return _dispatchClientCallbacks.call(this, eventName, context, eventArgs, performCallbackAsync);
2166
+ /**
2167
+ * Stores the pending data to inject into the clipboard.
2168
+ *
2169
+ * @returns `this`
2170
+ */
2171
+ ZeroClipboard.prototype.setData = function() {
2172
+ ZeroClipboard.setData.apply(this, _args(arguments));
2173
+ return this;
2174
+ };
2175
+ /**
2176
+ * Clears the pending data to inject into the clipboard.
2177
+ * If no `format` is provided, all pending data formats will be cleared.
2178
+ *
2179
+ * @returns `this`
2180
+ */
2181
+ ZeroClipboard.prototype.clearData = function() {
2182
+ ZeroClipboard.clearData.apply(this, _args(arguments));
2183
+ return this;
2184
+ };
2185
+ /**
2186
+ * Gets a copy of the pending data to inject into the clipboard.
2187
+ * If no `format` is provided, a copy of ALL pending data formats will be returned.
2188
+ *
2189
+ * @returns `String` or `Object`
2190
+ */
2191
+ ZeroClipboard.prototype.getData = function() {
2192
+ return ZeroClipboard.getData.apply(this, _args(arguments));
1017
2193
  };
1018
2194
  if (typeof define === "function" && define.amd) {
1019
- define([ "require", "exports", "module" ], function(require, exports, module) {
1020
- _amdModuleId = module && module.id || null;
2195
+ define(function() {
1021
2196
  return ZeroClipboard;
1022
2197
  });
1023
- } else if (typeof module === "object" && module && typeof module.exports === "object" && module.exports && typeof window.require === "function") {
1024
- _cjsModuleId = module.id || null;
2198
+ } else if (typeof module === "object" && module && typeof module.exports === "object" && module.exports) {
1025
2199
  module.exports = ZeroClipboard;
1026
2200
  } else {
1027
2201
  window.ZeroClipboard = ZeroClipboard;
1028
2202
  }
1029
2203
  })(function() {
1030
- return this;
1031
- }());
2204
+ return this || window;
2205
+ }());