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