Plugin Directory

Changeset 1208875


Ignore:
Timestamp:
07/29/2015 09:52:45 AM (11 years ago)
Author:
woorockets
Message:

Update zeroclipboard library

Location:
wr-contactform/trunk/assets/3rd-party/zeroclipboard
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • wr-contactform/trunk/assets/3rd-party/zeroclipboard/ZeroClipboard.js

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