From 1d940898b5d608eaad3b689a317d85a9490b592b Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Wed, 1 Apr 2015 18:19:05 +0200 Subject: [PATCH 01/42] Add Task and template for building examples --- config/examples/example.html | 86 + package.json | 4 + resources/example-behaviour.js | 11 + resources/layout.css | 2 +- resources/prism/prism.css | 137 + resources/prism/prism.min.js | 6 + resources/zeroclipboard/.jshintrc | 70 + resources/zeroclipboard/ZeroClipboard.Core.js | 2017 +++++++++++++ .../zeroclipboard/ZeroClipboard.Core.min.js | 10 + .../zeroclipboard/ZeroClipboard.Core.min.map | 1 + resources/zeroclipboard/ZeroClipboard.js | 2581 +++++++++++++++++ resources/zeroclipboard/ZeroClipboard.min.js | 10 + resources/zeroclipboard/ZeroClipboard.min.map | 1 + resources/zeroclipboard/ZeroClipboard.swf | Bin 0 -> 6580 bytes tasks/build-examples.js | 71 + 15 files changed, 5006 insertions(+), 1 deletion(-) create mode 100644 config/examples/example.html create mode 100644 resources/prism/prism.css create mode 100644 resources/prism/prism.min.js create mode 100644 resources/zeroclipboard/.jshintrc create mode 100644 resources/zeroclipboard/ZeroClipboard.Core.js create mode 100644 resources/zeroclipboard/ZeroClipboard.Core.min.js create mode 100644 resources/zeroclipboard/ZeroClipboard.Core.min.map create mode 100644 resources/zeroclipboard/ZeroClipboard.js create mode 100644 resources/zeroclipboard/ZeroClipboard.min.js create mode 100644 resources/zeroclipboard/ZeroClipboard.min.map create mode 100644 resources/zeroclipboard/ZeroClipboard.swf create mode 100644 tasks/build-examples.js diff --git a/config/examples/example.html b/config/examples/example.html new file mode 100644 index 0000000000..328c595cd0 --- /dev/null +++ b/config/examples/example.html @@ -0,0 +1,86 @@ + + + + + + + + + + + {{{ css_resource }}} + + + {{ title }} + + + + + +
+ + {{{ contents }}} + +
+ +
+

{{ title }}

+

{{ shortdesc }}

+
+ {{{ docs }}} +
+
{{ tags }}
+
+ +
+ +
+
+
+ + + + + + + +
<!-- DOCTYPE html -->
+<html>
+<head>
+<title>{{ title }}</title>
+<script src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
+<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
+<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
+<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ol3/{{ ol_version }}/ol.css" type="text/css">
+<script src="https://cdnjs.cloudflare.com/ajax/libs/ol3/{{ ol_version }}/ol.js"></script>
+<style>
+{{ css_inline }}
+</style<
+</head>
+<body>
+<div class="container-fluid">
+
+{{ contents }}
+</div>
+<script>
+{{ js_inline }}
+</script>
+</body>
+</html>
+
+
+ + + + + + {{{ js_resource }}} + + + diff --git a/package.json b/package.json index 961eba0072..b3ad9bb5b2 100644 --- a/package.json +++ b/package.json @@ -30,8 +30,12 @@ "fs-extra": "0.12.0", "glob": "5.0.3", "graceful-fs": "3.0.2", + "handlebars": "3.0.1", "htmlparser2": "3.7.3", "jsdoc": "3.3.0-alpha9", + "marked": "0.3.3", + "metalsmith": "1.5.0", + "metalsmith-templates": "0.7.0", "nomnom": "1.8.0", "rbush": "1.3.5", "temp": "0.8.1", diff --git a/resources/example-behaviour.js b/resources/example-behaviour.js index 161f51d790..6fefba2de7 100644 --- a/resources/example-behaviour.js +++ b/resources/example-behaviour.js @@ -1,4 +1,15 @@ ;(function() { + var copyButton = document.getElementById('copy-button'); + if (copyButton) { + var data = document.getElementById('example-source').textContent; + new ZeroClipboard(copyButton).on('copy', function(event) { + event.clipboardData.setData({ + 'text/plain': data, + 'text/html': data + }); + }); + } + if (window.location.host === 'localhost:3000') { return; } diff --git a/resources/layout.css b/resources/layout.css index f4d25d5391..99ea34f221 100644 --- a/resources/layout.css +++ b/resources/layout.css @@ -15,7 +15,7 @@ body { font-family: 'Lucida Grande',Verdana,Geneva,Lucida,Arial,Helvetica,sans-serif; } -#tags { +#tags, .hidden { display: none; } diff --git a/resources/prism/prism.css b/resources/prism/prism.css new file mode 100644 index 0000000000..e643c21e06 --- /dev/null +++ b/resources/prism/prism.css @@ -0,0 +1,137 @@ +/* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript */ +/** + * prism.js default theme for JavaScript, CSS and HTML + * Based on dabblet (http://dabblet.com) + * @author Lea Verou + */ + +code[class*="language-"], +pre[class*="language-"] { + color: black; + text-shadow: 0 1px white; + font-family: Consolas, Monaco, 'Andale Mono', monospace; + direction: ltr; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + line-height: 1.5; + + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none; +} + +pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection, +code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection { + text-shadow: none; + background: #b3d4fc; +} + +pre[class*="language-"]::selection, pre[class*="language-"] ::selection, +code[class*="language-"]::selection, code[class*="language-"] ::selection { + text-shadow: none; + background: #b3d4fc; +} + +@media print { + code[class*="language-"], + pre[class*="language-"] { + text-shadow: none; + } +} + +/* Code blocks */ +pre[class*="language-"] { + padding: 1em; + margin: .5em 0; + overflow: auto; +} + +:not(pre) > code[class*="language-"], +pre[class*="language-"] { + background: #f5f2f0; +} + +/* Inline code */ +:not(pre) > code[class*="language-"] { + padding: .1em; + border-radius: .3em; +} + +.token.comment, +.token.prolog, +.token.doctype, +.token.cdata { + color: slategray; +} + +.token.punctuation { + color: #999; +} + +.namespace { + opacity: .7; +} + +.token.property, +.token.tag, +.token.boolean, +.token.number, +.token.constant, +.token.symbol, +.token.deleted { + color: #905; +} + +.token.selector, +.token.attr-name, +.token.string, +.token.char, +.token.builtin, +.token.inserted { + color: #690; +} + +.token.operator, +.token.entity, +.token.url, +.language-css .token.string, +.style .token.string { + color: #a67f59; + background: hsla(0, 0%, 100%, .5); +} + +.token.atrule, +.token.attr-value, +.token.keyword { + color: #07a; +} + +.token.function { + color: #DD4A68; +} + +.token.regex, +.token.important, +.token.variable { + color: #e90; +} + +.token.important, +.token.bold { + font-weight: bold; +} +.token.italic { + font-style: italic; +} + +.token.entity { + cursor: help; +} + diff --git a/resources/prism/prism.min.js b/resources/prism/prism.min.js new file mode 100644 index 0000000000..21ea6df0f1 --- /dev/null +++ b/resources/prism/prism.min.js @@ -0,0 +1,6 @@ +/* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript */ +self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{};var Prism=function(){var e=/\blang(?:uage)?-(?!\*)(\w+)\b/i,t=self.Prism={util:{encode:function(e){return e instanceof n?new n(e.type,t.util.encode(e.content),e.alias):"Array"===t.util.type(e)?e.map(t.util.encode):e.replace(/&/g,"&").replace(/e.length)break e;if(!(d instanceof a)){u.lastIndex=0;var m=u.exec(d);if(m){c&&(f=m[1].length);var y=m.index-1+f,m=m[0].slice(f),v=m.length,k=y+v,b=d.slice(0,y+1),w=d.slice(k+1),N=[p,1];b&&N.push(b);var O=new a(l,g?t.tokenize(m,g):m,h);N.push(O),w&&N.push(w),Array.prototype.splice.apply(r,N)}}}}}return r},hooks:{all:{},add:function(e,n){var a=t.hooks.all;a[e]=a[e]||[],a[e].push(n)},run:function(e,n){var a=t.hooks.all[e];if(a&&a.length)for(var r,i=0;r=a[i++];)r(n)}}},n=t.Token=function(e,t,n){this.type=e,this.content=t,this.alias=n};if(n.stringify=function(e,a,r){if("string"==typeof e)return e;if("Array"===t.util.type(e))return e.map(function(t){return n.stringify(t,a,e)}).join("");var i={type:e.type,content:n.stringify(e.content,a,r),tag:"span",classes:["token",e.type],attributes:{},language:a,parent:r};if("comment"==i.type&&(i.attributes.spellcheck="true"),e.alias){var l="Array"===t.util.type(e.alias)?e.alias:[e.alias];Array.prototype.push.apply(i.classes,l)}t.hooks.run("wrap",i);var s="";for(var o in i.attributes)s+=o+'="'+(i.attributes[o]||"")+'"';return"<"+i.tag+' class="'+i.classes.join(" ")+'" '+s+">"+i.content+""},!self.document)return self.addEventListener?(self.addEventListener("message",function(e){var n=JSON.parse(e.data),a=n.language,r=n.code;self.postMessage(JSON.stringify(t.util.encode(t.tokenize(r,t.languages[a])))),self.close()},!1),self.Prism):self.Prism;var a=document.getElementsByTagName("script");return a=a[a.length-1],a&&(t.filename=a.src,document.addEventListener&&!a.hasAttribute("data-manual")&&document.addEventListener("DOMContentLoaded",t.highlightAll)),self.Prism}();"undefined"!=typeof module&&module.exports&&(module.exports=Prism);; +Prism.languages.markup={comment://,prolog:/<\?.+?\?>/,doctype://,cdata://i,tag:{pattern:/<\/?[\w:-]+\s*(?:\s+[\w:-]+(?:=(?:("|')(\\?[\w\W])*?\1|[^\s'">=]+))?\s*)*\/?>/i,inside:{tag:{pattern:/^<\/?[\w:-]+/i,inside:{punctuation:/^<\/?/,namespace:/^[\w-]+?:/}},"attr-value":{pattern:/=(?:('|")[\w\W]*?(\1)|[^\s>]+)/i,inside:{punctuation:/=|>|"/}},punctuation:/\/?>/,"attr-name":{pattern:/[\w:-]+/,inside:{namespace:/^[\w-]+?:/}}}},entity:/&#?[\da-z]{1,8};/i},Prism.hooks.add("wrap",function(t){"entity"===t.type&&(t.attributes.title=t.content.replace(/&/,"&"))});; +Prism.languages.css={comment:/\/\*[\w\W]*?\*\//,atrule:{pattern:/@[\w-]+?.*?(;|(?=\s*\{))/i,inside:{punctuation:/[;:]/}},url:/url\((?:(["'])(\\\n|\\?.)*?\1|.*?)\)/i,selector:/[^\{\}\s][^\{\};]*(?=\s*\{)/,string:/("|')(\\\n|\\?.)*?\1/,property:/(\b|\B)[\w-]+(?=\s*:)/i,important:/\B!important\b/i,punctuation:/[\{\};:]/,"function":/[-a-z0-9]+(?=\()/i},Prism.languages.markup&&(Prism.languages.insertBefore("markup","tag",{style:{pattern:/[\w\W]*?<\/style>/i,inside:{tag:{pattern:/|<\/style>/i,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.css},alias:"language-css"}}),Prism.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|').*?\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:Prism.languages.markup.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:Prism.languages.css}},alias:"language-css"}},Prism.languages.markup.tag));; +Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\w\W]*?\*\//,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.+/,lookbehind:!0}],string:/("|')(\\\n|\\?.)*?\1/,"class-name":{pattern:/((?:(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,"boolean":/\b(true|false)\b/,"function":{pattern:/[a-z0-9_]+\(/i,inside:{punctuation:/\(/}},number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/,operator:/[-+]{1,2}|!|<=?|>=?|={1,3}|&{1,2}|\|?\||\?|\*|\/|~|\^|%/,ignore:/&(lt|gt|amp);/i,punctuation:/[{}[\];(),.:]/};; +Prism.languages.javascript=Prism.languages.extend("clike",{keyword:/\b(break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|function|get|if|implements|import|in|instanceof|interface|let|new|null|package|private|protected|public|return|set|static|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/,number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|-?Infinity)\b/,"function":/(?!\d)[a-z0-9_$]+(?=\()/i}),Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/,lookbehind:!0}}),Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{script:{pattern:/[\w\W]*?<\/script>/i,inside:{tag:{pattern:/|<\/script>/i,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.javascript},alias:"language-javascript"}});; diff --git a/resources/zeroclipboard/.jshintrc b/resources/zeroclipboard/.jshintrc new file mode 100644 index 0000000000..15359aa1a5 --- /dev/null +++ b/resources/zeroclipboard/.jshintrc @@ -0,0 +1,70 @@ +{ + /* Enforcing options */ + "bitwise": true, + "camelcase": true, + "curly": true, + "eqeqeq": true, + "es3": true, + "es5": false, + "forin": true, + "freeze": true, + "immed": true, + "indent": 2, + "latedef": true, + "newcap": true, + "noarg": true, + "noempty": true, + "nonbsp": true, + "nonew": true, + "plusplus": false, + "quotmark": "double", + "undef": true, + "unused": true, + "strict": true, + "trailing": true, + "maxparams": 4, + "maxdepth": 5, + "maxstatements": false, + "maxlen": false, /* IDEAL: 120? */ + + + /* Relaxing options */ + "asi": false, + "boss": false, + "debug": false, + "eqnull": true, + "esnext": false, + "evil": false, + "expr": false, + "funcscope": false, + "gcl": false, + "globalstrict": false, + "iterator": false, + "lastsemic": false, + "laxbreak": false, + "laxcomma": false, + "loopfunc": false, + "maxerr": 50, + "moz": false, + "multistr": false, + "notypeof": false, + "proto": false, + "scripturl": false, + "smarttabs": false, + "shadow": false, + "sub": false, + "supernew": false, + "validthis": false, + "noyield": false, + + /* Environments */ + "browser": true, + + /* Global variables */ + "globals": { + /* AMD */ + "define": false, + /* CommonJS */ + "module": false + } +} \ No newline at end of file diff --git a/resources/zeroclipboard/ZeroClipboard.Core.js b/resources/zeroclipboard/ZeroClipboard.Core.js new file mode 100644 index 0000000000..b58b14675b --- /dev/null +++ b/resources/zeroclipboard/ZeroClipboard.Core.js @@ -0,0 +1,2017 @@ +/*! + * ZeroClipboard + * The ZeroClipboard library provides an easy way to copy text to the clipboard using an invisible Adobe Flash movie and a JavaScript interface. + * Copyright (c) 2009-2014 Jon Rohan, James M. Greene + * Licensed MIT + * http://zeroclipboard.org/ + * v2.2.0 + */ +(function(window, undefined) { + "use strict"; + /** + * Store references to critically important global functions that may be + * overridden on certain web pages. + */ + 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() { + var unwrapper = function(el) { + return el; + }; + if (typeof _window.wrap === "function" && typeof _window.unwrap === "function") { + try { + var div = _document.createElement("div"); + var unwrappedDiv = _window.unwrap(div); + if (div.nodeType === 1 && unwrappedDiv && unwrappedDiv.nodeType === 1) { + unwrapper = _window.unwrap; + } + } catch (e) {} + } + return unwrapper; + }(); + /** + * Convert an `arguments` object into an Array. + * + * @returns The arguments as an Array + * @private + */ + var _args = function(argumentsObj) { + return _slice.call(argumentsObj, 0); + }; + /** + * Shallow-copy the owned, enumerable properties of one object over to another, similar to jQuery's `$.extend`. + * + * @returns The target object, augmented + * @private + */ + var _extend = function() { + var i, len, arg, prop, src, copy, args = _args(arguments), target = args[0] || {}; + for (i = 1, len = args.length; i < len; i++) { + if ((arg = args[i]) != null) { + for (prop in arg) { + if (_hasOwn.call(arg, prop)) { + src = target[prop]; + copy = arg[prop]; + if (target !== copy && copy !== undefined) { + target[prop] = copy; + } + } + } + } + } + return target; + }; + /** + * Return a deep copy of the source object or array. + * + * @returns Object or Array + * @private + */ + var _deepCopy = function(source) { + var copy, i, len, prop; + if (typeof source !== "object" || source == null || typeof source.nodeType === "number") { + copy = source; + } else if (typeof source.length === "number") { + copy = []; + for (i = 0, len = source.length; i < len; i++) { + if (_hasOwn.call(source, i)) { + copy[i] = _deepCopy(source[i]); + } + } + } else { + copy = {}; + for (prop in source) { + if (_hasOwn.call(source, prop)) { + copy[prop] = _deepCopy(source[prop]); + } + } + } + return copy; + }; + /** + * Makes a shallow copy of `obj` (like `_extend`) but filters its properties based on a list of `keys` to keep. + * The inverse of `_omit`, mostly. The big difference is that these properties do NOT need to be enumerable to + * be kept. + * + * @returns A new filtered object. + * @private + */ + var _pick = function(obj, keys) { + var newObj = {}; + for (var i = 0, len = keys.length; i < len; i++) { + if (keys[i] in obj) { + newObj[keys[i]] = obj[keys[i]]; + } + } + return newObj; + }; + /** + * Makes a shallow copy of `obj` (like `_extend`) but filters its properties based on a list of `keys` to omit. + * The inverse of `_pick`. + * + * @returns A new filtered object. + * @private + */ + var _omit = function(obj, keys) { + var newObj = {}; + for (var prop in obj) { + if (keys.indexOf(prop) === -1) { + newObj[prop] = obj[prop]; + } + } + return newObj; + }; + /** + * Remove all owned, enumerable properties from an object. + * + * @returns The original object without its owned, enumerable properties. + * @private + */ + var _deleteOwnProperties = function(obj) { + if (obj) { + for (var prop in obj) { + if (_hasOwn.call(obj, prop)) { + delete obj[prop]; + } + } + } + return obj; + }; + /** + * Determine if an element is contained within another element. + * + * @returns Boolean + * @private + */ + var _containedBy = function(el, ancestorEl) { + 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)) { + do { + if (el === ancestorEl) { + return true; + } + el = el.parentNode; + } while (el); + } + return false; + }; + /** + * Get the URL path's parent directory. + * + * @returns String or `undefined` + * @private + */ + var _getDirPathOfUrl = function(url) { + var dir; + if (typeof url === "string" && url) { + dir = url.split("#")[0].split("?")[0]; + dir = url.slice(0, url.lastIndexOf("/") + 1); + } + return dir; + }; + /** + * Get the current script's URL by throwing an `Error` and analyzing it. + * + * @returns String or `undefined` + * @private + */ + var _getCurrentScriptUrlFromErrorStack = function(stack) { + var url, matches; + if (typeof stack === "string" && stack) { + matches = stack.match(/^(?:|[^:@]*@|.+\)@(?=http[s]?|file)|.+?\s+(?: at |@)(?:[^:\(]+ )*[\(]?)((?:http[s]?|file):\/\/[\/]?.+?\/[^:\)]*?)(?::\d+)(?::\d+)?/); + if (matches && matches[1]) { + url = matches[1]; + } else { + matches = stack.match(/\)@((?:http[s]?|file):\/\/[\/]?.+?\/[^:\)]*?)(?::\d+)(?::\d+)?/); + if (matches && matches[1]) { + url = matches[1]; + } + } + } + return url; + }; + /** + * Get the current script's URL by throwing an `Error` and analyzing it. + * + * @returns String or `undefined` + * @private + */ + var _getCurrentScriptUrlFromError = function() { + var url, err; + try { + throw new _Error(); + } catch (e) { + err = e; + } + if (err) { + url = err.sourceURL || err.fileName || _getCurrentScriptUrlFromErrorStack(err.stack); + } + return url; + }; + /** + * Get the current script's URL. + * + * @returns String or `undefined` + * @private + */ + var _getCurrentScriptUrl = function() { + var jsPath, scripts, i; + if (_document.currentScript && (jsPath = _document.currentScript.src)) { + return jsPath; + } + scripts = _document.getElementsByTagName("script"); + if (scripts.length === 1) { + return scripts[0].src || undefined; + } + if ("readyState" in scripts[0]) { + for (i = scripts.length; i--; ) { + if (scripts[i].readyState === "interactive" && (jsPath = scripts[i].src)) { + return jsPath; + } + } + } + if (_document.readyState === "loading" && (jsPath = scripts[scripts.length - 1].src)) { + return jsPath; + } + if (jsPath = _getCurrentScriptUrlFromError()) { + return jsPath; + } + return undefined; + }; + /** + * Get the unanimous parent directory of ALL script tags. + * If any script tags are either (a) inline or (b) from differing parent + * directories, this method must return `undefined`. + * + * @returns String or `undefined` + * @private + */ + var _getUnanimousScriptParentDir = function() { + var i, jsDir, jsPath, scripts = _document.getElementsByTagName("script"); + for (i = scripts.length; i--; ) { + if (!(jsPath = scripts[i].src)) { + jsDir = null; + break; + } + jsPath = _getDirPathOfUrl(jsPath); + if (jsDir == null) { + jsDir = jsPath; + } else if (jsDir !== jsPath) { + jsDir = null; + break; + } + } + return jsDir || undefined; + }; + /** + * Get the presumed location of the "ZeroClipboard.swf" file, based on the location + * of the executing JavaScript file (e.g. "ZeroClipboard.js", etc.). + * + * @returns String + * @private + */ + var _getDefaultSwfPath = function() { + var jsDir = _getDirPathOfUrl(_getCurrentScriptUrl()) || _getUnanimousScriptParentDir() || ""; + return jsDir + "ZeroClipboard.swf"; + }; + /** + * Keep track of if the page is framed (in an `iframe`). This can never change. + * @private + */ + var _pageIsFramed = function() { + return window.opener == null && (!!window.top && window != window.top || !!window.parent && window != window.parent); + }(); + /** + * Keep track of the state of the Flash object. + * @private + */ + var _flashState = { + bridge: null, + version: "0.0.0", + pluginType: "unknown", + disabled: null, + outdated: null, + sandboxed: null, + unavailable: null, + degraded: null, + deactivated: null, + overdue: null, + ready: null + }; + /** + * The minimum Flash Player version required to use ZeroClipboard completely. + * @readonly + * @private + */ + var _minimumFlashVersion = "11.0.0"; + /** + * The ZeroClipboard library version number, as reported by Flash, at the time the SWF was compiled. + */ + var _zcSwfVersion; + /** + * Keep track of all event listener registrations. + * @private + */ + var _handlers = {}; + /** + * Keep track of the currently activated element. + * @private + */ + var _currentElement; + /** + * Keep track of the element that was activated when a `copy` process started. + * @private + */ + var _copyTarget; + /** + * Keep track of data for the pending clipboard transaction. + * @private + */ + var _clipData = {}; + /** + * Keep track of data formats for the pending clipboard transaction. + * @private + */ + var _clipDataFormatMap = null; + /** + * Keep track of the Flash availability check timeout. + * @private + */ + var _flashCheckTimeout = 0; + /** + * Keep track of SWF network errors interval polling. + * @private + */ + var _swfFallbackCheckInterval = 0; + /** + * The `message` store for events + * @private + */ + var _eventMessages = { + ready: "Flash communication is established", + error: { + "flash-disabled": "Flash is disabled or not installed. May also be attempting to run Flash in a sandboxed iframe, which is impossible.", + "flash-outdated": "Flash is too outdated to support ZeroClipboard", + "flash-sandboxed": "Attempting to run Flash in a sandboxed iframe, which is impossible", + "flash-unavailable": "Flash is unable to communicate bidirectionally with JavaScript", + "flash-degraded": "Flash is unable to preserve data fidelity when communicating with JavaScript", + "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.", + "flash-overdue": "Flash communication was established but NOT within the acceptable time limit", + "version-mismatch": "ZeroClipboard JS version number does not match ZeroClipboard SWF version number", + "clipboard-error": "At least one error was thrown while ZeroClipboard was attempting to inject your data into the clipboard", + "config-mismatch": "ZeroClipboard configuration does not match Flash's reality", + "swf-not-found": "The ZeroClipboard SWF object could not be loaded, so please check your `swfPath` configuration and/or network connectivity" + } + }; + /** + * The `name`s of `error` events that can only occur is Flash has at least + * been able to load the SWF successfully. + * @private + */ + var _errorsThatOnlyOccurAfterFlashLoads = [ "flash-unavailable", "flash-degraded", "flash-overdue", "version-mismatch", "config-mismatch", "clipboard-error" ]; + /** + * The `name`s of `error` events that should likely result in the `_flashState` + * variable's property values being updated. + * @private + */ + var _flashStateErrorNames = [ "flash-disabled", "flash-outdated", "flash-sandboxed", "flash-unavailable", "flash-degraded", "flash-deactivated", "flash-overdue" ]; + /** + * A RegExp to match the `name` property of `error` events related to Flash. + * @private + */ + var _flashStateErrorNameMatchingRegex = new RegExp("^flash-(" + _flashStateErrorNames.map(function(errorName) { + return errorName.replace(/^flash-/, ""); + }).join("|") + ")$"); + /** + * A RegExp to match the `name` property of `error` events related to Flash, + * which is enabled. + * @private + */ + var _flashStateEnabledErrorNameMatchingRegex = new RegExp("^flash-(" + _flashStateErrorNames.slice(1).map(function(errorName) { + return errorName.replace(/^flash-/, ""); + }).join("|") + ")$"); + /** + * ZeroClipboard configuration defaults for the Core module. + * @private + */ + var _globalConfig = { + swfPath: _getDefaultSwfPath(), + trustedDomains: window.location.host ? [ window.location.host ] : [], + cacheBust: true, + forceEnhancedClipboard: false, + flashLoadTimeout: 3e4, + autoActivate: true, + bubbleEvents: true, + containerId: "global-zeroclipboard-html-bridge", + containerClass: "global-zeroclipboard-container", + swfObjectId: "global-zeroclipboard-flash-bridge", + hoverClass: "zeroclipboard-is-hover", + activeClass: "zeroclipboard-is-active", + forceHandCursor: false, + title: null, + zIndex: 999999999 + }; + /** + * The underlying implementation of `ZeroClipboard.config`. + * @private + */ + var _config = function(options) { + if (typeof options === "object" && options !== null) { + for (var prop in options) { + if (_hasOwn.call(options, prop)) { + if (/^(?:forceHandCursor|title|zIndex|bubbleEvents)$/.test(prop)) { + _globalConfig[prop] = options[prop]; + } else if (_flashState.bridge == null) { + if (prop === "containerId" || prop === "swfObjectId") { + if (_isValidHtml4Id(options[prop])) { + _globalConfig[prop] = options[prop]; + } else { + throw new Error("The specified `" + prop + "` value is not valid as an HTML4 Element ID"); + } + } else { + _globalConfig[prop] = options[prop]; + } + } + } + } + } + if (typeof options === "string" && options) { + if (_hasOwn.call(_globalConfig, options)) { + return _globalConfig[options]; + } + return; + } + return _deepCopy(_globalConfig); + }; + /** + * The underlying implementation of `ZeroClipboard.state`. + * @private + */ + var _state = function() { + _detectSandbox(); + return { + browser: _pick(_navigator, [ "userAgent", "platform", "appName" ]), + flash: _omit(_flashState, [ "bridge" ]), + zeroclipboard: { + version: ZeroClipboard.version, + config: ZeroClipboard.config() + } + }; + }; + /** + * The underlying implementation of `ZeroClipboard.isFlashUnusable`. + * @private + */ + var _isFlashUnusable = function() { + return !!(_flashState.disabled || _flashState.outdated || _flashState.sandboxed || _flashState.unavailable || _flashState.degraded || _flashState.deactivated); + }; + /** + * The underlying implementation of `ZeroClipboard.on`. + * @private + */ + var _on = function(eventType, listener) { + var i, len, events, added = {}; + if (typeof eventType === "string" && eventType) { + events = eventType.toLowerCase().split(/\s+/); + } else if (typeof eventType === "object" && eventType && typeof listener === "undefined") { + for (i in eventType) { + if (_hasOwn.call(eventType, i) && typeof i === "string" && i && typeof eventType[i] === "function") { + ZeroClipboard.on(i, eventType[i]); + } + } + } + if (events && events.length) { + for (i = 0, len = events.length; i < len; i++) { + eventType = events[i].replace(/^on/, ""); + added[eventType] = true; + if (!_handlers[eventType]) { + _handlers[eventType] = []; + } + _handlers[eventType].push(listener); + } + if (added.ready && _flashState.ready) { + ZeroClipboard.emit({ + type: "ready" + }); + } + if (added.error) { + for (i = 0, len = _flashStateErrorNames.length; i < len; i++) { + if (_flashState[_flashStateErrorNames[i].replace(/^flash-/, "")] === true) { + ZeroClipboard.emit({ + type: "error", + name: _flashStateErrorNames[i] + }); + break; + } + } + if (_zcSwfVersion !== undefined && ZeroClipboard.version !== _zcSwfVersion) { + ZeroClipboard.emit({ + type: "error", + name: "version-mismatch", + jsVersion: ZeroClipboard.version, + swfVersion: _zcSwfVersion + }); + } + } + } + return ZeroClipboard; + }; + /** + * The underlying implementation of `ZeroClipboard.off`. + * @private + */ + var _off = function(eventType, listener) { + var i, len, foundIndex, events, perEventHandlers; + if (arguments.length === 0) { + events = _keys(_handlers); + } else if (typeof eventType === "string" && eventType) { + events = eventType.split(/\s+/); + } else if (typeof eventType === "object" && eventType && typeof listener === "undefined") { + for (i in eventType) { + if (_hasOwn.call(eventType, i) && typeof i === "string" && i && typeof eventType[i] === "function") { + ZeroClipboard.off(i, eventType[i]); + } + } + } + if (events && events.length) { + for (i = 0, len = events.length; i < len; i++) { + eventType = events[i].toLowerCase().replace(/^on/, ""); + perEventHandlers = _handlers[eventType]; + if (perEventHandlers && perEventHandlers.length) { + if (listener) { + foundIndex = perEventHandlers.indexOf(listener); + while (foundIndex !== -1) { + perEventHandlers.splice(foundIndex, 1); + foundIndex = perEventHandlers.indexOf(listener, foundIndex); + } + } else { + perEventHandlers.length = 0; + } + } + } + } + return ZeroClipboard; + }; + /** + * The underlying implementation of `ZeroClipboard.handlers`. + * @private + */ + var _listeners = function(eventType) { + var copy; + if (typeof eventType === "string" && eventType) { + copy = _deepCopy(_handlers[eventType]) || null; + } else { + copy = _deepCopy(_handlers); + } + return copy; + }; + /** + * The underlying implementation of `ZeroClipboard.emit`. + * @private + */ + var _emit = function(event) { + var eventCopy, returnVal, tmp; + event = _createEvent(event); + if (!event) { + return; + } + if (_preprocessEvent(event)) { + return; + } + if (event.type === "ready" && _flashState.overdue === true) { + return ZeroClipboard.emit({ + type: "error", + name: "flash-overdue" + }); + } + eventCopy = _extend({}, event); + _dispatchCallbacks.call(this, eventCopy); + if (event.type === "copy") { + tmp = _mapClipDataToFlash(_clipData); + returnVal = tmp.data; + _clipDataFormatMap = tmp.formatMap; + } + return returnVal; + }; + /** + * The underlying implementation of `ZeroClipboard.create`. + * @private + */ + var _create = function() { + var previousState = _flashState.sandboxed; + _detectSandbox(); + if (typeof _flashState.ready !== "boolean") { + _flashState.ready = false; + } + if (_flashState.sandboxed !== previousState && _flashState.sandboxed === true) { + _flashState.ready = false; + ZeroClipboard.emit({ + type: "error", + name: "flash-sandboxed" + }); + } else if (!ZeroClipboard.isFlashUnusable() && _flashState.bridge === null) { + var maxWait = _globalConfig.flashLoadTimeout; + if (typeof maxWait === "number" && maxWait >= 0) { + _flashCheckTimeout = _setTimeout(function() { + if (typeof _flashState.deactivated !== "boolean") { + _flashState.deactivated = true; + } + if (_flashState.deactivated === true) { + ZeroClipboard.emit({ + type: "error", + name: "flash-deactivated" + }); + } + }, maxWait); + } + _flashState.overdue = false; + _embedSwf(); + } + }; + /** + * The underlying implementation of `ZeroClipboard.destroy`. + * @private + */ + var _destroy = function() { + ZeroClipboard.clearData(); + ZeroClipboard.blur(); + ZeroClipboard.emit("destroy"); + _unembedSwf(); + ZeroClipboard.off(); + }; + /** + * The underlying implementation of `ZeroClipboard.setData`. + * @private + */ + var _setData = function(format, data) { + var dataObj; + if (typeof format === "object" && format && typeof data === "undefined") { + dataObj = format; + ZeroClipboard.clearData(); + } else if (typeof format === "string" && format) { + dataObj = {}; + dataObj[format] = data; + } else { + return; + } + for (var dataFormat in dataObj) { + if (typeof dataFormat === "string" && dataFormat && _hasOwn.call(dataObj, dataFormat) && typeof dataObj[dataFormat] === "string" && dataObj[dataFormat]) { + _clipData[dataFormat] = dataObj[dataFormat]; + } + } + }; + /** + * The underlying implementation of `ZeroClipboard.clearData`. + * @private + */ + var _clearData = function(format) { + if (typeof format === "undefined") { + _deleteOwnProperties(_clipData); + _clipDataFormatMap = null; + } else if (typeof format === "string" && _hasOwn.call(_clipData, format)) { + delete _clipData[format]; + } + }; + /** + * The underlying implementation of `ZeroClipboard.getData`. + * @private + */ + var _getData = function(format) { + if (typeof format === "undefined") { + return _deepCopy(_clipData); + } else if (typeof format === "string" && _hasOwn.call(_clipData, format)) { + return _clipData[format]; + } + }; + /** + * The underlying implementation of `ZeroClipboard.focus`/`ZeroClipboard.activate`. + * @private + */ + var _focus = function(element) { + if (!(element && element.nodeType === 1)) { + return; + } + if (_currentElement) { + _removeClass(_currentElement, _globalConfig.activeClass); + if (_currentElement !== element) { + _removeClass(_currentElement, _globalConfig.hoverClass); + } + } + _currentElement = element; + _addClass(element, _globalConfig.hoverClass); + var newTitle = element.getAttribute("title") || _globalConfig.title; + if (typeof newTitle === "string" && newTitle) { + var htmlBridge = _getHtmlBridge(_flashState.bridge); + if (htmlBridge) { + htmlBridge.setAttribute("title", newTitle); + } + } + var useHandCursor = _globalConfig.forceHandCursor === true || _getStyle(element, "cursor") === "pointer"; + _setHandCursor(useHandCursor); + _reposition(); + }; + /** + * The underlying implementation of `ZeroClipboard.blur`/`ZeroClipboard.deactivate`. + * @private + */ + var _blur = function() { + var htmlBridge = _getHtmlBridge(_flashState.bridge); + if (htmlBridge) { + htmlBridge.removeAttribute("title"); + htmlBridge.style.left = "0px"; + htmlBridge.style.top = "-9999px"; + htmlBridge.style.width = "1px"; + htmlBridge.style.height = "1px"; + } + if (_currentElement) { + _removeClass(_currentElement, _globalConfig.hoverClass); + _removeClass(_currentElement, _globalConfig.activeClass); + _currentElement = null; + } + }; + /** + * The underlying implementation of `ZeroClipboard.activeElement`. + * @private + */ + var _activeElement = function() { + return _currentElement || null; + }; + /** + * Check if a value is a valid HTML4 `ID` or `Name` token. + * @private + */ + var _isValidHtml4Id = function(id) { + return typeof id === "string" && id && /^[A-Za-z][A-Za-z0-9_:\-\.]*$/.test(id); + }; + /** + * Create or update an `event` object, based on the `eventType`. + * @private + */ + var _createEvent = function(event) { + var eventType; + if (typeof event === "string" && event) { + eventType = event; + event = {}; + } else if (typeof event === "object" && event && typeof event.type === "string" && event.type) { + eventType = event.type; + } + if (!eventType) { + return; + } + eventType = eventType.toLowerCase(); + if (!event.target && (/^(copy|aftercopy|_click)$/.test(eventType) || eventType === "error" && event.name === "clipboard-error")) { + event.target = _copyTarget; + } + _extend(event, { + type: eventType, + target: event.target || _currentElement || null, + relatedTarget: event.relatedTarget || null, + currentTarget: _flashState && _flashState.bridge || null, + timeStamp: event.timeStamp || _now() || null + }); + var msg = _eventMessages[event.type]; + if (event.type === "error" && event.name && msg) { + msg = msg[event.name]; + } + if (msg) { + event.message = msg; + } + if (event.type === "ready") { + _extend(event, { + target: null, + version: _flashState.version + }); + } + if (event.type === "error") { + if (_flashStateErrorNameMatchingRegex.test(event.name)) { + _extend(event, { + target: null, + minimumVersion: _minimumFlashVersion + }); + } + if (_flashStateEnabledErrorNameMatchingRegex.test(event.name)) { + _extend(event, { + version: _flashState.version + }); + } + } + if (event.type === "copy") { + event.clipboardData = { + setData: ZeroClipboard.setData, + clearData: ZeroClipboard.clearData + }; + } + if (event.type === "aftercopy") { + event = _mapClipResultsFromFlash(event, _clipDataFormatMap); + } + if (event.target && !event.relatedTarget) { + event.relatedTarget = _getRelatedTarget(event.target); + } + return _addMouseData(event); + }; + /** + * Get a relatedTarget from the target's `data-clipboard-target` attribute + * @private + */ + var _getRelatedTarget = function(targetEl) { + var relatedTargetId = targetEl && targetEl.getAttribute && targetEl.getAttribute("data-clipboard-target"); + return relatedTargetId ? _document.getElementById(relatedTargetId) : null; + }; + /** + * Add element and position data to `MouseEvent` instances + * @private + */ + var _addMouseData = function(event) { + if (event && /^_(?:click|mouse(?:over|out|down|up|move))$/.test(event.type)) { + var srcElement = event.target; + var fromElement = event.type === "_mouseover" && event.relatedTarget ? event.relatedTarget : undefined; + var toElement = event.type === "_mouseout" && event.relatedTarget ? event.relatedTarget : undefined; + var pos = _getElementPosition(srcElement); + var screenLeft = _window.screenLeft || _window.screenX || 0; + var screenTop = _window.screenTop || _window.screenY || 0; + var scrollLeft = _document.body.scrollLeft + _document.documentElement.scrollLeft; + var scrollTop = _document.body.scrollTop + _document.documentElement.scrollTop; + var pageX = pos.left + (typeof event._stageX === "number" ? event._stageX : 0); + var pageY = pos.top + (typeof event._stageY === "number" ? event._stageY : 0); + var clientX = pageX - scrollLeft; + var clientY = pageY - scrollTop; + var screenX = screenLeft + clientX; + var screenY = screenTop + clientY; + var moveX = typeof event.movementX === "number" ? event.movementX : 0; + var moveY = typeof event.movementY === "number" ? event.movementY : 0; + delete event._stageX; + delete event._stageY; + _extend(event, { + srcElement: srcElement, + fromElement: fromElement, + toElement: toElement, + screenX: screenX, + screenY: screenY, + pageX: pageX, + pageY: pageY, + clientX: clientX, + clientY: clientY, + x: clientX, + y: clientY, + movementX: moveX, + movementY: moveY, + offsetX: 0, + offsetY: 0, + layerX: 0, + layerY: 0 + }); + } + return event; + }; + /** + * Determine if an event's registered handlers should be execute synchronously or asynchronously. + * + * @returns {boolean} + * @private + */ + var _shouldPerformAsync = function(event) { + var eventType = event && typeof event.type === "string" && event.type || ""; + return !/^(?:(?:before)?copy|destroy)$/.test(eventType); + }; + /** + * Control if a callback should be executed asynchronously or not. + * + * @returns `undefined` + * @private + */ + var _dispatchCallback = function(func, context, args, async) { + if (async) { + _setTimeout(function() { + func.apply(context, args); + }, 0); + } else { + func.apply(context, args); + } + }; + /** + * Handle the actual dispatching of events to client instances. + * + * @returns `undefined` + * @private + */ + var _dispatchCallbacks = function(event) { + if (!(typeof event === "object" && event && event.type)) { + return; + } + var async = _shouldPerformAsync(event); + var wildcardTypeHandlers = _handlers["*"] || []; + var specificTypeHandlers = _handlers[event.type] || []; + var handlers = wildcardTypeHandlers.concat(specificTypeHandlers); + if (handlers && handlers.length) { + var i, len, func, context, eventCopy, originalContext = this; + for (i = 0, len = handlers.length; i < len; i++) { + func = handlers[i]; + context = originalContext; + if (typeof func === "string" && typeof _window[func] === "function") { + func = _window[func]; + } + if (typeof func === "object" && func && typeof func.handleEvent === "function") { + context = func; + func = func.handleEvent; + } + if (typeof func === "function") { + eventCopy = _extend({}, event); + _dispatchCallback(func, context, [ eventCopy ], async); + } + } + } + return this; + }; + /** + * Check an `error` event's `name` property to see if Flash has + * already loaded, which rules out possible `iframe` sandboxing. + * @private + */ + var _getSandboxStatusFromErrorEvent = function(event) { + var isSandboxed = null; + if (_pageIsFramed === false || event && event.type === "error" && event.name && _errorsThatOnlyOccurAfterFlashLoads.indexOf(event.name) !== -1) { + isSandboxed = false; + } + return isSandboxed; + }; + /** + * Preprocess any special behaviors, reactions, or state changes after receiving this event. + * Executes only once per event emitted, NOT once per client. + * @private + */ + var _preprocessEvent = function(event) { + var element = event.target || _currentElement || null; + var sourceIsSwf = event._source === "swf"; + delete event._source; + switch (event.type) { + case "error": + var isSandboxed = event.name === "flash-sandboxed" || _getSandboxStatusFromErrorEvent(event); + if (typeof isSandboxed === "boolean") { + _flashState.sandboxed = isSandboxed; + } + if (_flashStateErrorNames.indexOf(event.name) !== -1) { + _extend(_flashState, { + disabled: event.name === "flash-disabled", + outdated: event.name === "flash-outdated", + unavailable: event.name === "flash-unavailable", + degraded: event.name === "flash-degraded", + deactivated: event.name === "flash-deactivated", + overdue: event.name === "flash-overdue", + ready: false + }); + } else if (event.name === "version-mismatch") { + _zcSwfVersion = event.swfVersion; + _extend(_flashState, { + disabled: false, + outdated: false, + unavailable: false, + degraded: false, + deactivated: false, + overdue: false, + ready: false + }); + } + _clearTimeoutsAndPolling(); + break; + + case "ready": + _zcSwfVersion = event.swfVersion; + var wasDeactivated = _flashState.deactivated === true; + _extend(_flashState, { + disabled: false, + outdated: false, + sandboxed: false, + unavailable: false, + degraded: false, + deactivated: false, + overdue: wasDeactivated, + ready: !wasDeactivated + }); + _clearTimeoutsAndPolling(); + break; + + case "beforecopy": + _copyTarget = element; + break; + + case "copy": + var textContent, htmlContent, targetEl = event.relatedTarget; + if (!(_clipData["text/html"] || _clipData["text/plain"]) && targetEl && (htmlContent = targetEl.value || targetEl.outerHTML || targetEl.innerHTML) && (textContent = targetEl.value || targetEl.textContent || targetEl.innerText)) { + event.clipboardData.clearData(); + event.clipboardData.setData("text/plain", textContent); + if (htmlContent !== textContent) { + event.clipboardData.setData("text/html", htmlContent); + } + } else if (!_clipData["text/plain"] && event.target && (textContent = event.target.getAttribute("data-clipboard-text"))) { + event.clipboardData.clearData(); + event.clipboardData.setData("text/plain", textContent); + } + break; + + case "aftercopy": + _queueEmitClipboardErrors(event); + ZeroClipboard.clearData(); + if (element && element !== _safeActiveElement() && element.focus) { + element.focus(); + } + break; + + case "_mouseover": + ZeroClipboard.focus(element); + if (_globalConfig.bubbleEvents === true && sourceIsSwf) { + if (element && element !== event.relatedTarget && !_containedBy(event.relatedTarget, element)) { + _fireMouseEvent(_extend({}, event, { + type: "mouseenter", + bubbles: false, + cancelable: false + })); + } + _fireMouseEvent(_extend({}, event, { + type: "mouseover" + })); + } + break; + + case "_mouseout": + ZeroClipboard.blur(); + if (_globalConfig.bubbleEvents === true && sourceIsSwf) { + if (element && element !== event.relatedTarget && !_containedBy(event.relatedTarget, element)) { + _fireMouseEvent(_extend({}, event, { + type: "mouseleave", + bubbles: false, + cancelable: false + })); + } + _fireMouseEvent(_extend({}, event, { + type: "mouseout" + })); + } + break; + + case "_mousedown": + _addClass(element, _globalConfig.activeClass); + if (_globalConfig.bubbleEvents === true && sourceIsSwf) { + _fireMouseEvent(_extend({}, event, { + type: event.type.slice(1) + })); + } + break; + + case "_mouseup": + _removeClass(element, _globalConfig.activeClass); + if (_globalConfig.bubbleEvents === true && sourceIsSwf) { + _fireMouseEvent(_extend({}, event, { + type: event.type.slice(1) + })); + } + break; + + case "_click": + _copyTarget = null; + if (_globalConfig.bubbleEvents === true && sourceIsSwf) { + _fireMouseEvent(_extend({}, event, { + type: event.type.slice(1) + })); + } + break; + + case "_mousemove": + if (_globalConfig.bubbleEvents === true && sourceIsSwf) { + _fireMouseEvent(_extend({}, event, { + type: event.type.slice(1) + })); + } + break; + } + if (/^_(?:click|mouse(?:over|out|down|up|move))$/.test(event.type)) { + return true; + } + }; + /** + * Check an "aftercopy" event for clipboard errors and emit a corresponding "error" event. + * @private + */ + var _queueEmitClipboardErrors = function(aftercopyEvent) { + if (aftercopyEvent.errors && aftercopyEvent.errors.length > 0) { + var errorEvent = _deepCopy(aftercopyEvent); + _extend(errorEvent, { + type: "error", + name: "clipboard-error" + }); + delete errorEvent.success; + _setTimeout(function() { + ZeroClipboard.emit(errorEvent); + }, 0); + } + }; + /** + * Dispatch a synthetic MouseEvent. + * + * @returns `undefined` + * @private + */ + var _fireMouseEvent = function(event) { + if (!(event && typeof event.type === "string" && event)) { + return; + } + var e, target = event.target || null, doc = target && target.ownerDocument || _document, defaults = { + view: doc.defaultView || _window, + canBubble: true, + cancelable: true, + detail: event.type === "click" ? 1 : 0, + button: typeof event.which === "number" ? event.which - 1 : typeof event.button === "number" ? event.button : doc.createEvent ? 0 : 1 + }, args = _extend(defaults, event); + if (!target) { + return; + } + if (doc.createEvent && target.dispatchEvent) { + 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 ]; + e = doc.createEvent("MouseEvents"); + if (e.initMouseEvent) { + e.initMouseEvent.apply(e, args); + e._source = "js"; + target.dispatchEvent(e); + } + } + }; + /** + * Continuously poll the DOM until either: + * (a) the fallback content becomes visible, or + * (b) we receive an event from SWF (handled elsewhere) + * + * IMPORTANT: + * This is NOT a necessary check but it can result in significantly faster + * detection of bad `swfPath` configuration and/or network/server issues [in + * supported browsers] than waiting for the entire `flashLoadTimeout` duration + * to elapse before detecting that the SWF cannot be loaded. The detection + * duration can be anywhere from 10-30 times faster [in supported browsers] by + * using this approach. + * + * @returns `undefined` + * @private + */ + var _watchForSwfFallbackContent = function() { + var maxWait = _globalConfig.flashLoadTimeout; + if (typeof maxWait === "number" && maxWait >= 0) { + var pollWait = Math.min(1e3, maxWait / 10); + var fallbackContentId = _globalConfig.swfObjectId + "_fallbackContent"; + _swfFallbackCheckInterval = _setInterval(function() { + var el = _document.getElementById(fallbackContentId); + if (_isElementVisible(el)) { + _clearTimeoutsAndPolling(); + _flashState.deactivated = null; + ZeroClipboard.emit({ + type: "error", + name: "swf-not-found" + }); + } + }, pollWait); + } + }; + /** + * Create the HTML bridge element to embed the Flash object into. + * @private + */ + var _createHtmlBridge = function() { + var container = _document.createElement("div"); + container.id = _globalConfig.containerId; + container.className = _globalConfig.containerClass; + container.style.position = "absolute"; + container.style.left = "0px"; + container.style.top = "-9999px"; + container.style.width = "1px"; + container.style.height = "1px"; + container.style.zIndex = "" + _getSafeZIndex(_globalConfig.zIndex); + return container; + }; + /** + * Get the HTML element container that wraps the Flash bridge object/element. + * @private + */ + var _getHtmlBridge = function(flashBridge) { + var htmlBridge = flashBridge && flashBridge.parentNode; + while (htmlBridge && htmlBridge.nodeName === "OBJECT" && htmlBridge.parentNode) { + htmlBridge = htmlBridge.parentNode; + } + return htmlBridge || null; + }; + /** + * Create the SWF object. + * + * @returns The SWF object reference. + * @private + */ + var _embedSwf = function() { + var len, flashBridge = _flashState.bridge, container = _getHtmlBridge(flashBridge); + if (!flashBridge) { + var allowScriptAccess = _determineScriptAccess(_window.location.host, _globalConfig); + var allowNetworking = allowScriptAccess === "never" ? "none" : "all"; + var flashvars = _vars(_extend({ + jsVersion: ZeroClipboard.version + }, _globalConfig)); + var swfUrl = _globalConfig.swfPath + _cacheBust(_globalConfig.swfPath, _globalConfig); + container = _createHtmlBridge(); + var divToBeReplaced = _document.createElement("div"); + container.appendChild(divToBeReplaced); + _document.body.appendChild(container); + var tmpDiv = _document.createElement("div"); + var usingActiveX = _flashState.pluginType === "activex"; + tmpDiv.innerHTML = '" + (usingActiveX ? '' : "") + '' + '' + '' + '' + '' + '
 
' + "
"; + flashBridge = tmpDiv.firstChild; + tmpDiv = null; + _unwrap(flashBridge).ZeroClipboard = ZeroClipboard; + container.replaceChild(flashBridge, divToBeReplaced); + _watchForSwfFallbackContent(); + } + if (!flashBridge) { + flashBridge = _document[_globalConfig.swfObjectId]; + if (flashBridge && (len = flashBridge.length)) { + flashBridge = flashBridge[len - 1]; + } + if (!flashBridge && container) { + flashBridge = container.firstChild; + } + } + _flashState.bridge = flashBridge || null; + return flashBridge; + }; + /** + * Destroy the SWF object. + * @private + */ + var _unembedSwf = function() { + var flashBridge = _flashState.bridge; + if (flashBridge) { + var htmlBridge = _getHtmlBridge(flashBridge); + if (htmlBridge) { + if (_flashState.pluginType === "activex" && "readyState" in flashBridge) { + flashBridge.style.display = "none"; + (function removeSwfFromIE() { + if (flashBridge.readyState === 4) { + for (var prop in flashBridge) { + if (typeof flashBridge[prop] === "function") { + flashBridge[prop] = null; + } + } + if (flashBridge.parentNode) { + flashBridge.parentNode.removeChild(flashBridge); + } + if (htmlBridge.parentNode) { + htmlBridge.parentNode.removeChild(htmlBridge); + } + } else { + _setTimeout(removeSwfFromIE, 10); + } + })(); + } else { + if (flashBridge.parentNode) { + flashBridge.parentNode.removeChild(flashBridge); + } + if (htmlBridge.parentNode) { + htmlBridge.parentNode.removeChild(htmlBridge); + } + } + } + _clearTimeoutsAndPolling(); + _flashState.ready = null; + _flashState.bridge = null; + _flashState.deactivated = null; + _zcSwfVersion = undefined; + } + }; + /** + * Map the data format names of the "clipData" to Flash-friendly names. + * + * @returns A new transformed object. + * @private + */ + var _mapClipDataToFlash = function(clipData) { + var newClipData = {}, formatMap = {}; + if (!(typeof clipData === "object" && clipData)) { + return; + } + for (var dataFormat in clipData) { + if (dataFormat && _hasOwn.call(clipData, dataFormat) && typeof clipData[dataFormat] === "string" && clipData[dataFormat]) { + switch (dataFormat.toLowerCase()) { + case "text/plain": + case "text": + case "air:text": + case "flash:text": + newClipData.text = clipData[dataFormat]; + formatMap.text = dataFormat; + break; + + case "text/html": + case "html": + case "air:html": + case "flash:html": + newClipData.html = clipData[dataFormat]; + formatMap.html = dataFormat; + break; + + case "application/rtf": + case "text/rtf": + case "rtf": + case "richtext": + case "air:rtf": + case "flash:rtf": + newClipData.rtf = clipData[dataFormat]; + formatMap.rtf = dataFormat; + break; + + default: + break; + } + } + } + return { + data: newClipData, + formatMap: formatMap + }; + }; + /** + * Map the data format names from Flash-friendly names back to their original "clipData" names (via a format mapping). + * + * @returns A new transformed object. + * @private + */ + var _mapClipResultsFromFlash = function(clipResults, formatMap) { + if (!(typeof clipResults === "object" && clipResults && typeof formatMap === "object" && formatMap)) { + return clipResults; + } + var newResults = {}; + for (var prop in clipResults) { + if (_hasOwn.call(clipResults, prop)) { + if (prop === "errors") { + newResults[prop] = clipResults[prop] ? clipResults[prop].slice() : []; + for (var i = 0, len = newResults[prop].length; i < len; i++) { + newResults[prop][i].format = formatMap[newResults[prop][i].format]; + } + } else if (prop !== "success" && prop !== "data") { + newResults[prop] = clipResults[prop]; + } else { + newResults[prop] = {}; + var tmpHash = clipResults[prop]; + for (var dataFormat in tmpHash) { + if (dataFormat && _hasOwn.call(tmpHash, dataFormat) && _hasOwn.call(formatMap, dataFormat)) { + newResults[prop][formatMap[dataFormat]] = tmpHash[dataFormat]; + } + } + } + } + } + return newResults; + }; + /** + * Will look at a path, and will create a "?noCache={time}" or "&noCache={time}" + * query param string to return. Does NOT append that string to the original path. + * This is useful because ExternalInterface often breaks when a Flash SWF is cached. + * + * @returns The `noCache` query param with necessary "?"/"&" prefix. + * @private + */ + var _cacheBust = function(path, options) { + var cacheBust = options == null || options && options.cacheBust === true; + if (cacheBust) { + return (path.indexOf("?") === -1 ? "?" : "&") + "noCache=" + _now(); + } else { + return ""; + } + }; + /** + * Creates a query string for the FlashVars param. + * Does NOT include the cache-busting query param. + * + * @returns FlashVars query string + * @private + */ + var _vars = function(options) { + var i, len, domain, domains, str = "", trustedOriginsExpanded = []; + if (options.trustedDomains) { + if (typeof options.trustedDomains === "string") { + domains = [ options.trustedDomains ]; + } else if (typeof options.trustedDomains === "object" && "length" in options.trustedDomains) { + domains = options.trustedDomains; + } + } + if (domains && domains.length) { + for (i = 0, len = domains.length; i < len; i++) { + if (_hasOwn.call(domains, i) && domains[i] && typeof domains[i] === "string") { + domain = _extractDomain(domains[i]); + if (!domain) { + continue; + } + if (domain === "*") { + trustedOriginsExpanded.length = 0; + trustedOriginsExpanded.push(domain); + break; + } + trustedOriginsExpanded.push.apply(trustedOriginsExpanded, [ domain, "//" + domain, _window.location.protocol + "//" + domain ]); + } + } + } + if (trustedOriginsExpanded.length) { + str += "trustedOrigins=" + _encodeURIComponent(trustedOriginsExpanded.join(",")); + } + if (options.forceEnhancedClipboard === true) { + str += (str ? "&" : "") + "forceEnhancedClipboard=true"; + } + if (typeof options.swfObjectId === "string" && options.swfObjectId) { + str += (str ? "&" : "") + "swfObjectId=" + _encodeURIComponent(options.swfObjectId); + } + if (typeof options.jsVersion === "string" && options.jsVersion) { + str += (str ? "&" : "") + "jsVersion=" + _encodeURIComponent(options.jsVersion); + } + return str; + }; + /** + * Extract the domain (e.g. "github.com") from an origin (e.g. "https://github.com") or + * URL (e.g. "https://github.com/zeroclipboard/zeroclipboard/"). + * + * @returns the domain + * @private + */ + var _extractDomain = function(originOrUrl) { + if (originOrUrl == null || originOrUrl === "") { + return null; + } + originOrUrl = originOrUrl.replace(/^\s+|\s+$/g, ""); + if (originOrUrl === "") { + return null; + } + var protocolIndex = originOrUrl.indexOf("//"); + originOrUrl = protocolIndex === -1 ? originOrUrl : originOrUrl.slice(protocolIndex + 2); + var pathIndex = originOrUrl.indexOf("/"); + originOrUrl = pathIndex === -1 ? originOrUrl : protocolIndex === -1 || pathIndex === 0 ? null : originOrUrl.slice(0, pathIndex); + if (originOrUrl && originOrUrl.slice(-4).toLowerCase() === ".swf") { + return null; + } + return originOrUrl || null; + }; + /** + * Set `allowScriptAccess` based on `trustedDomains` and `window.location.host` vs. `swfPath`. + * + * @returns The appropriate script access level. + * @private + */ + var _determineScriptAccess = function() { + var _extractAllDomains = function(origins) { + var i, len, tmp, resultsArray = []; + if (typeof origins === "string") { + origins = [ origins ]; + } + if (!(typeof origins === "object" && origins && typeof origins.length === "number")) { + return resultsArray; + } + for (i = 0, len = origins.length; i < len; i++) { + if (_hasOwn.call(origins, i) && (tmp = _extractDomain(origins[i]))) { + if (tmp === "*") { + resultsArray.length = 0; + resultsArray.push("*"); + break; + } + if (resultsArray.indexOf(tmp) === -1) { + resultsArray.push(tmp); + } + } + } + return resultsArray; + }; + return function(currentDomain, configOptions) { + var swfDomain = _extractDomain(configOptions.swfPath); + if (swfDomain === null) { + swfDomain = currentDomain; + } + var trustedDomains = _extractAllDomains(configOptions.trustedDomains); + var len = trustedDomains.length; + if (len > 0) { + if (len === 1 && trustedDomains[0] === "*") { + return "always"; + } + if (trustedDomains.indexOf(currentDomain) !== -1) { + if (len === 1 && currentDomain === swfDomain) { + return "sameDomain"; + } + return "always"; + } + } + return "never"; + }; + }(); + /** + * Get the currently active/focused DOM element. + * + * @returns the currently active/focused element, or `null` + * @private + */ + var _safeActiveElement = function() { + try { + return _document.activeElement; + } catch (err) { + return null; + } + }; + /** + * Add a class to an element, if it doesn't already have it. + * + * @returns The element, with its new class added. + * @private + */ + var _addClass = function(element, value) { + var c, cl, className, classNames = []; + if (typeof value === "string" && value) { + classNames = value.split(/\s+/); + } + if (element && element.nodeType === 1 && classNames.length > 0) { + if (element.classList) { + for (c = 0, cl = classNames.length; c < cl; c++) { + element.classList.add(classNames[c]); + } + } else if (element.hasOwnProperty("className")) { + className = " " + element.className + " "; + for (c = 0, cl = classNames.length; c < cl; c++) { + if (className.indexOf(" " + classNames[c] + " ") === -1) { + className += classNames[c] + " "; + } + } + element.className = className.replace(/^\s+|\s+$/g, ""); + } + } + return element; + }; + /** + * Remove a class from an element, if it has it. + * + * @returns The element, with its class removed. + * @private + */ + var _removeClass = function(element, value) { + var c, cl, className, classNames = []; + if (typeof value === "string" && value) { + classNames = value.split(/\s+/); + } + if (element && element.nodeType === 1 && classNames.length > 0) { + if (element.classList && element.classList.length > 0) { + for (c = 0, cl = classNames.length; c < cl; c++) { + element.classList.remove(classNames[c]); + } + } else if (element.className) { + className = (" " + element.className + " ").replace(/[\r\n\t]/g, " "); + for (c = 0, cl = classNames.length; c < cl; c++) { + className = className.replace(" " + classNames[c] + " ", " "); + } + element.className = className.replace(/^\s+|\s+$/g, ""); + } + } + return element; + }; + /** + * Attempt to interpret the element's CSS styling. If `prop` is `"cursor"`, + * then we assume that it should be a hand ("pointer") cursor if the element + * is an anchor element ("a" tag). + * + * @returns The computed style property. + * @private + */ + var _getStyle = function(el, prop) { + var value = _getComputedStyle(el, null).getPropertyValue(prop); + if (prop === "cursor") { + if (!value || value === "auto") { + if (el.nodeName === "A") { + return "pointer"; + } + } + } + return value; + }; + /** + * Get the absolutely positioned coordinates of a DOM element. + * + * @returns Object containing the element's position, width, and height. + * @private + */ + var _getElementPosition = function(el) { + var pos = { + left: 0, + top: 0, + width: 0, + height: 0 + }; + if (el.getBoundingClientRect) { + var elRect = el.getBoundingClientRect(); + var pageXOffset = _window.pageXOffset; + var pageYOffset = _window.pageYOffset; + var leftBorderWidth = _document.documentElement.clientLeft || 0; + var topBorderWidth = _document.documentElement.clientTop || 0; + var leftBodyOffset = 0; + var topBodyOffset = 0; + if (_getStyle(_document.body, "position") === "relative") { + var bodyRect = _document.body.getBoundingClientRect(); + var htmlRect = _document.documentElement.getBoundingClientRect(); + leftBodyOffset = bodyRect.left - htmlRect.left || 0; + topBodyOffset = bodyRect.top - htmlRect.top || 0; + } + pos.left = elRect.left + pageXOffset - leftBorderWidth - leftBodyOffset; + pos.top = elRect.top + pageYOffset - topBorderWidth - topBodyOffset; + pos.width = "width" in elRect ? elRect.width : elRect.right - elRect.left; + pos.height = "height" in elRect ? elRect.height : elRect.bottom - elRect.top; + } + return pos; + }; + /** + * Determine is an element is visible somewhere within the document (page). + * + * @returns Boolean + * @private + */ + var _isElementVisible = function(el) { + if (!el) { + return false; + } + var styles = _getComputedStyle(el, null); + var hasCssHeight = _parseFloat(styles.height) > 0; + var hasCssWidth = _parseFloat(styles.width) > 0; + var hasCssTop = _parseFloat(styles.top) >= 0; + var hasCssLeft = _parseFloat(styles.left) >= 0; + var cssKnows = hasCssHeight && hasCssWidth && hasCssTop && hasCssLeft; + var rect = cssKnows ? null : _getElementPosition(el); + 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)); + return isVisible; + }; + /** + * Clear all existing timeouts and interval polling delegates. + * + * @returns `undefined` + * @private + */ + var _clearTimeoutsAndPolling = function() { + _clearTimeout(_flashCheckTimeout); + _flashCheckTimeout = 0; + _clearInterval(_swfFallbackCheckInterval); + _swfFallbackCheckInterval = 0; + }; + /** + * Reposition the Flash object to cover the currently activated element. + * + * @returns `undefined` + * @private + */ + var _reposition = function() { + var htmlBridge; + if (_currentElement && (htmlBridge = _getHtmlBridge(_flashState.bridge))) { + var pos = _getElementPosition(_currentElement); + _extend(htmlBridge.style, { + width: pos.width + "px", + height: pos.height + "px", + top: pos.top + "px", + left: pos.left + "px", + zIndex: "" + _getSafeZIndex(_globalConfig.zIndex) + }); + } + }; + /** + * Sends a signal to the Flash object to display the hand cursor if `true`. + * + * @returns `undefined` + * @private + */ + var _setHandCursor = function(enabled) { + if (_flashState.ready === true) { + if (_flashState.bridge && typeof _flashState.bridge.setHandCursor === "function") { + _flashState.bridge.setHandCursor(enabled); + } else { + _flashState.ready = false; + } + } + }; + /** + * Get a safe value for `zIndex` + * + * @returns an integer, or "auto" + * @private + */ + var _getSafeZIndex = function(val) { + if (/^(?:auto|inherit)$/.test(val)) { + return val; + } + var zIndex; + if (typeof val === "number" && !_isNaN(val)) { + zIndex = val; + } else if (typeof val === "string") { + zIndex = _getSafeZIndex(_parseInt(val, 10)); + } + return typeof zIndex === "number" ? zIndex : "auto"; + }; + /** + * Attempt to detect if ZeroClipboard is executing inside of a sandboxed iframe. + * If it is, Flash Player cannot be used, so ZeroClipboard is dead in the water. + * + * @see {@link http://lists.w3.org/Archives/Public/public-whatwg-archive/2014Dec/0002.html} + * @see {@link https://github.com/zeroclipboard/zeroclipboard/issues/511} + * @see {@link http://zeroclipboard.org/test-iframes.html} + * + * @returns `true` (is sandboxed), `false` (is not sandboxed), or `null` (uncertain) + * @private + */ + var _detectSandbox = function(doNotReassessFlashSupport) { + var effectiveScriptOrigin, frame, frameError, previousState = _flashState.sandboxed, isSandboxed = null; + doNotReassessFlashSupport = doNotReassessFlashSupport === true; + if (_pageIsFramed === false) { + isSandboxed = false; + } else { + try { + frame = window.frameElement || null; + } catch (e) { + frameError = { + name: e.name, + message: e.message + }; + } + if (frame && frame.nodeType === 1 && frame.nodeName === "IFRAME") { + try { + isSandboxed = frame.hasAttribute("sandbox"); + } catch (e) { + isSandboxed = null; + } + } else { + try { + effectiveScriptOrigin = document.domain || null; + } catch (e) { + effectiveScriptOrigin = null; + } + if (effectiveScriptOrigin === null || frameError && frameError.name === "SecurityError" && /(^|[\s\(\[@])sandbox(es|ed|ing|[\s\.,!\)\]@]|$)/.test(frameError.message.toLowerCase())) { + isSandboxed = true; + } + } + } + _flashState.sandboxed = isSandboxed; + if (previousState !== isSandboxed && !doNotReassessFlashSupport) { + _detectFlashSupport(_ActiveXObject); + } + return isSandboxed; + }; + /** + * Detect the Flash Player status, version, and plugin type. + * + * @see {@link https://code.google.com/p/doctype-mirror/wiki/ArticleDetectFlash#The_code} + * @see {@link http://stackoverflow.com/questions/12866060/detecting-pepper-ppapi-flash-with-javascript} + * + * @returns `undefined` + * @private + */ + var _detectFlashSupport = function(ActiveXObject) { + var plugin, ax, mimeType, hasFlash = false, isActiveX = false, isPPAPI = false, flashVersion = ""; + /** + * Derived from Apple's suggested sniffer. + * @param {String} desc e.g. "Shockwave Flash 7.0 r61" + * @returns {String} "7.0.61" + * @private + */ + function parseFlashVersion(desc) { + var matches = desc.match(/[\d]+/g); + matches.length = 3; + return matches.join("."); + } + function isPepperFlash(flashPlayerFileName) { + return !!flashPlayerFileName && (flashPlayerFileName = flashPlayerFileName.toLowerCase()) && (/^(pepflashplayer\.dll|libpepflashplayer\.so|pepperflashplayer\.plugin)$/.test(flashPlayerFileName) || flashPlayerFileName.slice(-13) === "chrome.plugin"); + } + function inspectPlugin(plugin) { + if (plugin) { + hasFlash = true; + if (plugin.version) { + flashVersion = parseFlashVersion(plugin.version); + } + if (!flashVersion && plugin.description) { + flashVersion = parseFlashVersion(plugin.description); + } + if (plugin.filename) { + isPPAPI = isPepperFlash(plugin.filename); + } + } + } + if (_navigator.plugins && _navigator.plugins.length) { + plugin = _navigator.plugins["Shockwave Flash"]; + inspectPlugin(plugin); + if (_navigator.plugins["Shockwave Flash 2.0"]) { + hasFlash = true; + flashVersion = "2.0.0.11"; + } + } else if (_navigator.mimeTypes && _navigator.mimeTypes.length) { + mimeType = _navigator.mimeTypes["application/x-shockwave-flash"]; + plugin = mimeType && mimeType.enabledPlugin; + inspectPlugin(plugin); + } else if (typeof ActiveXObject !== "undefined") { + isActiveX = true; + try { + ax = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7"); + hasFlash = true; + flashVersion = parseFlashVersion(ax.GetVariable("$version")); + } catch (e1) { + try { + ax = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6"); + hasFlash = true; + flashVersion = "6.0.21"; + } catch (e2) { + try { + ax = new ActiveXObject("ShockwaveFlash.ShockwaveFlash"); + hasFlash = true; + flashVersion = parseFlashVersion(ax.GetVariable("$version")); + } catch (e3) { + isActiveX = false; + } + } + } + } + _flashState.disabled = hasFlash !== true; + _flashState.outdated = flashVersion && _parseFloat(flashVersion) < _parseFloat(_minimumFlashVersion); + _flashState.version = flashVersion || "0.0.0"; + _flashState.pluginType = isPPAPI ? "pepper" : isActiveX ? "activex" : hasFlash ? "netscape" : "unknown"; + }; + /** + * Invoke the Flash detection algorithms immediately upon inclusion so we're not waiting later. + */ + _detectFlashSupport(_ActiveXObject); + /** + * Always assess the `sandboxed` state of the page at important Flash-related moments. + */ + _detectSandbox(true); + /** + * A shell constructor for `ZeroClipboard` client instances. + * + * @constructor + */ + var ZeroClipboard = function() { + if (!(this instanceof ZeroClipboard)) { + return new ZeroClipboard(); + } + if (typeof ZeroClipboard._createClient === "function") { + ZeroClipboard._createClient.apply(this, _args(arguments)); + } + }; + /** + * The ZeroClipboard library's version number. + * + * @static + * @readonly + * @property {string} + */ + _defineProperty(ZeroClipboard, "version", { + value: "2.2.0", + writable: false, + configurable: true, + enumerable: true + }); + /** + * Update or get a copy of the ZeroClipboard global configuration. + * Returns a copy of the current/updated configuration. + * + * @returns Object + * @static + */ + ZeroClipboard.config = function() { + return _config.apply(this, _args(arguments)); + }; + /** + * Diagnostic method that describes the state of the browser, Flash Player, and ZeroClipboard. + * + * @returns Object + * @static + */ + ZeroClipboard.state = function() { + return _state.apply(this, _args(arguments)); + }; + /** + * Check if Flash is unusable for any reason: disabled, outdated, deactivated, etc. + * + * @returns Boolean + * @static + */ + ZeroClipboard.isFlashUnusable = function() { + return _isFlashUnusable.apply(this, _args(arguments)); + }; + /** + * Register an event listener. + * + * @returns `ZeroClipboard` + * @static + */ + ZeroClipboard.on = function() { + return _on.apply(this, _args(arguments)); + }; + /** + * Unregister an event listener. + * If no `listener` function/object is provided, it will unregister all listeners for the provided `eventType`. + * If no `eventType` is provided, it will unregister all listeners for every event type. + * + * @returns `ZeroClipboard` + * @static + */ + ZeroClipboard.off = function() { + return _off.apply(this, _args(arguments)); + }; + /** + * Retrieve event listeners for an `eventType`. + * If no `eventType` is provided, it will retrieve all listeners for every event type. + * + * @returns array of listeners for the `eventType`; if no `eventType`, then a map/hash object of listeners for all event types; or `null` + */ + ZeroClipboard.handlers = function() { + return _listeners.apply(this, _args(arguments)); + }; + /** + * Event emission receiver from the Flash object, forwarding to any registered JavaScript event listeners. + * + * @returns For the "copy" event, returns the Flash-friendly "clipData" object; otherwise `undefined`. + * @static + */ + ZeroClipboard.emit = function() { + return _emit.apply(this, _args(arguments)); + }; + /** + * Create and embed the Flash object. + * + * @returns The Flash object + * @static + */ + ZeroClipboard.create = function() { + return _create.apply(this, _args(arguments)); + }; + /** + * Self-destruct and clean up everything, including the embedded Flash object. + * + * @returns `undefined` + * @static + */ + ZeroClipboard.destroy = function() { + return _destroy.apply(this, _args(arguments)); + }; + /** + * Set the pending data for clipboard injection. + * + * @returns `undefined` + * @static + */ + ZeroClipboard.setData = function() { + return _setData.apply(this, _args(arguments)); + }; + /** + * Clear the pending data for clipboard injection. + * If no `format` is provided, all pending data formats will be cleared. + * + * @returns `undefined` + * @static + */ + ZeroClipboard.clearData = function() { + return _clearData.apply(this, _args(arguments)); + }; + /** + * Get a copy of the pending data for clipboard injection. + * If no `format` is provided, a copy of ALL pending data formats will be returned. + * + * @returns `String` or `Object` + * @static + */ + ZeroClipboard.getData = function() { + return _getData.apply(this, _args(arguments)); + }; + /** + * Sets the current HTML object that the Flash object should overlay. This will put the global + * Flash object on top of the current element; depending on the setup, this may also set the + * pending clipboard text data as well as the Flash object's wrapping element's title attribute + * based on the underlying HTML element and ZeroClipboard configuration. + * + * @returns `undefined` + * @static + */ + ZeroClipboard.focus = ZeroClipboard.activate = function() { + return _focus.apply(this, _args(arguments)); + }; + /** + * Un-overlays the Flash object. This will put the global Flash object off-screen; depending on + * the setup, this may also unset the Flash object's wrapping element's title attribute based on + * the underlying HTML element and ZeroClipboard configuration. + * + * @returns `undefined` + * @static + */ + ZeroClipboard.blur = ZeroClipboard.deactivate = function() { + return _blur.apply(this, _args(arguments)); + }; + /** + * Returns the currently focused/"activated" HTML element that the Flash object is wrapping. + * + * @returns `HTMLElement` or `null` + * @static + */ + ZeroClipboard.activeElement = function() { + return _activeElement.apply(this, _args(arguments)); + }; + if (typeof define === "function" && define.amd) { + define(function() { + return ZeroClipboard; + }); + } else if (typeof module === "object" && module && typeof module.exports === "object" && module.exports) { + module.exports = ZeroClipboard; + } else { + window.ZeroClipboard = ZeroClipboard; + } +})(function() { + return this || window; +}()); \ No newline at end of file diff --git a/resources/zeroclipboard/ZeroClipboard.Core.min.js b/resources/zeroclipboard/ZeroClipboard.Core.min.js new file mode 100644 index 0000000000..01efd47115 --- /dev/null +++ b/resources/zeroclipboard/ZeroClipboard.Core.min.js @@ -0,0 +1,10 @@ +/*! + * ZeroClipboard + * The ZeroClipboard library provides an easy way to copy text to the clipboard using an invisible Adobe Flash movie and a JavaScript interface. + * Copyright (c) 2009-2014 Jon Rohan, James M. Greene + * Licensed MIT + * http://zeroclipboard.org/ + * v2.2.0 + */ +!function(a,b){"use strict";var c,d,e,f=a,g=f.document,h=f.navigator,i=f.setTimeout,j=f.clearTimeout,k=f.setInterval,l=f.clearInterval,m=f.getComputedStyle,n=f.encodeURIComponent,o=f.ActiveXObject,p=f.Error,q=f.Number.parseInt||f.parseInt,r=f.Number.parseFloat||f.parseFloat,s=f.Number.isNaN||f.isNaN,t=f.Date.now,u=f.Object.keys,v=f.Object.defineProperty,w=f.Object.prototype.hasOwnProperty,x=f.Array.prototype.slice,y=function(){var a=function(a){return a};if("function"==typeof f.wrap&&"function"==typeof f.unwrap)try{var b=g.createElement("div"),c=f.unwrap(b);1===b.nodeType&&c&&1===c.nodeType&&(a=f.unwrap)}catch(d){}return a}(),z=function(a){return x.call(a,0)},A=function(){var a,c,d,e,f,g,h=z(arguments),i=h[0]||{};for(a=1,c=h.length;c>a;a++)if(null!=(d=h[a]))for(e in d)w.call(d,e)&&(f=i[e],g=d[e],i!==g&&g!==b&&(i[e]=g));return i},B=function(a){var b,c,d,e;if("object"!=typeof a||null==a||"number"==typeof a.nodeType)b=a;else if("number"==typeof a.length)for(b=[],c=0,d=a.length;d>c;c++)w.call(a,c)&&(b[c]=B(a[c]));else{b={};for(e in a)w.call(a,e)&&(b[e]=B(a[e]))}return b},C=function(a,b){for(var c={},d=0,e=b.length;e>d;d++)b[d]in a&&(c[b[d]]=a[b[d]]);return c},D=function(a,b){var c={};for(var d in a)-1===b.indexOf(d)&&(c[d]=a[d]);return c},E=function(a){if(a)for(var b in a)w.call(a,b)&&delete a[b];return a},F=function(a,b){if(a&&1===a.nodeType&&a.ownerDocument&&b&&(1===b.nodeType&&b.ownerDocument&&b.ownerDocument===a.ownerDocument||9===b.nodeType&&!b.ownerDocument&&b===a.ownerDocument))do{if(a===b)return!0;a=a.parentNode}while(a);return!1},G=function(a){var b;return"string"==typeof a&&a&&(b=a.split("#")[0].split("?")[0],b=a.slice(0,a.lastIndexOf("/")+1)),b},H=function(a){var b,c;return"string"==typeof a&&a&&(c=a.match(/^(?:|[^:@]*@|.+\)@(?=http[s]?|file)|.+?\s+(?: at |@)(?:[^:\(]+ )*[\(]?)((?:http[s]?|file):\/\/[\/]?.+?\/[^:\)]*?)(?::\d+)(?::\d+)?/),c&&c[1]?b=c[1]:(c=a.match(/\)@((?:http[s]?|file):\/\/[\/]?.+?\/[^:\)]*?)(?::\d+)(?::\d+)?/),c&&c[1]&&(b=c[1]))),b},I=function(){var a,b;try{throw new p}catch(c){b=c}return b&&(a=b.sourceURL||b.fileName||H(b.stack)),a},J=function(){var a,c,d;if(g.currentScript&&(a=g.currentScript.src))return a;if(c=g.getElementsByTagName("script"),1===c.length)return c[0].src||b;if("readyState"in c[0])for(d=c.length;d--;)if("interactive"===c[d].readyState&&(a=c[d].src))return a;return"loading"===g.readyState&&(a=c[c.length-1].src)?a:(a=I())?a:b},K=function(){var a,c,d,e=g.getElementsByTagName("script");for(a=e.length;a--;){if(!(d=e[a].src)){c=null;break}if(d=G(d),null==c)c=d;else if(c!==d){c=null;break}}return c||b},L=function(){var a=G(J())||K()||"";return a+"ZeroClipboard.swf"},M=function(){return null==a.opener&&(!!a.top&&a!=a.top||!!a.parent&&a!=a.parent)}(),N={bridge:null,version:"0.0.0",pluginType:"unknown",disabled:null,outdated:null,sandboxed:null,unavailable:null,degraded:null,deactivated:null,overdue:null,ready:null},O="11.0.0",P={},Q={},R=null,S=0,T=0,U={ready:"Flash communication is established",error:{"flash-disabled":"Flash is disabled or not installed. May also be attempting to run Flash in a sandboxed iframe, which is impossible.","flash-outdated":"Flash is too outdated to support ZeroClipboard","flash-sandboxed":"Attempting to run Flash in a sandboxed iframe, which is impossible","flash-unavailable":"Flash is unable to communicate bidirectionally with JavaScript","flash-degraded":"Flash is unable to preserve data fidelity when communicating with JavaScript","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.","flash-overdue":"Flash communication was established but NOT within the acceptable time limit","version-mismatch":"ZeroClipboard JS version number does not match ZeroClipboard SWF version number","clipboard-error":"At least one error was thrown while ZeroClipboard was attempting to inject your data into the clipboard","config-mismatch":"ZeroClipboard configuration does not match Flash's reality","swf-not-found":"The ZeroClipboard SWF object could not be loaded, so please check your `swfPath` configuration and/or network connectivity"}},V=["flash-unavailable","flash-degraded","flash-overdue","version-mismatch","config-mismatch","clipboard-error"],W=["flash-disabled","flash-outdated","flash-sandboxed","flash-unavailable","flash-degraded","flash-deactivated","flash-overdue"],X=new RegExp("^flash-("+W.map(function(a){return a.replace(/^flash-/,"")}).join("|")+")$"),Y=new RegExp("^flash-("+W.slice(1).map(function(a){return a.replace(/^flash-/,"")}).join("|")+")$"),Z={swfPath:L(),trustedDomains:a.location.host?[a.location.host]:[],cacheBust:!0,forceEnhancedClipboard:!1,flashLoadTimeout:3e4,autoActivate:!0,bubbleEvents:!0,containerId:"global-zeroclipboard-html-bridge",containerClass:"global-zeroclipboard-container",swfObjectId:"global-zeroclipboard-flash-bridge",hoverClass:"zeroclipboard-is-hover",activeClass:"zeroclipboard-is-active",forceHandCursor:!1,title:null,zIndex:999999999},$=function(a){if("object"==typeof a&&null!==a)for(var b in a)if(w.call(a,b))if(/^(?:forceHandCursor|title|zIndex|bubbleEvents)$/.test(b))Z[b]=a[b];else if(null==N.bridge)if("containerId"===b||"swfObjectId"===b){if(!nb(a[b]))throw new Error("The specified `"+b+"` value is not valid as an HTML4 Element ID");Z[b]=a[b]}else Z[b]=a[b];{if("string"!=typeof a||!a)return B(Z);if(w.call(Z,a))return Z[a]}},_=function(){return Tb(),{browser:C(h,["userAgent","platform","appName"]),flash:D(N,["bridge"]),zeroclipboard:{version:Vb.version,config:Vb.config()}}},ab=function(){return!!(N.disabled||N.outdated||N.sandboxed||N.unavailable||N.degraded||N.deactivated)},bb=function(a,d){var e,f,g,h={};if("string"==typeof a&&a)g=a.toLowerCase().split(/\s+/);else if("object"==typeof a&&a&&"undefined"==typeof d)for(e in a)w.call(a,e)&&"string"==typeof e&&e&&"function"==typeof a[e]&&Vb.on(e,a[e]);if(g&&g.length){for(e=0,f=g.length;f>e;e++)a=g[e].replace(/^on/,""),h[a]=!0,P[a]||(P[a]=[]),P[a].push(d);if(h.ready&&N.ready&&Vb.emit({type:"ready"}),h.error){for(e=0,f=W.length;f>e;e++)if(N[W[e].replace(/^flash-/,"")]===!0){Vb.emit({type:"error",name:W[e]});break}c!==b&&Vb.version!==c&&Vb.emit({type:"error",name:"version-mismatch",jsVersion:Vb.version,swfVersion:c})}}return Vb},cb=function(a,b){var c,d,e,f,g;if(0===arguments.length)f=u(P);else if("string"==typeof a&&a)f=a.split(/\s+/);else if("object"==typeof a&&a&&"undefined"==typeof b)for(c in a)w.call(a,c)&&"string"==typeof c&&c&&"function"==typeof a[c]&&Vb.off(c,a[c]);if(f&&f.length)for(c=0,d=f.length;d>c;c++)if(a=f[c].toLowerCase().replace(/^on/,""),g=P[a],g&&g.length)if(b)for(e=g.indexOf(b);-1!==e;)g.splice(e,1),e=g.indexOf(b,e);else g.length=0;return Vb},db=function(a){var b;return b="string"==typeof a&&a?B(P[a])||null:B(P)},eb=function(a){var b,c,d;return a=ob(a),a&&!vb(a)?"ready"===a.type&&N.overdue===!0?Vb.emit({type:"error",name:"flash-overdue"}):(b=A({},a),tb.call(this,b),"copy"===a.type&&(d=Db(Q),c=d.data,R=d.formatMap),c):void 0},fb=function(){var a=N.sandboxed;if(Tb(),"boolean"!=typeof N.ready&&(N.ready=!1),N.sandboxed!==a&&N.sandboxed===!0)N.ready=!1,Vb.emit({type:"error",name:"flash-sandboxed"});else if(!Vb.isFlashUnusable()&&null===N.bridge){var b=Z.flashLoadTimeout;"number"==typeof b&&b>=0&&(S=i(function(){"boolean"!=typeof N.deactivated&&(N.deactivated=!0),N.deactivated===!0&&Vb.emit({type:"error",name:"flash-deactivated"})},b)),N.overdue=!1,Bb()}},gb=function(){Vb.clearData(),Vb.blur(),Vb.emit("destroy"),Cb(),Vb.off()},hb=function(a,b){var c;if("object"==typeof a&&a&&"undefined"==typeof b)c=a,Vb.clearData();else{if("string"!=typeof a||!a)return;c={},c[a]=b}for(var d in c)"string"==typeof d&&d&&w.call(c,d)&&"string"==typeof c[d]&&c[d]&&(Q[d]=c[d])},ib=function(a){"undefined"==typeof a?(E(Q),R=null):"string"==typeof a&&w.call(Q,a)&&delete Q[a]},jb=function(a){return"undefined"==typeof a?B(Q):"string"==typeof a&&w.call(Q,a)?Q[a]:void 0},kb=function(a){if(a&&1===a.nodeType){d&&(Lb(d,Z.activeClass),d!==a&&Lb(d,Z.hoverClass)),d=a,Kb(a,Z.hoverClass);var b=a.getAttribute("title")||Z.title;if("string"==typeof b&&b){var c=Ab(N.bridge);c&&c.setAttribute("title",b)}var e=Z.forceHandCursor===!0||"pointer"===Mb(a,"cursor");Rb(e),Qb()}},lb=function(){var a=Ab(N.bridge);a&&(a.removeAttribute("title"),a.style.left="0px",a.style.top="-9999px",a.style.width="1px",a.style.height="1px"),d&&(Lb(d,Z.hoverClass),Lb(d,Z.activeClass),d=null)},mb=function(){return d||null},nb=function(a){return"string"==typeof a&&a&&/^[A-Za-z][A-Za-z0-9_:\-\.]*$/.test(a)},ob=function(a){var b;if("string"==typeof a&&a?(b=a,a={}):"object"==typeof a&&a&&"string"==typeof a.type&&a.type&&(b=a.type),b){b=b.toLowerCase(),!a.target&&(/^(copy|aftercopy|_click)$/.test(b)||"error"===b&&"clipboard-error"===a.name)&&(a.target=e),A(a,{type:b,target:a.target||d||null,relatedTarget:a.relatedTarget||null,currentTarget:N&&N.bridge||null,timeStamp:a.timeStamp||t()||null});var c=U[a.type];return"error"===a.type&&a.name&&c&&(c=c[a.name]),c&&(a.message=c),"ready"===a.type&&A(a,{target:null,version:N.version}),"error"===a.type&&(X.test(a.name)&&A(a,{target:null,minimumVersion:O}),Y.test(a.name)&&A(a,{version:N.version})),"copy"===a.type&&(a.clipboardData={setData:Vb.setData,clearData:Vb.clearData}),"aftercopy"===a.type&&(a=Eb(a,R)),a.target&&!a.relatedTarget&&(a.relatedTarget=pb(a.target)),qb(a)}},pb=function(a){var b=a&&a.getAttribute&&a.getAttribute("data-clipboard-target");return b?g.getElementById(b):null},qb=function(a){if(a&&/^_(?:click|mouse(?:over|out|down|up|move))$/.test(a.type)){var c=a.target,d="_mouseover"===a.type&&a.relatedTarget?a.relatedTarget:b,e="_mouseout"===a.type&&a.relatedTarget?a.relatedTarget:b,h=Nb(c),i=f.screenLeft||f.screenX||0,j=f.screenTop||f.screenY||0,k=g.body.scrollLeft+g.documentElement.scrollLeft,l=g.body.scrollTop+g.documentElement.scrollTop,m=h.left+("number"==typeof a._stageX?a._stageX:0),n=h.top+("number"==typeof a._stageY?a._stageY:0),o=m-k,p=n-l,q=i+o,r=j+p,s="number"==typeof a.movementX?a.movementX:0,t="number"==typeof a.movementY?a.movementY:0;delete a._stageX,delete a._stageY,A(a,{srcElement:c,fromElement:d,toElement:e,screenX:q,screenY:r,pageX:m,pageY:n,clientX:o,clientY:p,x:o,y:p,movementX:s,movementY:t,offsetX:0,offsetY:0,layerX:0,layerY:0})}return a},rb=function(a){var b=a&&"string"==typeof a.type&&a.type||"";return!/^(?:(?:before)?copy|destroy)$/.test(b)},sb=function(a,b,c,d){d?i(function(){a.apply(b,c)},0):a.apply(b,c)},tb=function(a){if("object"==typeof a&&a&&a.type){var b=rb(a),c=P["*"]||[],d=P[a.type]||[],e=c.concat(d);if(e&&e.length){var g,h,i,j,k,l=this;for(g=0,h=e.length;h>g;g++)i=e[g],j=l,"string"==typeof i&&"function"==typeof f[i]&&(i=f[i]),"object"==typeof i&&i&&"function"==typeof i.handleEvent&&(j=i,i=i.handleEvent),"function"==typeof i&&(k=A({},a),sb(i,j,[k],b))}return this}},ub=function(a){var b=null;return(M===!1||a&&"error"===a.type&&a.name&&-1!==V.indexOf(a.name))&&(b=!1),b},vb=function(a){var b=a.target||d||null,f="swf"===a._source;switch(delete a._source,a.type){case"error":var g="flash-sandboxed"===a.name||ub(a);"boolean"==typeof g&&(N.sandboxed=g),-1!==W.indexOf(a.name)?A(N,{disabled:"flash-disabled"===a.name,outdated:"flash-outdated"===a.name,unavailable:"flash-unavailable"===a.name,degraded:"flash-degraded"===a.name,deactivated:"flash-deactivated"===a.name,overdue:"flash-overdue"===a.name,ready:!1}):"version-mismatch"===a.name&&(c=a.swfVersion,A(N,{disabled:!1,outdated:!1,unavailable:!1,degraded:!1,deactivated:!1,overdue:!1,ready:!1})),Pb();break;case"ready":c=a.swfVersion;var h=N.deactivated===!0;A(N,{disabled:!1,outdated:!1,sandboxed:!1,unavailable:!1,degraded:!1,deactivated:!1,overdue:h,ready:!h}),Pb();break;case"beforecopy":e=b;break;case"copy":var i,j,k=a.relatedTarget;!Q["text/html"]&&!Q["text/plain"]&&k&&(j=k.value||k.outerHTML||k.innerHTML)&&(i=k.value||k.textContent||k.innerText)?(a.clipboardData.clearData(),a.clipboardData.setData("text/plain",i),j!==i&&a.clipboardData.setData("text/html",j)):!Q["text/plain"]&&a.target&&(i=a.target.getAttribute("data-clipboard-text"))&&(a.clipboardData.clearData(),a.clipboardData.setData("text/plain",i));break;case"aftercopy":wb(a),Vb.clearData(),b&&b!==Jb()&&b.focus&&b.focus();break;case"_mouseover":Vb.focus(b),Z.bubbleEvents===!0&&f&&(b&&b!==a.relatedTarget&&!F(a.relatedTarget,b)&&xb(A({},a,{type:"mouseenter",bubbles:!1,cancelable:!1})),xb(A({},a,{type:"mouseover"})));break;case"_mouseout":Vb.blur(),Z.bubbleEvents===!0&&f&&(b&&b!==a.relatedTarget&&!F(a.relatedTarget,b)&&xb(A({},a,{type:"mouseleave",bubbles:!1,cancelable:!1})),xb(A({},a,{type:"mouseout"})));break;case"_mousedown":Kb(b,Z.activeClass),Z.bubbleEvents===!0&&f&&xb(A({},a,{type:a.type.slice(1)}));break;case"_mouseup":Lb(b,Z.activeClass),Z.bubbleEvents===!0&&f&&xb(A({},a,{type:a.type.slice(1)}));break;case"_click":e=null,Z.bubbleEvents===!0&&f&&xb(A({},a,{type:a.type.slice(1)}));break;case"_mousemove":Z.bubbleEvents===!0&&f&&xb(A({},a,{type:a.type.slice(1)}))}return/^_(?:click|mouse(?:over|out|down|up|move))$/.test(a.type)?!0:void 0},wb=function(a){if(a.errors&&a.errors.length>0){var b=B(a);A(b,{type:"error",name:"clipboard-error"}),delete b.success,i(function(){Vb.emit(b)},0)}},xb=function(a){if(a&&"string"==typeof a.type&&a){var b,c=a.target||null,d=c&&c.ownerDocument||g,e={view:d.defaultView||f,canBubble:!0,cancelable:!0,detail:"click"===a.type?1:0,button:"number"==typeof a.which?a.which-1:"number"==typeof a.button?a.button:d.createEvent?0:1},h=A(e,a);c&&d.createEvent&&c.dispatchEvent&&(h=[h.type,h.canBubble,h.cancelable,h.view,h.detail,h.screenX,h.screenY,h.clientX,h.clientY,h.ctrlKey,h.altKey,h.shiftKey,h.metaKey,h.button,h.relatedTarget],b=d.createEvent("MouseEvents"),b.initMouseEvent&&(b.initMouseEvent.apply(b,h),b._source="js",c.dispatchEvent(b)))}},yb=function(){var a=Z.flashLoadTimeout;if("number"==typeof a&&a>=0){var b=Math.min(1e3,a/10),c=Z.swfObjectId+"_fallbackContent";T=k(function(){var a=g.getElementById(c);Ob(a)&&(Pb(),N.deactivated=null,Vb.emit({type:"error",name:"swf-not-found"}))},b)}},zb=function(){var a=g.createElement("div");return a.id=Z.containerId,a.className=Z.containerClass,a.style.position="absolute",a.style.left="0px",a.style.top="-9999px",a.style.width="1px",a.style.height="1px",a.style.zIndex=""+Sb(Z.zIndex),a},Ab=function(a){for(var b=a&&a.parentNode;b&&"OBJECT"===b.nodeName&&b.parentNode;)b=b.parentNode;return b||null},Bb=function(){var a,b=N.bridge,c=Ab(b);if(!b){var d=Ib(f.location.host,Z),e="never"===d?"none":"all",h=Gb(A({jsVersion:Vb.version},Z)),i=Z.swfPath+Fb(Z.swfPath,Z);c=zb();var j=g.createElement("div");c.appendChild(j),g.body.appendChild(c);var k=g.createElement("div"),l="activex"===N.pluginType;k.innerHTML='"+(l?'':"")+'
 
',b=k.firstChild,k=null,y(b).ZeroClipboard=Vb,c.replaceChild(b,j),yb()}return b||(b=g[Z.swfObjectId],b&&(a=b.length)&&(b=b[a-1]),!b&&c&&(b=c.firstChild)),N.bridge=b||null,b},Cb=function(){var a=N.bridge;if(a){var d=Ab(a);d&&("activex"===N.pluginType&&"readyState"in a?(a.style.display="none",function e(){if(4===a.readyState){for(var b in a)"function"==typeof a[b]&&(a[b]=null);a.parentNode&&a.parentNode.removeChild(a),d.parentNode&&d.parentNode.removeChild(d)}else i(e,10)}()):(a.parentNode&&a.parentNode.removeChild(a),d.parentNode&&d.parentNode.removeChild(d))),Pb(),N.ready=null,N.bridge=null,N.deactivated=null,c=b}},Db=function(a){var b={},c={};if("object"==typeof a&&a){for(var d in a)if(d&&w.call(a,d)&&"string"==typeof a[d]&&a[d])switch(d.toLowerCase()){case"text/plain":case"text":case"air:text":case"flash:text":b.text=a[d],c.text=d;break;case"text/html":case"html":case"air:html":case"flash:html":b.html=a[d],c.html=d;break;case"application/rtf":case"text/rtf":case"rtf":case"richtext":case"air:rtf":case"flash:rtf":b.rtf=a[d],c.rtf=d}return{data:b,formatMap:c}}},Eb=function(a,b){if("object"!=typeof a||!a||"object"!=typeof b||!b)return a;var c={};for(var d in a)if(w.call(a,d))if("errors"===d){c[d]=a[d]?a[d].slice():[];for(var e=0,f=c[d].length;f>e;e++)c[d][e].format=b[c[d][e].format]}else if("success"!==d&&"data"!==d)c[d]=a[d];else{c[d]={};var g=a[d];for(var h in g)h&&w.call(g,h)&&w.call(b,h)&&(c[d][b[h]]=g[h])}return c},Fb=function(a,b){var c=null==b||b&&b.cacheBust===!0;return c?(-1===a.indexOf("?")?"?":"&")+"noCache="+t():""},Gb=function(a){var b,c,d,e,g="",h=[];if(a.trustedDomains&&("string"==typeof a.trustedDomains?e=[a.trustedDomains]:"object"==typeof a.trustedDomains&&"length"in a.trustedDomains&&(e=a.trustedDomains)),e&&e.length)for(b=0,c=e.length;c>b;b++)if(w.call(e,b)&&e[b]&&"string"==typeof e[b]){if(d=Hb(e[b]),!d)continue;if("*"===d){h.length=0,h.push(d);break}h.push.apply(h,[d,"//"+d,f.location.protocol+"//"+d])}return h.length&&(g+="trustedOrigins="+n(h.join(","))),a.forceEnhancedClipboard===!0&&(g+=(g?"&":"")+"forceEnhancedClipboard=true"),"string"==typeof a.swfObjectId&&a.swfObjectId&&(g+=(g?"&":"")+"swfObjectId="+n(a.swfObjectId)),"string"==typeof a.jsVersion&&a.jsVersion&&(g+=(g?"&":"")+"jsVersion="+n(a.jsVersion)),g},Hb=function(a){if(null==a||""===a)return null;if(a=a.replace(/^\s+|\s+$/g,""),""===a)return null;var b=a.indexOf("//");a=-1===b?a:a.slice(b+2);var c=a.indexOf("/");return a=-1===c?a:-1===b||0===c?null:a.slice(0,c),a&&".swf"===a.slice(-4).toLowerCase()?null:a||null},Ib=function(){var a=function(a){var b,c,d,e=[];if("string"==typeof a&&(a=[a]),"object"!=typeof a||!a||"number"!=typeof a.length)return e;for(b=0,c=a.length;c>b;b++)if(w.call(a,b)&&(d=Hb(a[b]))){if("*"===d){e.length=0,e.push("*");break}-1===e.indexOf(d)&&e.push(d)}return e};return function(b,c){var d=Hb(c.swfPath);null===d&&(d=b);var e=a(c.trustedDomains),f=e.length;if(f>0){if(1===f&&"*"===e[0])return"always";if(-1!==e.indexOf(b))return 1===f&&b===d?"sameDomain":"always"}return"never"}}(),Jb=function(){try{return g.activeElement}catch(a){return null}},Kb=function(a,b){var c,d,e,f=[];if("string"==typeof b&&b&&(f=b.split(/\s+/)),a&&1===a.nodeType&&f.length>0)if(a.classList)for(c=0,d=f.length;d>c;c++)a.classList.add(f[c]);else if(a.hasOwnProperty("className")){for(e=" "+a.className+" ",c=0,d=f.length;d>c;c++)-1===e.indexOf(" "+f[c]+" ")&&(e+=f[c]+" ");a.className=e.replace(/^\s+|\s+$/g,"")}return a},Lb=function(a,b){var c,d,e,f=[];if("string"==typeof b&&b&&(f=b.split(/\s+/)),a&&1===a.nodeType&&f.length>0)if(a.classList&&a.classList.length>0)for(c=0,d=f.length;d>c;c++)a.classList.remove(f[c]);else if(a.className){for(e=(" "+a.className+" ").replace(/[\r\n\t]/g," "),c=0,d=f.length;d>c;c++)e=e.replace(" "+f[c]+" "," ");a.className=e.replace(/^\s+|\s+$/g,"")}return a},Mb=function(a,b){var c=m(a,null).getPropertyValue(b);return"cursor"!==b||c&&"auto"!==c||"A"!==a.nodeName?c:"pointer"},Nb=function(a){var b={left:0,top:0,width:0,height:0};if(a.getBoundingClientRect){var c=a.getBoundingClientRect(),d=f.pageXOffset,e=f.pageYOffset,h=g.documentElement.clientLeft||0,i=g.documentElement.clientTop||0,j=0,k=0;if("relative"===Mb(g.body,"position")){var l=g.body.getBoundingClientRect(),m=g.documentElement.getBoundingClientRect();j=l.left-m.left||0,k=l.top-m.top||0}b.left=c.left+d-h-j,b.top=c.top+e-i-k,b.width="width"in c?c.width:c.right-c.left,b.height="height"in c?c.height:c.bottom-c.top}return b},Ob=function(a){if(!a)return!1;var b=m(a,null),c=r(b.height)>0,d=r(b.width)>0,e=r(b.top)>=0,f=r(b.left)>=0,g=c&&d&&e&&f,h=g?null:Nb(a),i="none"!==b.display&&"collapse"!==b.visibility&&(g||!!h&&(c||h.height>0)&&(d||h.width>0)&&(e||h.top>=0)&&(f||h.left>=0));return i},Pb=function(){j(S),S=0,l(T),T=0},Qb=function(){var a;if(d&&(a=Ab(N.bridge))){var b=Nb(d);A(a.style,{width:b.width+"px",height:b.height+"px",top:b.top+"px",left:b.left+"px",zIndex:""+Sb(Z.zIndex)})}},Rb=function(a){N.ready===!0&&(N.bridge&&"function"==typeof N.bridge.setHandCursor?N.bridge.setHandCursor(a):N.ready=!1)},Sb=function(a){if(/^(?:auto|inherit)$/.test(a))return a;var b;return"number"!=typeof a||s(a)?"string"==typeof a&&(b=Sb(q(a,10))):b=a,"number"==typeof b?b:"auto"},Tb=function(b){var c,d,e,f=N.sandboxed,g=null;if(b=b===!0,M===!1)g=!1;else{try{d=a.frameElement||null}catch(h){e={name:h.name,message:h.message}}if(d&&1===d.nodeType&&"IFRAME"===d.nodeName)try{g=d.hasAttribute("sandbox")}catch(h){g=null}else{try{c=document.domain||null}catch(h){c=null}(null===c||e&&"SecurityError"===e.name&&/(^|[\s\(\[@])sandbox(es|ed|ing|[\s\.,!\)\]@]|$)/.test(e.message.toLowerCase()))&&(g=!0)}}return N.sandboxed=g,f===g||b||Ub(o),g},Ub=function(a){function b(a){var b=a.match(/[\d]+/g);return b.length=3,b.join(".")}function c(a){return!!a&&(a=a.toLowerCase())&&(/^(pepflashplayer\.dll|libpepflashplayer\.so|pepperflashplayer\.plugin)$/.test(a)||"chrome.plugin"===a.slice(-13))}function d(a){a&&(i=!0,a.version&&(l=b(a.version)),!l&&a.description&&(l=b(a.description)),a.filename&&(k=c(a.filename)))}var e,f,g,i=!1,j=!1,k=!1,l="";if(h.plugins&&h.plugins.length)e=h.plugins["Shockwave Flash"],d(e),h.plugins["Shockwave Flash 2.0"]&&(i=!0,l="2.0.0.11");else if(h.mimeTypes&&h.mimeTypes.length)g=h.mimeTypes["application/x-shockwave-flash"],e=g&&g.enabledPlugin,d(e);else if("undefined"!=typeof a){j=!0;try{f=new a("ShockwaveFlash.ShockwaveFlash.7"),i=!0,l=b(f.GetVariable("$version"))}catch(m){try{f=new a("ShockwaveFlash.ShockwaveFlash.6"),i=!0,l="6.0.21"}catch(n){try{f=new a("ShockwaveFlash.ShockwaveFlash"),i=!0,l=b(f.GetVariable("$version"))}catch(o){j=!1}}}}N.disabled=i!==!0,N.outdated=l&&r(l)= 0) {\n _flashCheckTimeout = _setTimeout(function() {\n if (typeof _flashState.deactivated !== \"boolean\") {\n _flashState.deactivated = true;\n }\n if (_flashState.deactivated === true) {\n ZeroClipboard.emit({\n type: \"error\",\n name: \"flash-deactivated\"\n });\n }\n }, maxWait);\n }\n _flashState.overdue = false;\n _embedSwf();\n }\n };\n /**\n * The underlying implementation of `ZeroClipboard.destroy`.\n * @private\n */\n var _destroy = function() {\n ZeroClipboard.clearData();\n ZeroClipboard.blur();\n ZeroClipboard.emit(\"destroy\");\n _unembedSwf();\n ZeroClipboard.off();\n };\n /**\n * The underlying implementation of `ZeroClipboard.setData`.\n * @private\n */\n var _setData = function(format, data) {\n var dataObj;\n if (typeof format === \"object\" && format && typeof data === \"undefined\") {\n dataObj = format;\n ZeroClipboard.clearData();\n } else if (typeof format === \"string\" && format) {\n dataObj = {};\n dataObj[format] = data;\n } else {\n return;\n }\n for (var dataFormat in dataObj) {\n if (typeof dataFormat === \"string\" && dataFormat && _hasOwn.call(dataObj, dataFormat) && typeof dataObj[dataFormat] === \"string\" && dataObj[dataFormat]) {\n _clipData[dataFormat] = dataObj[dataFormat];\n }\n }\n };\n /**\n * The underlying implementation of `ZeroClipboard.clearData`.\n * @private\n */\n var _clearData = function(format) {\n if (typeof format === \"undefined\") {\n _deleteOwnProperties(_clipData);\n _clipDataFormatMap = null;\n } else if (typeof format === \"string\" && _hasOwn.call(_clipData, format)) {\n delete _clipData[format];\n }\n };\n /**\n * The underlying implementation of `ZeroClipboard.getData`.\n * @private\n */\n var _getData = function(format) {\n if (typeof format === \"undefined\") {\n return _deepCopy(_clipData);\n } else if (typeof format === \"string\" && _hasOwn.call(_clipData, format)) {\n return _clipData[format];\n }\n };\n /**\n * The underlying implementation of `ZeroClipboard.focus`/`ZeroClipboard.activate`.\n * @private\n */\n var _focus = function(element) {\n if (!(element && element.nodeType === 1)) {\n return;\n }\n if (_currentElement) {\n _removeClass(_currentElement, _globalConfig.activeClass);\n if (_currentElement !== element) {\n _removeClass(_currentElement, _globalConfig.hoverClass);\n }\n }\n _currentElement = element;\n _addClass(element, _globalConfig.hoverClass);\n var newTitle = element.getAttribute(\"title\") || _globalConfig.title;\n if (typeof newTitle === \"string\" && newTitle) {\n var htmlBridge = _getHtmlBridge(_flashState.bridge);\n if (htmlBridge) {\n htmlBridge.setAttribute(\"title\", newTitle);\n }\n }\n var useHandCursor = _globalConfig.forceHandCursor === true || _getStyle(element, \"cursor\") === \"pointer\";\n _setHandCursor(useHandCursor);\n _reposition();\n };\n /**\n * The underlying implementation of `ZeroClipboard.blur`/`ZeroClipboard.deactivate`.\n * @private\n */\n var _blur = function() {\n var htmlBridge = _getHtmlBridge(_flashState.bridge);\n if (htmlBridge) {\n htmlBridge.removeAttribute(\"title\");\n htmlBridge.style.left = \"0px\";\n htmlBridge.style.top = \"-9999px\";\n htmlBridge.style.width = \"1px\";\n htmlBridge.style.height = \"1px\";\n }\n if (_currentElement) {\n _removeClass(_currentElement, _globalConfig.hoverClass);\n _removeClass(_currentElement, _globalConfig.activeClass);\n _currentElement = null;\n }\n };\n /**\n * The underlying implementation of `ZeroClipboard.activeElement`.\n * @private\n */\n var _activeElement = function() {\n return _currentElement || null;\n };\n /**\n * Check if a value is a valid HTML4 `ID` or `Name` token.\n * @private\n */\n var _isValidHtml4Id = function(id) {\n return typeof id === \"string\" && id && /^[A-Za-z][A-Za-z0-9_:\\-\\.]*$/.test(id);\n };\n /**\n * Create or update an `event` object, based on the `eventType`.\n * @private\n */\n var _createEvent = function(event) {\n var eventType;\n if (typeof event === \"string\" && event) {\n eventType = event;\n event = {};\n } else if (typeof event === \"object\" && event && typeof event.type === \"string\" && event.type) {\n eventType = event.type;\n }\n if (!eventType) {\n return;\n }\n eventType = eventType.toLowerCase();\n if (!event.target && (/^(copy|aftercopy|_click)$/.test(eventType) || eventType === \"error\" && event.name === \"clipboard-error\")) {\n event.target = _copyTarget;\n }\n _extend(event, {\n type: eventType,\n target: event.target || _currentElement || null,\n relatedTarget: event.relatedTarget || null,\n currentTarget: _flashState && _flashState.bridge || null,\n timeStamp: event.timeStamp || _now() || null\n });\n var msg = _eventMessages[event.type];\n if (event.type === \"error\" && event.name && msg) {\n msg = msg[event.name];\n }\n if (msg) {\n event.message = msg;\n }\n if (event.type === \"ready\") {\n _extend(event, {\n target: null,\n version: _flashState.version\n });\n }\n if (event.type === \"error\") {\n if (_flashStateErrorNameMatchingRegex.test(event.name)) {\n _extend(event, {\n target: null,\n minimumVersion: _minimumFlashVersion\n });\n }\n if (_flashStateEnabledErrorNameMatchingRegex.test(event.name)) {\n _extend(event, {\n version: _flashState.version\n });\n }\n }\n if (event.type === \"copy\") {\n event.clipboardData = {\n setData: ZeroClipboard.setData,\n clearData: ZeroClipboard.clearData\n };\n }\n if (event.type === \"aftercopy\") {\n event = _mapClipResultsFromFlash(event, _clipDataFormatMap);\n }\n if (event.target && !event.relatedTarget) {\n event.relatedTarget = _getRelatedTarget(event.target);\n }\n return _addMouseData(event);\n };\n /**\n * Get a relatedTarget from the target's `data-clipboard-target` attribute\n * @private\n */\n var _getRelatedTarget = function(targetEl) {\n var relatedTargetId = targetEl && targetEl.getAttribute && targetEl.getAttribute(\"data-clipboard-target\");\n return relatedTargetId ? _document.getElementById(relatedTargetId) : null;\n };\n /**\n * Add element and position data to `MouseEvent` instances\n * @private\n */\n var _addMouseData = function(event) {\n if (event && /^_(?:click|mouse(?:over|out|down|up|move))$/.test(event.type)) {\n var srcElement = event.target;\n var fromElement = event.type === \"_mouseover\" && event.relatedTarget ? event.relatedTarget : undefined;\n var toElement = event.type === \"_mouseout\" && event.relatedTarget ? event.relatedTarget : undefined;\n var pos = _getElementPosition(srcElement);\n var screenLeft = _window.screenLeft || _window.screenX || 0;\n var screenTop = _window.screenTop || _window.screenY || 0;\n var scrollLeft = _document.body.scrollLeft + _document.documentElement.scrollLeft;\n var scrollTop = _document.body.scrollTop + _document.documentElement.scrollTop;\n var pageX = pos.left + (typeof event._stageX === \"number\" ? event._stageX : 0);\n var pageY = pos.top + (typeof event._stageY === \"number\" ? event._stageY : 0);\n var clientX = pageX - scrollLeft;\n var clientY = pageY - scrollTop;\n var screenX = screenLeft + clientX;\n var screenY = screenTop + clientY;\n var moveX = typeof event.movementX === \"number\" ? event.movementX : 0;\n var moveY = typeof event.movementY === \"number\" ? event.movementY : 0;\n delete event._stageX;\n delete event._stageY;\n _extend(event, {\n srcElement: srcElement,\n fromElement: fromElement,\n toElement: toElement,\n screenX: screenX,\n screenY: screenY,\n pageX: pageX,\n pageY: pageY,\n clientX: clientX,\n clientY: clientY,\n x: clientX,\n y: clientY,\n movementX: moveX,\n movementY: moveY,\n offsetX: 0,\n offsetY: 0,\n layerX: 0,\n layerY: 0\n });\n }\n return event;\n };\n /**\n * Determine if an event's registered handlers should be execute synchronously or asynchronously.\n *\n * @returns {boolean}\n * @private\n */\n var _shouldPerformAsync = function(event) {\n var eventType = event && typeof event.type === \"string\" && event.type || \"\";\n return !/^(?:(?:before)?copy|destroy)$/.test(eventType);\n };\n /**\n * Control if a callback should be executed asynchronously or not.\n *\n * @returns `undefined`\n * @private\n */\n var _dispatchCallback = function(func, context, args, async) {\n if (async) {\n _setTimeout(function() {\n func.apply(context, args);\n }, 0);\n } else {\n func.apply(context, args);\n }\n };\n /**\n * Handle the actual dispatching of events to client instances.\n *\n * @returns `undefined`\n * @private\n */\n var _dispatchCallbacks = function(event) {\n if (!(typeof event === \"object\" && event && event.type)) {\n return;\n }\n var async = _shouldPerformAsync(event);\n var wildcardTypeHandlers = _handlers[\"*\"] || [];\n var specificTypeHandlers = _handlers[event.type] || [];\n var handlers = wildcardTypeHandlers.concat(specificTypeHandlers);\n if (handlers && handlers.length) {\n var i, len, func, context, eventCopy, originalContext = this;\n for (i = 0, len = handlers.length; i < len; i++) {\n func = handlers[i];\n context = originalContext;\n if (typeof func === \"string\" && typeof _window[func] === \"function\") {\n func = _window[func];\n }\n if (typeof func === \"object\" && func && typeof func.handleEvent === \"function\") {\n context = func;\n func = func.handleEvent;\n }\n if (typeof func === \"function\") {\n eventCopy = _extend({}, event);\n _dispatchCallback(func, context, [ eventCopy ], async);\n }\n }\n }\n return this;\n };\n /**\n * Check an `error` event's `name` property to see if Flash has\n * already loaded, which rules out possible `iframe` sandboxing.\n * @private\n */\n var _getSandboxStatusFromErrorEvent = function(event) {\n var isSandboxed = null;\n if (_pageIsFramed === false || event && event.type === \"error\" && event.name && _errorsThatOnlyOccurAfterFlashLoads.indexOf(event.name) !== -1) {\n isSandboxed = false;\n }\n return isSandboxed;\n };\n /**\n * Preprocess any special behaviors, reactions, or state changes after receiving this event.\n * Executes only once per event emitted, NOT once per client.\n * @private\n */\n var _preprocessEvent = function(event) {\n var element = event.target || _currentElement || null;\n var sourceIsSwf = event._source === \"swf\";\n delete event._source;\n switch (event.type) {\n case \"error\":\n var isSandboxed = event.name === \"flash-sandboxed\" || _getSandboxStatusFromErrorEvent(event);\n if (typeof isSandboxed === \"boolean\") {\n _flashState.sandboxed = isSandboxed;\n }\n if (_flashStateErrorNames.indexOf(event.name) !== -1) {\n _extend(_flashState, {\n disabled: event.name === \"flash-disabled\",\n outdated: event.name === \"flash-outdated\",\n unavailable: event.name === \"flash-unavailable\",\n degraded: event.name === \"flash-degraded\",\n deactivated: event.name === \"flash-deactivated\",\n overdue: event.name === \"flash-overdue\",\n ready: false\n });\n } else if (event.name === \"version-mismatch\") {\n _zcSwfVersion = event.swfVersion;\n _extend(_flashState, {\n disabled: false,\n outdated: false,\n unavailable: false,\n degraded: false,\n deactivated: false,\n overdue: false,\n ready: false\n });\n }\n _clearTimeoutsAndPolling();\n break;\n\n case \"ready\":\n _zcSwfVersion = event.swfVersion;\n var wasDeactivated = _flashState.deactivated === true;\n _extend(_flashState, {\n disabled: false,\n outdated: false,\n sandboxed: false,\n unavailable: false,\n degraded: false,\n deactivated: false,\n overdue: wasDeactivated,\n ready: !wasDeactivated\n });\n _clearTimeoutsAndPolling();\n break;\n\n case \"beforecopy\":\n _copyTarget = element;\n break;\n\n case \"copy\":\n var textContent, htmlContent, targetEl = event.relatedTarget;\n if (!(_clipData[\"text/html\"] || _clipData[\"text/plain\"]) && targetEl && (htmlContent = targetEl.value || targetEl.outerHTML || targetEl.innerHTML) && (textContent = targetEl.value || targetEl.textContent || targetEl.innerText)) {\n event.clipboardData.clearData();\n event.clipboardData.setData(\"text/plain\", textContent);\n if (htmlContent !== textContent) {\n event.clipboardData.setData(\"text/html\", htmlContent);\n }\n } else if (!_clipData[\"text/plain\"] && event.target && (textContent = event.target.getAttribute(\"data-clipboard-text\"))) {\n event.clipboardData.clearData();\n event.clipboardData.setData(\"text/plain\", textContent);\n }\n break;\n\n case \"aftercopy\":\n _queueEmitClipboardErrors(event);\n ZeroClipboard.clearData();\n if (element && element !== _safeActiveElement() && element.focus) {\n element.focus();\n }\n break;\n\n case \"_mouseover\":\n ZeroClipboard.focus(element);\n if (_globalConfig.bubbleEvents === true && sourceIsSwf) {\n if (element && element !== event.relatedTarget && !_containedBy(event.relatedTarget, element)) {\n _fireMouseEvent(_extend({}, event, {\n type: \"mouseenter\",\n bubbles: false,\n cancelable: false\n }));\n }\n _fireMouseEvent(_extend({}, event, {\n type: \"mouseover\"\n }));\n }\n break;\n\n case \"_mouseout\":\n ZeroClipboard.blur();\n if (_globalConfig.bubbleEvents === true && sourceIsSwf) {\n if (element && element !== event.relatedTarget && !_containedBy(event.relatedTarget, element)) {\n _fireMouseEvent(_extend({}, event, {\n type: \"mouseleave\",\n bubbles: false,\n cancelable: false\n }));\n }\n _fireMouseEvent(_extend({}, event, {\n type: \"mouseout\"\n }));\n }\n break;\n\n case \"_mousedown\":\n _addClass(element, _globalConfig.activeClass);\n if (_globalConfig.bubbleEvents === true && sourceIsSwf) {\n _fireMouseEvent(_extend({}, event, {\n type: event.type.slice(1)\n }));\n }\n break;\n\n case \"_mouseup\":\n _removeClass(element, _globalConfig.activeClass);\n if (_globalConfig.bubbleEvents === true && sourceIsSwf) {\n _fireMouseEvent(_extend({}, event, {\n type: event.type.slice(1)\n }));\n }\n break;\n\n case \"_click\":\n _copyTarget = null;\n if (_globalConfig.bubbleEvents === true && sourceIsSwf) {\n _fireMouseEvent(_extend({}, event, {\n type: event.type.slice(1)\n }));\n }\n break;\n\n case \"_mousemove\":\n if (_globalConfig.bubbleEvents === true && sourceIsSwf) {\n _fireMouseEvent(_extend({}, event, {\n type: event.type.slice(1)\n }));\n }\n break;\n }\n if (/^_(?:click|mouse(?:over|out|down|up|move))$/.test(event.type)) {\n return true;\n }\n };\n /**\n * Check an \"aftercopy\" event for clipboard errors and emit a corresponding \"error\" event.\n * @private\n */\n var _queueEmitClipboardErrors = function(aftercopyEvent) {\n if (aftercopyEvent.errors && aftercopyEvent.errors.length > 0) {\n var errorEvent = _deepCopy(aftercopyEvent);\n _extend(errorEvent, {\n type: \"error\",\n name: \"clipboard-error\"\n });\n delete errorEvent.success;\n _setTimeout(function() {\n ZeroClipboard.emit(errorEvent);\n }, 0);\n }\n };\n /**\n * Dispatch a synthetic MouseEvent.\n *\n * @returns `undefined`\n * @private\n */\n var _fireMouseEvent = function(event) {\n if (!(event && typeof event.type === \"string\" && event)) {\n return;\n }\n var e, target = event.target || null, doc = target && target.ownerDocument || _document, defaults = {\n view: doc.defaultView || _window,\n canBubble: true,\n cancelable: true,\n detail: event.type === \"click\" ? 1 : 0,\n button: typeof event.which === \"number\" ? event.which - 1 : typeof event.button === \"number\" ? event.button : doc.createEvent ? 0 : 1\n }, args = _extend(defaults, event);\n if (!target) {\n return;\n }\n if (doc.createEvent && target.dispatchEvent) {\n 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 ];\n e = doc.createEvent(\"MouseEvents\");\n if (e.initMouseEvent) {\n e.initMouseEvent.apply(e, args);\n e._source = \"js\";\n target.dispatchEvent(e);\n }\n }\n };\n /**\n * Continuously poll the DOM until either:\n * (a) the fallback content becomes visible, or\n * (b) we receive an event from SWF (handled elsewhere)\n *\n * IMPORTANT:\n * This is NOT a necessary check but it can result in significantly faster\n * detection of bad `swfPath` configuration and/or network/server issues [in\n * supported browsers] than waiting for the entire `flashLoadTimeout` duration\n * to elapse before detecting that the SWF cannot be loaded. The detection\n * duration can be anywhere from 10-30 times faster [in supported browsers] by\n * using this approach.\n *\n * @returns `undefined`\n * @private\n */\n var _watchForSwfFallbackContent = function() {\n var maxWait = _globalConfig.flashLoadTimeout;\n if (typeof maxWait === \"number\" && maxWait >= 0) {\n var pollWait = Math.min(1e3, maxWait / 10);\n var fallbackContentId = _globalConfig.swfObjectId + \"_fallbackContent\";\n _swfFallbackCheckInterval = _setInterval(function() {\n var el = _document.getElementById(fallbackContentId);\n if (_isElementVisible(el)) {\n _clearTimeoutsAndPolling();\n _flashState.deactivated = null;\n ZeroClipboard.emit({\n type: \"error\",\n name: \"swf-not-found\"\n });\n }\n }, pollWait);\n }\n };\n /**\n * Create the HTML bridge element to embed the Flash object into.\n * @private\n */\n var _createHtmlBridge = function() {\n var container = _document.createElement(\"div\");\n container.id = _globalConfig.containerId;\n container.className = _globalConfig.containerClass;\n container.style.position = \"absolute\";\n container.style.left = \"0px\";\n container.style.top = \"-9999px\";\n container.style.width = \"1px\";\n container.style.height = \"1px\";\n container.style.zIndex = \"\" + _getSafeZIndex(_globalConfig.zIndex);\n return container;\n };\n /**\n * Get the HTML element container that wraps the Flash bridge object/element.\n * @private\n */\n var _getHtmlBridge = function(flashBridge) {\n var htmlBridge = flashBridge && flashBridge.parentNode;\n while (htmlBridge && htmlBridge.nodeName === \"OBJECT\" && htmlBridge.parentNode) {\n htmlBridge = htmlBridge.parentNode;\n }\n return htmlBridge || null;\n };\n /**\n * Create the SWF object.\n *\n * @returns The SWF object reference.\n * @private\n */\n var _embedSwf = function() {\n var len, flashBridge = _flashState.bridge, container = _getHtmlBridge(flashBridge);\n if (!flashBridge) {\n var allowScriptAccess = _determineScriptAccess(_window.location.host, _globalConfig);\n var allowNetworking = allowScriptAccess === \"never\" ? \"none\" : \"all\";\n var flashvars = _vars(_extend({\n jsVersion: ZeroClipboard.version\n }, _globalConfig));\n var swfUrl = _globalConfig.swfPath + _cacheBust(_globalConfig.swfPath, _globalConfig);\n container = _createHtmlBridge();\n var divToBeReplaced = _document.createElement(\"div\");\n container.appendChild(divToBeReplaced);\n _document.body.appendChild(container);\n var tmpDiv = _document.createElement(\"div\");\n var usingActiveX = _flashState.pluginType === \"activex\";\n tmpDiv.innerHTML = '\" + (usingActiveX ? '' : \"\") + '' + '' + '' + '' + '' + '
 
' + \"
\";\n flashBridge = tmpDiv.firstChild;\n tmpDiv = null;\n _unwrap(flashBridge).ZeroClipboard = ZeroClipboard;\n container.replaceChild(flashBridge, divToBeReplaced);\n _watchForSwfFallbackContent();\n }\n if (!flashBridge) {\n flashBridge = _document[_globalConfig.swfObjectId];\n if (flashBridge && (len = flashBridge.length)) {\n flashBridge = flashBridge[len - 1];\n }\n if (!flashBridge && container) {\n flashBridge = container.firstChild;\n }\n }\n _flashState.bridge = flashBridge || null;\n return flashBridge;\n };\n /**\n * Destroy the SWF object.\n * @private\n */\n var _unembedSwf = function() {\n var flashBridge = _flashState.bridge;\n if (flashBridge) {\n var htmlBridge = _getHtmlBridge(flashBridge);\n if (htmlBridge) {\n if (_flashState.pluginType === \"activex\" && \"readyState\" in flashBridge) {\n flashBridge.style.display = \"none\";\n (function removeSwfFromIE() {\n if (flashBridge.readyState === 4) {\n for (var prop in flashBridge) {\n if (typeof flashBridge[prop] === \"function\") {\n flashBridge[prop] = null;\n }\n }\n if (flashBridge.parentNode) {\n flashBridge.parentNode.removeChild(flashBridge);\n }\n if (htmlBridge.parentNode) {\n htmlBridge.parentNode.removeChild(htmlBridge);\n }\n } else {\n _setTimeout(removeSwfFromIE, 10);\n }\n })();\n } else {\n if (flashBridge.parentNode) {\n flashBridge.parentNode.removeChild(flashBridge);\n }\n if (htmlBridge.parentNode) {\n htmlBridge.parentNode.removeChild(htmlBridge);\n }\n }\n }\n _clearTimeoutsAndPolling();\n _flashState.ready = null;\n _flashState.bridge = null;\n _flashState.deactivated = null;\n _zcSwfVersion = undefined;\n }\n };\n /**\n * Map the data format names of the \"clipData\" to Flash-friendly names.\n *\n * @returns A new transformed object.\n * @private\n */\n var _mapClipDataToFlash = function(clipData) {\n var newClipData = {}, formatMap = {};\n if (!(typeof clipData === \"object\" && clipData)) {\n return;\n }\n for (var dataFormat in clipData) {\n if (dataFormat && _hasOwn.call(clipData, dataFormat) && typeof clipData[dataFormat] === \"string\" && clipData[dataFormat]) {\n switch (dataFormat.toLowerCase()) {\n case \"text/plain\":\n case \"text\":\n case \"air:text\":\n case \"flash:text\":\n newClipData.text = clipData[dataFormat];\n formatMap.text = dataFormat;\n break;\n\n case \"text/html\":\n case \"html\":\n case \"air:html\":\n case \"flash:html\":\n newClipData.html = clipData[dataFormat];\n formatMap.html = dataFormat;\n break;\n\n case \"application/rtf\":\n case \"text/rtf\":\n case \"rtf\":\n case \"richtext\":\n case \"air:rtf\":\n case \"flash:rtf\":\n newClipData.rtf = clipData[dataFormat];\n formatMap.rtf = dataFormat;\n break;\n\n default:\n break;\n }\n }\n }\n return {\n data: newClipData,\n formatMap: formatMap\n };\n };\n /**\n * Map the data format names from Flash-friendly names back to their original \"clipData\" names (via a format mapping).\n *\n * @returns A new transformed object.\n * @private\n */\n var _mapClipResultsFromFlash = function(clipResults, formatMap) {\n if (!(typeof clipResults === \"object\" && clipResults && typeof formatMap === \"object\" && formatMap)) {\n return clipResults;\n }\n var newResults = {};\n for (var prop in clipResults) {\n if (_hasOwn.call(clipResults, prop)) {\n if (prop === \"errors\") {\n newResults[prop] = clipResults[prop] ? clipResults[prop].slice() : [];\n for (var i = 0, len = newResults[prop].length; i < len; i++) {\n newResults[prop][i].format = formatMap[newResults[prop][i].format];\n }\n } else if (prop !== \"success\" && prop !== \"data\") {\n newResults[prop] = clipResults[prop];\n } else {\n newResults[prop] = {};\n var tmpHash = clipResults[prop];\n for (var dataFormat in tmpHash) {\n if (dataFormat && _hasOwn.call(tmpHash, dataFormat) && _hasOwn.call(formatMap, dataFormat)) {\n newResults[prop][formatMap[dataFormat]] = tmpHash[dataFormat];\n }\n }\n }\n }\n }\n return newResults;\n };\n /**\n * Will look at a path, and will create a \"?noCache={time}\" or \"&noCache={time}\"\n * query param string to return. Does NOT append that string to the original path.\n * This is useful because ExternalInterface often breaks when a Flash SWF is cached.\n *\n * @returns The `noCache` query param with necessary \"?\"/\"&\" prefix.\n * @private\n */\n var _cacheBust = function(path, options) {\n var cacheBust = options == null || options && options.cacheBust === true;\n if (cacheBust) {\n return (path.indexOf(\"?\") === -1 ? \"?\" : \"&\") + \"noCache=\" + _now();\n } else {\n return \"\";\n }\n };\n /**\n * Creates a query string for the FlashVars param.\n * Does NOT include the cache-busting query param.\n *\n * @returns FlashVars query string\n * @private\n */\n var _vars = function(options) {\n var i, len, domain, domains, str = \"\", trustedOriginsExpanded = [];\n if (options.trustedDomains) {\n if (typeof options.trustedDomains === \"string\") {\n domains = [ options.trustedDomains ];\n } else if (typeof options.trustedDomains === \"object\" && \"length\" in options.trustedDomains) {\n domains = options.trustedDomains;\n }\n }\n if (domains && domains.length) {\n for (i = 0, len = domains.length; i < len; i++) {\n if (_hasOwn.call(domains, i) && domains[i] && typeof domains[i] === \"string\") {\n domain = _extractDomain(domains[i]);\n if (!domain) {\n continue;\n }\n if (domain === \"*\") {\n trustedOriginsExpanded.length = 0;\n trustedOriginsExpanded.push(domain);\n break;\n }\n trustedOriginsExpanded.push.apply(trustedOriginsExpanded, [ domain, \"//\" + domain, _window.location.protocol + \"//\" + domain ]);\n }\n }\n }\n if (trustedOriginsExpanded.length) {\n str += \"trustedOrigins=\" + _encodeURIComponent(trustedOriginsExpanded.join(\",\"));\n }\n if (options.forceEnhancedClipboard === true) {\n str += (str ? \"&\" : \"\") + \"forceEnhancedClipboard=true\";\n }\n if (typeof options.swfObjectId === \"string\" && options.swfObjectId) {\n str += (str ? \"&\" : \"\") + \"swfObjectId=\" + _encodeURIComponent(options.swfObjectId);\n }\n if (typeof options.jsVersion === \"string\" && options.jsVersion) {\n str += (str ? \"&\" : \"\") + \"jsVersion=\" + _encodeURIComponent(options.jsVersion);\n }\n return str;\n };\n /**\n * Extract the domain (e.g. \"github.com\") from an origin (e.g. \"https://github.com\") or\n * URL (e.g. \"https://github.com/zeroclipboard/zeroclipboard/\").\n *\n * @returns the domain\n * @private\n */\n var _extractDomain = function(originOrUrl) {\n if (originOrUrl == null || originOrUrl === \"\") {\n return null;\n }\n originOrUrl = originOrUrl.replace(/^\\s+|\\s+$/g, \"\");\n if (originOrUrl === \"\") {\n return null;\n }\n var protocolIndex = originOrUrl.indexOf(\"//\");\n originOrUrl = protocolIndex === -1 ? originOrUrl : originOrUrl.slice(protocolIndex + 2);\n var pathIndex = originOrUrl.indexOf(\"/\");\n originOrUrl = pathIndex === -1 ? originOrUrl : protocolIndex === -1 || pathIndex === 0 ? null : originOrUrl.slice(0, pathIndex);\n if (originOrUrl && originOrUrl.slice(-4).toLowerCase() === \".swf\") {\n return null;\n }\n return originOrUrl || null;\n };\n /**\n * Set `allowScriptAccess` based on `trustedDomains` and `window.location.host` vs. `swfPath`.\n *\n * @returns The appropriate script access level.\n * @private\n */\n var _determineScriptAccess = function() {\n var _extractAllDomains = function(origins) {\n var i, len, tmp, resultsArray = [];\n if (typeof origins === \"string\") {\n origins = [ origins ];\n }\n if (!(typeof origins === \"object\" && origins && typeof origins.length === \"number\")) {\n return resultsArray;\n }\n for (i = 0, len = origins.length; i < len; i++) {\n if (_hasOwn.call(origins, i) && (tmp = _extractDomain(origins[i]))) {\n if (tmp === \"*\") {\n resultsArray.length = 0;\n resultsArray.push(\"*\");\n break;\n }\n if (resultsArray.indexOf(tmp) === -1) {\n resultsArray.push(tmp);\n }\n }\n }\n return resultsArray;\n };\n return function(currentDomain, configOptions) {\n var swfDomain = _extractDomain(configOptions.swfPath);\n if (swfDomain === null) {\n swfDomain = currentDomain;\n }\n var trustedDomains = _extractAllDomains(configOptions.trustedDomains);\n var len = trustedDomains.length;\n if (len > 0) {\n if (len === 1 && trustedDomains[0] === \"*\") {\n return \"always\";\n }\n if (trustedDomains.indexOf(currentDomain) !== -1) {\n if (len === 1 && currentDomain === swfDomain) {\n return \"sameDomain\";\n }\n return \"always\";\n }\n }\n return \"never\";\n };\n }();\n /**\n * Get the currently active/focused DOM element.\n *\n * @returns the currently active/focused element, or `null`\n * @private\n */\n var _safeActiveElement = function() {\n try {\n return _document.activeElement;\n } catch (err) {\n return null;\n }\n };\n /**\n * Add a class to an element, if it doesn't already have it.\n *\n * @returns The element, with its new class added.\n * @private\n */\n var _addClass = function(element, value) {\n var c, cl, className, classNames = [];\n if (typeof value === \"string\" && value) {\n classNames = value.split(/\\s+/);\n }\n if (element && element.nodeType === 1 && classNames.length > 0) {\n if (element.classList) {\n for (c = 0, cl = classNames.length; c < cl; c++) {\n element.classList.add(classNames[c]);\n }\n } else if (element.hasOwnProperty(\"className\")) {\n className = \" \" + element.className + \" \";\n for (c = 0, cl = classNames.length; c < cl; c++) {\n if (className.indexOf(\" \" + classNames[c] + \" \") === -1) {\n className += classNames[c] + \" \";\n }\n }\n element.className = className.replace(/^\\s+|\\s+$/g, \"\");\n }\n }\n return element;\n };\n /**\n * Remove a class from an element, if it has it.\n *\n * @returns The element, with its class removed.\n * @private\n */\n var _removeClass = function(element, value) {\n var c, cl, className, classNames = [];\n if (typeof value === \"string\" && value) {\n classNames = value.split(/\\s+/);\n }\n if (element && element.nodeType === 1 && classNames.length > 0) {\n if (element.classList && element.classList.length > 0) {\n for (c = 0, cl = classNames.length; c < cl; c++) {\n element.classList.remove(classNames[c]);\n }\n } else if (element.className) {\n className = (\" \" + element.className + \" \").replace(/[\\r\\n\\t]/g, \" \");\n for (c = 0, cl = classNames.length; c < cl; c++) {\n className = className.replace(\" \" + classNames[c] + \" \", \" \");\n }\n element.className = className.replace(/^\\s+|\\s+$/g, \"\");\n }\n }\n return element;\n };\n /**\n * Attempt to interpret the element's CSS styling. If `prop` is `\"cursor\"`,\n * then we assume that it should be a hand (\"pointer\") cursor if the element\n * is an anchor element (\"a\" tag).\n *\n * @returns The computed style property.\n * @private\n */\n var _getStyle = function(el, prop) {\n var value = _getComputedStyle(el, null).getPropertyValue(prop);\n if (prop === \"cursor\") {\n if (!value || value === \"auto\") {\n if (el.nodeName === \"A\") {\n return \"pointer\";\n }\n }\n }\n return value;\n };\n /**\n * Get the absolutely positioned coordinates of a DOM element.\n *\n * @returns Object containing the element's position, width, and height.\n * @private\n */\n var _getElementPosition = function(el) {\n var pos = {\n left: 0,\n top: 0,\n width: 0,\n height: 0\n };\n if (el.getBoundingClientRect) {\n var elRect = el.getBoundingClientRect();\n var pageXOffset = _window.pageXOffset;\n var pageYOffset = _window.pageYOffset;\n var leftBorderWidth = _document.documentElement.clientLeft || 0;\n var topBorderWidth = _document.documentElement.clientTop || 0;\n var leftBodyOffset = 0;\n var topBodyOffset = 0;\n if (_getStyle(_document.body, \"position\") === \"relative\") {\n var bodyRect = _document.body.getBoundingClientRect();\n var htmlRect = _document.documentElement.getBoundingClientRect();\n leftBodyOffset = bodyRect.left - htmlRect.left || 0;\n topBodyOffset = bodyRect.top - htmlRect.top || 0;\n }\n pos.left = elRect.left + pageXOffset - leftBorderWidth - leftBodyOffset;\n pos.top = elRect.top + pageYOffset - topBorderWidth - topBodyOffset;\n pos.width = \"width\" in elRect ? elRect.width : elRect.right - elRect.left;\n pos.height = \"height\" in elRect ? elRect.height : elRect.bottom - elRect.top;\n }\n return pos;\n };\n /**\n * Determine is an element is visible somewhere within the document (page).\n *\n * @returns Boolean\n * @private\n */\n var _isElementVisible = function(el) {\n if (!el) {\n return false;\n }\n var styles = _getComputedStyle(el, null);\n var hasCssHeight = _parseFloat(styles.height) > 0;\n var hasCssWidth = _parseFloat(styles.width) > 0;\n var hasCssTop = _parseFloat(styles.top) >= 0;\n var hasCssLeft = _parseFloat(styles.left) >= 0;\n var cssKnows = hasCssHeight && hasCssWidth && hasCssTop && hasCssLeft;\n var rect = cssKnows ? null : _getElementPosition(el);\n 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));\n return isVisible;\n };\n /**\n * Clear all existing timeouts and interval polling delegates.\n *\n * @returns `undefined`\n * @private\n */\n var _clearTimeoutsAndPolling = function() {\n _clearTimeout(_flashCheckTimeout);\n _flashCheckTimeout = 0;\n _clearInterval(_swfFallbackCheckInterval);\n _swfFallbackCheckInterval = 0;\n };\n /**\n * Reposition the Flash object to cover the currently activated element.\n *\n * @returns `undefined`\n * @private\n */\n var _reposition = function() {\n var htmlBridge;\n if (_currentElement && (htmlBridge = _getHtmlBridge(_flashState.bridge))) {\n var pos = _getElementPosition(_currentElement);\n _extend(htmlBridge.style, {\n width: pos.width + \"px\",\n height: pos.height + \"px\",\n top: pos.top + \"px\",\n left: pos.left + \"px\",\n zIndex: \"\" + _getSafeZIndex(_globalConfig.zIndex)\n });\n }\n };\n /**\n * Sends a signal to the Flash object to display the hand cursor if `true`.\n *\n * @returns `undefined`\n * @private\n */\n var _setHandCursor = function(enabled) {\n if (_flashState.ready === true) {\n if (_flashState.bridge && typeof _flashState.bridge.setHandCursor === \"function\") {\n _flashState.bridge.setHandCursor(enabled);\n } else {\n _flashState.ready = false;\n }\n }\n };\n /**\n * Get a safe value for `zIndex`\n *\n * @returns an integer, or \"auto\"\n * @private\n */\n var _getSafeZIndex = function(val) {\n if (/^(?:auto|inherit)$/.test(val)) {\n return val;\n }\n var zIndex;\n if (typeof val === \"number\" && !_isNaN(val)) {\n zIndex = val;\n } else if (typeof val === \"string\") {\n zIndex = _getSafeZIndex(_parseInt(val, 10));\n }\n return typeof zIndex === \"number\" ? zIndex : \"auto\";\n };\n /**\n * Attempt to detect if ZeroClipboard is executing inside of a sandboxed iframe.\n * If it is, Flash Player cannot be used, so ZeroClipboard is dead in the water.\n *\n * @see {@link http://lists.w3.org/Archives/Public/public-whatwg-archive/2014Dec/0002.html}\n * @see {@link https://github.com/zeroclipboard/zeroclipboard/issues/511}\n * @see {@link http://zeroclipboard.org/test-iframes.html}\n *\n * @returns `true` (is sandboxed), `false` (is not sandboxed), or `null` (uncertain) \n * @private\n */\n var _detectSandbox = function(doNotReassessFlashSupport) {\n var effectiveScriptOrigin, frame, frameError, previousState = _flashState.sandboxed, isSandboxed = null;\n doNotReassessFlashSupport = doNotReassessFlashSupport === true;\n if (_pageIsFramed === false) {\n isSandboxed = false;\n } else {\n try {\n frame = window.frameElement || null;\n } catch (e) {\n frameError = {\n name: e.name,\n message: e.message\n };\n }\n if (frame && frame.nodeType === 1 && frame.nodeName === \"IFRAME\") {\n try {\n isSandboxed = frame.hasAttribute(\"sandbox\");\n } catch (e) {\n isSandboxed = null;\n }\n } else {\n try {\n effectiveScriptOrigin = document.domain || null;\n } catch (e) {\n effectiveScriptOrigin = null;\n }\n if (effectiveScriptOrigin === null || frameError && frameError.name === \"SecurityError\" && /(^|[\\s\\(\\[@])sandbox(es|ed|ing|[\\s\\.,!\\)\\]@]|$)/.test(frameError.message.toLowerCase())) {\n isSandboxed = true;\n }\n }\n }\n _flashState.sandboxed = isSandboxed;\n if (previousState !== isSandboxed && !doNotReassessFlashSupport) {\n _detectFlashSupport(_ActiveXObject);\n }\n return isSandboxed;\n };\n /**\n * Detect the Flash Player status, version, and plugin type.\n *\n * @see {@link https://code.google.com/p/doctype-mirror/wiki/ArticleDetectFlash#The_code}\n * @see {@link http://stackoverflow.com/questions/12866060/detecting-pepper-ppapi-flash-with-javascript}\n *\n * @returns `undefined`\n * @private\n */\n var _detectFlashSupport = function(ActiveXObject) {\n var plugin, ax, mimeType, hasFlash = false, isActiveX = false, isPPAPI = false, flashVersion = \"\";\n /**\n * Derived from Apple's suggested sniffer.\n * @param {String} desc e.g. \"Shockwave Flash 7.0 r61\"\n * @returns {String} \"7.0.61\"\n * @private\n */\n function parseFlashVersion(desc) {\n var matches = desc.match(/[\\d]+/g);\n matches.length = 3;\n return matches.join(\".\");\n }\n function isPepperFlash(flashPlayerFileName) {\n return !!flashPlayerFileName && (flashPlayerFileName = flashPlayerFileName.toLowerCase()) && (/^(pepflashplayer\\.dll|libpepflashplayer\\.so|pepperflashplayer\\.plugin)$/.test(flashPlayerFileName) || flashPlayerFileName.slice(-13) === \"chrome.plugin\");\n }\n function inspectPlugin(plugin) {\n if (plugin) {\n hasFlash = true;\n if (plugin.version) {\n flashVersion = parseFlashVersion(plugin.version);\n }\n if (!flashVersion && plugin.description) {\n flashVersion = parseFlashVersion(plugin.description);\n }\n if (plugin.filename) {\n isPPAPI = isPepperFlash(plugin.filename);\n }\n }\n }\n if (_navigator.plugins && _navigator.plugins.length) {\n plugin = _navigator.plugins[\"Shockwave Flash\"];\n inspectPlugin(plugin);\n if (_navigator.plugins[\"Shockwave Flash 2.0\"]) {\n hasFlash = true;\n flashVersion = \"2.0.0.11\";\n }\n } else if (_navigator.mimeTypes && _navigator.mimeTypes.length) {\n mimeType = _navigator.mimeTypes[\"application/x-shockwave-flash\"];\n plugin = mimeType && mimeType.enabledPlugin;\n inspectPlugin(plugin);\n } else if (typeof ActiveXObject !== \"undefined\") {\n isActiveX = true;\n try {\n ax = new ActiveXObject(\"ShockwaveFlash.ShockwaveFlash.7\");\n hasFlash = true;\n flashVersion = parseFlashVersion(ax.GetVariable(\"$version\"));\n } catch (e1) {\n try {\n ax = new ActiveXObject(\"ShockwaveFlash.ShockwaveFlash.6\");\n hasFlash = true;\n flashVersion = \"6.0.21\";\n } catch (e2) {\n try {\n ax = new ActiveXObject(\"ShockwaveFlash.ShockwaveFlash\");\n hasFlash = true;\n flashVersion = parseFlashVersion(ax.GetVariable(\"$version\"));\n } catch (e3) {\n isActiveX = false;\n }\n }\n }\n }\n _flashState.disabled = hasFlash !== true;\n _flashState.outdated = flashVersion && _parseFloat(flashVersion) < _parseFloat(_minimumFlashVersion);\n _flashState.version = flashVersion || \"0.0.0\";\n _flashState.pluginType = isPPAPI ? \"pepper\" : isActiveX ? \"activex\" : hasFlash ? \"netscape\" : \"unknown\";\n };\n /**\n * Invoke the Flash detection algorithms immediately upon inclusion so we're not waiting later.\n */\n _detectFlashSupport(_ActiveXObject);\n /**\n * Always assess the `sandboxed` state of the page at important Flash-related moments.\n */\n _detectSandbox(true);\n /**\n * A shell constructor for `ZeroClipboard` client instances.\n *\n * @constructor\n */\n var ZeroClipboard = function() {\n if (!(this instanceof ZeroClipboard)) {\n return new ZeroClipboard();\n }\n if (typeof ZeroClipboard._createClient === \"function\") {\n ZeroClipboard._createClient.apply(this, _args(arguments));\n }\n };\n /**\n * The ZeroClipboard library's version number.\n *\n * @static\n * @readonly\n * @property {string}\n */\n _defineProperty(ZeroClipboard, \"version\", {\n value: \"2.2.0\",\n writable: false,\n configurable: true,\n enumerable: true\n });\n /**\n * Update or get a copy of the ZeroClipboard global configuration.\n * Returns a copy of the current/updated configuration.\n *\n * @returns Object\n * @static\n */\n ZeroClipboard.config = function() {\n return _config.apply(this, _args(arguments));\n };\n /**\n * Diagnostic method that describes the state of the browser, Flash Player, and ZeroClipboard.\n *\n * @returns Object\n * @static\n */\n ZeroClipboard.state = function() {\n return _state.apply(this, _args(arguments));\n };\n /**\n * Check if Flash is unusable for any reason: disabled, outdated, deactivated, etc.\n *\n * @returns Boolean\n * @static\n */\n ZeroClipboard.isFlashUnusable = function() {\n return _isFlashUnusable.apply(this, _args(arguments));\n };\n /**\n * Register an event listener.\n *\n * @returns `ZeroClipboard`\n * @static\n */\n ZeroClipboard.on = function() {\n return _on.apply(this, _args(arguments));\n };\n /**\n * Unregister an event listener.\n * If no `listener` function/object is provided, it will unregister all listeners for the provided `eventType`.\n * If no `eventType` is provided, it will unregister all listeners for every event type.\n *\n * @returns `ZeroClipboard`\n * @static\n */\n ZeroClipboard.off = function() {\n return _off.apply(this, _args(arguments));\n };\n /**\n * Retrieve event listeners for an `eventType`.\n * If no `eventType` is provided, it will retrieve all listeners for every event type.\n *\n * @returns array of listeners for the `eventType`; if no `eventType`, then a map/hash object of listeners for all event types; or `null`\n */\n ZeroClipboard.handlers = function() {\n return _listeners.apply(this, _args(arguments));\n };\n /**\n * Event emission receiver from the Flash object, forwarding to any registered JavaScript event listeners.\n *\n * @returns For the \"copy\" event, returns the Flash-friendly \"clipData\" object; otherwise `undefined`.\n * @static\n */\n ZeroClipboard.emit = function() {\n return _emit.apply(this, _args(arguments));\n };\n /**\n * Create and embed the Flash object.\n *\n * @returns The Flash object\n * @static\n */\n ZeroClipboard.create = function() {\n return _create.apply(this, _args(arguments));\n };\n /**\n * Self-destruct and clean up everything, including the embedded Flash object.\n *\n * @returns `undefined`\n * @static\n */\n ZeroClipboard.destroy = function() {\n return _destroy.apply(this, _args(arguments));\n };\n /**\n * Set the pending data for clipboard injection.\n *\n * @returns `undefined`\n * @static\n */\n ZeroClipboard.setData = function() {\n return _setData.apply(this, _args(arguments));\n };\n /**\n * Clear the pending data for clipboard injection.\n * If no `format` is provided, all pending data formats will be cleared.\n *\n * @returns `undefined`\n * @static\n */\n ZeroClipboard.clearData = function() {\n return _clearData.apply(this, _args(arguments));\n };\n /**\n * Get a copy of the pending data for clipboard injection.\n * If no `format` is provided, a copy of ALL pending data formats will be returned.\n *\n * @returns `String` or `Object`\n * @static\n */\n ZeroClipboard.getData = function() {\n return _getData.apply(this, _args(arguments));\n };\n /**\n * Sets the current HTML object that the Flash object should overlay. This will put the global\n * Flash object on top of the current element; depending on the setup, this may also set the\n * pending clipboard text data as well as the Flash object's wrapping element's title attribute\n * based on the underlying HTML element and ZeroClipboard configuration.\n *\n * @returns `undefined`\n * @static\n */\n ZeroClipboard.focus = ZeroClipboard.activate = function() {\n return _focus.apply(this, _args(arguments));\n };\n /**\n * Un-overlays the Flash object. This will put the global Flash object off-screen; depending on\n * the setup, this may also unset the Flash object's wrapping element's title attribute based on\n * the underlying HTML element and ZeroClipboard configuration.\n *\n * @returns `undefined`\n * @static\n */\n ZeroClipboard.blur = ZeroClipboard.deactivate = function() {\n return _blur.apply(this, _args(arguments));\n };\n /**\n * Returns the currently focused/\"activated\" HTML element that the Flash object is wrapping.\n *\n * @returns `HTMLElement` or `null`\n * @static\n */\n ZeroClipboard.activeElement = function() {\n return _activeElement.apply(this, _args(arguments));\n };\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return ZeroClipboard;\n });\n } else if (typeof module === \"object\" && module && typeof module.exports === \"object\" && module.exports) {\n module.exports = ZeroClipboard;\n } else {\n window.ZeroClipboard = ZeroClipboard;\n }\n})(function() {\n return this || window;\n}());"]} \ No newline at end of file diff --git a/resources/zeroclipboard/ZeroClipboard.js b/resources/zeroclipboard/ZeroClipboard.js new file mode 100644 index 0000000000..6e20b5910f --- /dev/null +++ b/resources/zeroclipboard/ZeroClipboard.js @@ -0,0 +1,2581 @@ +/*! + * ZeroClipboard + * The ZeroClipboard library provides an easy way to copy text to the clipboard using an invisible Adobe Flash movie and a JavaScript interface. + * Copyright (c) 2009-2014 Jon Rohan, James M. Greene + * Licensed MIT + * http://zeroclipboard.org/ + * v2.2.0 + */ +(function(window, undefined) { + "use strict"; + /** + * Store references to critically important global functions that may be + * overridden on certain web pages. + */ + 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() { + var unwrapper = function(el) { + return el; + }; + if (typeof _window.wrap === "function" && typeof _window.unwrap === "function") { + try { + var div = _document.createElement("div"); + var unwrappedDiv = _window.unwrap(div); + if (div.nodeType === 1 && unwrappedDiv && unwrappedDiv.nodeType === 1) { + unwrapper = _window.unwrap; + } + } catch (e) {} + } + return unwrapper; + }(); + /** + * Convert an `arguments` object into an Array. + * + * @returns The arguments as an Array + * @private + */ + var _args = function(argumentsObj) { + return _slice.call(argumentsObj, 0); + }; + /** + * Shallow-copy the owned, enumerable properties of one object over to another, similar to jQuery's `$.extend`. + * + * @returns The target object, augmented + * @private + */ + var _extend = function() { + var i, len, arg, prop, src, copy, args = _args(arguments), target = args[0] || {}; + for (i = 1, len = args.length; i < len; i++) { + if ((arg = args[i]) != null) { + for (prop in arg) { + if (_hasOwn.call(arg, prop)) { + src = target[prop]; + copy = arg[prop]; + if (target !== copy && copy !== undefined) { + target[prop] = copy; + } + } + } + } + } + return target; + }; + /** + * Return a deep copy of the source object or array. + * + * @returns Object or Array + * @private + */ + var _deepCopy = function(source) { + var copy, i, len, prop; + if (typeof source !== "object" || source == null || typeof source.nodeType === "number") { + copy = source; + } else if (typeof source.length === "number") { + copy = []; + for (i = 0, len = source.length; i < len; i++) { + if (_hasOwn.call(source, i)) { + copy[i] = _deepCopy(source[i]); + } + } + } else { + copy = {}; + for (prop in source) { + if (_hasOwn.call(source, prop)) { + copy[prop] = _deepCopy(source[prop]); + } + } + } + return copy; + }; + /** + * Makes a shallow copy of `obj` (like `_extend`) but filters its properties based on a list of `keys` to keep. + * The inverse of `_omit`, mostly. The big difference is that these properties do NOT need to be enumerable to + * be kept. + * + * @returns A new filtered object. + * @private + */ + var _pick = function(obj, keys) { + var newObj = {}; + for (var i = 0, len = keys.length; i < len; i++) { + if (keys[i] in obj) { + newObj[keys[i]] = obj[keys[i]]; + } + } + return newObj; + }; + /** + * Makes a shallow copy of `obj` (like `_extend`) but filters its properties based on a list of `keys` to omit. + * The inverse of `_pick`. + * + * @returns A new filtered object. + * @private + */ + var _omit = function(obj, keys) { + var newObj = {}; + for (var prop in obj) { + if (keys.indexOf(prop) === -1) { + newObj[prop] = obj[prop]; + } + } + return newObj; + }; + /** + * Remove all owned, enumerable properties from an object. + * + * @returns The original object without its owned, enumerable properties. + * @private + */ + var _deleteOwnProperties = function(obj) { + if (obj) { + for (var prop in obj) { + if (_hasOwn.call(obj, prop)) { + delete obj[prop]; + } + } + } + return obj; + }; + /** + * Determine if an element is contained within another element. + * + * @returns Boolean + * @private + */ + var _containedBy = function(el, ancestorEl) { + 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)) { + do { + if (el === ancestorEl) { + return true; + } + el = el.parentNode; + } while (el); + } + return false; + }; + /** + * Get the URL path's parent directory. + * + * @returns String or `undefined` + * @private + */ + var _getDirPathOfUrl = function(url) { + var dir; + if (typeof url === "string" && url) { + dir = url.split("#")[0].split("?")[0]; + dir = url.slice(0, url.lastIndexOf("/") + 1); + } + return dir; + }; + /** + * Get the current script's URL by throwing an `Error` and analyzing it. + * + * @returns String or `undefined` + * @private + */ + var _getCurrentScriptUrlFromErrorStack = function(stack) { + var url, matches; + if (typeof stack === "string" && stack) { + matches = stack.match(/^(?:|[^:@]*@|.+\)@(?=http[s]?|file)|.+?\s+(?: at |@)(?:[^:\(]+ )*[\(]?)((?:http[s]?|file):\/\/[\/]?.+?\/[^:\)]*?)(?::\d+)(?::\d+)?/); + if (matches && matches[1]) { + url = matches[1]; + } else { + matches = stack.match(/\)@((?:http[s]?|file):\/\/[\/]?.+?\/[^:\)]*?)(?::\d+)(?::\d+)?/); + if (matches && matches[1]) { + url = matches[1]; + } + } + } + return url; + }; + /** + * Get the current script's URL by throwing an `Error` and analyzing it. + * + * @returns String or `undefined` + * @private + */ + var _getCurrentScriptUrlFromError = function() { + var url, err; + try { + throw new _Error(); + } catch (e) { + err = e; + } + if (err) { + url = err.sourceURL || err.fileName || _getCurrentScriptUrlFromErrorStack(err.stack); + } + return url; + }; + /** + * Get the current script's URL. + * + * @returns String or `undefined` + * @private + */ + var _getCurrentScriptUrl = function() { + var jsPath, scripts, i; + if (_document.currentScript && (jsPath = _document.currentScript.src)) { + return jsPath; + } + scripts = _document.getElementsByTagName("script"); + if (scripts.length === 1) { + return scripts[0].src || undefined; + } + if ("readyState" in scripts[0]) { + for (i = scripts.length; i--; ) { + if (scripts[i].readyState === "interactive" && (jsPath = scripts[i].src)) { + return jsPath; + } + } + } + if (_document.readyState === "loading" && (jsPath = scripts[scripts.length - 1].src)) { + return jsPath; + } + if (jsPath = _getCurrentScriptUrlFromError()) { + return jsPath; + } + return undefined; + }; + /** + * Get the unanimous parent directory of ALL script tags. + * If any script tags are either (a) inline or (b) from differing parent + * directories, this method must return `undefined`. + * + * @returns String or `undefined` + * @private + */ + var _getUnanimousScriptParentDir = function() { + var i, jsDir, jsPath, scripts = _document.getElementsByTagName("script"); + for (i = scripts.length; i--; ) { + if (!(jsPath = scripts[i].src)) { + jsDir = null; + break; + } + jsPath = _getDirPathOfUrl(jsPath); + if (jsDir == null) { + jsDir = jsPath; + } else if (jsDir !== jsPath) { + jsDir = null; + break; + } + } + return jsDir || undefined; + }; + /** + * Get the presumed location of the "ZeroClipboard.swf" file, based on the location + * of the executing JavaScript file (e.g. "ZeroClipboard.js", etc.). + * + * @returns String + * @private + */ + var _getDefaultSwfPath = function() { + var jsDir = _getDirPathOfUrl(_getCurrentScriptUrl()) || _getUnanimousScriptParentDir() || ""; + return jsDir + "ZeroClipboard.swf"; + }; + /** + * Keep track of if the page is framed (in an `iframe`). This can never change. + * @private + */ + var _pageIsFramed = function() { + return window.opener == null && (!!window.top && window != window.top || !!window.parent && window != window.parent); + }(); + /** + * Keep track of the state of the Flash object. + * @private + */ + var _flashState = { + bridge: null, + version: "0.0.0", + pluginType: "unknown", + disabled: null, + outdated: null, + sandboxed: null, + unavailable: null, + degraded: null, + deactivated: null, + overdue: null, + ready: null + }; + /** + * The minimum Flash Player version required to use ZeroClipboard completely. + * @readonly + * @private + */ + var _minimumFlashVersion = "11.0.0"; + /** + * The ZeroClipboard library version number, as reported by Flash, at the time the SWF was compiled. + */ + var _zcSwfVersion; + /** + * Keep track of all event listener registrations. + * @private + */ + var _handlers = {}; + /** + * Keep track of the currently activated element. + * @private + */ + var _currentElement; + /** + * Keep track of the element that was activated when a `copy` process started. + * @private + */ + var _copyTarget; + /** + * Keep track of data for the pending clipboard transaction. + * @private + */ + var _clipData = {}; + /** + * Keep track of data formats for the pending clipboard transaction. + * @private + */ + var _clipDataFormatMap = null; + /** + * Keep track of the Flash availability check timeout. + * @private + */ + var _flashCheckTimeout = 0; + /** + * Keep track of SWF network errors interval polling. + * @private + */ + var _swfFallbackCheckInterval = 0; + /** + * The `message` store for events + * @private + */ + var _eventMessages = { + ready: "Flash communication is established", + error: { + "flash-disabled": "Flash is disabled or not installed. May also be attempting to run Flash in a sandboxed iframe, which is impossible.", + "flash-outdated": "Flash is too outdated to support ZeroClipboard", + "flash-sandboxed": "Attempting to run Flash in a sandboxed iframe, which is impossible", + "flash-unavailable": "Flash is unable to communicate bidirectionally with JavaScript", + "flash-degraded": "Flash is unable to preserve data fidelity when communicating with JavaScript", + "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.", + "flash-overdue": "Flash communication was established but NOT within the acceptable time limit", + "version-mismatch": "ZeroClipboard JS version number does not match ZeroClipboard SWF version number", + "clipboard-error": "At least one error was thrown while ZeroClipboard was attempting to inject your data into the clipboard", + "config-mismatch": "ZeroClipboard configuration does not match Flash's reality", + "swf-not-found": "The ZeroClipboard SWF object could not be loaded, so please check your `swfPath` configuration and/or network connectivity" + } + }; + /** + * The `name`s of `error` events that can only occur is Flash has at least + * been able to load the SWF successfully. + * @private + */ + var _errorsThatOnlyOccurAfterFlashLoads = [ "flash-unavailable", "flash-degraded", "flash-overdue", "version-mismatch", "config-mismatch", "clipboard-error" ]; + /** + * The `name`s of `error` events that should likely result in the `_flashState` + * variable's property values being updated. + * @private + */ + var _flashStateErrorNames = [ "flash-disabled", "flash-outdated", "flash-sandboxed", "flash-unavailable", "flash-degraded", "flash-deactivated", "flash-overdue" ]; + /** + * A RegExp to match the `name` property of `error` events related to Flash. + * @private + */ + var _flashStateErrorNameMatchingRegex = new RegExp("^flash-(" + _flashStateErrorNames.map(function(errorName) { + return errorName.replace(/^flash-/, ""); + }).join("|") + ")$"); + /** + * A RegExp to match the `name` property of `error` events related to Flash, + * which is enabled. + * @private + */ + var _flashStateEnabledErrorNameMatchingRegex = new RegExp("^flash-(" + _flashStateErrorNames.slice(1).map(function(errorName) { + return errorName.replace(/^flash-/, ""); + }).join("|") + ")$"); + /** + * ZeroClipboard configuration defaults for the Core module. + * @private + */ + var _globalConfig = { + swfPath: _getDefaultSwfPath(), + trustedDomains: window.location.host ? [ window.location.host ] : [], + cacheBust: true, + forceEnhancedClipboard: false, + flashLoadTimeout: 3e4, + autoActivate: true, + bubbleEvents: true, + containerId: "global-zeroclipboard-html-bridge", + containerClass: "global-zeroclipboard-container", + swfObjectId: "global-zeroclipboard-flash-bridge", + hoverClass: "zeroclipboard-is-hover", + activeClass: "zeroclipboard-is-active", + forceHandCursor: false, + title: null, + zIndex: 999999999 + }; + /** + * The underlying implementation of `ZeroClipboard.config`. + * @private + */ + var _config = function(options) { + if (typeof options === "object" && options !== null) { + for (var prop in options) { + if (_hasOwn.call(options, prop)) { + if (/^(?:forceHandCursor|title|zIndex|bubbleEvents)$/.test(prop)) { + _globalConfig[prop] = options[prop]; + } else if (_flashState.bridge == null) { + if (prop === "containerId" || prop === "swfObjectId") { + if (_isValidHtml4Id(options[prop])) { + _globalConfig[prop] = options[prop]; + } else { + throw new Error("The specified `" + prop + "` value is not valid as an HTML4 Element ID"); + } + } else { + _globalConfig[prop] = options[prop]; + } + } + } + } + } + if (typeof options === "string" && options) { + if (_hasOwn.call(_globalConfig, options)) { + return _globalConfig[options]; + } + return; + } + return _deepCopy(_globalConfig); + }; + /** + * The underlying implementation of `ZeroClipboard.state`. + * @private + */ + var _state = function() { + _detectSandbox(); + return { + browser: _pick(_navigator, [ "userAgent", "platform", "appName" ]), + flash: _omit(_flashState, [ "bridge" ]), + zeroclipboard: { + version: ZeroClipboard.version, + config: ZeroClipboard.config() + } + }; + }; + /** + * The underlying implementation of `ZeroClipboard.isFlashUnusable`. + * @private + */ + var _isFlashUnusable = function() { + return !!(_flashState.disabled || _flashState.outdated || _flashState.sandboxed || _flashState.unavailable || _flashState.degraded || _flashState.deactivated); + }; + /** + * The underlying implementation of `ZeroClipboard.on`. + * @private + */ + var _on = function(eventType, listener) { + var i, len, events, added = {}; + if (typeof eventType === "string" && eventType) { + events = eventType.toLowerCase().split(/\s+/); + } else if (typeof eventType === "object" && eventType && typeof listener === "undefined") { + for (i in eventType) { + if (_hasOwn.call(eventType, i) && typeof i === "string" && i && typeof eventType[i] === "function") { + ZeroClipboard.on(i, eventType[i]); + } + } + } + if (events && events.length) { + for (i = 0, len = events.length; i < len; i++) { + eventType = events[i].replace(/^on/, ""); + added[eventType] = true; + if (!_handlers[eventType]) { + _handlers[eventType] = []; + } + _handlers[eventType].push(listener); + } + if (added.ready && _flashState.ready) { + ZeroClipboard.emit({ + type: "ready" + }); + } + if (added.error) { + for (i = 0, len = _flashStateErrorNames.length; i < len; i++) { + if (_flashState[_flashStateErrorNames[i].replace(/^flash-/, "")] === true) { + ZeroClipboard.emit({ + type: "error", + name: _flashStateErrorNames[i] + }); + break; + } + } + if (_zcSwfVersion !== undefined && ZeroClipboard.version !== _zcSwfVersion) { + ZeroClipboard.emit({ + type: "error", + name: "version-mismatch", + jsVersion: ZeroClipboard.version, + swfVersion: _zcSwfVersion + }); + } + } + } + return ZeroClipboard; + }; + /** + * The underlying implementation of `ZeroClipboard.off`. + * @private + */ + var _off = function(eventType, listener) { + var i, len, foundIndex, events, perEventHandlers; + if (arguments.length === 0) { + events = _keys(_handlers); + } else if (typeof eventType === "string" && eventType) { + events = eventType.split(/\s+/); + } else if (typeof eventType === "object" && eventType && typeof listener === "undefined") { + for (i in eventType) { + if (_hasOwn.call(eventType, i) && typeof i === "string" && i && typeof eventType[i] === "function") { + ZeroClipboard.off(i, eventType[i]); + } + } + } + if (events && events.length) { + for (i = 0, len = events.length; i < len; i++) { + eventType = events[i].toLowerCase().replace(/^on/, ""); + perEventHandlers = _handlers[eventType]; + if (perEventHandlers && perEventHandlers.length) { + if (listener) { + foundIndex = perEventHandlers.indexOf(listener); + while (foundIndex !== -1) { + perEventHandlers.splice(foundIndex, 1); + foundIndex = perEventHandlers.indexOf(listener, foundIndex); + } + } else { + perEventHandlers.length = 0; + } + } + } + } + return ZeroClipboard; + }; + /** + * The underlying implementation of `ZeroClipboard.handlers`. + * @private + */ + var _listeners = function(eventType) { + var copy; + if (typeof eventType === "string" && eventType) { + copy = _deepCopy(_handlers[eventType]) || null; + } else { + copy = _deepCopy(_handlers); + } + return copy; + }; + /** + * The underlying implementation of `ZeroClipboard.emit`. + * @private + */ + var _emit = function(event) { + var eventCopy, returnVal, tmp; + event = _createEvent(event); + if (!event) { + return; + } + if (_preprocessEvent(event)) { + return; + } + if (event.type === "ready" && _flashState.overdue === true) { + return ZeroClipboard.emit({ + type: "error", + name: "flash-overdue" + }); + } + eventCopy = _extend({}, event); + _dispatchCallbacks.call(this, eventCopy); + if (event.type === "copy") { + tmp = _mapClipDataToFlash(_clipData); + returnVal = tmp.data; + _clipDataFormatMap = tmp.formatMap; + } + return returnVal; + }; + /** + * The underlying implementation of `ZeroClipboard.create`. + * @private + */ + var _create = function() { + var previousState = _flashState.sandboxed; + _detectSandbox(); + if (typeof _flashState.ready !== "boolean") { + _flashState.ready = false; + } + if (_flashState.sandboxed !== previousState && _flashState.sandboxed === true) { + _flashState.ready = false; + ZeroClipboard.emit({ + type: "error", + name: "flash-sandboxed" + }); + } else if (!ZeroClipboard.isFlashUnusable() && _flashState.bridge === null) { + var maxWait = _globalConfig.flashLoadTimeout; + if (typeof maxWait === "number" && maxWait >= 0) { + _flashCheckTimeout = _setTimeout(function() { + if (typeof _flashState.deactivated !== "boolean") { + _flashState.deactivated = true; + } + if (_flashState.deactivated === true) { + ZeroClipboard.emit({ + type: "error", + name: "flash-deactivated" + }); + } + }, maxWait); + } + _flashState.overdue = false; + _embedSwf(); + } + }; + /** + * The underlying implementation of `ZeroClipboard.destroy`. + * @private + */ + var _destroy = function() { + ZeroClipboard.clearData(); + ZeroClipboard.blur(); + ZeroClipboard.emit("destroy"); + _unembedSwf(); + ZeroClipboard.off(); + }; + /** + * The underlying implementation of `ZeroClipboard.setData`. + * @private + */ + var _setData = function(format, data) { + var dataObj; + if (typeof format === "object" && format && typeof data === "undefined") { + dataObj = format; + ZeroClipboard.clearData(); + } else if (typeof format === "string" && format) { + dataObj = {}; + dataObj[format] = data; + } else { + return; + } + for (var dataFormat in dataObj) { + if (typeof dataFormat === "string" && dataFormat && _hasOwn.call(dataObj, dataFormat) && typeof dataObj[dataFormat] === "string" && dataObj[dataFormat]) { + _clipData[dataFormat] = dataObj[dataFormat]; + } + } + }; + /** + * The underlying implementation of `ZeroClipboard.clearData`. + * @private + */ + var _clearData = function(format) { + if (typeof format === "undefined") { + _deleteOwnProperties(_clipData); + _clipDataFormatMap = null; + } else if (typeof format === "string" && _hasOwn.call(_clipData, format)) { + delete _clipData[format]; + } + }; + /** + * The underlying implementation of `ZeroClipboard.getData`. + * @private + */ + var _getData = function(format) { + if (typeof format === "undefined") { + return _deepCopy(_clipData); + } else if (typeof format === "string" && _hasOwn.call(_clipData, format)) { + return _clipData[format]; + } + }; + /** + * The underlying implementation of `ZeroClipboard.focus`/`ZeroClipboard.activate`. + * @private + */ + var _focus = function(element) { + if (!(element && element.nodeType === 1)) { + return; + } + if (_currentElement) { + _removeClass(_currentElement, _globalConfig.activeClass); + if (_currentElement !== element) { + _removeClass(_currentElement, _globalConfig.hoverClass); + } + } + _currentElement = element; + _addClass(element, _globalConfig.hoverClass); + var newTitle = element.getAttribute("title") || _globalConfig.title; + if (typeof newTitle === "string" && newTitle) { + var htmlBridge = _getHtmlBridge(_flashState.bridge); + if (htmlBridge) { + htmlBridge.setAttribute("title", newTitle); + } + } + var useHandCursor = _globalConfig.forceHandCursor === true || _getStyle(element, "cursor") === "pointer"; + _setHandCursor(useHandCursor); + _reposition(); + }; + /** + * The underlying implementation of `ZeroClipboard.blur`/`ZeroClipboard.deactivate`. + * @private + */ + var _blur = function() { + var htmlBridge = _getHtmlBridge(_flashState.bridge); + if (htmlBridge) { + htmlBridge.removeAttribute("title"); + htmlBridge.style.left = "0px"; + htmlBridge.style.top = "-9999px"; + htmlBridge.style.width = "1px"; + htmlBridge.style.height = "1px"; + } + if (_currentElement) { + _removeClass(_currentElement, _globalConfig.hoverClass); + _removeClass(_currentElement, _globalConfig.activeClass); + _currentElement = null; + } + }; + /** + * The underlying implementation of `ZeroClipboard.activeElement`. + * @private + */ + var _activeElement = function() { + return _currentElement || null; + }; + /** + * Check if a value is a valid HTML4 `ID` or `Name` token. + * @private + */ + var _isValidHtml4Id = function(id) { + return typeof id === "string" && id && /^[A-Za-z][A-Za-z0-9_:\-\.]*$/.test(id); + }; + /** + * Create or update an `event` object, based on the `eventType`. + * @private + */ + var _createEvent = function(event) { + var eventType; + if (typeof event === "string" && event) { + eventType = event; + event = {}; + } else if (typeof event === "object" && event && typeof event.type === "string" && event.type) { + eventType = event.type; + } + if (!eventType) { + return; + } + eventType = eventType.toLowerCase(); + if (!event.target && (/^(copy|aftercopy|_click)$/.test(eventType) || eventType === "error" && event.name === "clipboard-error")) { + event.target = _copyTarget; + } + _extend(event, { + type: eventType, + target: event.target || _currentElement || null, + relatedTarget: event.relatedTarget || null, + currentTarget: _flashState && _flashState.bridge || null, + timeStamp: event.timeStamp || _now() || null + }); + var msg = _eventMessages[event.type]; + if (event.type === "error" && event.name && msg) { + msg = msg[event.name]; + } + if (msg) { + event.message = msg; + } + if (event.type === "ready") { + _extend(event, { + target: null, + version: _flashState.version + }); + } + if (event.type === "error") { + if (_flashStateErrorNameMatchingRegex.test(event.name)) { + _extend(event, { + target: null, + minimumVersion: _minimumFlashVersion + }); + } + if (_flashStateEnabledErrorNameMatchingRegex.test(event.name)) { + _extend(event, { + version: _flashState.version + }); + } + } + if (event.type === "copy") { + event.clipboardData = { + setData: ZeroClipboard.setData, + clearData: ZeroClipboard.clearData + }; + } + if (event.type === "aftercopy") { + event = _mapClipResultsFromFlash(event, _clipDataFormatMap); + } + if (event.target && !event.relatedTarget) { + event.relatedTarget = _getRelatedTarget(event.target); + } + return _addMouseData(event); + }; + /** + * Get a relatedTarget from the target's `data-clipboard-target` attribute + * @private + */ + var _getRelatedTarget = function(targetEl) { + var relatedTargetId = targetEl && targetEl.getAttribute && targetEl.getAttribute("data-clipboard-target"); + return relatedTargetId ? _document.getElementById(relatedTargetId) : null; + }; + /** + * Add element and position data to `MouseEvent` instances + * @private + */ + var _addMouseData = function(event) { + if (event && /^_(?:click|mouse(?:over|out|down|up|move))$/.test(event.type)) { + var srcElement = event.target; + var fromElement = event.type === "_mouseover" && event.relatedTarget ? event.relatedTarget : undefined; + var toElement = event.type === "_mouseout" && event.relatedTarget ? event.relatedTarget : undefined; + var pos = _getElementPosition(srcElement); + var screenLeft = _window.screenLeft || _window.screenX || 0; + var screenTop = _window.screenTop || _window.screenY || 0; + var scrollLeft = _document.body.scrollLeft + _document.documentElement.scrollLeft; + var scrollTop = _document.body.scrollTop + _document.documentElement.scrollTop; + var pageX = pos.left + (typeof event._stageX === "number" ? event._stageX : 0); + var pageY = pos.top + (typeof event._stageY === "number" ? event._stageY : 0); + var clientX = pageX - scrollLeft; + var clientY = pageY - scrollTop; + var screenX = screenLeft + clientX; + var screenY = screenTop + clientY; + var moveX = typeof event.movementX === "number" ? event.movementX : 0; + var moveY = typeof event.movementY === "number" ? event.movementY : 0; + delete event._stageX; + delete event._stageY; + _extend(event, { + srcElement: srcElement, + fromElement: fromElement, + toElement: toElement, + screenX: screenX, + screenY: screenY, + pageX: pageX, + pageY: pageY, + clientX: clientX, + clientY: clientY, + x: clientX, + y: clientY, + movementX: moveX, + movementY: moveY, + offsetX: 0, + offsetY: 0, + layerX: 0, + layerY: 0 + }); + } + return event; + }; + /** + * Determine if an event's registered handlers should be execute synchronously or asynchronously. + * + * @returns {boolean} + * @private + */ + var _shouldPerformAsync = function(event) { + var eventType = event && typeof event.type === "string" && event.type || ""; + return !/^(?:(?:before)?copy|destroy)$/.test(eventType); + }; + /** + * Control if a callback should be executed asynchronously or not. + * + * @returns `undefined` + * @private + */ + var _dispatchCallback = function(func, context, args, async) { + if (async) { + _setTimeout(function() { + func.apply(context, args); + }, 0); + } else { + func.apply(context, args); + } + }; + /** + * Handle the actual dispatching of events to client instances. + * + * @returns `undefined` + * @private + */ + var _dispatchCallbacks = function(event) { + if (!(typeof event === "object" && event && event.type)) { + return; + } + var async = _shouldPerformAsync(event); + var wildcardTypeHandlers = _handlers["*"] || []; + var specificTypeHandlers = _handlers[event.type] || []; + var handlers = wildcardTypeHandlers.concat(specificTypeHandlers); + if (handlers && handlers.length) { + var i, len, func, context, eventCopy, originalContext = this; + for (i = 0, len = handlers.length; i < len; i++) { + func = handlers[i]; + context = originalContext; + if (typeof func === "string" && typeof _window[func] === "function") { + func = _window[func]; + } + if (typeof func === "object" && func && typeof func.handleEvent === "function") { + context = func; + func = func.handleEvent; + } + if (typeof func === "function") { + eventCopy = _extend({}, event); + _dispatchCallback(func, context, [ eventCopy ], async); + } + } + } + return this; + }; + /** + * Check an `error` event's `name` property to see if Flash has + * already loaded, which rules out possible `iframe` sandboxing. + * @private + */ + var _getSandboxStatusFromErrorEvent = function(event) { + var isSandboxed = null; + if (_pageIsFramed === false || event && event.type === "error" && event.name && _errorsThatOnlyOccurAfterFlashLoads.indexOf(event.name) !== -1) { + isSandboxed = false; + } + return isSandboxed; + }; + /** + * Preprocess any special behaviors, reactions, or state changes after receiving this event. + * Executes only once per event emitted, NOT once per client. + * @private + */ + var _preprocessEvent = function(event) { + var element = event.target || _currentElement || null; + var sourceIsSwf = event._source === "swf"; + delete event._source; + switch (event.type) { + case "error": + var isSandboxed = event.name === "flash-sandboxed" || _getSandboxStatusFromErrorEvent(event); + if (typeof isSandboxed === "boolean") { + _flashState.sandboxed = isSandboxed; + } + if (_flashStateErrorNames.indexOf(event.name) !== -1) { + _extend(_flashState, { + disabled: event.name === "flash-disabled", + outdated: event.name === "flash-outdated", + unavailable: event.name === "flash-unavailable", + degraded: event.name === "flash-degraded", + deactivated: event.name === "flash-deactivated", + overdue: event.name === "flash-overdue", + ready: false + }); + } else if (event.name === "version-mismatch") { + _zcSwfVersion = event.swfVersion; + _extend(_flashState, { + disabled: false, + outdated: false, + unavailable: false, + degraded: false, + deactivated: false, + overdue: false, + ready: false + }); + } + _clearTimeoutsAndPolling(); + break; + + case "ready": + _zcSwfVersion = event.swfVersion; + var wasDeactivated = _flashState.deactivated === true; + _extend(_flashState, { + disabled: false, + outdated: false, + sandboxed: false, + unavailable: false, + degraded: false, + deactivated: false, + overdue: wasDeactivated, + ready: !wasDeactivated + }); + _clearTimeoutsAndPolling(); + break; + + case "beforecopy": + _copyTarget = element; + break; + + case "copy": + var textContent, htmlContent, targetEl = event.relatedTarget; + if (!(_clipData["text/html"] || _clipData["text/plain"]) && targetEl && (htmlContent = targetEl.value || targetEl.outerHTML || targetEl.innerHTML) && (textContent = targetEl.value || targetEl.textContent || targetEl.innerText)) { + event.clipboardData.clearData(); + event.clipboardData.setData("text/plain", textContent); + if (htmlContent !== textContent) { + event.clipboardData.setData("text/html", htmlContent); + } + } else if (!_clipData["text/plain"] && event.target && (textContent = event.target.getAttribute("data-clipboard-text"))) { + event.clipboardData.clearData(); + event.clipboardData.setData("text/plain", textContent); + } + break; + + case "aftercopy": + _queueEmitClipboardErrors(event); + ZeroClipboard.clearData(); + if (element && element !== _safeActiveElement() && element.focus) { + element.focus(); + } + break; + + case "_mouseover": + ZeroClipboard.focus(element); + if (_globalConfig.bubbleEvents === true && sourceIsSwf) { + if (element && element !== event.relatedTarget && !_containedBy(event.relatedTarget, element)) { + _fireMouseEvent(_extend({}, event, { + type: "mouseenter", + bubbles: false, + cancelable: false + })); + } + _fireMouseEvent(_extend({}, event, { + type: "mouseover" + })); + } + break; + + case "_mouseout": + ZeroClipboard.blur(); + if (_globalConfig.bubbleEvents === true && sourceIsSwf) { + if (element && element !== event.relatedTarget && !_containedBy(event.relatedTarget, element)) { + _fireMouseEvent(_extend({}, event, { + type: "mouseleave", + bubbles: false, + cancelable: false + })); + } + _fireMouseEvent(_extend({}, event, { + type: "mouseout" + })); + } + break; + + case "_mousedown": + _addClass(element, _globalConfig.activeClass); + if (_globalConfig.bubbleEvents === true && sourceIsSwf) { + _fireMouseEvent(_extend({}, event, { + type: event.type.slice(1) + })); + } + break; + + case "_mouseup": + _removeClass(element, _globalConfig.activeClass); + if (_globalConfig.bubbleEvents === true && sourceIsSwf) { + _fireMouseEvent(_extend({}, event, { + type: event.type.slice(1) + })); + } + break; + + case "_click": + _copyTarget = null; + if (_globalConfig.bubbleEvents === true && sourceIsSwf) { + _fireMouseEvent(_extend({}, event, { + type: event.type.slice(1) + })); + } + break; + + case "_mousemove": + if (_globalConfig.bubbleEvents === true && sourceIsSwf) { + _fireMouseEvent(_extend({}, event, { + type: event.type.slice(1) + })); + } + break; + } + if (/^_(?:click|mouse(?:over|out|down|up|move))$/.test(event.type)) { + return true; + } + }; + /** + * Check an "aftercopy" event for clipboard errors and emit a corresponding "error" event. + * @private + */ + var _queueEmitClipboardErrors = function(aftercopyEvent) { + if (aftercopyEvent.errors && aftercopyEvent.errors.length > 0) { + var errorEvent = _deepCopy(aftercopyEvent); + _extend(errorEvent, { + type: "error", + name: "clipboard-error" + }); + delete errorEvent.success; + _setTimeout(function() { + ZeroClipboard.emit(errorEvent); + }, 0); + } + }; + /** + * Dispatch a synthetic MouseEvent. + * + * @returns `undefined` + * @private + */ + var _fireMouseEvent = function(event) { + if (!(event && typeof event.type === "string" && event)) { + return; + } + var e, target = event.target || null, doc = target && target.ownerDocument || _document, defaults = { + view: doc.defaultView || _window, + canBubble: true, + cancelable: true, + detail: event.type === "click" ? 1 : 0, + button: typeof event.which === "number" ? event.which - 1 : typeof event.button === "number" ? event.button : doc.createEvent ? 0 : 1 + }, args = _extend(defaults, event); + if (!target) { + return; + } + if (doc.createEvent && target.dispatchEvent) { + 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 ]; + e = doc.createEvent("MouseEvents"); + if (e.initMouseEvent) { + e.initMouseEvent.apply(e, args); + e._source = "js"; + target.dispatchEvent(e); + } + } + }; + /** + * Continuously poll the DOM until either: + * (a) the fallback content becomes visible, or + * (b) we receive an event from SWF (handled elsewhere) + * + * IMPORTANT: + * This is NOT a necessary check but it can result in significantly faster + * detection of bad `swfPath` configuration and/or network/server issues [in + * supported browsers] than waiting for the entire `flashLoadTimeout` duration + * to elapse before detecting that the SWF cannot be loaded. The detection + * duration can be anywhere from 10-30 times faster [in supported browsers] by + * using this approach. + * + * @returns `undefined` + * @private + */ + var _watchForSwfFallbackContent = function() { + var maxWait = _globalConfig.flashLoadTimeout; + if (typeof maxWait === "number" && maxWait >= 0) { + var pollWait = Math.min(1e3, maxWait / 10); + var fallbackContentId = _globalConfig.swfObjectId + "_fallbackContent"; + _swfFallbackCheckInterval = _setInterval(function() { + var el = _document.getElementById(fallbackContentId); + if (_isElementVisible(el)) { + _clearTimeoutsAndPolling(); + _flashState.deactivated = null; + ZeroClipboard.emit({ + type: "error", + name: "swf-not-found" + }); + } + }, pollWait); + } + }; + /** + * Create the HTML bridge element to embed the Flash object into. + * @private + */ + var _createHtmlBridge = function() { + var container = _document.createElement("div"); + container.id = _globalConfig.containerId; + container.className = _globalConfig.containerClass; + container.style.position = "absolute"; + container.style.left = "0px"; + container.style.top = "-9999px"; + container.style.width = "1px"; + container.style.height = "1px"; + container.style.zIndex = "" + _getSafeZIndex(_globalConfig.zIndex); + return container; + }; + /** + * Get the HTML element container that wraps the Flash bridge object/element. + * @private + */ + var _getHtmlBridge = function(flashBridge) { + var htmlBridge = flashBridge && flashBridge.parentNode; + while (htmlBridge && htmlBridge.nodeName === "OBJECT" && htmlBridge.parentNode) { + htmlBridge = htmlBridge.parentNode; + } + return htmlBridge || null; + }; + /** + * Create the SWF object. + * + * @returns The SWF object reference. + * @private + */ + var _embedSwf = function() { + var len, flashBridge = _flashState.bridge, container = _getHtmlBridge(flashBridge); + if (!flashBridge) { + var allowScriptAccess = _determineScriptAccess(_window.location.host, _globalConfig); + var allowNetworking = allowScriptAccess === "never" ? "none" : "all"; + var flashvars = _vars(_extend({ + jsVersion: ZeroClipboard.version + }, _globalConfig)); + var swfUrl = _globalConfig.swfPath + _cacheBust(_globalConfig.swfPath, _globalConfig); + container = _createHtmlBridge(); + var divToBeReplaced = _document.createElement("div"); + container.appendChild(divToBeReplaced); + _document.body.appendChild(container); + var tmpDiv = _document.createElement("div"); + var usingActiveX = _flashState.pluginType === "activex"; + tmpDiv.innerHTML = '" + (usingActiveX ? '' : "") + '' + '' + '' + '' + '' + '
 
' + "
"; + flashBridge = tmpDiv.firstChild; + tmpDiv = null; + _unwrap(flashBridge).ZeroClipboard = ZeroClipboard; + container.replaceChild(flashBridge, divToBeReplaced); + _watchForSwfFallbackContent(); + } + if (!flashBridge) { + flashBridge = _document[_globalConfig.swfObjectId]; + if (flashBridge && (len = flashBridge.length)) { + flashBridge = flashBridge[len - 1]; + } + if (!flashBridge && container) { + flashBridge = container.firstChild; + } + } + _flashState.bridge = flashBridge || null; + return flashBridge; + }; + /** + * Destroy the SWF object. + * @private + */ + var _unembedSwf = function() { + var flashBridge = _flashState.bridge; + if (flashBridge) { + var htmlBridge = _getHtmlBridge(flashBridge); + if (htmlBridge) { + if (_flashState.pluginType === "activex" && "readyState" in flashBridge) { + flashBridge.style.display = "none"; + (function removeSwfFromIE() { + if (flashBridge.readyState === 4) { + for (var prop in flashBridge) { + if (typeof flashBridge[prop] === "function") { + flashBridge[prop] = null; + } + } + if (flashBridge.parentNode) { + flashBridge.parentNode.removeChild(flashBridge); + } + if (htmlBridge.parentNode) { + htmlBridge.parentNode.removeChild(htmlBridge); + } + } else { + _setTimeout(removeSwfFromIE, 10); + } + })(); + } else { + if (flashBridge.parentNode) { + flashBridge.parentNode.removeChild(flashBridge); + } + if (htmlBridge.parentNode) { + htmlBridge.parentNode.removeChild(htmlBridge); + } + } + } + _clearTimeoutsAndPolling(); + _flashState.ready = null; + _flashState.bridge = null; + _flashState.deactivated = null; + _zcSwfVersion = undefined; + } + }; + /** + * Map the data format names of the "clipData" to Flash-friendly names. + * + * @returns A new transformed object. + * @private + */ + var _mapClipDataToFlash = function(clipData) { + var newClipData = {}, formatMap = {}; + if (!(typeof clipData === "object" && clipData)) { + return; + } + for (var dataFormat in clipData) { + if (dataFormat && _hasOwn.call(clipData, dataFormat) && typeof clipData[dataFormat] === "string" && clipData[dataFormat]) { + switch (dataFormat.toLowerCase()) { + case "text/plain": + case "text": + case "air:text": + case "flash:text": + newClipData.text = clipData[dataFormat]; + formatMap.text = dataFormat; + break; + + case "text/html": + case "html": + case "air:html": + case "flash:html": + newClipData.html = clipData[dataFormat]; + formatMap.html = dataFormat; + break; + + case "application/rtf": + case "text/rtf": + case "rtf": + case "richtext": + case "air:rtf": + case "flash:rtf": + newClipData.rtf = clipData[dataFormat]; + formatMap.rtf = dataFormat; + break; + + default: + break; + } + } + } + return { + data: newClipData, + formatMap: formatMap + }; + }; + /** + * Map the data format names from Flash-friendly names back to their original "clipData" names (via a format mapping). + * + * @returns A new transformed object. + * @private + */ + var _mapClipResultsFromFlash = function(clipResults, formatMap) { + if (!(typeof clipResults === "object" && clipResults && typeof formatMap === "object" && formatMap)) { + return clipResults; + } + var newResults = {}; + for (var prop in clipResults) { + if (_hasOwn.call(clipResults, prop)) { + if (prop === "errors") { + newResults[prop] = clipResults[prop] ? clipResults[prop].slice() : []; + for (var i = 0, len = newResults[prop].length; i < len; i++) { + newResults[prop][i].format = formatMap[newResults[prop][i].format]; + } + } else if (prop !== "success" && prop !== "data") { + newResults[prop] = clipResults[prop]; + } else { + newResults[prop] = {}; + var tmpHash = clipResults[prop]; + for (var dataFormat in tmpHash) { + if (dataFormat && _hasOwn.call(tmpHash, dataFormat) && _hasOwn.call(formatMap, dataFormat)) { + newResults[prop][formatMap[dataFormat]] = tmpHash[dataFormat]; + } + } + } + } + } + return newResults; + }; + /** + * Will look at a path, and will create a "?noCache={time}" or "&noCache={time}" + * query param string to return. Does NOT append that string to the original path. + * This is useful because ExternalInterface often breaks when a Flash SWF is cached. + * + * @returns The `noCache` query param with necessary "?"/"&" prefix. + * @private + */ + var _cacheBust = function(path, options) { + var cacheBust = options == null || options && options.cacheBust === true; + if (cacheBust) { + return (path.indexOf("?") === -1 ? "?" : "&") + "noCache=" + _now(); + } else { + return ""; + } + }; + /** + * Creates a query string for the FlashVars param. + * Does NOT include the cache-busting query param. + * + * @returns FlashVars query string + * @private + */ + var _vars = function(options) { + var i, len, domain, domains, str = "", trustedOriginsExpanded = []; + if (options.trustedDomains) { + if (typeof options.trustedDomains === "string") { + domains = [ options.trustedDomains ]; + } else if (typeof options.trustedDomains === "object" && "length" in options.trustedDomains) { + domains = options.trustedDomains; + } + } + if (domains && domains.length) { + for (i = 0, len = domains.length; i < len; i++) { + if (_hasOwn.call(domains, i) && domains[i] && typeof domains[i] === "string") { + domain = _extractDomain(domains[i]); + if (!domain) { + continue; + } + if (domain === "*") { + trustedOriginsExpanded.length = 0; + trustedOriginsExpanded.push(domain); + break; + } + trustedOriginsExpanded.push.apply(trustedOriginsExpanded, [ domain, "//" + domain, _window.location.protocol + "//" + domain ]); + } + } + } + if (trustedOriginsExpanded.length) { + str += "trustedOrigins=" + _encodeURIComponent(trustedOriginsExpanded.join(",")); + } + if (options.forceEnhancedClipboard === true) { + str += (str ? "&" : "") + "forceEnhancedClipboard=true"; + } + if (typeof options.swfObjectId === "string" && options.swfObjectId) { + str += (str ? "&" : "") + "swfObjectId=" + _encodeURIComponent(options.swfObjectId); + } + if (typeof options.jsVersion === "string" && options.jsVersion) { + str += (str ? "&" : "") + "jsVersion=" + _encodeURIComponent(options.jsVersion); + } + return str; + }; + /** + * Extract the domain (e.g. "github.com") from an origin (e.g. "https://github.com") or + * URL (e.g. "https://github.com/zeroclipboard/zeroclipboard/"). + * + * @returns the domain + * @private + */ + var _extractDomain = function(originOrUrl) { + if (originOrUrl == null || originOrUrl === "") { + return null; + } + originOrUrl = originOrUrl.replace(/^\s+|\s+$/g, ""); + if (originOrUrl === "") { + return null; + } + var protocolIndex = originOrUrl.indexOf("//"); + originOrUrl = protocolIndex === -1 ? originOrUrl : originOrUrl.slice(protocolIndex + 2); + var pathIndex = originOrUrl.indexOf("/"); + originOrUrl = pathIndex === -1 ? originOrUrl : protocolIndex === -1 || pathIndex === 0 ? null : originOrUrl.slice(0, pathIndex); + if (originOrUrl && originOrUrl.slice(-4).toLowerCase() === ".swf") { + return null; + } + return originOrUrl || null; + }; + /** + * Set `allowScriptAccess` based on `trustedDomains` and `window.location.host` vs. `swfPath`. + * + * @returns The appropriate script access level. + * @private + */ + var _determineScriptAccess = function() { + var _extractAllDomains = function(origins) { + var i, len, tmp, resultsArray = []; + if (typeof origins === "string") { + origins = [ origins ]; + } + if (!(typeof origins === "object" && origins && typeof origins.length === "number")) { + return resultsArray; + } + for (i = 0, len = origins.length; i < len; i++) { + if (_hasOwn.call(origins, i) && (tmp = _extractDomain(origins[i]))) { + if (tmp === "*") { + resultsArray.length = 0; + resultsArray.push("*"); + break; + } + if (resultsArray.indexOf(tmp) === -1) { + resultsArray.push(tmp); + } + } + } + return resultsArray; + }; + return function(currentDomain, configOptions) { + var swfDomain = _extractDomain(configOptions.swfPath); + if (swfDomain === null) { + swfDomain = currentDomain; + } + var trustedDomains = _extractAllDomains(configOptions.trustedDomains); + var len = trustedDomains.length; + if (len > 0) { + if (len === 1 && trustedDomains[0] === "*") { + return "always"; + } + if (trustedDomains.indexOf(currentDomain) !== -1) { + if (len === 1 && currentDomain === swfDomain) { + return "sameDomain"; + } + return "always"; + } + } + return "never"; + }; + }(); + /** + * Get the currently active/focused DOM element. + * + * @returns the currently active/focused element, or `null` + * @private + */ + var _safeActiveElement = function() { + try { + return _document.activeElement; + } catch (err) { + return null; + } + }; + /** + * Add a class to an element, if it doesn't already have it. + * + * @returns The element, with its new class added. + * @private + */ + var _addClass = function(element, value) { + var c, cl, className, classNames = []; + if (typeof value === "string" && value) { + classNames = value.split(/\s+/); + } + if (element && element.nodeType === 1 && classNames.length > 0) { + if (element.classList) { + for (c = 0, cl = classNames.length; c < cl; c++) { + element.classList.add(classNames[c]); + } + } else if (element.hasOwnProperty("className")) { + className = " " + element.className + " "; + for (c = 0, cl = classNames.length; c < cl; c++) { + if (className.indexOf(" " + classNames[c] + " ") === -1) { + className += classNames[c] + " "; + } + } + element.className = className.replace(/^\s+|\s+$/g, ""); + } + } + return element; + }; + /** + * Remove a class from an element, if it has it. + * + * @returns The element, with its class removed. + * @private + */ + var _removeClass = function(element, value) { + var c, cl, className, classNames = []; + if (typeof value === "string" && value) { + classNames = value.split(/\s+/); + } + if (element && element.nodeType === 1 && classNames.length > 0) { + if (element.classList && element.classList.length > 0) { + for (c = 0, cl = classNames.length; c < cl; c++) { + element.classList.remove(classNames[c]); + } + } else if (element.className) { + className = (" " + element.className + " ").replace(/[\r\n\t]/g, " "); + for (c = 0, cl = classNames.length; c < cl; c++) { + className = className.replace(" " + classNames[c] + " ", " "); + } + element.className = className.replace(/^\s+|\s+$/g, ""); + } + } + return element; + }; + /** + * Attempt to interpret the element's CSS styling. If `prop` is `"cursor"`, + * then we assume that it should be a hand ("pointer") cursor if the element + * is an anchor element ("a" tag). + * + * @returns The computed style property. + * @private + */ + var _getStyle = function(el, prop) { + var value = _getComputedStyle(el, null).getPropertyValue(prop); + if (prop === "cursor") { + if (!value || value === "auto") { + if (el.nodeName === "A") { + return "pointer"; + } + } + } + return value; + }; + /** + * Get the absolutely positioned coordinates of a DOM element. + * + * @returns Object containing the element's position, width, and height. + * @private + */ + var _getElementPosition = function(el) { + var pos = { + left: 0, + top: 0, + width: 0, + height: 0 + }; + if (el.getBoundingClientRect) { + var elRect = el.getBoundingClientRect(); + var pageXOffset = _window.pageXOffset; + var pageYOffset = _window.pageYOffset; + var leftBorderWidth = _document.documentElement.clientLeft || 0; + var topBorderWidth = _document.documentElement.clientTop || 0; + var leftBodyOffset = 0; + var topBodyOffset = 0; + if (_getStyle(_document.body, "position") === "relative") { + var bodyRect = _document.body.getBoundingClientRect(); + var htmlRect = _document.documentElement.getBoundingClientRect(); + leftBodyOffset = bodyRect.left - htmlRect.left || 0; + topBodyOffset = bodyRect.top - htmlRect.top || 0; + } + pos.left = elRect.left + pageXOffset - leftBorderWidth - leftBodyOffset; + pos.top = elRect.top + pageYOffset - topBorderWidth - topBodyOffset; + pos.width = "width" in elRect ? elRect.width : elRect.right - elRect.left; + pos.height = "height" in elRect ? elRect.height : elRect.bottom - elRect.top; + } + return pos; + }; + /** + * Determine is an element is visible somewhere within the document (page). + * + * @returns Boolean + * @private + */ + var _isElementVisible = function(el) { + if (!el) { + return false; + } + var styles = _getComputedStyle(el, null); + var hasCssHeight = _parseFloat(styles.height) > 0; + var hasCssWidth = _parseFloat(styles.width) > 0; + var hasCssTop = _parseFloat(styles.top) >= 0; + var hasCssLeft = _parseFloat(styles.left) >= 0; + var cssKnows = hasCssHeight && hasCssWidth && hasCssTop && hasCssLeft; + var rect = cssKnows ? null : _getElementPosition(el); + 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)); + return isVisible; + }; + /** + * Clear all existing timeouts and interval polling delegates. + * + * @returns `undefined` + * @private + */ + var _clearTimeoutsAndPolling = function() { + _clearTimeout(_flashCheckTimeout); + _flashCheckTimeout = 0; + _clearInterval(_swfFallbackCheckInterval); + _swfFallbackCheckInterval = 0; + }; + /** + * Reposition the Flash object to cover the currently activated element. + * + * @returns `undefined` + * @private + */ + var _reposition = function() { + var htmlBridge; + if (_currentElement && (htmlBridge = _getHtmlBridge(_flashState.bridge))) { + var pos = _getElementPosition(_currentElement); + _extend(htmlBridge.style, { + width: pos.width + "px", + height: pos.height + "px", + top: pos.top + "px", + left: pos.left + "px", + zIndex: "" + _getSafeZIndex(_globalConfig.zIndex) + }); + } + }; + /** + * Sends a signal to the Flash object to display the hand cursor if `true`. + * + * @returns `undefined` + * @private + */ + var _setHandCursor = function(enabled) { + if (_flashState.ready === true) { + if (_flashState.bridge && typeof _flashState.bridge.setHandCursor === "function") { + _flashState.bridge.setHandCursor(enabled); + } else { + _flashState.ready = false; + } + } + }; + /** + * Get a safe value for `zIndex` + * + * @returns an integer, or "auto" + * @private + */ + var _getSafeZIndex = function(val) { + if (/^(?:auto|inherit)$/.test(val)) { + return val; + } + var zIndex; + if (typeof val === "number" && !_isNaN(val)) { + zIndex = val; + } else if (typeof val === "string") { + zIndex = _getSafeZIndex(_parseInt(val, 10)); + } + return typeof zIndex === "number" ? zIndex : "auto"; + }; + /** + * Attempt to detect if ZeroClipboard is executing inside of a sandboxed iframe. + * If it is, Flash Player cannot be used, so ZeroClipboard is dead in the water. + * + * @see {@link http://lists.w3.org/Archives/Public/public-whatwg-archive/2014Dec/0002.html} + * @see {@link https://github.com/zeroclipboard/zeroclipboard/issues/511} + * @see {@link http://zeroclipboard.org/test-iframes.html} + * + * @returns `true` (is sandboxed), `false` (is not sandboxed), or `null` (uncertain) + * @private + */ + var _detectSandbox = function(doNotReassessFlashSupport) { + var effectiveScriptOrigin, frame, frameError, previousState = _flashState.sandboxed, isSandboxed = null; + doNotReassessFlashSupport = doNotReassessFlashSupport === true; + if (_pageIsFramed === false) { + isSandboxed = false; + } else { + try { + frame = window.frameElement || null; + } catch (e) { + frameError = { + name: e.name, + message: e.message + }; + } + if (frame && frame.nodeType === 1 && frame.nodeName === "IFRAME") { + try { + isSandboxed = frame.hasAttribute("sandbox"); + } catch (e) { + isSandboxed = null; + } + } else { + try { + effectiveScriptOrigin = document.domain || null; + } catch (e) { + effectiveScriptOrigin = null; + } + if (effectiveScriptOrigin === null || frameError && frameError.name === "SecurityError" && /(^|[\s\(\[@])sandbox(es|ed|ing|[\s\.,!\)\]@]|$)/.test(frameError.message.toLowerCase())) { + isSandboxed = true; + } + } + } + _flashState.sandboxed = isSandboxed; + if (previousState !== isSandboxed && !doNotReassessFlashSupport) { + _detectFlashSupport(_ActiveXObject); + } + return isSandboxed; + }; + /** + * Detect the Flash Player status, version, and plugin type. + * + * @see {@link https://code.google.com/p/doctype-mirror/wiki/ArticleDetectFlash#The_code} + * @see {@link http://stackoverflow.com/questions/12866060/detecting-pepper-ppapi-flash-with-javascript} + * + * @returns `undefined` + * @private + */ + var _detectFlashSupport = function(ActiveXObject) { + var plugin, ax, mimeType, hasFlash = false, isActiveX = false, isPPAPI = false, flashVersion = ""; + /** + * Derived from Apple's suggested sniffer. + * @param {String} desc e.g. "Shockwave Flash 7.0 r61" + * @returns {String} "7.0.61" + * @private + */ + function parseFlashVersion(desc) { + var matches = desc.match(/[\d]+/g); + matches.length = 3; + return matches.join("."); + } + function isPepperFlash(flashPlayerFileName) { + return !!flashPlayerFileName && (flashPlayerFileName = flashPlayerFileName.toLowerCase()) && (/^(pepflashplayer\.dll|libpepflashplayer\.so|pepperflashplayer\.plugin)$/.test(flashPlayerFileName) || flashPlayerFileName.slice(-13) === "chrome.plugin"); + } + function inspectPlugin(plugin) { + if (plugin) { + hasFlash = true; + if (plugin.version) { + flashVersion = parseFlashVersion(plugin.version); + } + if (!flashVersion && plugin.description) { + flashVersion = parseFlashVersion(plugin.description); + } + if (plugin.filename) { + isPPAPI = isPepperFlash(plugin.filename); + } + } + } + if (_navigator.plugins && _navigator.plugins.length) { + plugin = _navigator.plugins["Shockwave Flash"]; + inspectPlugin(plugin); + if (_navigator.plugins["Shockwave Flash 2.0"]) { + hasFlash = true; + flashVersion = "2.0.0.11"; + } + } else if (_navigator.mimeTypes && _navigator.mimeTypes.length) { + mimeType = _navigator.mimeTypes["application/x-shockwave-flash"]; + plugin = mimeType && mimeType.enabledPlugin; + inspectPlugin(plugin); + } else if (typeof ActiveXObject !== "undefined") { + isActiveX = true; + try { + ax = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7"); + hasFlash = true; + flashVersion = parseFlashVersion(ax.GetVariable("$version")); + } catch (e1) { + try { + ax = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6"); + hasFlash = true; + flashVersion = "6.0.21"; + } catch (e2) { + try { + ax = new ActiveXObject("ShockwaveFlash.ShockwaveFlash"); + hasFlash = true; + flashVersion = parseFlashVersion(ax.GetVariable("$version")); + } catch (e3) { + isActiveX = false; + } + } + } + } + _flashState.disabled = hasFlash !== true; + _flashState.outdated = flashVersion && _parseFloat(flashVersion) < _parseFloat(_minimumFlashVersion); + _flashState.version = flashVersion || "0.0.0"; + _flashState.pluginType = isPPAPI ? "pepper" : isActiveX ? "activex" : hasFlash ? "netscape" : "unknown"; + }; + /** + * Invoke the Flash detection algorithms immediately upon inclusion so we're not waiting later. + */ + _detectFlashSupport(_ActiveXObject); + /** + * Always assess the `sandboxed` state of the page at important Flash-related moments. + */ + _detectSandbox(true); + /** + * A shell constructor for `ZeroClipboard` client instances. + * + * @constructor + */ + var ZeroClipboard = function() { + if (!(this instanceof ZeroClipboard)) { + return new ZeroClipboard(); + } + if (typeof ZeroClipboard._createClient === "function") { + ZeroClipboard._createClient.apply(this, _args(arguments)); + } + }; + /** + * The ZeroClipboard library's version number. + * + * @static + * @readonly + * @property {string} + */ + _defineProperty(ZeroClipboard, "version", { + value: "2.2.0", + writable: false, + configurable: true, + enumerable: true + }); + /** + * Update or get a copy of the ZeroClipboard global configuration. + * Returns a copy of the current/updated configuration. + * + * @returns Object + * @static + */ + ZeroClipboard.config = function() { + return _config.apply(this, _args(arguments)); + }; + /** + * Diagnostic method that describes the state of the browser, Flash Player, and ZeroClipboard. + * + * @returns Object + * @static + */ + ZeroClipboard.state = function() { + return _state.apply(this, _args(arguments)); + }; + /** + * Check if Flash is unusable for any reason: disabled, outdated, deactivated, etc. + * + * @returns Boolean + * @static + */ + ZeroClipboard.isFlashUnusable = function() { + return _isFlashUnusable.apply(this, _args(arguments)); + }; + /** + * Register an event listener. + * + * @returns `ZeroClipboard` + * @static + */ + ZeroClipboard.on = function() { + return _on.apply(this, _args(arguments)); + }; + /** + * Unregister an event listener. + * If no `listener` function/object is provided, it will unregister all listeners for the provided `eventType`. + * If no `eventType` is provided, it will unregister all listeners for every event type. + * + * @returns `ZeroClipboard` + * @static + */ + ZeroClipboard.off = function() { + return _off.apply(this, _args(arguments)); + }; + /** + * Retrieve event listeners for an `eventType`. + * If no `eventType` is provided, it will retrieve all listeners for every event type. + * + * @returns array of listeners for the `eventType`; if no `eventType`, then a map/hash object of listeners for all event types; or `null` + */ + ZeroClipboard.handlers = function() { + return _listeners.apply(this, _args(arguments)); + }; + /** + * Event emission receiver from the Flash object, forwarding to any registered JavaScript event listeners. + * + * @returns For the "copy" event, returns the Flash-friendly "clipData" object; otherwise `undefined`. + * @static + */ + ZeroClipboard.emit = function() { + return _emit.apply(this, _args(arguments)); + }; + /** + * Create and embed the Flash object. + * + * @returns The Flash object + * @static + */ + ZeroClipboard.create = function() { + return _create.apply(this, _args(arguments)); + }; + /** + * Self-destruct and clean up everything, including the embedded Flash object. + * + * @returns `undefined` + * @static + */ + ZeroClipboard.destroy = function() { + return _destroy.apply(this, _args(arguments)); + }; + /** + * Set the pending data for clipboard injection. + * + * @returns `undefined` + * @static + */ + ZeroClipboard.setData = function() { + return _setData.apply(this, _args(arguments)); + }; + /** + * Clear the pending data for clipboard injection. + * If no `format` is provided, all pending data formats will be cleared. + * + * @returns `undefined` + * @static + */ + ZeroClipboard.clearData = function() { + return _clearData.apply(this, _args(arguments)); + }; + /** + * Get a copy of the pending data for clipboard injection. + * If no `format` is provided, a copy of ALL pending data formats will be returned. + * + * @returns `String` or `Object` + * @static + */ + ZeroClipboard.getData = function() { + return _getData.apply(this, _args(arguments)); + }; + /** + * Sets the current HTML object that the Flash object should overlay. This will put the global + * Flash object on top of the current element; depending on the setup, this may also set the + * pending clipboard text data as well as the Flash object's wrapping element's title attribute + * based on the underlying HTML element and ZeroClipboard configuration. + * + * @returns `undefined` + * @static + */ + ZeroClipboard.focus = ZeroClipboard.activate = function() { + return _focus.apply(this, _args(arguments)); + }; + /** + * Un-overlays the Flash object. This will put the global Flash object off-screen; depending on + * the setup, this may also unset the Flash object's wrapping element's title attribute based on + * the underlying HTML element and ZeroClipboard configuration. + * + * @returns `undefined` + * @static + */ + ZeroClipboard.blur = ZeroClipboard.deactivate = function() { + return _blur.apply(this, _args(arguments)); + }; + /** + * Returns the currently focused/"activated" HTML element that the Flash object is wrapping. + * + * @returns `HTMLElement` or `null` + * @static + */ + ZeroClipboard.activeElement = function() { + return _activeElement.apply(this, _args(arguments)); + }; + /** + * Keep track of the ZeroClipboard client instance counter. + */ + var _clientIdCounter = 0; + /** + * Keep track of the state of the client instances. + * + * Entry structure: + * _clientMeta[client.id] = { + * instance: client, + * elements: [], + * handlers: {} + * }; + */ + var _clientMeta = {}; + /** + * Keep track of the ZeroClipboard clipped elements counter. + */ + var _elementIdCounter = 0; + /** + * Keep track of the state of the clipped element relationships to clients. + * + * Entry structure: + * _elementMeta[element.zcClippingId] = [client1.id, client2.id]; + */ + var _elementMeta = {}; + /** + * Keep track of the state of the mouse event handlers for clipped elements. + * + * Entry structure: + * _mouseHandlers[element.zcClippingId] = { + * mouseover: function(event) {}, + * mouseout: function(event) {}, + * mouseenter: function(event) {}, + * mouseleave: function(event) {}, + * mousemove: function(event) {} + * }; + */ + var _mouseHandlers = {}; + /** + * Extending the ZeroClipboard configuration defaults for the Client module. + */ + _extend(_globalConfig, { + autoActivate: true + }); + /** + * The real constructor for `ZeroClipboard` client instances. + * @private + */ + var _clientConstructor = function(elements) { + var client = this; + client.id = "" + _clientIdCounter++; + _clientMeta[client.id] = { + instance: client, + elements: [], + handlers: {} + }; + if (elements) { + client.clip(elements); + } + ZeroClipboard.on("*", function(event) { + return client.emit(event); + }); + ZeroClipboard.on("destroy", function() { + client.destroy(); + }); + ZeroClipboard.create(); + }; + /** + * The underlying implementation of `ZeroClipboard.Client.prototype.on`. + * @private + */ + var _clientOn = function(eventType, listener) { + var i, len, events, added = {}, meta = _clientMeta[this.id], handlers = meta && meta.handlers; + if (!meta) { + throw new Error("Attempted to add new listener(s) to a destroyed ZeroClipboard client instance"); + } + if (typeof eventType === "string" && eventType) { + events = eventType.toLowerCase().split(/\s+/); + } else if (typeof eventType === "object" && eventType && typeof listener === "undefined") { + for (i in eventType) { + if (_hasOwn.call(eventType, i) && typeof i === "string" && i && typeof eventType[i] === "function") { + this.on(i, eventType[i]); + } + } + } + if (events && events.length) { + for (i = 0, len = events.length; i < len; i++) { + eventType = events[i].replace(/^on/, ""); + added[eventType] = true; + if (!handlers[eventType]) { + handlers[eventType] = []; + } + handlers[eventType].push(listener); + } + if (added.ready && _flashState.ready) { + this.emit({ + type: "ready", + client: this + }); + } + if (added.error) { + for (i = 0, len = _flashStateErrorNames.length; i < len; i++) { + if (_flashState[_flashStateErrorNames[i].replace(/^flash-/, "")]) { + this.emit({ + type: "error", + name: _flashStateErrorNames[i], + client: this + }); + break; + } + } + if (_zcSwfVersion !== undefined && ZeroClipboard.version !== _zcSwfVersion) { + this.emit({ + type: "error", + name: "version-mismatch", + jsVersion: ZeroClipboard.version, + swfVersion: _zcSwfVersion + }); + } + } + } + return this; + }; + /** + * The underlying implementation of `ZeroClipboard.Client.prototype.off`. + * @private + */ + var _clientOff = function(eventType, listener) { + var i, len, foundIndex, events, perEventHandlers, meta = _clientMeta[this.id], handlers = meta && meta.handlers; + if (!handlers) { + return this; + } + if (arguments.length === 0) { + events = _keys(handlers); + } else if (typeof eventType === "string" && eventType) { + events = eventType.split(/\s+/); + } else if (typeof eventType === "object" && eventType && typeof listener === "undefined") { + for (i in eventType) { + if (_hasOwn.call(eventType, i) && typeof i === "string" && i && typeof eventType[i] === "function") { + this.off(i, eventType[i]); + } + } + } + if (events && events.length) { + for (i = 0, len = events.length; i < len; i++) { + eventType = events[i].toLowerCase().replace(/^on/, ""); + perEventHandlers = handlers[eventType]; + if (perEventHandlers && perEventHandlers.length) { + if (listener) { + foundIndex = perEventHandlers.indexOf(listener); + while (foundIndex !== -1) { + perEventHandlers.splice(foundIndex, 1); + foundIndex = perEventHandlers.indexOf(listener, foundIndex); + } + } else { + perEventHandlers.length = 0; + } + } + } + } + return this; + }; + /** + * The underlying implementation of `ZeroClipboard.Client.prototype.handlers`. + * @private + */ + var _clientListeners = function(eventType) { + var copy = null, handlers = _clientMeta[this.id] && _clientMeta[this.id].handlers; + if (handlers) { + if (typeof eventType === "string" && eventType) { + copy = handlers[eventType] ? handlers[eventType].slice(0) : []; + } else { + copy = _deepCopy(handlers); + } + } + return copy; + }; + /** + * The underlying implementation of `ZeroClipboard.Client.prototype.emit`. + * @private + */ + var _clientEmit = function(event) { + if (_clientShouldEmit.call(this, event)) { + if (typeof event === "object" && event && typeof event.type === "string" && event.type) { + event = _extend({}, event); + } + var eventCopy = _extend({}, _createEvent(event), { + client: this + }); + _clientDispatchCallbacks.call(this, eventCopy); + } + return this; + }; + /** + * The underlying implementation of `ZeroClipboard.Client.prototype.clip`. + * @private + */ + var _clientClip = function(elements) { + if (!_clientMeta[this.id]) { + throw new Error("Attempted to clip element(s) to a destroyed ZeroClipboard client instance"); + } + elements = _prepClip(elements); + for (var i = 0; i < elements.length; i++) { + if (_hasOwn.call(elements, i) && elements[i] && elements[i].nodeType === 1) { + if (!elements[i].zcClippingId) { + elements[i].zcClippingId = "zcClippingId_" + _elementIdCounter++; + _elementMeta[elements[i].zcClippingId] = [ this.id ]; + if (_globalConfig.autoActivate === true) { + _addMouseHandlers(elements[i]); + } + } else if (_elementMeta[elements[i].zcClippingId].indexOf(this.id) === -1) { + _elementMeta[elements[i].zcClippingId].push(this.id); + } + var clippedElements = _clientMeta[this.id] && _clientMeta[this.id].elements; + if (clippedElements.indexOf(elements[i]) === -1) { + clippedElements.push(elements[i]); + } + } + } + return this; + }; + /** + * The underlying implementation of `ZeroClipboard.Client.prototype.unclip`. + * @private + */ + var _clientUnclip = function(elements) { + var meta = _clientMeta[this.id]; + if (!meta) { + return this; + } + var clippedElements = meta.elements; + var arrayIndex; + if (typeof elements === "undefined") { + elements = clippedElements.slice(0); + } else { + elements = _prepClip(elements); + } + for (var i = elements.length; i--; ) { + if (_hasOwn.call(elements, i) && elements[i] && elements[i].nodeType === 1) { + arrayIndex = 0; + while ((arrayIndex = clippedElements.indexOf(elements[i], arrayIndex)) !== -1) { + clippedElements.splice(arrayIndex, 1); + } + var clientIds = _elementMeta[elements[i].zcClippingId]; + if (clientIds) { + arrayIndex = 0; + while ((arrayIndex = clientIds.indexOf(this.id, arrayIndex)) !== -1) { + clientIds.splice(arrayIndex, 1); + } + if (clientIds.length === 0) { + if (_globalConfig.autoActivate === true) { + _removeMouseHandlers(elements[i]); + } + delete elements[i].zcClippingId; + } + } + } + } + return this; + }; + /** + * The underlying implementation of `ZeroClipboard.Client.prototype.elements`. + * @private + */ + var _clientElements = function() { + var meta = _clientMeta[this.id]; + return meta && meta.elements ? meta.elements.slice(0) : []; + }; + /** + * The underlying implementation of `ZeroClipboard.Client.prototype.destroy`. + * @private + */ + var _clientDestroy = function() { + if (!_clientMeta[this.id]) { + return; + } + this.unclip(); + this.off(); + delete _clientMeta[this.id]; + }; + /** + * Inspect an Event to see if the Client (`this`) should honor it for emission. + * @private + */ + var _clientShouldEmit = function(event) { + if (!(event && event.type)) { + return false; + } + if (event.client && event.client !== this) { + return false; + } + var meta = _clientMeta[this.id]; + var clippedEls = meta && meta.elements; + var hasClippedEls = !!clippedEls && clippedEls.length > 0; + var goodTarget = !event.target || hasClippedEls && clippedEls.indexOf(event.target) !== -1; + var goodRelTarget = event.relatedTarget && hasClippedEls && clippedEls.indexOf(event.relatedTarget) !== -1; + var goodClient = event.client && event.client === this; + if (!meta || !(goodTarget || goodRelTarget || goodClient)) { + return false; + } + return true; + }; + /** + * Handle the actual dispatching of events to a client instance. + * + * @returns `undefined` + * @private + */ + var _clientDispatchCallbacks = function(event) { + var meta = _clientMeta[this.id]; + if (!(typeof event === "object" && event && event.type && meta)) { + return; + } + var async = _shouldPerformAsync(event); + var wildcardTypeHandlers = meta && meta.handlers["*"] || []; + var specificTypeHandlers = meta && meta.handlers[event.type] || []; + var handlers = wildcardTypeHandlers.concat(specificTypeHandlers); + if (handlers && handlers.length) { + var i, len, func, context, eventCopy, originalContext = this; + for (i = 0, len = handlers.length; i < len; i++) { + func = handlers[i]; + context = originalContext; + if (typeof func === "string" && typeof _window[func] === "function") { + func = _window[func]; + } + if (typeof func === "object" && func && typeof func.handleEvent === "function") { + context = func; + func = func.handleEvent; + } + if (typeof func === "function") { + eventCopy = _extend({}, event); + _dispatchCallback(func, context, [ eventCopy ], async); + } + } + } + }; + /** + * Prepares the elements for clipping/unclipping. + * + * @returns An Array of elements. + * @private + */ + var _prepClip = function(elements) { + if (typeof elements === "string") { + elements = []; + } + return typeof elements.length !== "number" ? [ elements ] : elements; + }; + /** + * Add a `mouseover` handler function for a clipped element. + * + * @returns `undefined` + * @private + */ + var _addMouseHandlers = function(element) { + if (!(element && element.nodeType === 1)) { + return; + } + var _suppressMouseEvents = function(event) { + if (!(event || (event = _window.event))) { + return; + } + if (event._source !== "js") { + event.stopImmediatePropagation(); + event.preventDefault(); + } + delete event._source; + }; + var _elementMouseOver = function(event) { + if (!(event || (event = _window.event))) { + return; + } + _suppressMouseEvents(event); + ZeroClipboard.focus(element); + }; + element.addEventListener("mouseover", _elementMouseOver, false); + element.addEventListener("mouseout", _suppressMouseEvents, false); + element.addEventListener("mouseenter", _suppressMouseEvents, false); + element.addEventListener("mouseleave", _suppressMouseEvents, false); + element.addEventListener("mousemove", _suppressMouseEvents, false); + _mouseHandlers[element.zcClippingId] = { + mouseover: _elementMouseOver, + mouseout: _suppressMouseEvents, + mouseenter: _suppressMouseEvents, + mouseleave: _suppressMouseEvents, + mousemove: _suppressMouseEvents + }; + }; + /** + * Remove a `mouseover` handler function for a clipped element. + * + * @returns `undefined` + * @private + */ + var _removeMouseHandlers = function(element) { + if (!(element && element.nodeType === 1)) { + return; + } + var mouseHandlers = _mouseHandlers[element.zcClippingId]; + if (!(typeof mouseHandlers === "object" && mouseHandlers)) { + return; + } + var key, val, mouseEvents = [ "move", "leave", "enter", "out", "over" ]; + for (var i = 0, len = mouseEvents.length; i < len; i++) { + key = "mouse" + mouseEvents[i]; + val = mouseHandlers[key]; + if (typeof val === "function") { + element.removeEventListener(key, val, false); + } + } + delete _mouseHandlers[element.zcClippingId]; + }; + /** + * Creates a new ZeroClipboard client instance. + * Optionally, auto-`clip` an element or collection of elements. + * + * @constructor + */ + ZeroClipboard._createClient = function() { + _clientConstructor.apply(this, _args(arguments)); + }; + /** + * Register an event listener to the client. + * + * @returns `this` + */ + ZeroClipboard.prototype.on = function() { + return _clientOn.apply(this, _args(arguments)); + }; + /** + * Unregister an event handler from the client. + * If no `listener` function/object is provided, it will unregister all handlers for the provided `eventType`. + * If no `eventType` is provided, it will unregister all handlers for every event type. + * + * @returns `this` + */ + ZeroClipboard.prototype.off = function() { + return _clientOff.apply(this, _args(arguments)); + }; + /** + * Retrieve event listeners for an `eventType` from the client. + * If no `eventType` is provided, it will retrieve all listeners for every event type. + * + * @returns array of listeners for the `eventType`; if no `eventType`, then a map/hash object of listeners for all event types; or `null` + */ + ZeroClipboard.prototype.handlers = function() { + return _clientListeners.apply(this, _args(arguments)); + }; + /** + * Event emission receiver from the Flash object for this client's registered JavaScript event listeners. + * + * @returns For the "copy" event, returns the Flash-friendly "clipData" object; otherwise `undefined`. + */ + ZeroClipboard.prototype.emit = function() { + return _clientEmit.apply(this, _args(arguments)); + }; + /** + * Register clipboard actions for new element(s) to the client. + * + * @returns `this` + */ + ZeroClipboard.prototype.clip = function() { + return _clientClip.apply(this, _args(arguments)); + }; + /** + * Unregister the clipboard actions of previously registered element(s) on the page. + * If no elements are provided, ALL registered elements will be unregistered. + * + * @returns `this` + */ + ZeroClipboard.prototype.unclip = function() { + return _clientUnclip.apply(this, _args(arguments)); + }; + /** + * Get all of the elements to which this client is clipped. + * + * @returns array of clipped elements + */ + ZeroClipboard.prototype.elements = function() { + return _clientElements.apply(this, _args(arguments)); + }; + /** + * Self-destruct and clean up everything for a single client. + * This will NOT destroy the embedded Flash object. + * + * @returns `undefined` + */ + ZeroClipboard.prototype.destroy = function() { + return _clientDestroy.apply(this, _args(arguments)); + }; + /** + * Stores the pending plain text to inject into the clipboard. + * + * @returns `this` + */ + ZeroClipboard.prototype.setText = function(text) { + if (!_clientMeta[this.id]) { + throw new Error("Attempted to set pending clipboard data from a destroyed ZeroClipboard client instance"); + } + ZeroClipboard.setData("text/plain", text); + return this; + }; + /** + * Stores the pending HTML text to inject into the clipboard. + * + * @returns `this` + */ + ZeroClipboard.prototype.setHtml = function(html) { + if (!_clientMeta[this.id]) { + throw new Error("Attempted to set pending clipboard data from a destroyed ZeroClipboard client instance"); + } + ZeroClipboard.setData("text/html", html); + return this; + }; + /** + * Stores the pending rich text (RTF) to inject into the clipboard. + * + * @returns `this` + */ + ZeroClipboard.prototype.setRichText = function(richText) { + if (!_clientMeta[this.id]) { + throw new Error("Attempted to set pending clipboard data from a destroyed ZeroClipboard client instance"); + } + ZeroClipboard.setData("application/rtf", richText); + return this; + }; + /** + * Stores the pending data to inject into the clipboard. + * + * @returns `this` + */ + ZeroClipboard.prototype.setData = function() { + if (!_clientMeta[this.id]) { + throw new Error("Attempted to set pending clipboard data from a destroyed ZeroClipboard client instance"); + } + ZeroClipboard.setData.apply(this, _args(arguments)); + return this; + }; + /** + * Clears the pending data to inject into the clipboard. + * If no `format` is provided, all pending data formats will be cleared. + * + * @returns `this` + */ + ZeroClipboard.prototype.clearData = function() { + if (!_clientMeta[this.id]) { + throw new Error("Attempted to clear pending clipboard data from a destroyed ZeroClipboard client instance"); + } + ZeroClipboard.clearData.apply(this, _args(arguments)); + return this; + }; + /** + * Gets a copy of the pending data to inject into the clipboard. + * If no `format` is provided, a copy of ALL pending data formats will be returned. + * + * @returns `String` or `Object` + */ + ZeroClipboard.prototype.getData = function() { + if (!_clientMeta[this.id]) { + throw new Error("Attempted to get pending clipboard data from a destroyed ZeroClipboard client instance"); + } + return ZeroClipboard.getData.apply(this, _args(arguments)); + }; + if (typeof define === "function" && define.amd) { + define(function() { + return ZeroClipboard; + }); + } else if (typeof module === "object" && module && typeof module.exports === "object" && module.exports) { + module.exports = ZeroClipboard; + } else { + window.ZeroClipboard = ZeroClipboard; + } +})(function() { + return this || window; +}()); \ No newline at end of file diff --git a/resources/zeroclipboard/ZeroClipboard.min.js b/resources/zeroclipboard/ZeroClipboard.min.js new file mode 100644 index 0000000000..6ecd08854a --- /dev/null +++ b/resources/zeroclipboard/ZeroClipboard.min.js @@ -0,0 +1,10 @@ +/*! + * ZeroClipboard + * The ZeroClipboard library provides an easy way to copy text to the clipboard using an invisible Adobe Flash movie and a JavaScript interface. + * Copyright (c) 2009-2014 Jon Rohan, James M. Greene + * Licensed MIT + * http://zeroclipboard.org/ + * v2.2.0 + */ +!function(a,b){"use strict";var c,d,e,f=a,g=f.document,h=f.navigator,i=f.setTimeout,j=f.clearTimeout,k=f.setInterval,l=f.clearInterval,m=f.getComputedStyle,n=f.encodeURIComponent,o=f.ActiveXObject,p=f.Error,q=f.Number.parseInt||f.parseInt,r=f.Number.parseFloat||f.parseFloat,s=f.Number.isNaN||f.isNaN,t=f.Date.now,u=f.Object.keys,v=f.Object.defineProperty,w=f.Object.prototype.hasOwnProperty,x=f.Array.prototype.slice,y=function(){var a=function(a){return a};if("function"==typeof f.wrap&&"function"==typeof f.unwrap)try{var b=g.createElement("div"),c=f.unwrap(b);1===b.nodeType&&c&&1===c.nodeType&&(a=f.unwrap)}catch(d){}return a}(),z=function(a){return x.call(a,0)},A=function(){var a,c,d,e,f,g,h=z(arguments),i=h[0]||{};for(a=1,c=h.length;c>a;a++)if(null!=(d=h[a]))for(e in d)w.call(d,e)&&(f=i[e],g=d[e],i!==g&&g!==b&&(i[e]=g));return i},B=function(a){var b,c,d,e;if("object"!=typeof a||null==a||"number"==typeof a.nodeType)b=a;else if("number"==typeof a.length)for(b=[],c=0,d=a.length;d>c;c++)w.call(a,c)&&(b[c]=B(a[c]));else{b={};for(e in a)w.call(a,e)&&(b[e]=B(a[e]))}return b},C=function(a,b){for(var c={},d=0,e=b.length;e>d;d++)b[d]in a&&(c[b[d]]=a[b[d]]);return c},D=function(a,b){var c={};for(var d in a)-1===b.indexOf(d)&&(c[d]=a[d]);return c},E=function(a){if(a)for(var b in a)w.call(a,b)&&delete a[b];return a},F=function(a,b){if(a&&1===a.nodeType&&a.ownerDocument&&b&&(1===b.nodeType&&b.ownerDocument&&b.ownerDocument===a.ownerDocument||9===b.nodeType&&!b.ownerDocument&&b===a.ownerDocument))do{if(a===b)return!0;a=a.parentNode}while(a);return!1},G=function(a){var b;return"string"==typeof a&&a&&(b=a.split("#")[0].split("?")[0],b=a.slice(0,a.lastIndexOf("/")+1)),b},H=function(a){var b,c;return"string"==typeof a&&a&&(c=a.match(/^(?:|[^:@]*@|.+\)@(?=http[s]?|file)|.+?\s+(?: at |@)(?:[^:\(]+ )*[\(]?)((?:http[s]?|file):\/\/[\/]?.+?\/[^:\)]*?)(?::\d+)(?::\d+)?/),c&&c[1]?b=c[1]:(c=a.match(/\)@((?:http[s]?|file):\/\/[\/]?.+?\/[^:\)]*?)(?::\d+)(?::\d+)?/),c&&c[1]&&(b=c[1]))),b},I=function(){var a,b;try{throw new p}catch(c){b=c}return b&&(a=b.sourceURL||b.fileName||H(b.stack)),a},J=function(){var a,c,d;if(g.currentScript&&(a=g.currentScript.src))return a;if(c=g.getElementsByTagName("script"),1===c.length)return c[0].src||b;if("readyState"in c[0])for(d=c.length;d--;)if("interactive"===c[d].readyState&&(a=c[d].src))return a;return"loading"===g.readyState&&(a=c[c.length-1].src)?a:(a=I())?a:b},K=function(){var a,c,d,e=g.getElementsByTagName("script");for(a=e.length;a--;){if(!(d=e[a].src)){c=null;break}if(d=G(d),null==c)c=d;else if(c!==d){c=null;break}}return c||b},L=function(){var a=G(J())||K()||"";return a+"ZeroClipboard.swf"},M=function(){return null==a.opener&&(!!a.top&&a!=a.top||!!a.parent&&a!=a.parent)}(),N={bridge:null,version:"0.0.0",pluginType:"unknown",disabled:null,outdated:null,sandboxed:null,unavailable:null,degraded:null,deactivated:null,overdue:null,ready:null},O="11.0.0",P={},Q={},R=null,S=0,T=0,U={ready:"Flash communication is established",error:{"flash-disabled":"Flash is disabled or not installed. May also be attempting to run Flash in a sandboxed iframe, which is impossible.","flash-outdated":"Flash is too outdated to support ZeroClipboard","flash-sandboxed":"Attempting to run Flash in a sandboxed iframe, which is impossible","flash-unavailable":"Flash is unable to communicate bidirectionally with JavaScript","flash-degraded":"Flash is unable to preserve data fidelity when communicating with JavaScript","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.","flash-overdue":"Flash communication was established but NOT within the acceptable time limit","version-mismatch":"ZeroClipboard JS version number does not match ZeroClipboard SWF version number","clipboard-error":"At least one error was thrown while ZeroClipboard was attempting to inject your data into the clipboard","config-mismatch":"ZeroClipboard configuration does not match Flash's reality","swf-not-found":"The ZeroClipboard SWF object could not be loaded, so please check your `swfPath` configuration and/or network connectivity"}},V=["flash-unavailable","flash-degraded","flash-overdue","version-mismatch","config-mismatch","clipboard-error"],W=["flash-disabled","flash-outdated","flash-sandboxed","flash-unavailable","flash-degraded","flash-deactivated","flash-overdue"],X=new RegExp("^flash-("+W.map(function(a){return a.replace(/^flash-/,"")}).join("|")+")$"),Y=new RegExp("^flash-("+W.slice(1).map(function(a){return a.replace(/^flash-/,"")}).join("|")+")$"),Z={swfPath:L(),trustedDomains:a.location.host?[a.location.host]:[],cacheBust:!0,forceEnhancedClipboard:!1,flashLoadTimeout:3e4,autoActivate:!0,bubbleEvents:!0,containerId:"global-zeroclipboard-html-bridge",containerClass:"global-zeroclipboard-container",swfObjectId:"global-zeroclipboard-flash-bridge",hoverClass:"zeroclipboard-is-hover",activeClass:"zeroclipboard-is-active",forceHandCursor:!1,title:null,zIndex:999999999},$=function(a){if("object"==typeof a&&null!==a)for(var b in a)if(w.call(a,b))if(/^(?:forceHandCursor|title|zIndex|bubbleEvents)$/.test(b))Z[b]=a[b];else if(null==N.bridge)if("containerId"===b||"swfObjectId"===b){if(!nb(a[b]))throw new Error("The specified `"+b+"` value is not valid as an HTML4 Element ID");Z[b]=a[b]}else Z[b]=a[b];{if("string"!=typeof a||!a)return B(Z);if(w.call(Z,a))return Z[a]}},_=function(){return Tb(),{browser:C(h,["userAgent","platform","appName"]),flash:D(N,["bridge"]),zeroclipboard:{version:Vb.version,config:Vb.config()}}},ab=function(){return!!(N.disabled||N.outdated||N.sandboxed||N.unavailable||N.degraded||N.deactivated)},bb=function(a,d){var e,f,g,h={};if("string"==typeof a&&a)g=a.toLowerCase().split(/\s+/);else if("object"==typeof a&&a&&"undefined"==typeof d)for(e in a)w.call(a,e)&&"string"==typeof e&&e&&"function"==typeof a[e]&&Vb.on(e,a[e]);if(g&&g.length){for(e=0,f=g.length;f>e;e++)a=g[e].replace(/^on/,""),h[a]=!0,P[a]||(P[a]=[]),P[a].push(d);if(h.ready&&N.ready&&Vb.emit({type:"ready"}),h.error){for(e=0,f=W.length;f>e;e++)if(N[W[e].replace(/^flash-/,"")]===!0){Vb.emit({type:"error",name:W[e]});break}c!==b&&Vb.version!==c&&Vb.emit({type:"error",name:"version-mismatch",jsVersion:Vb.version,swfVersion:c})}}return Vb},cb=function(a,b){var c,d,e,f,g;if(0===arguments.length)f=u(P);else if("string"==typeof a&&a)f=a.split(/\s+/);else if("object"==typeof a&&a&&"undefined"==typeof b)for(c in a)w.call(a,c)&&"string"==typeof c&&c&&"function"==typeof a[c]&&Vb.off(c,a[c]);if(f&&f.length)for(c=0,d=f.length;d>c;c++)if(a=f[c].toLowerCase().replace(/^on/,""),g=P[a],g&&g.length)if(b)for(e=g.indexOf(b);-1!==e;)g.splice(e,1),e=g.indexOf(b,e);else g.length=0;return Vb},db=function(a){var b;return b="string"==typeof a&&a?B(P[a])||null:B(P)},eb=function(a){var b,c,d;return a=ob(a),a&&!vb(a)?"ready"===a.type&&N.overdue===!0?Vb.emit({type:"error",name:"flash-overdue"}):(b=A({},a),tb.call(this,b),"copy"===a.type&&(d=Db(Q),c=d.data,R=d.formatMap),c):void 0},fb=function(){var a=N.sandboxed;if(Tb(),"boolean"!=typeof N.ready&&(N.ready=!1),N.sandboxed!==a&&N.sandboxed===!0)N.ready=!1,Vb.emit({type:"error",name:"flash-sandboxed"});else if(!Vb.isFlashUnusable()&&null===N.bridge){var b=Z.flashLoadTimeout;"number"==typeof b&&b>=0&&(S=i(function(){"boolean"!=typeof N.deactivated&&(N.deactivated=!0),N.deactivated===!0&&Vb.emit({type:"error",name:"flash-deactivated"})},b)),N.overdue=!1,Bb()}},gb=function(){Vb.clearData(),Vb.blur(),Vb.emit("destroy"),Cb(),Vb.off()},hb=function(a,b){var c;if("object"==typeof a&&a&&"undefined"==typeof b)c=a,Vb.clearData();else{if("string"!=typeof a||!a)return;c={},c[a]=b}for(var d in c)"string"==typeof d&&d&&w.call(c,d)&&"string"==typeof c[d]&&c[d]&&(Q[d]=c[d])},ib=function(a){"undefined"==typeof a?(E(Q),R=null):"string"==typeof a&&w.call(Q,a)&&delete Q[a]},jb=function(a){return"undefined"==typeof a?B(Q):"string"==typeof a&&w.call(Q,a)?Q[a]:void 0},kb=function(a){if(a&&1===a.nodeType){d&&(Lb(d,Z.activeClass),d!==a&&Lb(d,Z.hoverClass)),d=a,Kb(a,Z.hoverClass);var b=a.getAttribute("title")||Z.title;if("string"==typeof b&&b){var c=Ab(N.bridge);c&&c.setAttribute("title",b)}var e=Z.forceHandCursor===!0||"pointer"===Mb(a,"cursor");Rb(e),Qb()}},lb=function(){var a=Ab(N.bridge);a&&(a.removeAttribute("title"),a.style.left="0px",a.style.top="-9999px",a.style.width="1px",a.style.height="1px"),d&&(Lb(d,Z.hoverClass),Lb(d,Z.activeClass),d=null)},mb=function(){return d||null},nb=function(a){return"string"==typeof a&&a&&/^[A-Za-z][A-Za-z0-9_:\-\.]*$/.test(a)},ob=function(a){var b;if("string"==typeof a&&a?(b=a,a={}):"object"==typeof a&&a&&"string"==typeof a.type&&a.type&&(b=a.type),b){b=b.toLowerCase(),!a.target&&(/^(copy|aftercopy|_click)$/.test(b)||"error"===b&&"clipboard-error"===a.name)&&(a.target=e),A(a,{type:b,target:a.target||d||null,relatedTarget:a.relatedTarget||null,currentTarget:N&&N.bridge||null,timeStamp:a.timeStamp||t()||null});var c=U[a.type];return"error"===a.type&&a.name&&c&&(c=c[a.name]),c&&(a.message=c),"ready"===a.type&&A(a,{target:null,version:N.version}),"error"===a.type&&(X.test(a.name)&&A(a,{target:null,minimumVersion:O}),Y.test(a.name)&&A(a,{version:N.version})),"copy"===a.type&&(a.clipboardData={setData:Vb.setData,clearData:Vb.clearData}),"aftercopy"===a.type&&(a=Eb(a,R)),a.target&&!a.relatedTarget&&(a.relatedTarget=pb(a.target)),qb(a)}},pb=function(a){var b=a&&a.getAttribute&&a.getAttribute("data-clipboard-target");return b?g.getElementById(b):null},qb=function(a){if(a&&/^_(?:click|mouse(?:over|out|down|up|move))$/.test(a.type)){var c=a.target,d="_mouseover"===a.type&&a.relatedTarget?a.relatedTarget:b,e="_mouseout"===a.type&&a.relatedTarget?a.relatedTarget:b,h=Nb(c),i=f.screenLeft||f.screenX||0,j=f.screenTop||f.screenY||0,k=g.body.scrollLeft+g.documentElement.scrollLeft,l=g.body.scrollTop+g.documentElement.scrollTop,m=h.left+("number"==typeof a._stageX?a._stageX:0),n=h.top+("number"==typeof a._stageY?a._stageY:0),o=m-k,p=n-l,q=i+o,r=j+p,s="number"==typeof a.movementX?a.movementX:0,t="number"==typeof a.movementY?a.movementY:0;delete a._stageX,delete a._stageY,A(a,{srcElement:c,fromElement:d,toElement:e,screenX:q,screenY:r,pageX:m,pageY:n,clientX:o,clientY:p,x:o,y:p,movementX:s,movementY:t,offsetX:0,offsetY:0,layerX:0,layerY:0})}return a},rb=function(a){var b=a&&"string"==typeof a.type&&a.type||"";return!/^(?:(?:before)?copy|destroy)$/.test(b)},sb=function(a,b,c,d){d?i(function(){a.apply(b,c)},0):a.apply(b,c)},tb=function(a){if("object"==typeof a&&a&&a.type){var b=rb(a),c=P["*"]||[],d=P[a.type]||[],e=c.concat(d);if(e&&e.length){var g,h,i,j,k,l=this;for(g=0,h=e.length;h>g;g++)i=e[g],j=l,"string"==typeof i&&"function"==typeof f[i]&&(i=f[i]),"object"==typeof i&&i&&"function"==typeof i.handleEvent&&(j=i,i=i.handleEvent),"function"==typeof i&&(k=A({},a),sb(i,j,[k],b))}return this}},ub=function(a){var b=null;return(M===!1||a&&"error"===a.type&&a.name&&-1!==V.indexOf(a.name))&&(b=!1),b},vb=function(a){var b=a.target||d||null,f="swf"===a._source;switch(delete a._source,a.type){case"error":var g="flash-sandboxed"===a.name||ub(a);"boolean"==typeof g&&(N.sandboxed=g),-1!==W.indexOf(a.name)?A(N,{disabled:"flash-disabled"===a.name,outdated:"flash-outdated"===a.name,unavailable:"flash-unavailable"===a.name,degraded:"flash-degraded"===a.name,deactivated:"flash-deactivated"===a.name,overdue:"flash-overdue"===a.name,ready:!1}):"version-mismatch"===a.name&&(c=a.swfVersion,A(N,{disabled:!1,outdated:!1,unavailable:!1,degraded:!1,deactivated:!1,overdue:!1,ready:!1})),Pb();break;case"ready":c=a.swfVersion;var h=N.deactivated===!0;A(N,{disabled:!1,outdated:!1,sandboxed:!1,unavailable:!1,degraded:!1,deactivated:!1,overdue:h,ready:!h}),Pb();break;case"beforecopy":e=b;break;case"copy":var i,j,k=a.relatedTarget;!Q["text/html"]&&!Q["text/plain"]&&k&&(j=k.value||k.outerHTML||k.innerHTML)&&(i=k.value||k.textContent||k.innerText)?(a.clipboardData.clearData(),a.clipboardData.setData("text/plain",i),j!==i&&a.clipboardData.setData("text/html",j)):!Q["text/plain"]&&a.target&&(i=a.target.getAttribute("data-clipboard-text"))&&(a.clipboardData.clearData(),a.clipboardData.setData("text/plain",i));break;case"aftercopy":wb(a),Vb.clearData(),b&&b!==Jb()&&b.focus&&b.focus();break;case"_mouseover":Vb.focus(b),Z.bubbleEvents===!0&&f&&(b&&b!==a.relatedTarget&&!F(a.relatedTarget,b)&&xb(A({},a,{type:"mouseenter",bubbles:!1,cancelable:!1})),xb(A({},a,{type:"mouseover"})));break;case"_mouseout":Vb.blur(),Z.bubbleEvents===!0&&f&&(b&&b!==a.relatedTarget&&!F(a.relatedTarget,b)&&xb(A({},a,{type:"mouseleave",bubbles:!1,cancelable:!1})),xb(A({},a,{type:"mouseout"})));break;case"_mousedown":Kb(b,Z.activeClass),Z.bubbleEvents===!0&&f&&xb(A({},a,{type:a.type.slice(1)}));break;case"_mouseup":Lb(b,Z.activeClass),Z.bubbleEvents===!0&&f&&xb(A({},a,{type:a.type.slice(1)}));break;case"_click":e=null,Z.bubbleEvents===!0&&f&&xb(A({},a,{type:a.type.slice(1)}));break;case"_mousemove":Z.bubbleEvents===!0&&f&&xb(A({},a,{type:a.type.slice(1)}))}return/^_(?:click|mouse(?:over|out|down|up|move))$/.test(a.type)?!0:void 0},wb=function(a){if(a.errors&&a.errors.length>0){var b=B(a);A(b,{type:"error",name:"clipboard-error"}),delete b.success,i(function(){Vb.emit(b)},0)}},xb=function(a){if(a&&"string"==typeof a.type&&a){var b,c=a.target||null,d=c&&c.ownerDocument||g,e={view:d.defaultView||f,canBubble:!0,cancelable:!0,detail:"click"===a.type?1:0,button:"number"==typeof a.which?a.which-1:"number"==typeof a.button?a.button:d.createEvent?0:1},h=A(e,a);c&&d.createEvent&&c.dispatchEvent&&(h=[h.type,h.canBubble,h.cancelable,h.view,h.detail,h.screenX,h.screenY,h.clientX,h.clientY,h.ctrlKey,h.altKey,h.shiftKey,h.metaKey,h.button,h.relatedTarget],b=d.createEvent("MouseEvents"),b.initMouseEvent&&(b.initMouseEvent.apply(b,h),b._source="js",c.dispatchEvent(b)))}},yb=function(){var a=Z.flashLoadTimeout;if("number"==typeof a&&a>=0){var b=Math.min(1e3,a/10),c=Z.swfObjectId+"_fallbackContent";T=k(function(){var a=g.getElementById(c);Ob(a)&&(Pb(),N.deactivated=null,Vb.emit({type:"error",name:"swf-not-found"}))},b)}},zb=function(){var a=g.createElement("div");return a.id=Z.containerId,a.className=Z.containerClass,a.style.position="absolute",a.style.left="0px",a.style.top="-9999px",a.style.width="1px",a.style.height="1px",a.style.zIndex=""+Sb(Z.zIndex),a},Ab=function(a){for(var b=a&&a.parentNode;b&&"OBJECT"===b.nodeName&&b.parentNode;)b=b.parentNode;return b||null},Bb=function(){var a,b=N.bridge,c=Ab(b);if(!b){var d=Ib(f.location.host,Z),e="never"===d?"none":"all",h=Gb(A({jsVersion:Vb.version},Z)),i=Z.swfPath+Fb(Z.swfPath,Z);c=zb();var j=g.createElement("div");c.appendChild(j),g.body.appendChild(c);var k=g.createElement("div"),l="activex"===N.pluginType;k.innerHTML='"+(l?'':"")+'
 
',b=k.firstChild,k=null,y(b).ZeroClipboard=Vb,c.replaceChild(b,j),yb()}return b||(b=g[Z.swfObjectId],b&&(a=b.length)&&(b=b[a-1]),!b&&c&&(b=c.firstChild)),N.bridge=b||null,b},Cb=function(){var a=N.bridge;if(a){var d=Ab(a);d&&("activex"===N.pluginType&&"readyState"in a?(a.style.display="none",function e(){if(4===a.readyState){for(var b in a)"function"==typeof a[b]&&(a[b]=null);a.parentNode&&a.parentNode.removeChild(a),d.parentNode&&d.parentNode.removeChild(d)}else i(e,10)}()):(a.parentNode&&a.parentNode.removeChild(a),d.parentNode&&d.parentNode.removeChild(d))),Pb(),N.ready=null,N.bridge=null,N.deactivated=null,c=b}},Db=function(a){var b={},c={};if("object"==typeof a&&a){for(var d in a)if(d&&w.call(a,d)&&"string"==typeof a[d]&&a[d])switch(d.toLowerCase()){case"text/plain":case"text":case"air:text":case"flash:text":b.text=a[d],c.text=d;break;case"text/html":case"html":case"air:html":case"flash:html":b.html=a[d],c.html=d;break;case"application/rtf":case"text/rtf":case"rtf":case"richtext":case"air:rtf":case"flash:rtf":b.rtf=a[d],c.rtf=d}return{data:b,formatMap:c}}},Eb=function(a,b){if("object"!=typeof a||!a||"object"!=typeof b||!b)return a;var c={};for(var d in a)if(w.call(a,d))if("errors"===d){c[d]=a[d]?a[d].slice():[];for(var e=0,f=c[d].length;f>e;e++)c[d][e].format=b[c[d][e].format]}else if("success"!==d&&"data"!==d)c[d]=a[d];else{c[d]={};var g=a[d];for(var h in g)h&&w.call(g,h)&&w.call(b,h)&&(c[d][b[h]]=g[h])}return c},Fb=function(a,b){var c=null==b||b&&b.cacheBust===!0;return c?(-1===a.indexOf("?")?"?":"&")+"noCache="+t():""},Gb=function(a){var b,c,d,e,g="",h=[];if(a.trustedDomains&&("string"==typeof a.trustedDomains?e=[a.trustedDomains]:"object"==typeof a.trustedDomains&&"length"in a.trustedDomains&&(e=a.trustedDomains)),e&&e.length)for(b=0,c=e.length;c>b;b++)if(w.call(e,b)&&e[b]&&"string"==typeof e[b]){if(d=Hb(e[b]),!d)continue;if("*"===d){h.length=0,h.push(d);break}h.push.apply(h,[d,"//"+d,f.location.protocol+"//"+d])}return h.length&&(g+="trustedOrigins="+n(h.join(","))),a.forceEnhancedClipboard===!0&&(g+=(g?"&":"")+"forceEnhancedClipboard=true"),"string"==typeof a.swfObjectId&&a.swfObjectId&&(g+=(g?"&":"")+"swfObjectId="+n(a.swfObjectId)),"string"==typeof a.jsVersion&&a.jsVersion&&(g+=(g?"&":"")+"jsVersion="+n(a.jsVersion)),g},Hb=function(a){if(null==a||""===a)return null;if(a=a.replace(/^\s+|\s+$/g,""),""===a)return null;var b=a.indexOf("//");a=-1===b?a:a.slice(b+2);var c=a.indexOf("/");return a=-1===c?a:-1===b||0===c?null:a.slice(0,c),a&&".swf"===a.slice(-4).toLowerCase()?null:a||null},Ib=function(){var a=function(a){var b,c,d,e=[];if("string"==typeof a&&(a=[a]),"object"!=typeof a||!a||"number"!=typeof a.length)return e;for(b=0,c=a.length;c>b;b++)if(w.call(a,b)&&(d=Hb(a[b]))){if("*"===d){e.length=0,e.push("*");break}-1===e.indexOf(d)&&e.push(d)}return e};return function(b,c){var d=Hb(c.swfPath);null===d&&(d=b);var e=a(c.trustedDomains),f=e.length;if(f>0){if(1===f&&"*"===e[0])return"always";if(-1!==e.indexOf(b))return 1===f&&b===d?"sameDomain":"always"}return"never"}}(),Jb=function(){try{return g.activeElement}catch(a){return null}},Kb=function(a,b){var c,d,e,f=[];if("string"==typeof b&&b&&(f=b.split(/\s+/)),a&&1===a.nodeType&&f.length>0)if(a.classList)for(c=0,d=f.length;d>c;c++)a.classList.add(f[c]);else if(a.hasOwnProperty("className")){for(e=" "+a.className+" ",c=0,d=f.length;d>c;c++)-1===e.indexOf(" "+f[c]+" ")&&(e+=f[c]+" ");a.className=e.replace(/^\s+|\s+$/g,"")}return a},Lb=function(a,b){var c,d,e,f=[];if("string"==typeof b&&b&&(f=b.split(/\s+/)),a&&1===a.nodeType&&f.length>0)if(a.classList&&a.classList.length>0)for(c=0,d=f.length;d>c;c++)a.classList.remove(f[c]);else if(a.className){for(e=(" "+a.className+" ").replace(/[\r\n\t]/g," "),c=0,d=f.length;d>c;c++)e=e.replace(" "+f[c]+" "," ");a.className=e.replace(/^\s+|\s+$/g,"")}return a},Mb=function(a,b){var c=m(a,null).getPropertyValue(b);return"cursor"!==b||c&&"auto"!==c||"A"!==a.nodeName?c:"pointer"},Nb=function(a){var b={left:0,top:0,width:0,height:0};if(a.getBoundingClientRect){var c=a.getBoundingClientRect(),d=f.pageXOffset,e=f.pageYOffset,h=g.documentElement.clientLeft||0,i=g.documentElement.clientTop||0,j=0,k=0;if("relative"===Mb(g.body,"position")){var l=g.body.getBoundingClientRect(),m=g.documentElement.getBoundingClientRect();j=l.left-m.left||0,k=l.top-m.top||0}b.left=c.left+d-h-j,b.top=c.top+e-i-k,b.width="width"in c?c.width:c.right-c.left,b.height="height"in c?c.height:c.bottom-c.top}return b},Ob=function(a){if(!a)return!1;var b=m(a,null),c=r(b.height)>0,d=r(b.width)>0,e=r(b.top)>=0,f=r(b.left)>=0,g=c&&d&&e&&f,h=g?null:Nb(a),i="none"!==b.display&&"collapse"!==b.visibility&&(g||!!h&&(c||h.height>0)&&(d||h.width>0)&&(e||h.top>=0)&&(f||h.left>=0));return i},Pb=function(){j(S),S=0,l(T),T=0},Qb=function(){var a;if(d&&(a=Ab(N.bridge))){var b=Nb(d);A(a.style,{width:b.width+"px",height:b.height+"px",top:b.top+"px",left:b.left+"px",zIndex:""+Sb(Z.zIndex)})}},Rb=function(a){N.ready===!0&&(N.bridge&&"function"==typeof N.bridge.setHandCursor?N.bridge.setHandCursor(a):N.ready=!1)},Sb=function(a){if(/^(?:auto|inherit)$/.test(a))return a;var b;return"number"!=typeof a||s(a)?"string"==typeof a&&(b=Sb(q(a,10))):b=a,"number"==typeof b?b:"auto"},Tb=function(b){var c,d,e,f=N.sandboxed,g=null;if(b=b===!0,M===!1)g=!1;else{try{d=a.frameElement||null}catch(h){e={name:h.name,message:h.message}}if(d&&1===d.nodeType&&"IFRAME"===d.nodeName)try{g=d.hasAttribute("sandbox")}catch(h){g=null}else{try{c=document.domain||null}catch(h){c=null}(null===c||e&&"SecurityError"===e.name&&/(^|[\s\(\[@])sandbox(es|ed|ing|[\s\.,!\)\]@]|$)/.test(e.message.toLowerCase()))&&(g=!0)}}return N.sandboxed=g,f===g||b||Ub(o),g},Ub=function(a){function b(a){var b=a.match(/[\d]+/g);return b.length=3,b.join(".")}function c(a){return!!a&&(a=a.toLowerCase())&&(/^(pepflashplayer\.dll|libpepflashplayer\.so|pepperflashplayer\.plugin)$/.test(a)||"chrome.plugin"===a.slice(-13))}function d(a){a&&(i=!0,a.version&&(l=b(a.version)),!l&&a.description&&(l=b(a.description)),a.filename&&(k=c(a.filename)))}var e,f,g,i=!1,j=!1,k=!1,l="";if(h.plugins&&h.plugins.length)e=h.plugins["Shockwave Flash"],d(e),h.plugins["Shockwave Flash 2.0"]&&(i=!0,l="2.0.0.11");else if(h.mimeTypes&&h.mimeTypes.length)g=h.mimeTypes["application/x-shockwave-flash"],e=g&&g.enabledPlugin,d(e);else if("undefined"!=typeof a){j=!0;try{f=new a("ShockwaveFlash.ShockwaveFlash.7"),i=!0,l=b(f.GetVariable("$version"))}catch(m){try{f=new a("ShockwaveFlash.ShockwaveFlash.6"),i=!0,l="6.0.21"}catch(n){try{f=new a("ShockwaveFlash.ShockwaveFlash"),i=!0,l=b(f.GetVariable("$version"))}catch(o){j=!1}}}}N.disabled=i!==!0,N.outdated=l&&r(l)e;e++)a=g[e].replace(/^on/,""),h[a]=!0,j[a]||(j[a]=[]),j[a].push(d);if(h.ready&&N.ready&&this.emit({type:"ready",client:this}),h.error){for(e=0,f=W.length;f>e;e++)if(N[W[e].replace(/^flash-/,"")]){this.emit({type:"error",name:W[e],client:this});break}c!==b&&Vb.version!==c&&this.emit({type:"error",name:"version-mismatch",jsVersion:Vb.version,swfVersion:c})}}return this},bc=function(a,b){var c,d,e,f,g,h=Xb[this.id],i=h&&h.handlers;if(!i)return this;if(0===arguments.length)f=u(i);else if("string"==typeof a&&a)f=a.split(/\s+/);else if("object"==typeof a&&a&&"undefined"==typeof b)for(c in a)w.call(a,c)&&"string"==typeof c&&c&&"function"==typeof a[c]&&this.off(c,a[c]);if(f&&f.length)for(c=0,d=f.length;d>c;c++)if(a=f[c].toLowerCase().replace(/^on/,""),g=i[a],g&&g.length)if(b)for(e=g.indexOf(b);-1!==e;)g.splice(e,1),e=g.indexOf(b,e);else g.length=0;return this},cc=function(a){var b=null,c=Xb[this.id]&&Xb[this.id].handlers;return c&&(b="string"==typeof a&&a?c[a]?c[a].slice(0):[]:B(c)),b},dc=function(a){if(ic.call(this,a)){"object"==typeof a&&a&&"string"==typeof a.type&&a.type&&(a=A({},a));var b=A({},ob(a),{client:this});jc.call(this,b)}return this},ec=function(a){if(!Xb[this.id])throw new Error("Attempted to clip element(s) to a destroyed ZeroClipboard client instance");a=kc(a);for(var b=0;b0,e=!a.target||d&&-1!==c.indexOf(a.target),f=a.relatedTarget&&d&&-1!==c.indexOf(a.relatedTarget),g=a.client&&a.client===this;return b&&(e||f||g)?!0:!1},jc=function(a){var b=Xb[this.id];if("object"==typeof a&&a&&a.type&&b){var c=rb(a),d=b&&b.handlers["*"]||[],e=b&&b.handlers[a.type]||[],g=d.concat(e);if(g&&g.length){var h,i,j,k,l,m=this;for(h=0,i=g.length;i>h;h++)j=g[h],k=m,"string"==typeof j&&"function"==typeof f[j]&&(j=f[j]),"object"==typeof j&&j&&"function"==typeof j.handleEvent&&(k=j,j=j.handleEvent),"function"==typeof j&&(l=A({},a),sb(j,k,[l],c))}}},kc=function(a){return"string"==typeof a&&(a=[]),"number"!=typeof a.length?[a]:a},lc=function(a){if(a&&1===a.nodeType){var b=function(a){(a||(a=f.event))&&("js"!==a._source&&(a.stopImmediatePropagation(),a.preventDefault()),delete a._source)},c=function(c){(c||(c=f.event))&&(b(c),Vb.focus(a))};a.addEventListener("mouseover",c,!1),a.addEventListener("mouseout",b,!1),a.addEventListener("mouseenter",b,!1),a.addEventListener("mouseleave",b,!1),a.addEventListener("mousemove",b,!1),$b[a.zcClippingId]={mouseover:c,mouseout:b,mouseenter:b,mouseleave:b,mousemove:b}}},mc=function(a){if(a&&1===a.nodeType){var b=$b[a.zcClippingId];if("object"==typeof b&&b){for(var c,d,e=["move","leave","enter","out","over"],f=0,g=e.length;g>f;f++)c="mouse"+e[f],d=b[c],"function"==typeof d&&a.removeEventListener(c,d,!1);delete $b[a.zcClippingId]}}};Vb._createClient=function(){_b.apply(this,z(arguments))},Vb.prototype.on=function(){return ac.apply(this,z(arguments))},Vb.prototype.off=function(){return bc.apply(this,z(arguments))},Vb.prototype.handlers=function(){return cc.apply(this,z(arguments))},Vb.prototype.emit=function(){return dc.apply(this,z(arguments))},Vb.prototype.clip=function(){return ec.apply(this,z(arguments))},Vb.prototype.unclip=function(){return fc.apply(this,z(arguments))},Vb.prototype.elements=function(){return gc.apply(this,z(arguments))},Vb.prototype.destroy=function(){return hc.apply(this,z(arguments))},Vb.prototype.setText=function(a){if(!Xb[this.id])throw new Error("Attempted to set pending clipboard data from a destroyed ZeroClipboard client instance");return Vb.setData("text/plain",a),this},Vb.prototype.setHtml=function(a){if(!Xb[this.id])throw new Error("Attempted to set pending clipboard data from a destroyed ZeroClipboard client instance");return Vb.setData("text/html",a),this},Vb.prototype.setRichText=function(a){if(!Xb[this.id])throw new Error("Attempted to set pending clipboard data from a destroyed ZeroClipboard client instance");return Vb.setData("application/rtf",a),this},Vb.prototype.setData=function(){if(!Xb[this.id])throw new Error("Attempted to set pending clipboard data from a destroyed ZeroClipboard client instance");return Vb.setData.apply(this,z(arguments)),this},Vb.prototype.clearData=function(){if(!Xb[this.id])throw new Error("Attempted to clear pending clipboard data from a destroyed ZeroClipboard client instance");return Vb.clearData.apply(this,z(arguments)),this},Vb.prototype.getData=function(){if(!Xb[this.id])throw new Error("Attempted to get pending clipboard data from a destroyed ZeroClipboard client instance");return Vb.getData.apply(this,z(arguments))},"function"==typeof define&&define.amd?define(function(){return Vb}):"object"==typeof module&&module&&"object"==typeof module.exports&&module.exports?module.exports=Vb:a.ZeroClipboard=Vb}(function(){return this||window}()); +//# sourceMappingURL=ZeroClipboard.min.map \ No newline at end of file diff --git a/resources/zeroclipboard/ZeroClipboard.min.map b/resources/zeroclipboard/ZeroClipboard.min.map new file mode 100644 index 0000000000..8d7dc47ac1 --- /dev/null +++ b/resources/zeroclipboard/ZeroClipboard.min.map @@ -0,0 +1 @@ +{"version":3,"file":"ZeroClipboard.min.js","sources":["ZeroClipboard.js"],"names":["window","undefined","_zcSwfVersion","_currentElement","_copyTarget","_window","_document","document","_navigator","navigator","_setTimeout","setTimeout","_clearTimeout","clearTimeout","_setInterval","setInterval","_clearInterval","clearInterval","_getComputedStyle","getComputedStyle","_encodeURIComponent","encodeURIComponent","_ActiveXObject","ActiveXObject","_Error","Error","_parseInt","Number","parseInt","_parseFloat","parseFloat","_isNaN","isNaN","_now","Date","now","_keys","Object","keys","_defineProperty","defineProperty","_hasOwn","prototype","hasOwnProperty","_slice","Array","slice","_unwrap","unwrapper","el","wrap","unwrap","div","createElement","unwrappedDiv","nodeType","e","_args","argumentsObj","call","_extend","i","len","arg","prop","src","copy","args","arguments","target","length","_deepCopy","source","_pick","obj","newObj","_omit","indexOf","_deleteOwnProperties","_containedBy","ancestorEl","ownerDocument","parentNode","_getDirPathOfUrl","url","dir","split","lastIndexOf","_getCurrentScriptUrlFromErrorStack","stack","matches","match","_getCurrentScriptUrlFromError","err","sourceURL","fileName","_getCurrentScriptUrl","jsPath","scripts","currentScript","getElementsByTagName","readyState","_getUnanimousScriptParentDir","jsDir","_getDefaultSwfPath","_pageIsFramed","opener","top","parent","_flashState","bridge","version","pluginType","disabled","outdated","sandboxed","unavailable","degraded","deactivated","overdue","ready","_minimumFlashVersion","_handlers","_clipData","_clipDataFormatMap","_flashCheckTimeout","_swfFallbackCheckInterval","_eventMessages","error","flash-disabled","flash-outdated","flash-sandboxed","flash-unavailable","flash-degraded","flash-deactivated","flash-overdue","version-mismatch","clipboard-error","config-mismatch","swf-not-found","_errorsThatOnlyOccurAfterFlashLoads","_flashStateErrorNames","_flashStateErrorNameMatchingRegex","RegExp","map","errorName","replace","join","_flashStateEnabledErrorNameMatchingRegex","_globalConfig","swfPath","trustedDomains","location","host","cacheBust","forceEnhancedClipboard","flashLoadTimeout","autoActivate","bubbleEvents","containerId","containerClass","swfObjectId","hoverClass","activeClass","forceHandCursor","title","zIndex","_config","options","test","_isValidHtml4Id","_state","_detectSandbox","browser","flash","zeroclipboard","ZeroClipboard","config","_isFlashUnusable","_on","eventType","listener","events","added","toLowerCase","on","push","emit","type","name","jsVersion","swfVersion","_off","foundIndex","perEventHandlers","off","splice","_listeners","_emit","event","eventCopy","returnVal","tmp","_createEvent","_preprocessEvent","_dispatchCallbacks","this","_mapClipDataToFlash","data","formatMap","_create","previousState","isFlashUnusable","maxWait","_embedSwf","_destroy","clearData","blur","_unembedSwf","_setData","format","dataObj","dataFormat","_clearData","_getData","_focus","element","_removeClass","_addClass","newTitle","getAttribute","htmlBridge","_getHtmlBridge","setAttribute","useHandCursor","_getStyle","_setHandCursor","_reposition","_blur","removeAttribute","style","left","width","height","_activeElement","id","relatedTarget","currentTarget","timeStamp","msg","message","minimumVersion","clipboardData","setData","_mapClipResultsFromFlash","_getRelatedTarget","_addMouseData","targetEl","relatedTargetId","getElementById","srcElement","fromElement","toElement","pos","_getElementPosition","screenLeft","screenX","screenTop","screenY","scrollLeft","body","documentElement","scrollTop","pageX","_stageX","pageY","_stageY","clientX","clientY","moveX","movementX","moveY","movementY","x","y","offsetX","offsetY","layerX","layerY","_shouldPerformAsync","_dispatchCallback","func","context","async","apply","wildcardTypeHandlers","specificTypeHandlers","handlers","concat","originalContext","handleEvent","_getSandboxStatusFromErrorEvent","isSandboxed","sourceIsSwf","_source","_clearTimeoutsAndPolling","wasDeactivated","textContent","htmlContent","value","outerHTML","innerHTML","innerText","_queueEmitClipboardErrors","_safeActiveElement","focus","_fireMouseEvent","bubbles","cancelable","aftercopyEvent","errors","errorEvent","success","doc","defaults","view","defaultView","canBubble","detail","button","which","createEvent","dispatchEvent","ctrlKey","altKey","shiftKey","metaKey","initMouseEvent","_watchForSwfFallbackContent","pollWait","Math","min","fallbackContentId","_isElementVisible","_createHtmlBridge","container","className","position","_getSafeZIndex","flashBridge","nodeName","allowScriptAccess","_determineScriptAccess","allowNetworking","flashvars","_vars","swfUrl","_cacheBust","divToBeReplaced","appendChild","tmpDiv","usingActiveX","firstChild","replaceChild","display","removeSwfFromIE","removeChild","clipData","newClipData","text","html","rtf","clipResults","newResults","tmpHash","path","domain","domains","str","trustedOriginsExpanded","_extractDomain","protocol","originOrUrl","protocolIndex","pathIndex","_extractAllDomains","origins","resultsArray","currentDomain","configOptions","swfDomain","activeElement","c","cl","classNames","classList","add","remove","getPropertyValue","getBoundingClientRect","elRect","pageXOffset","pageYOffset","leftBorderWidth","clientLeft","topBorderWidth","clientTop","leftBodyOffset","topBodyOffset","bodyRect","htmlRect","right","bottom","styles","hasCssHeight","hasCssWidth","hasCssTop","hasCssLeft","cssKnows","rect","isVisible","visibility","enabled","setHandCursor","val","doNotReassessFlashSupport","effectiveScriptOrigin","frame","frameError","frameElement","hasAttribute","_detectFlashSupport","parseFlashVersion","desc","isPepperFlash","flashPlayerFileName","inspectPlugin","plugin","hasFlash","flashVersion","description","filename","isPPAPI","ax","mimeType","isActiveX","plugins","mimeTypes","enabledPlugin","GetVariable","e1","e2","e3","_createClient","writable","configurable","enumerable","state","create","destroy","getData","activate","deactivate","_clientIdCounter","_clientMeta","_elementIdCounter","_elementMeta","_mouseHandlers","_clientConstructor","elements","client","instance","clip","_clientOn","meta","_clientOff","_clientListeners","_clientEmit","_clientShouldEmit","_clientDispatchCallbacks","_clientClip","_prepClip","zcClippingId","_addMouseHandlers","clippedElements","_clientUnclip","arrayIndex","clientIds","_removeMouseHandlers","_clientElements","_clientDestroy","unclip","clippedEls","hasClippedEls","goodTarget","goodRelTarget","goodClient","_suppressMouseEvents","stopImmediatePropagation","preventDefault","_elementMouseOver","addEventListener","mouseover","mouseout","mouseenter","mouseleave","mousemove","mouseHandlers","key","mouseEvents","removeEventListener","setText","setHtml","setRichText","richText","define","amd","module","exports"],"mappings":"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","sourcesContent":["/*!\n * ZeroClipboard\n * The ZeroClipboard library provides an easy way to copy text to the clipboard using an invisible Adobe Flash movie and a JavaScript interface.\n * Copyright (c) 2009-2014 Jon Rohan, James M. Greene\n * Licensed MIT\n * http://zeroclipboard.org/\n * v2.2.0\n */\n(function(window, undefined) {\n \"use strict\";\n /**\n * Store references to critically important global functions that may be\n * overridden on certain web pages.\n */\n 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() {\n var unwrapper = function(el) {\n return el;\n };\n if (typeof _window.wrap === \"function\" && typeof _window.unwrap === \"function\") {\n try {\n var div = _document.createElement(\"div\");\n var unwrappedDiv = _window.unwrap(div);\n if (div.nodeType === 1 && unwrappedDiv && unwrappedDiv.nodeType === 1) {\n unwrapper = _window.unwrap;\n }\n } catch (e) {}\n }\n return unwrapper;\n }();\n /**\n * Convert an `arguments` object into an Array.\n *\n * @returns The arguments as an Array\n * @private\n */\n var _args = function(argumentsObj) {\n return _slice.call(argumentsObj, 0);\n };\n /**\n * Shallow-copy the owned, enumerable properties of one object over to another, similar to jQuery's `$.extend`.\n *\n * @returns The target object, augmented\n * @private\n */\n var _extend = function() {\n var i, len, arg, prop, src, copy, args = _args(arguments), target = args[0] || {};\n for (i = 1, len = args.length; i < len; i++) {\n if ((arg = args[i]) != null) {\n for (prop in arg) {\n if (_hasOwn.call(arg, prop)) {\n src = target[prop];\n copy = arg[prop];\n if (target !== copy && copy !== undefined) {\n target[prop] = copy;\n }\n }\n }\n }\n }\n return target;\n };\n /**\n * Return a deep copy of the source object or array.\n *\n * @returns Object or Array\n * @private\n */\n var _deepCopy = function(source) {\n var copy, i, len, prop;\n if (typeof source !== \"object\" || source == null || typeof source.nodeType === \"number\") {\n copy = source;\n } else if (typeof source.length === \"number\") {\n copy = [];\n for (i = 0, len = source.length; i < len; i++) {\n if (_hasOwn.call(source, i)) {\n copy[i] = _deepCopy(source[i]);\n }\n }\n } else {\n copy = {};\n for (prop in source) {\n if (_hasOwn.call(source, prop)) {\n copy[prop] = _deepCopy(source[prop]);\n }\n }\n }\n return copy;\n };\n /**\n * Makes a shallow copy of `obj` (like `_extend`) but filters its properties based on a list of `keys` to keep.\n * The inverse of `_omit`, mostly. The big difference is that these properties do NOT need to be enumerable to\n * be kept.\n *\n * @returns A new filtered object.\n * @private\n */\n var _pick = function(obj, keys) {\n var newObj = {};\n for (var i = 0, len = keys.length; i < len; i++) {\n if (keys[i] in obj) {\n newObj[keys[i]] = obj[keys[i]];\n }\n }\n return newObj;\n };\n /**\n * Makes a shallow copy of `obj` (like `_extend`) but filters its properties based on a list of `keys` to omit.\n * The inverse of `_pick`.\n *\n * @returns A new filtered object.\n * @private\n */\n var _omit = function(obj, keys) {\n var newObj = {};\n for (var prop in obj) {\n if (keys.indexOf(prop) === -1) {\n newObj[prop] = obj[prop];\n }\n }\n return newObj;\n };\n /**\n * Remove all owned, enumerable properties from an object.\n *\n * @returns The original object without its owned, enumerable properties.\n * @private\n */\n var _deleteOwnProperties = function(obj) {\n if (obj) {\n for (var prop in obj) {\n if (_hasOwn.call(obj, prop)) {\n delete obj[prop];\n }\n }\n }\n return obj;\n };\n /**\n * Determine if an element is contained within another element.\n *\n * @returns Boolean\n * @private\n */\n var _containedBy = function(el, ancestorEl) {\n 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)) {\n do {\n if (el === ancestorEl) {\n return true;\n }\n el = el.parentNode;\n } while (el);\n }\n return false;\n };\n /**\n * Get the URL path's parent directory.\n *\n * @returns String or `undefined`\n * @private\n */\n var _getDirPathOfUrl = function(url) {\n var dir;\n if (typeof url === \"string\" && url) {\n dir = url.split(\"#\")[0].split(\"?\")[0];\n dir = url.slice(0, url.lastIndexOf(\"/\") + 1);\n }\n return dir;\n };\n /**\n * Get the current script's URL by throwing an `Error` and analyzing it.\n *\n * @returns String or `undefined`\n * @private\n */\n var _getCurrentScriptUrlFromErrorStack = function(stack) {\n var url, matches;\n if (typeof stack === \"string\" && stack) {\n matches = stack.match(/^(?:|[^:@]*@|.+\\)@(?=http[s]?|file)|.+?\\s+(?: at |@)(?:[^:\\(]+ )*[\\(]?)((?:http[s]?|file):\\/\\/[\\/]?.+?\\/[^:\\)]*?)(?::\\d+)(?::\\d+)?/);\n if (matches && matches[1]) {\n url = matches[1];\n } else {\n matches = stack.match(/\\)@((?:http[s]?|file):\\/\\/[\\/]?.+?\\/[^:\\)]*?)(?::\\d+)(?::\\d+)?/);\n if (matches && matches[1]) {\n url = matches[1];\n }\n }\n }\n return url;\n };\n /**\n * Get the current script's URL by throwing an `Error` and analyzing it.\n *\n * @returns String or `undefined`\n * @private\n */\n var _getCurrentScriptUrlFromError = function() {\n var url, err;\n try {\n throw new _Error();\n } catch (e) {\n err = e;\n }\n if (err) {\n url = err.sourceURL || err.fileName || _getCurrentScriptUrlFromErrorStack(err.stack);\n }\n return url;\n };\n /**\n * Get the current script's URL.\n *\n * @returns String or `undefined`\n * @private\n */\n var _getCurrentScriptUrl = function() {\n var jsPath, scripts, i;\n if (_document.currentScript && (jsPath = _document.currentScript.src)) {\n return jsPath;\n }\n scripts = _document.getElementsByTagName(\"script\");\n if (scripts.length === 1) {\n return scripts[0].src || undefined;\n }\n if (\"readyState\" in scripts[0]) {\n for (i = scripts.length; i--; ) {\n if (scripts[i].readyState === \"interactive\" && (jsPath = scripts[i].src)) {\n return jsPath;\n }\n }\n }\n if (_document.readyState === \"loading\" && (jsPath = scripts[scripts.length - 1].src)) {\n return jsPath;\n }\n if (jsPath = _getCurrentScriptUrlFromError()) {\n return jsPath;\n }\n return undefined;\n };\n /**\n * Get the unanimous parent directory of ALL script tags.\n * If any script tags are either (a) inline or (b) from differing parent\n * directories, this method must return `undefined`.\n *\n * @returns String or `undefined`\n * @private\n */\n var _getUnanimousScriptParentDir = function() {\n var i, jsDir, jsPath, scripts = _document.getElementsByTagName(\"script\");\n for (i = scripts.length; i--; ) {\n if (!(jsPath = scripts[i].src)) {\n jsDir = null;\n break;\n }\n jsPath = _getDirPathOfUrl(jsPath);\n if (jsDir == null) {\n jsDir = jsPath;\n } else if (jsDir !== jsPath) {\n jsDir = null;\n break;\n }\n }\n return jsDir || undefined;\n };\n /**\n * Get the presumed location of the \"ZeroClipboard.swf\" file, based on the location\n * of the executing JavaScript file (e.g. \"ZeroClipboard.js\", etc.).\n *\n * @returns String\n * @private\n */\n var _getDefaultSwfPath = function() {\n var jsDir = _getDirPathOfUrl(_getCurrentScriptUrl()) || _getUnanimousScriptParentDir() || \"\";\n return jsDir + \"ZeroClipboard.swf\";\n };\n /**\n * Keep track of if the page is framed (in an `iframe`). This can never change.\n * @private\n */\n var _pageIsFramed = function() {\n return window.opener == null && (!!window.top && window != window.top || !!window.parent && window != window.parent);\n }();\n /**\n * Keep track of the state of the Flash object.\n * @private\n */\n var _flashState = {\n bridge: null,\n version: \"0.0.0\",\n pluginType: \"unknown\",\n disabled: null,\n outdated: null,\n sandboxed: null,\n unavailable: null,\n degraded: null,\n deactivated: null,\n overdue: null,\n ready: null\n };\n /**\n * The minimum Flash Player version required to use ZeroClipboard completely.\n * @readonly\n * @private\n */\n var _minimumFlashVersion = \"11.0.0\";\n /**\n * The ZeroClipboard library version number, as reported by Flash, at the time the SWF was compiled.\n */\n var _zcSwfVersion;\n /**\n * Keep track of all event listener registrations.\n * @private\n */\n var _handlers = {};\n /**\n * Keep track of the currently activated element.\n * @private\n */\n var _currentElement;\n /**\n * Keep track of the element that was activated when a `copy` process started.\n * @private\n */\n var _copyTarget;\n /**\n * Keep track of data for the pending clipboard transaction.\n * @private\n */\n var _clipData = {};\n /**\n * Keep track of data formats for the pending clipboard transaction.\n * @private\n */\n var _clipDataFormatMap = null;\n /**\n * Keep track of the Flash availability check timeout.\n * @private\n */\n var _flashCheckTimeout = 0;\n /**\n * Keep track of SWF network errors interval polling.\n * @private\n */\n var _swfFallbackCheckInterval = 0;\n /**\n * The `message` store for events\n * @private\n */\n var _eventMessages = {\n ready: \"Flash communication is established\",\n error: {\n \"flash-disabled\": \"Flash is disabled or not installed. May also be attempting to run Flash in a sandboxed iframe, which is impossible.\",\n \"flash-outdated\": \"Flash is too outdated to support ZeroClipboard\",\n \"flash-sandboxed\": \"Attempting to run Flash in a sandboxed iframe, which is impossible\",\n \"flash-unavailable\": \"Flash is unable to communicate bidirectionally with JavaScript\",\n \"flash-degraded\": \"Flash is unable to preserve data fidelity when communicating with JavaScript\",\n \"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.\",\n \"flash-overdue\": \"Flash communication was established but NOT within the acceptable time limit\",\n \"version-mismatch\": \"ZeroClipboard JS version number does not match ZeroClipboard SWF version number\",\n \"clipboard-error\": \"At least one error was thrown while ZeroClipboard was attempting to inject your data into the clipboard\",\n \"config-mismatch\": \"ZeroClipboard configuration does not match Flash's reality\",\n \"swf-not-found\": \"The ZeroClipboard SWF object could not be loaded, so please check your `swfPath` configuration and/or network connectivity\"\n }\n };\n /**\n * The `name`s of `error` events that can only occur is Flash has at least\n * been able to load the SWF successfully.\n * @private\n */\n var _errorsThatOnlyOccurAfterFlashLoads = [ \"flash-unavailable\", \"flash-degraded\", \"flash-overdue\", \"version-mismatch\", \"config-mismatch\", \"clipboard-error\" ];\n /**\n * The `name`s of `error` events that should likely result in the `_flashState`\n * variable's property values being updated.\n * @private\n */\n var _flashStateErrorNames = [ \"flash-disabled\", \"flash-outdated\", \"flash-sandboxed\", \"flash-unavailable\", \"flash-degraded\", \"flash-deactivated\", \"flash-overdue\" ];\n /**\n * A RegExp to match the `name` property of `error` events related to Flash.\n * @private\n */\n var _flashStateErrorNameMatchingRegex = new RegExp(\"^flash-(\" + _flashStateErrorNames.map(function(errorName) {\n return errorName.replace(/^flash-/, \"\");\n }).join(\"|\") + \")$\");\n /**\n * A RegExp to match the `name` property of `error` events related to Flash,\n * which is enabled.\n * @private\n */\n var _flashStateEnabledErrorNameMatchingRegex = new RegExp(\"^flash-(\" + _flashStateErrorNames.slice(1).map(function(errorName) {\n return errorName.replace(/^flash-/, \"\");\n }).join(\"|\") + \")$\");\n /**\n * ZeroClipboard configuration defaults for the Core module.\n * @private\n */\n var _globalConfig = {\n swfPath: _getDefaultSwfPath(),\n trustedDomains: window.location.host ? [ window.location.host ] : [],\n cacheBust: true,\n forceEnhancedClipboard: false,\n flashLoadTimeout: 3e4,\n autoActivate: true,\n bubbleEvents: true,\n containerId: \"global-zeroclipboard-html-bridge\",\n containerClass: \"global-zeroclipboard-container\",\n swfObjectId: \"global-zeroclipboard-flash-bridge\",\n hoverClass: \"zeroclipboard-is-hover\",\n activeClass: \"zeroclipboard-is-active\",\n forceHandCursor: false,\n title: null,\n zIndex: 999999999\n };\n /**\n * The underlying implementation of `ZeroClipboard.config`.\n * @private\n */\n var _config = function(options) {\n if (typeof options === \"object\" && options !== null) {\n for (var prop in options) {\n if (_hasOwn.call(options, prop)) {\n if (/^(?:forceHandCursor|title|zIndex|bubbleEvents)$/.test(prop)) {\n _globalConfig[prop] = options[prop];\n } else if (_flashState.bridge == null) {\n if (prop === \"containerId\" || prop === \"swfObjectId\") {\n if (_isValidHtml4Id(options[prop])) {\n _globalConfig[prop] = options[prop];\n } else {\n throw new Error(\"The specified `\" + prop + \"` value is not valid as an HTML4 Element ID\");\n }\n } else {\n _globalConfig[prop] = options[prop];\n }\n }\n }\n }\n }\n if (typeof options === \"string\" && options) {\n if (_hasOwn.call(_globalConfig, options)) {\n return _globalConfig[options];\n }\n return;\n }\n return _deepCopy(_globalConfig);\n };\n /**\n * The underlying implementation of `ZeroClipboard.state`.\n * @private\n */\n var _state = function() {\n _detectSandbox();\n return {\n browser: _pick(_navigator, [ \"userAgent\", \"platform\", \"appName\" ]),\n flash: _omit(_flashState, [ \"bridge\" ]),\n zeroclipboard: {\n version: ZeroClipboard.version,\n config: ZeroClipboard.config()\n }\n };\n };\n /**\n * The underlying implementation of `ZeroClipboard.isFlashUnusable`.\n * @private\n */\n var _isFlashUnusable = function() {\n return !!(_flashState.disabled || _flashState.outdated || _flashState.sandboxed || _flashState.unavailable || _flashState.degraded || _flashState.deactivated);\n };\n /**\n * The underlying implementation of `ZeroClipboard.on`.\n * @private\n */\n var _on = function(eventType, listener) {\n var i, len, events, added = {};\n if (typeof eventType === \"string\" && eventType) {\n events = eventType.toLowerCase().split(/\\s+/);\n } else if (typeof eventType === \"object\" && eventType && typeof listener === \"undefined\") {\n for (i in eventType) {\n if (_hasOwn.call(eventType, i) && typeof i === \"string\" && i && typeof eventType[i] === \"function\") {\n ZeroClipboard.on(i, eventType[i]);\n }\n }\n }\n if (events && events.length) {\n for (i = 0, len = events.length; i < len; i++) {\n eventType = events[i].replace(/^on/, \"\");\n added[eventType] = true;\n if (!_handlers[eventType]) {\n _handlers[eventType] = [];\n }\n _handlers[eventType].push(listener);\n }\n if (added.ready && _flashState.ready) {\n ZeroClipboard.emit({\n type: \"ready\"\n });\n }\n if (added.error) {\n for (i = 0, len = _flashStateErrorNames.length; i < len; i++) {\n if (_flashState[_flashStateErrorNames[i].replace(/^flash-/, \"\")] === true) {\n ZeroClipboard.emit({\n type: \"error\",\n name: _flashStateErrorNames[i]\n });\n break;\n }\n }\n if (_zcSwfVersion !== undefined && ZeroClipboard.version !== _zcSwfVersion) {\n ZeroClipboard.emit({\n type: \"error\",\n name: \"version-mismatch\",\n jsVersion: ZeroClipboard.version,\n swfVersion: _zcSwfVersion\n });\n }\n }\n }\n return ZeroClipboard;\n };\n /**\n * The underlying implementation of `ZeroClipboard.off`.\n * @private\n */\n var _off = function(eventType, listener) {\n var i, len, foundIndex, events, perEventHandlers;\n if (arguments.length === 0) {\n events = _keys(_handlers);\n } else if (typeof eventType === \"string\" && eventType) {\n events = eventType.split(/\\s+/);\n } else if (typeof eventType === \"object\" && eventType && typeof listener === \"undefined\") {\n for (i in eventType) {\n if (_hasOwn.call(eventType, i) && typeof i === \"string\" && i && typeof eventType[i] === \"function\") {\n ZeroClipboard.off(i, eventType[i]);\n }\n }\n }\n if (events && events.length) {\n for (i = 0, len = events.length; i < len; i++) {\n eventType = events[i].toLowerCase().replace(/^on/, \"\");\n perEventHandlers = _handlers[eventType];\n if (perEventHandlers && perEventHandlers.length) {\n if (listener) {\n foundIndex = perEventHandlers.indexOf(listener);\n while (foundIndex !== -1) {\n perEventHandlers.splice(foundIndex, 1);\n foundIndex = perEventHandlers.indexOf(listener, foundIndex);\n }\n } else {\n perEventHandlers.length = 0;\n }\n }\n }\n }\n return ZeroClipboard;\n };\n /**\n * The underlying implementation of `ZeroClipboard.handlers`.\n * @private\n */\n var _listeners = function(eventType) {\n var copy;\n if (typeof eventType === \"string\" && eventType) {\n copy = _deepCopy(_handlers[eventType]) || null;\n } else {\n copy = _deepCopy(_handlers);\n }\n return copy;\n };\n /**\n * The underlying implementation of `ZeroClipboard.emit`.\n * @private\n */\n var _emit = function(event) {\n var eventCopy, returnVal, tmp;\n event = _createEvent(event);\n if (!event) {\n return;\n }\n if (_preprocessEvent(event)) {\n return;\n }\n if (event.type === \"ready\" && _flashState.overdue === true) {\n return ZeroClipboard.emit({\n type: \"error\",\n name: \"flash-overdue\"\n });\n }\n eventCopy = _extend({}, event);\n _dispatchCallbacks.call(this, eventCopy);\n if (event.type === \"copy\") {\n tmp = _mapClipDataToFlash(_clipData);\n returnVal = tmp.data;\n _clipDataFormatMap = tmp.formatMap;\n }\n return returnVal;\n };\n /**\n * The underlying implementation of `ZeroClipboard.create`.\n * @private\n */\n var _create = function() {\n var previousState = _flashState.sandboxed;\n _detectSandbox();\n if (typeof _flashState.ready !== \"boolean\") {\n _flashState.ready = false;\n }\n if (_flashState.sandboxed !== previousState && _flashState.sandboxed === true) {\n _flashState.ready = false;\n ZeroClipboard.emit({\n type: \"error\",\n name: \"flash-sandboxed\"\n });\n } else if (!ZeroClipboard.isFlashUnusable() && _flashState.bridge === null) {\n var maxWait = _globalConfig.flashLoadTimeout;\n if (typeof maxWait === \"number\" && maxWait >= 0) {\n _flashCheckTimeout = _setTimeout(function() {\n if (typeof _flashState.deactivated !== \"boolean\") {\n _flashState.deactivated = true;\n }\n if (_flashState.deactivated === true) {\n ZeroClipboard.emit({\n type: \"error\",\n name: \"flash-deactivated\"\n });\n }\n }, maxWait);\n }\n _flashState.overdue = false;\n _embedSwf();\n }\n };\n /**\n * The underlying implementation of `ZeroClipboard.destroy`.\n * @private\n */\n var _destroy = function() {\n ZeroClipboard.clearData();\n ZeroClipboard.blur();\n ZeroClipboard.emit(\"destroy\");\n _unembedSwf();\n ZeroClipboard.off();\n };\n /**\n * The underlying implementation of `ZeroClipboard.setData`.\n * @private\n */\n var _setData = function(format, data) {\n var dataObj;\n if (typeof format === \"object\" && format && typeof data === \"undefined\") {\n dataObj = format;\n ZeroClipboard.clearData();\n } else if (typeof format === \"string\" && format) {\n dataObj = {};\n dataObj[format] = data;\n } else {\n return;\n }\n for (var dataFormat in dataObj) {\n if (typeof dataFormat === \"string\" && dataFormat && _hasOwn.call(dataObj, dataFormat) && typeof dataObj[dataFormat] === \"string\" && dataObj[dataFormat]) {\n _clipData[dataFormat] = dataObj[dataFormat];\n }\n }\n };\n /**\n * The underlying implementation of `ZeroClipboard.clearData`.\n * @private\n */\n var _clearData = function(format) {\n if (typeof format === \"undefined\") {\n _deleteOwnProperties(_clipData);\n _clipDataFormatMap = null;\n } else if (typeof format === \"string\" && _hasOwn.call(_clipData, format)) {\n delete _clipData[format];\n }\n };\n /**\n * The underlying implementation of `ZeroClipboard.getData`.\n * @private\n */\n var _getData = function(format) {\n if (typeof format === \"undefined\") {\n return _deepCopy(_clipData);\n } else if (typeof format === \"string\" && _hasOwn.call(_clipData, format)) {\n return _clipData[format];\n }\n };\n /**\n * The underlying implementation of `ZeroClipboard.focus`/`ZeroClipboard.activate`.\n * @private\n */\n var _focus = function(element) {\n if (!(element && element.nodeType === 1)) {\n return;\n }\n if (_currentElement) {\n _removeClass(_currentElement, _globalConfig.activeClass);\n if (_currentElement !== element) {\n _removeClass(_currentElement, _globalConfig.hoverClass);\n }\n }\n _currentElement = element;\n _addClass(element, _globalConfig.hoverClass);\n var newTitle = element.getAttribute(\"title\") || _globalConfig.title;\n if (typeof newTitle === \"string\" && newTitle) {\n var htmlBridge = _getHtmlBridge(_flashState.bridge);\n if (htmlBridge) {\n htmlBridge.setAttribute(\"title\", newTitle);\n }\n }\n var useHandCursor = _globalConfig.forceHandCursor === true || _getStyle(element, \"cursor\") === \"pointer\";\n _setHandCursor(useHandCursor);\n _reposition();\n };\n /**\n * The underlying implementation of `ZeroClipboard.blur`/`ZeroClipboard.deactivate`.\n * @private\n */\n var _blur = function() {\n var htmlBridge = _getHtmlBridge(_flashState.bridge);\n if (htmlBridge) {\n htmlBridge.removeAttribute(\"title\");\n htmlBridge.style.left = \"0px\";\n htmlBridge.style.top = \"-9999px\";\n htmlBridge.style.width = \"1px\";\n htmlBridge.style.height = \"1px\";\n }\n if (_currentElement) {\n _removeClass(_currentElement, _globalConfig.hoverClass);\n _removeClass(_currentElement, _globalConfig.activeClass);\n _currentElement = null;\n }\n };\n /**\n * The underlying implementation of `ZeroClipboard.activeElement`.\n * @private\n */\n var _activeElement = function() {\n return _currentElement || null;\n };\n /**\n * Check if a value is a valid HTML4 `ID` or `Name` token.\n * @private\n */\n var _isValidHtml4Id = function(id) {\n return typeof id === \"string\" && id && /^[A-Za-z][A-Za-z0-9_:\\-\\.]*$/.test(id);\n };\n /**\n * Create or update an `event` object, based on the `eventType`.\n * @private\n */\n var _createEvent = function(event) {\n var eventType;\n if (typeof event === \"string\" && event) {\n eventType = event;\n event = {};\n } else if (typeof event === \"object\" && event && typeof event.type === \"string\" && event.type) {\n eventType = event.type;\n }\n if (!eventType) {\n return;\n }\n eventType = eventType.toLowerCase();\n if (!event.target && (/^(copy|aftercopy|_click)$/.test(eventType) || eventType === \"error\" && event.name === \"clipboard-error\")) {\n event.target = _copyTarget;\n }\n _extend(event, {\n type: eventType,\n target: event.target || _currentElement || null,\n relatedTarget: event.relatedTarget || null,\n currentTarget: _flashState && _flashState.bridge || null,\n timeStamp: event.timeStamp || _now() || null\n });\n var msg = _eventMessages[event.type];\n if (event.type === \"error\" && event.name && msg) {\n msg = msg[event.name];\n }\n if (msg) {\n event.message = msg;\n }\n if (event.type === \"ready\") {\n _extend(event, {\n target: null,\n version: _flashState.version\n });\n }\n if (event.type === \"error\") {\n if (_flashStateErrorNameMatchingRegex.test(event.name)) {\n _extend(event, {\n target: null,\n minimumVersion: _minimumFlashVersion\n });\n }\n if (_flashStateEnabledErrorNameMatchingRegex.test(event.name)) {\n _extend(event, {\n version: _flashState.version\n });\n }\n }\n if (event.type === \"copy\") {\n event.clipboardData = {\n setData: ZeroClipboard.setData,\n clearData: ZeroClipboard.clearData\n };\n }\n if (event.type === \"aftercopy\") {\n event = _mapClipResultsFromFlash(event, _clipDataFormatMap);\n }\n if (event.target && !event.relatedTarget) {\n event.relatedTarget = _getRelatedTarget(event.target);\n }\n return _addMouseData(event);\n };\n /**\n * Get a relatedTarget from the target's `data-clipboard-target` attribute\n * @private\n */\n var _getRelatedTarget = function(targetEl) {\n var relatedTargetId = targetEl && targetEl.getAttribute && targetEl.getAttribute(\"data-clipboard-target\");\n return relatedTargetId ? _document.getElementById(relatedTargetId) : null;\n };\n /**\n * Add element and position data to `MouseEvent` instances\n * @private\n */\n var _addMouseData = function(event) {\n if (event && /^_(?:click|mouse(?:over|out|down|up|move))$/.test(event.type)) {\n var srcElement = event.target;\n var fromElement = event.type === \"_mouseover\" && event.relatedTarget ? event.relatedTarget : undefined;\n var toElement = event.type === \"_mouseout\" && event.relatedTarget ? event.relatedTarget : undefined;\n var pos = _getElementPosition(srcElement);\n var screenLeft = _window.screenLeft || _window.screenX || 0;\n var screenTop = _window.screenTop || _window.screenY || 0;\n var scrollLeft = _document.body.scrollLeft + _document.documentElement.scrollLeft;\n var scrollTop = _document.body.scrollTop + _document.documentElement.scrollTop;\n var pageX = pos.left + (typeof event._stageX === \"number\" ? event._stageX : 0);\n var pageY = pos.top + (typeof event._stageY === \"number\" ? event._stageY : 0);\n var clientX = pageX - scrollLeft;\n var clientY = pageY - scrollTop;\n var screenX = screenLeft + clientX;\n var screenY = screenTop + clientY;\n var moveX = typeof event.movementX === \"number\" ? event.movementX : 0;\n var moveY = typeof event.movementY === \"number\" ? event.movementY : 0;\n delete event._stageX;\n delete event._stageY;\n _extend(event, {\n srcElement: srcElement,\n fromElement: fromElement,\n toElement: toElement,\n screenX: screenX,\n screenY: screenY,\n pageX: pageX,\n pageY: pageY,\n clientX: clientX,\n clientY: clientY,\n x: clientX,\n y: clientY,\n movementX: moveX,\n movementY: moveY,\n offsetX: 0,\n offsetY: 0,\n layerX: 0,\n layerY: 0\n });\n }\n return event;\n };\n /**\n * Determine if an event's registered handlers should be execute synchronously or asynchronously.\n *\n * @returns {boolean}\n * @private\n */\n var _shouldPerformAsync = function(event) {\n var eventType = event && typeof event.type === \"string\" && event.type || \"\";\n return !/^(?:(?:before)?copy|destroy)$/.test(eventType);\n };\n /**\n * Control if a callback should be executed asynchronously or not.\n *\n * @returns `undefined`\n * @private\n */\n var _dispatchCallback = function(func, context, args, async) {\n if (async) {\n _setTimeout(function() {\n func.apply(context, args);\n }, 0);\n } else {\n func.apply(context, args);\n }\n };\n /**\n * Handle the actual dispatching of events to client instances.\n *\n * @returns `undefined`\n * @private\n */\n var _dispatchCallbacks = function(event) {\n if (!(typeof event === \"object\" && event && event.type)) {\n return;\n }\n var async = _shouldPerformAsync(event);\n var wildcardTypeHandlers = _handlers[\"*\"] || [];\n var specificTypeHandlers = _handlers[event.type] || [];\n var handlers = wildcardTypeHandlers.concat(specificTypeHandlers);\n if (handlers && handlers.length) {\n var i, len, func, context, eventCopy, originalContext = this;\n for (i = 0, len = handlers.length; i < len; i++) {\n func = handlers[i];\n context = originalContext;\n if (typeof func === \"string\" && typeof _window[func] === \"function\") {\n func = _window[func];\n }\n if (typeof func === \"object\" && func && typeof func.handleEvent === \"function\") {\n context = func;\n func = func.handleEvent;\n }\n if (typeof func === \"function\") {\n eventCopy = _extend({}, event);\n _dispatchCallback(func, context, [ eventCopy ], async);\n }\n }\n }\n return this;\n };\n /**\n * Check an `error` event's `name` property to see if Flash has\n * already loaded, which rules out possible `iframe` sandboxing.\n * @private\n */\n var _getSandboxStatusFromErrorEvent = function(event) {\n var isSandboxed = null;\n if (_pageIsFramed === false || event && event.type === \"error\" && event.name && _errorsThatOnlyOccurAfterFlashLoads.indexOf(event.name) !== -1) {\n isSandboxed = false;\n }\n return isSandboxed;\n };\n /**\n * Preprocess any special behaviors, reactions, or state changes after receiving this event.\n * Executes only once per event emitted, NOT once per client.\n * @private\n */\n var _preprocessEvent = function(event) {\n var element = event.target || _currentElement || null;\n var sourceIsSwf = event._source === \"swf\";\n delete event._source;\n switch (event.type) {\n case \"error\":\n var isSandboxed = event.name === \"flash-sandboxed\" || _getSandboxStatusFromErrorEvent(event);\n if (typeof isSandboxed === \"boolean\") {\n _flashState.sandboxed = isSandboxed;\n }\n if (_flashStateErrorNames.indexOf(event.name) !== -1) {\n _extend(_flashState, {\n disabled: event.name === \"flash-disabled\",\n outdated: event.name === \"flash-outdated\",\n unavailable: event.name === \"flash-unavailable\",\n degraded: event.name === \"flash-degraded\",\n deactivated: event.name === \"flash-deactivated\",\n overdue: event.name === \"flash-overdue\",\n ready: false\n });\n } else if (event.name === \"version-mismatch\") {\n _zcSwfVersion = event.swfVersion;\n _extend(_flashState, {\n disabled: false,\n outdated: false,\n unavailable: false,\n degraded: false,\n deactivated: false,\n overdue: false,\n ready: false\n });\n }\n _clearTimeoutsAndPolling();\n break;\n\n case \"ready\":\n _zcSwfVersion = event.swfVersion;\n var wasDeactivated = _flashState.deactivated === true;\n _extend(_flashState, {\n disabled: false,\n outdated: false,\n sandboxed: false,\n unavailable: false,\n degraded: false,\n deactivated: false,\n overdue: wasDeactivated,\n ready: !wasDeactivated\n });\n _clearTimeoutsAndPolling();\n break;\n\n case \"beforecopy\":\n _copyTarget = element;\n break;\n\n case \"copy\":\n var textContent, htmlContent, targetEl = event.relatedTarget;\n if (!(_clipData[\"text/html\"] || _clipData[\"text/plain\"]) && targetEl && (htmlContent = targetEl.value || targetEl.outerHTML || targetEl.innerHTML) && (textContent = targetEl.value || targetEl.textContent || targetEl.innerText)) {\n event.clipboardData.clearData();\n event.clipboardData.setData(\"text/plain\", textContent);\n if (htmlContent !== textContent) {\n event.clipboardData.setData(\"text/html\", htmlContent);\n }\n } else if (!_clipData[\"text/plain\"] && event.target && (textContent = event.target.getAttribute(\"data-clipboard-text\"))) {\n event.clipboardData.clearData();\n event.clipboardData.setData(\"text/plain\", textContent);\n }\n break;\n\n case \"aftercopy\":\n _queueEmitClipboardErrors(event);\n ZeroClipboard.clearData();\n if (element && element !== _safeActiveElement() && element.focus) {\n element.focus();\n }\n break;\n\n case \"_mouseover\":\n ZeroClipboard.focus(element);\n if (_globalConfig.bubbleEvents === true && sourceIsSwf) {\n if (element && element !== event.relatedTarget && !_containedBy(event.relatedTarget, element)) {\n _fireMouseEvent(_extend({}, event, {\n type: \"mouseenter\",\n bubbles: false,\n cancelable: false\n }));\n }\n _fireMouseEvent(_extend({}, event, {\n type: \"mouseover\"\n }));\n }\n break;\n\n case \"_mouseout\":\n ZeroClipboard.blur();\n if (_globalConfig.bubbleEvents === true && sourceIsSwf) {\n if (element && element !== event.relatedTarget && !_containedBy(event.relatedTarget, element)) {\n _fireMouseEvent(_extend({}, event, {\n type: \"mouseleave\",\n bubbles: false,\n cancelable: false\n }));\n }\n _fireMouseEvent(_extend({}, event, {\n type: \"mouseout\"\n }));\n }\n break;\n\n case \"_mousedown\":\n _addClass(element, _globalConfig.activeClass);\n if (_globalConfig.bubbleEvents === true && sourceIsSwf) {\n _fireMouseEvent(_extend({}, event, {\n type: event.type.slice(1)\n }));\n }\n break;\n\n case \"_mouseup\":\n _removeClass(element, _globalConfig.activeClass);\n if (_globalConfig.bubbleEvents === true && sourceIsSwf) {\n _fireMouseEvent(_extend({}, event, {\n type: event.type.slice(1)\n }));\n }\n break;\n\n case \"_click\":\n _copyTarget = null;\n if (_globalConfig.bubbleEvents === true && sourceIsSwf) {\n _fireMouseEvent(_extend({}, event, {\n type: event.type.slice(1)\n }));\n }\n break;\n\n case \"_mousemove\":\n if (_globalConfig.bubbleEvents === true && sourceIsSwf) {\n _fireMouseEvent(_extend({}, event, {\n type: event.type.slice(1)\n }));\n }\n break;\n }\n if (/^_(?:click|mouse(?:over|out|down|up|move))$/.test(event.type)) {\n return true;\n }\n };\n /**\n * Check an \"aftercopy\" event for clipboard errors and emit a corresponding \"error\" event.\n * @private\n */\n var _queueEmitClipboardErrors = function(aftercopyEvent) {\n if (aftercopyEvent.errors && aftercopyEvent.errors.length > 0) {\n var errorEvent = _deepCopy(aftercopyEvent);\n _extend(errorEvent, {\n type: \"error\",\n name: \"clipboard-error\"\n });\n delete errorEvent.success;\n _setTimeout(function() {\n ZeroClipboard.emit(errorEvent);\n }, 0);\n }\n };\n /**\n * Dispatch a synthetic MouseEvent.\n *\n * @returns `undefined`\n * @private\n */\n var _fireMouseEvent = function(event) {\n if (!(event && typeof event.type === \"string\" && event)) {\n return;\n }\n var e, target = event.target || null, doc = target && target.ownerDocument || _document, defaults = {\n view: doc.defaultView || _window,\n canBubble: true,\n cancelable: true,\n detail: event.type === \"click\" ? 1 : 0,\n button: typeof event.which === \"number\" ? event.which - 1 : typeof event.button === \"number\" ? event.button : doc.createEvent ? 0 : 1\n }, args = _extend(defaults, event);\n if (!target) {\n return;\n }\n if (doc.createEvent && target.dispatchEvent) {\n 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 ];\n e = doc.createEvent(\"MouseEvents\");\n if (e.initMouseEvent) {\n e.initMouseEvent.apply(e, args);\n e._source = \"js\";\n target.dispatchEvent(e);\n }\n }\n };\n /**\n * Continuously poll the DOM until either:\n * (a) the fallback content becomes visible, or\n * (b) we receive an event from SWF (handled elsewhere)\n *\n * IMPORTANT:\n * This is NOT a necessary check but it can result in significantly faster\n * detection of bad `swfPath` configuration and/or network/server issues [in\n * supported browsers] than waiting for the entire `flashLoadTimeout` duration\n * to elapse before detecting that the SWF cannot be loaded. The detection\n * duration can be anywhere from 10-30 times faster [in supported browsers] by\n * using this approach.\n *\n * @returns `undefined`\n * @private\n */\n var _watchForSwfFallbackContent = function() {\n var maxWait = _globalConfig.flashLoadTimeout;\n if (typeof maxWait === \"number\" && maxWait >= 0) {\n var pollWait = Math.min(1e3, maxWait / 10);\n var fallbackContentId = _globalConfig.swfObjectId + \"_fallbackContent\";\n _swfFallbackCheckInterval = _setInterval(function() {\n var el = _document.getElementById(fallbackContentId);\n if (_isElementVisible(el)) {\n _clearTimeoutsAndPolling();\n _flashState.deactivated = null;\n ZeroClipboard.emit({\n type: \"error\",\n name: \"swf-not-found\"\n });\n }\n }, pollWait);\n }\n };\n /**\n * Create the HTML bridge element to embed the Flash object into.\n * @private\n */\n var _createHtmlBridge = function() {\n var container = _document.createElement(\"div\");\n container.id = _globalConfig.containerId;\n container.className = _globalConfig.containerClass;\n container.style.position = \"absolute\";\n container.style.left = \"0px\";\n container.style.top = \"-9999px\";\n container.style.width = \"1px\";\n container.style.height = \"1px\";\n container.style.zIndex = \"\" + _getSafeZIndex(_globalConfig.zIndex);\n return container;\n };\n /**\n * Get the HTML element container that wraps the Flash bridge object/element.\n * @private\n */\n var _getHtmlBridge = function(flashBridge) {\n var htmlBridge = flashBridge && flashBridge.parentNode;\n while (htmlBridge && htmlBridge.nodeName === \"OBJECT\" && htmlBridge.parentNode) {\n htmlBridge = htmlBridge.parentNode;\n }\n return htmlBridge || null;\n };\n /**\n * Create the SWF object.\n *\n * @returns The SWF object reference.\n * @private\n */\n var _embedSwf = function() {\n var len, flashBridge = _flashState.bridge, container = _getHtmlBridge(flashBridge);\n if (!flashBridge) {\n var allowScriptAccess = _determineScriptAccess(_window.location.host, _globalConfig);\n var allowNetworking = allowScriptAccess === \"never\" ? \"none\" : \"all\";\n var flashvars = _vars(_extend({\n jsVersion: ZeroClipboard.version\n }, _globalConfig));\n var swfUrl = _globalConfig.swfPath + _cacheBust(_globalConfig.swfPath, _globalConfig);\n container = _createHtmlBridge();\n var divToBeReplaced = _document.createElement(\"div\");\n container.appendChild(divToBeReplaced);\n _document.body.appendChild(container);\n var tmpDiv = _document.createElement(\"div\");\n var usingActiveX = _flashState.pluginType === \"activex\";\n tmpDiv.innerHTML = '\" + (usingActiveX ? '' : \"\") + '' + '' + '' + '' + '' + '
 
' + \"
\";\n flashBridge = tmpDiv.firstChild;\n tmpDiv = null;\n _unwrap(flashBridge).ZeroClipboard = ZeroClipboard;\n container.replaceChild(flashBridge, divToBeReplaced);\n _watchForSwfFallbackContent();\n }\n if (!flashBridge) {\n flashBridge = _document[_globalConfig.swfObjectId];\n if (flashBridge && (len = flashBridge.length)) {\n flashBridge = flashBridge[len - 1];\n }\n if (!flashBridge && container) {\n flashBridge = container.firstChild;\n }\n }\n _flashState.bridge = flashBridge || null;\n return flashBridge;\n };\n /**\n * Destroy the SWF object.\n * @private\n */\n var _unembedSwf = function() {\n var flashBridge = _flashState.bridge;\n if (flashBridge) {\n var htmlBridge = _getHtmlBridge(flashBridge);\n if (htmlBridge) {\n if (_flashState.pluginType === \"activex\" && \"readyState\" in flashBridge) {\n flashBridge.style.display = \"none\";\n (function removeSwfFromIE() {\n if (flashBridge.readyState === 4) {\n for (var prop in flashBridge) {\n if (typeof flashBridge[prop] === \"function\") {\n flashBridge[prop] = null;\n }\n }\n if (flashBridge.parentNode) {\n flashBridge.parentNode.removeChild(flashBridge);\n }\n if (htmlBridge.parentNode) {\n htmlBridge.parentNode.removeChild(htmlBridge);\n }\n } else {\n _setTimeout(removeSwfFromIE, 10);\n }\n })();\n } else {\n if (flashBridge.parentNode) {\n flashBridge.parentNode.removeChild(flashBridge);\n }\n if (htmlBridge.parentNode) {\n htmlBridge.parentNode.removeChild(htmlBridge);\n }\n }\n }\n _clearTimeoutsAndPolling();\n _flashState.ready = null;\n _flashState.bridge = null;\n _flashState.deactivated = null;\n _zcSwfVersion = undefined;\n }\n };\n /**\n * Map the data format names of the \"clipData\" to Flash-friendly names.\n *\n * @returns A new transformed object.\n * @private\n */\n var _mapClipDataToFlash = function(clipData) {\n var newClipData = {}, formatMap = {};\n if (!(typeof clipData === \"object\" && clipData)) {\n return;\n }\n for (var dataFormat in clipData) {\n if (dataFormat && _hasOwn.call(clipData, dataFormat) && typeof clipData[dataFormat] === \"string\" && clipData[dataFormat]) {\n switch (dataFormat.toLowerCase()) {\n case \"text/plain\":\n case \"text\":\n case \"air:text\":\n case \"flash:text\":\n newClipData.text = clipData[dataFormat];\n formatMap.text = dataFormat;\n break;\n\n case \"text/html\":\n case \"html\":\n case \"air:html\":\n case \"flash:html\":\n newClipData.html = clipData[dataFormat];\n formatMap.html = dataFormat;\n break;\n\n case \"application/rtf\":\n case \"text/rtf\":\n case \"rtf\":\n case \"richtext\":\n case \"air:rtf\":\n case \"flash:rtf\":\n newClipData.rtf = clipData[dataFormat];\n formatMap.rtf = dataFormat;\n break;\n\n default:\n break;\n }\n }\n }\n return {\n data: newClipData,\n formatMap: formatMap\n };\n };\n /**\n * Map the data format names from Flash-friendly names back to their original \"clipData\" names (via a format mapping).\n *\n * @returns A new transformed object.\n * @private\n */\n var _mapClipResultsFromFlash = function(clipResults, formatMap) {\n if (!(typeof clipResults === \"object\" && clipResults && typeof formatMap === \"object\" && formatMap)) {\n return clipResults;\n }\n var newResults = {};\n for (var prop in clipResults) {\n if (_hasOwn.call(clipResults, prop)) {\n if (prop === \"errors\") {\n newResults[prop] = clipResults[prop] ? clipResults[prop].slice() : [];\n for (var i = 0, len = newResults[prop].length; i < len; i++) {\n newResults[prop][i].format = formatMap[newResults[prop][i].format];\n }\n } else if (prop !== \"success\" && prop !== \"data\") {\n newResults[prop] = clipResults[prop];\n } else {\n newResults[prop] = {};\n var tmpHash = clipResults[prop];\n for (var dataFormat in tmpHash) {\n if (dataFormat && _hasOwn.call(tmpHash, dataFormat) && _hasOwn.call(formatMap, dataFormat)) {\n newResults[prop][formatMap[dataFormat]] = tmpHash[dataFormat];\n }\n }\n }\n }\n }\n return newResults;\n };\n /**\n * Will look at a path, and will create a \"?noCache={time}\" or \"&noCache={time}\"\n * query param string to return. Does NOT append that string to the original path.\n * This is useful because ExternalInterface often breaks when a Flash SWF is cached.\n *\n * @returns The `noCache` query param with necessary \"?\"/\"&\" prefix.\n * @private\n */\n var _cacheBust = function(path, options) {\n var cacheBust = options == null || options && options.cacheBust === true;\n if (cacheBust) {\n return (path.indexOf(\"?\") === -1 ? \"?\" : \"&\") + \"noCache=\" + _now();\n } else {\n return \"\";\n }\n };\n /**\n * Creates a query string for the FlashVars param.\n * Does NOT include the cache-busting query param.\n *\n * @returns FlashVars query string\n * @private\n */\n var _vars = function(options) {\n var i, len, domain, domains, str = \"\", trustedOriginsExpanded = [];\n if (options.trustedDomains) {\n if (typeof options.trustedDomains === \"string\") {\n domains = [ options.trustedDomains ];\n } else if (typeof options.trustedDomains === \"object\" && \"length\" in options.trustedDomains) {\n domains = options.trustedDomains;\n }\n }\n if (domains && domains.length) {\n for (i = 0, len = domains.length; i < len; i++) {\n if (_hasOwn.call(domains, i) && domains[i] && typeof domains[i] === \"string\") {\n domain = _extractDomain(domains[i]);\n if (!domain) {\n continue;\n }\n if (domain === \"*\") {\n trustedOriginsExpanded.length = 0;\n trustedOriginsExpanded.push(domain);\n break;\n }\n trustedOriginsExpanded.push.apply(trustedOriginsExpanded, [ domain, \"//\" + domain, _window.location.protocol + \"//\" + domain ]);\n }\n }\n }\n if (trustedOriginsExpanded.length) {\n str += \"trustedOrigins=\" + _encodeURIComponent(trustedOriginsExpanded.join(\",\"));\n }\n if (options.forceEnhancedClipboard === true) {\n str += (str ? \"&\" : \"\") + \"forceEnhancedClipboard=true\";\n }\n if (typeof options.swfObjectId === \"string\" && options.swfObjectId) {\n str += (str ? \"&\" : \"\") + \"swfObjectId=\" + _encodeURIComponent(options.swfObjectId);\n }\n if (typeof options.jsVersion === \"string\" && options.jsVersion) {\n str += (str ? \"&\" : \"\") + \"jsVersion=\" + _encodeURIComponent(options.jsVersion);\n }\n return str;\n };\n /**\n * Extract the domain (e.g. \"github.com\") from an origin (e.g. \"https://github.com\") or\n * URL (e.g. \"https://github.com/zeroclipboard/zeroclipboard/\").\n *\n * @returns the domain\n * @private\n */\n var _extractDomain = function(originOrUrl) {\n if (originOrUrl == null || originOrUrl === \"\") {\n return null;\n }\n originOrUrl = originOrUrl.replace(/^\\s+|\\s+$/g, \"\");\n if (originOrUrl === \"\") {\n return null;\n }\n var protocolIndex = originOrUrl.indexOf(\"//\");\n originOrUrl = protocolIndex === -1 ? originOrUrl : originOrUrl.slice(protocolIndex + 2);\n var pathIndex = originOrUrl.indexOf(\"/\");\n originOrUrl = pathIndex === -1 ? originOrUrl : protocolIndex === -1 || pathIndex === 0 ? null : originOrUrl.slice(0, pathIndex);\n if (originOrUrl && originOrUrl.slice(-4).toLowerCase() === \".swf\") {\n return null;\n }\n return originOrUrl || null;\n };\n /**\n * Set `allowScriptAccess` based on `trustedDomains` and `window.location.host` vs. `swfPath`.\n *\n * @returns The appropriate script access level.\n * @private\n */\n var _determineScriptAccess = function() {\n var _extractAllDomains = function(origins) {\n var i, len, tmp, resultsArray = [];\n if (typeof origins === \"string\") {\n origins = [ origins ];\n }\n if (!(typeof origins === \"object\" && origins && typeof origins.length === \"number\")) {\n return resultsArray;\n }\n for (i = 0, len = origins.length; i < len; i++) {\n if (_hasOwn.call(origins, i) && (tmp = _extractDomain(origins[i]))) {\n if (tmp === \"*\") {\n resultsArray.length = 0;\n resultsArray.push(\"*\");\n break;\n }\n if (resultsArray.indexOf(tmp) === -1) {\n resultsArray.push(tmp);\n }\n }\n }\n return resultsArray;\n };\n return function(currentDomain, configOptions) {\n var swfDomain = _extractDomain(configOptions.swfPath);\n if (swfDomain === null) {\n swfDomain = currentDomain;\n }\n var trustedDomains = _extractAllDomains(configOptions.trustedDomains);\n var len = trustedDomains.length;\n if (len > 0) {\n if (len === 1 && trustedDomains[0] === \"*\") {\n return \"always\";\n }\n if (trustedDomains.indexOf(currentDomain) !== -1) {\n if (len === 1 && currentDomain === swfDomain) {\n return \"sameDomain\";\n }\n return \"always\";\n }\n }\n return \"never\";\n };\n }();\n /**\n * Get the currently active/focused DOM element.\n *\n * @returns the currently active/focused element, or `null`\n * @private\n */\n var _safeActiveElement = function() {\n try {\n return _document.activeElement;\n } catch (err) {\n return null;\n }\n };\n /**\n * Add a class to an element, if it doesn't already have it.\n *\n * @returns The element, with its new class added.\n * @private\n */\n var _addClass = function(element, value) {\n var c, cl, className, classNames = [];\n if (typeof value === \"string\" && value) {\n classNames = value.split(/\\s+/);\n }\n if (element && element.nodeType === 1 && classNames.length > 0) {\n if (element.classList) {\n for (c = 0, cl = classNames.length; c < cl; c++) {\n element.classList.add(classNames[c]);\n }\n } else if (element.hasOwnProperty(\"className\")) {\n className = \" \" + element.className + \" \";\n for (c = 0, cl = classNames.length; c < cl; c++) {\n if (className.indexOf(\" \" + classNames[c] + \" \") === -1) {\n className += classNames[c] + \" \";\n }\n }\n element.className = className.replace(/^\\s+|\\s+$/g, \"\");\n }\n }\n return element;\n };\n /**\n * Remove a class from an element, if it has it.\n *\n * @returns The element, with its class removed.\n * @private\n */\n var _removeClass = function(element, value) {\n var c, cl, className, classNames = [];\n if (typeof value === \"string\" && value) {\n classNames = value.split(/\\s+/);\n }\n if (element && element.nodeType === 1 && classNames.length > 0) {\n if (element.classList && element.classList.length > 0) {\n for (c = 0, cl = classNames.length; c < cl; c++) {\n element.classList.remove(classNames[c]);\n }\n } else if (element.className) {\n className = (\" \" + element.className + \" \").replace(/[\\r\\n\\t]/g, \" \");\n for (c = 0, cl = classNames.length; c < cl; c++) {\n className = className.replace(\" \" + classNames[c] + \" \", \" \");\n }\n element.className = className.replace(/^\\s+|\\s+$/g, \"\");\n }\n }\n return element;\n };\n /**\n * Attempt to interpret the element's CSS styling. If `prop` is `\"cursor\"`,\n * then we assume that it should be a hand (\"pointer\") cursor if the element\n * is an anchor element (\"a\" tag).\n *\n * @returns The computed style property.\n * @private\n */\n var _getStyle = function(el, prop) {\n var value = _getComputedStyle(el, null).getPropertyValue(prop);\n if (prop === \"cursor\") {\n if (!value || value === \"auto\") {\n if (el.nodeName === \"A\") {\n return \"pointer\";\n }\n }\n }\n return value;\n };\n /**\n * Get the absolutely positioned coordinates of a DOM element.\n *\n * @returns Object containing the element's position, width, and height.\n * @private\n */\n var _getElementPosition = function(el) {\n var pos = {\n left: 0,\n top: 0,\n width: 0,\n height: 0\n };\n if (el.getBoundingClientRect) {\n var elRect = el.getBoundingClientRect();\n var pageXOffset = _window.pageXOffset;\n var pageYOffset = _window.pageYOffset;\n var leftBorderWidth = _document.documentElement.clientLeft || 0;\n var topBorderWidth = _document.documentElement.clientTop || 0;\n var leftBodyOffset = 0;\n var topBodyOffset = 0;\n if (_getStyle(_document.body, \"position\") === \"relative\") {\n var bodyRect = _document.body.getBoundingClientRect();\n var htmlRect = _document.documentElement.getBoundingClientRect();\n leftBodyOffset = bodyRect.left - htmlRect.left || 0;\n topBodyOffset = bodyRect.top - htmlRect.top || 0;\n }\n pos.left = elRect.left + pageXOffset - leftBorderWidth - leftBodyOffset;\n pos.top = elRect.top + pageYOffset - topBorderWidth - topBodyOffset;\n pos.width = \"width\" in elRect ? elRect.width : elRect.right - elRect.left;\n pos.height = \"height\" in elRect ? elRect.height : elRect.bottom - elRect.top;\n }\n return pos;\n };\n /**\n * Determine is an element is visible somewhere within the document (page).\n *\n * @returns Boolean\n * @private\n */\n var _isElementVisible = function(el) {\n if (!el) {\n return false;\n }\n var styles = _getComputedStyle(el, null);\n var hasCssHeight = _parseFloat(styles.height) > 0;\n var hasCssWidth = _parseFloat(styles.width) > 0;\n var hasCssTop = _parseFloat(styles.top) >= 0;\n var hasCssLeft = _parseFloat(styles.left) >= 0;\n var cssKnows = hasCssHeight && hasCssWidth && hasCssTop && hasCssLeft;\n var rect = cssKnows ? null : _getElementPosition(el);\n 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));\n return isVisible;\n };\n /**\n * Clear all existing timeouts and interval polling delegates.\n *\n * @returns `undefined`\n * @private\n */\n var _clearTimeoutsAndPolling = function() {\n _clearTimeout(_flashCheckTimeout);\n _flashCheckTimeout = 0;\n _clearInterval(_swfFallbackCheckInterval);\n _swfFallbackCheckInterval = 0;\n };\n /**\n * Reposition the Flash object to cover the currently activated element.\n *\n * @returns `undefined`\n * @private\n */\n var _reposition = function() {\n var htmlBridge;\n if (_currentElement && (htmlBridge = _getHtmlBridge(_flashState.bridge))) {\n var pos = _getElementPosition(_currentElement);\n _extend(htmlBridge.style, {\n width: pos.width + \"px\",\n height: pos.height + \"px\",\n top: pos.top + \"px\",\n left: pos.left + \"px\",\n zIndex: \"\" + _getSafeZIndex(_globalConfig.zIndex)\n });\n }\n };\n /**\n * Sends a signal to the Flash object to display the hand cursor if `true`.\n *\n * @returns `undefined`\n * @private\n */\n var _setHandCursor = function(enabled) {\n if (_flashState.ready === true) {\n if (_flashState.bridge && typeof _flashState.bridge.setHandCursor === \"function\") {\n _flashState.bridge.setHandCursor(enabled);\n } else {\n _flashState.ready = false;\n }\n }\n };\n /**\n * Get a safe value for `zIndex`\n *\n * @returns an integer, or \"auto\"\n * @private\n */\n var _getSafeZIndex = function(val) {\n if (/^(?:auto|inherit)$/.test(val)) {\n return val;\n }\n var zIndex;\n if (typeof val === \"number\" && !_isNaN(val)) {\n zIndex = val;\n } else if (typeof val === \"string\") {\n zIndex = _getSafeZIndex(_parseInt(val, 10));\n }\n return typeof zIndex === \"number\" ? zIndex : \"auto\";\n };\n /**\n * Attempt to detect if ZeroClipboard is executing inside of a sandboxed iframe.\n * If it is, Flash Player cannot be used, so ZeroClipboard is dead in the water.\n *\n * @see {@link http://lists.w3.org/Archives/Public/public-whatwg-archive/2014Dec/0002.html}\n * @see {@link https://github.com/zeroclipboard/zeroclipboard/issues/511}\n * @see {@link http://zeroclipboard.org/test-iframes.html}\n *\n * @returns `true` (is sandboxed), `false` (is not sandboxed), or `null` (uncertain) \n * @private\n */\n var _detectSandbox = function(doNotReassessFlashSupport) {\n var effectiveScriptOrigin, frame, frameError, previousState = _flashState.sandboxed, isSandboxed = null;\n doNotReassessFlashSupport = doNotReassessFlashSupport === true;\n if (_pageIsFramed === false) {\n isSandboxed = false;\n } else {\n try {\n frame = window.frameElement || null;\n } catch (e) {\n frameError = {\n name: e.name,\n message: e.message\n };\n }\n if (frame && frame.nodeType === 1 && frame.nodeName === \"IFRAME\") {\n try {\n isSandboxed = frame.hasAttribute(\"sandbox\");\n } catch (e) {\n isSandboxed = null;\n }\n } else {\n try {\n effectiveScriptOrigin = document.domain || null;\n } catch (e) {\n effectiveScriptOrigin = null;\n }\n if (effectiveScriptOrigin === null || frameError && frameError.name === \"SecurityError\" && /(^|[\\s\\(\\[@])sandbox(es|ed|ing|[\\s\\.,!\\)\\]@]|$)/.test(frameError.message.toLowerCase())) {\n isSandboxed = true;\n }\n }\n }\n _flashState.sandboxed = isSandboxed;\n if (previousState !== isSandboxed && !doNotReassessFlashSupport) {\n _detectFlashSupport(_ActiveXObject);\n }\n return isSandboxed;\n };\n /**\n * Detect the Flash Player status, version, and plugin type.\n *\n * @see {@link https://code.google.com/p/doctype-mirror/wiki/ArticleDetectFlash#The_code}\n * @see {@link http://stackoverflow.com/questions/12866060/detecting-pepper-ppapi-flash-with-javascript}\n *\n * @returns `undefined`\n * @private\n */\n var _detectFlashSupport = function(ActiveXObject) {\n var plugin, ax, mimeType, hasFlash = false, isActiveX = false, isPPAPI = false, flashVersion = \"\";\n /**\n * Derived from Apple's suggested sniffer.\n * @param {String} desc e.g. \"Shockwave Flash 7.0 r61\"\n * @returns {String} \"7.0.61\"\n * @private\n */\n function parseFlashVersion(desc) {\n var matches = desc.match(/[\\d]+/g);\n matches.length = 3;\n return matches.join(\".\");\n }\n function isPepperFlash(flashPlayerFileName) {\n return !!flashPlayerFileName && (flashPlayerFileName = flashPlayerFileName.toLowerCase()) && (/^(pepflashplayer\\.dll|libpepflashplayer\\.so|pepperflashplayer\\.plugin)$/.test(flashPlayerFileName) || flashPlayerFileName.slice(-13) === \"chrome.plugin\");\n }\n function inspectPlugin(plugin) {\n if (plugin) {\n hasFlash = true;\n if (plugin.version) {\n flashVersion = parseFlashVersion(plugin.version);\n }\n if (!flashVersion && plugin.description) {\n flashVersion = parseFlashVersion(plugin.description);\n }\n if (plugin.filename) {\n isPPAPI = isPepperFlash(plugin.filename);\n }\n }\n }\n if (_navigator.plugins && _navigator.plugins.length) {\n plugin = _navigator.plugins[\"Shockwave Flash\"];\n inspectPlugin(plugin);\n if (_navigator.plugins[\"Shockwave Flash 2.0\"]) {\n hasFlash = true;\n flashVersion = \"2.0.0.11\";\n }\n } else if (_navigator.mimeTypes && _navigator.mimeTypes.length) {\n mimeType = _navigator.mimeTypes[\"application/x-shockwave-flash\"];\n plugin = mimeType && mimeType.enabledPlugin;\n inspectPlugin(plugin);\n } else if (typeof ActiveXObject !== \"undefined\") {\n isActiveX = true;\n try {\n ax = new ActiveXObject(\"ShockwaveFlash.ShockwaveFlash.7\");\n hasFlash = true;\n flashVersion = parseFlashVersion(ax.GetVariable(\"$version\"));\n } catch (e1) {\n try {\n ax = new ActiveXObject(\"ShockwaveFlash.ShockwaveFlash.6\");\n hasFlash = true;\n flashVersion = \"6.0.21\";\n } catch (e2) {\n try {\n ax = new ActiveXObject(\"ShockwaveFlash.ShockwaveFlash\");\n hasFlash = true;\n flashVersion = parseFlashVersion(ax.GetVariable(\"$version\"));\n } catch (e3) {\n isActiveX = false;\n }\n }\n }\n }\n _flashState.disabled = hasFlash !== true;\n _flashState.outdated = flashVersion && _parseFloat(flashVersion) < _parseFloat(_minimumFlashVersion);\n _flashState.version = flashVersion || \"0.0.0\";\n _flashState.pluginType = isPPAPI ? \"pepper\" : isActiveX ? \"activex\" : hasFlash ? \"netscape\" : \"unknown\";\n };\n /**\n * Invoke the Flash detection algorithms immediately upon inclusion so we're not waiting later.\n */\n _detectFlashSupport(_ActiveXObject);\n /**\n * Always assess the `sandboxed` state of the page at important Flash-related moments.\n */\n _detectSandbox(true);\n /**\n * A shell constructor for `ZeroClipboard` client instances.\n *\n * @constructor\n */\n var ZeroClipboard = function() {\n if (!(this instanceof ZeroClipboard)) {\n return new ZeroClipboard();\n }\n if (typeof ZeroClipboard._createClient === \"function\") {\n ZeroClipboard._createClient.apply(this, _args(arguments));\n }\n };\n /**\n * The ZeroClipboard library's version number.\n *\n * @static\n * @readonly\n * @property {string}\n */\n _defineProperty(ZeroClipboard, \"version\", {\n value: \"2.2.0\",\n writable: false,\n configurable: true,\n enumerable: true\n });\n /**\n * Update or get a copy of the ZeroClipboard global configuration.\n * Returns a copy of the current/updated configuration.\n *\n * @returns Object\n * @static\n */\n ZeroClipboard.config = function() {\n return _config.apply(this, _args(arguments));\n };\n /**\n * Diagnostic method that describes the state of the browser, Flash Player, and ZeroClipboard.\n *\n * @returns Object\n * @static\n */\n ZeroClipboard.state = function() {\n return _state.apply(this, _args(arguments));\n };\n /**\n * Check if Flash is unusable for any reason: disabled, outdated, deactivated, etc.\n *\n * @returns Boolean\n * @static\n */\n ZeroClipboard.isFlashUnusable = function() {\n return _isFlashUnusable.apply(this, _args(arguments));\n };\n /**\n * Register an event listener.\n *\n * @returns `ZeroClipboard`\n * @static\n */\n ZeroClipboard.on = function() {\n return _on.apply(this, _args(arguments));\n };\n /**\n * Unregister an event listener.\n * If no `listener` function/object is provided, it will unregister all listeners for the provided `eventType`.\n * If no `eventType` is provided, it will unregister all listeners for every event type.\n *\n * @returns `ZeroClipboard`\n * @static\n */\n ZeroClipboard.off = function() {\n return _off.apply(this, _args(arguments));\n };\n /**\n * Retrieve event listeners for an `eventType`.\n * If no `eventType` is provided, it will retrieve all listeners for every event type.\n *\n * @returns array of listeners for the `eventType`; if no `eventType`, then a map/hash object of listeners for all event types; or `null`\n */\n ZeroClipboard.handlers = function() {\n return _listeners.apply(this, _args(arguments));\n };\n /**\n * Event emission receiver from the Flash object, forwarding to any registered JavaScript event listeners.\n *\n * @returns For the \"copy\" event, returns the Flash-friendly \"clipData\" object; otherwise `undefined`.\n * @static\n */\n ZeroClipboard.emit = function() {\n return _emit.apply(this, _args(arguments));\n };\n /**\n * Create and embed the Flash object.\n *\n * @returns The Flash object\n * @static\n */\n ZeroClipboard.create = function() {\n return _create.apply(this, _args(arguments));\n };\n /**\n * Self-destruct and clean up everything, including the embedded Flash object.\n *\n * @returns `undefined`\n * @static\n */\n ZeroClipboard.destroy = function() {\n return _destroy.apply(this, _args(arguments));\n };\n /**\n * Set the pending data for clipboard injection.\n *\n * @returns `undefined`\n * @static\n */\n ZeroClipboard.setData = function() {\n return _setData.apply(this, _args(arguments));\n };\n /**\n * Clear the pending data for clipboard injection.\n * If no `format` is provided, all pending data formats will be cleared.\n *\n * @returns `undefined`\n * @static\n */\n ZeroClipboard.clearData = function() {\n return _clearData.apply(this, _args(arguments));\n };\n /**\n * Get a copy of the pending data for clipboard injection.\n * If no `format` is provided, a copy of ALL pending data formats will be returned.\n *\n * @returns `String` or `Object`\n * @static\n */\n ZeroClipboard.getData = function() {\n return _getData.apply(this, _args(arguments));\n };\n /**\n * Sets the current HTML object that the Flash object should overlay. This will put the global\n * Flash object on top of the current element; depending on the setup, this may also set the\n * pending clipboard text data as well as the Flash object's wrapping element's title attribute\n * based on the underlying HTML element and ZeroClipboard configuration.\n *\n * @returns `undefined`\n * @static\n */\n ZeroClipboard.focus = ZeroClipboard.activate = function() {\n return _focus.apply(this, _args(arguments));\n };\n /**\n * Un-overlays the Flash object. This will put the global Flash object off-screen; depending on\n * the setup, this may also unset the Flash object's wrapping element's title attribute based on\n * the underlying HTML element and ZeroClipboard configuration.\n *\n * @returns `undefined`\n * @static\n */\n ZeroClipboard.blur = ZeroClipboard.deactivate = function() {\n return _blur.apply(this, _args(arguments));\n };\n /**\n * Returns the currently focused/\"activated\" HTML element that the Flash object is wrapping.\n *\n * @returns `HTMLElement` or `null`\n * @static\n */\n ZeroClipboard.activeElement = function() {\n return _activeElement.apply(this, _args(arguments));\n };\n /**\n * Keep track of the ZeroClipboard client instance counter.\n */\n var _clientIdCounter = 0;\n /**\n * Keep track of the state of the client instances.\n *\n * Entry structure:\n * _clientMeta[client.id] = {\n * instance: client,\n * elements: [],\n * handlers: {}\n * };\n */\n var _clientMeta = {};\n /**\n * Keep track of the ZeroClipboard clipped elements counter.\n */\n var _elementIdCounter = 0;\n /**\n * Keep track of the state of the clipped element relationships to clients.\n *\n * Entry structure:\n * _elementMeta[element.zcClippingId] = [client1.id, client2.id];\n */\n var _elementMeta = {};\n /**\n * Keep track of the state of the mouse event handlers for clipped elements.\n *\n * Entry structure:\n * _mouseHandlers[element.zcClippingId] = {\n * mouseover: function(event) {},\n * mouseout: function(event) {},\n * mouseenter: function(event) {},\n * mouseleave: function(event) {},\n * mousemove: function(event) {}\n * };\n */\n var _mouseHandlers = {};\n /**\n * Extending the ZeroClipboard configuration defaults for the Client module.\n */\n _extend(_globalConfig, {\n autoActivate: true\n });\n /**\n * The real constructor for `ZeroClipboard` client instances.\n * @private\n */\n var _clientConstructor = function(elements) {\n var client = this;\n client.id = \"\" + _clientIdCounter++;\n _clientMeta[client.id] = {\n instance: client,\n elements: [],\n handlers: {}\n };\n if (elements) {\n client.clip(elements);\n }\n ZeroClipboard.on(\"*\", function(event) {\n return client.emit(event);\n });\n ZeroClipboard.on(\"destroy\", function() {\n client.destroy();\n });\n ZeroClipboard.create();\n };\n /**\n * The underlying implementation of `ZeroClipboard.Client.prototype.on`.\n * @private\n */\n var _clientOn = function(eventType, listener) {\n var i, len, events, added = {}, meta = _clientMeta[this.id], handlers = meta && meta.handlers;\n if (!meta) {\n throw new Error(\"Attempted to add new listener(s) to a destroyed ZeroClipboard client instance\");\n }\n if (typeof eventType === \"string\" && eventType) {\n events = eventType.toLowerCase().split(/\\s+/);\n } else if (typeof eventType === \"object\" && eventType && typeof listener === \"undefined\") {\n for (i in eventType) {\n if (_hasOwn.call(eventType, i) && typeof i === \"string\" && i && typeof eventType[i] === \"function\") {\n this.on(i, eventType[i]);\n }\n }\n }\n if (events && events.length) {\n for (i = 0, len = events.length; i < len; i++) {\n eventType = events[i].replace(/^on/, \"\");\n added[eventType] = true;\n if (!handlers[eventType]) {\n handlers[eventType] = [];\n }\n handlers[eventType].push(listener);\n }\n if (added.ready && _flashState.ready) {\n this.emit({\n type: \"ready\",\n client: this\n });\n }\n if (added.error) {\n for (i = 0, len = _flashStateErrorNames.length; i < len; i++) {\n if (_flashState[_flashStateErrorNames[i].replace(/^flash-/, \"\")]) {\n this.emit({\n type: \"error\",\n name: _flashStateErrorNames[i],\n client: this\n });\n break;\n }\n }\n if (_zcSwfVersion !== undefined && ZeroClipboard.version !== _zcSwfVersion) {\n this.emit({\n type: \"error\",\n name: \"version-mismatch\",\n jsVersion: ZeroClipboard.version,\n swfVersion: _zcSwfVersion\n });\n }\n }\n }\n return this;\n };\n /**\n * The underlying implementation of `ZeroClipboard.Client.prototype.off`.\n * @private\n */\n var _clientOff = function(eventType, listener) {\n var i, len, foundIndex, events, perEventHandlers, meta = _clientMeta[this.id], handlers = meta && meta.handlers;\n if (!handlers) {\n return this;\n }\n if (arguments.length === 0) {\n events = _keys(handlers);\n } else if (typeof eventType === \"string\" && eventType) {\n events = eventType.split(/\\s+/);\n } else if (typeof eventType === \"object\" && eventType && typeof listener === \"undefined\") {\n for (i in eventType) {\n if (_hasOwn.call(eventType, i) && typeof i === \"string\" && i && typeof eventType[i] === \"function\") {\n this.off(i, eventType[i]);\n }\n }\n }\n if (events && events.length) {\n for (i = 0, len = events.length; i < len; i++) {\n eventType = events[i].toLowerCase().replace(/^on/, \"\");\n perEventHandlers = handlers[eventType];\n if (perEventHandlers && perEventHandlers.length) {\n if (listener) {\n foundIndex = perEventHandlers.indexOf(listener);\n while (foundIndex !== -1) {\n perEventHandlers.splice(foundIndex, 1);\n foundIndex = perEventHandlers.indexOf(listener, foundIndex);\n }\n } else {\n perEventHandlers.length = 0;\n }\n }\n }\n }\n return this;\n };\n /**\n * The underlying implementation of `ZeroClipboard.Client.prototype.handlers`.\n * @private\n */\n var _clientListeners = function(eventType) {\n var copy = null, handlers = _clientMeta[this.id] && _clientMeta[this.id].handlers;\n if (handlers) {\n if (typeof eventType === \"string\" && eventType) {\n copy = handlers[eventType] ? handlers[eventType].slice(0) : [];\n } else {\n copy = _deepCopy(handlers);\n }\n }\n return copy;\n };\n /**\n * The underlying implementation of `ZeroClipboard.Client.prototype.emit`.\n * @private\n */\n var _clientEmit = function(event) {\n if (_clientShouldEmit.call(this, event)) {\n if (typeof event === \"object\" && event && typeof event.type === \"string\" && event.type) {\n event = _extend({}, event);\n }\n var eventCopy = _extend({}, _createEvent(event), {\n client: this\n });\n _clientDispatchCallbacks.call(this, eventCopy);\n }\n return this;\n };\n /**\n * The underlying implementation of `ZeroClipboard.Client.prototype.clip`.\n * @private\n */\n var _clientClip = function(elements) {\n if (!_clientMeta[this.id]) {\n throw new Error(\"Attempted to clip element(s) to a destroyed ZeroClipboard client instance\");\n }\n elements = _prepClip(elements);\n for (var i = 0; i < elements.length; i++) {\n if (_hasOwn.call(elements, i) && elements[i] && elements[i].nodeType === 1) {\n if (!elements[i].zcClippingId) {\n elements[i].zcClippingId = \"zcClippingId_\" + _elementIdCounter++;\n _elementMeta[elements[i].zcClippingId] = [ this.id ];\n if (_globalConfig.autoActivate === true) {\n _addMouseHandlers(elements[i]);\n }\n } else if (_elementMeta[elements[i].zcClippingId].indexOf(this.id) === -1) {\n _elementMeta[elements[i].zcClippingId].push(this.id);\n }\n var clippedElements = _clientMeta[this.id] && _clientMeta[this.id].elements;\n if (clippedElements.indexOf(elements[i]) === -1) {\n clippedElements.push(elements[i]);\n }\n }\n }\n return this;\n };\n /**\n * The underlying implementation of `ZeroClipboard.Client.prototype.unclip`.\n * @private\n */\n var _clientUnclip = function(elements) {\n var meta = _clientMeta[this.id];\n if (!meta) {\n return this;\n }\n var clippedElements = meta.elements;\n var arrayIndex;\n if (typeof elements === \"undefined\") {\n elements = clippedElements.slice(0);\n } else {\n elements = _prepClip(elements);\n }\n for (var i = elements.length; i--; ) {\n if (_hasOwn.call(elements, i) && elements[i] && elements[i].nodeType === 1) {\n arrayIndex = 0;\n while ((arrayIndex = clippedElements.indexOf(elements[i], arrayIndex)) !== -1) {\n clippedElements.splice(arrayIndex, 1);\n }\n var clientIds = _elementMeta[elements[i].zcClippingId];\n if (clientIds) {\n arrayIndex = 0;\n while ((arrayIndex = clientIds.indexOf(this.id, arrayIndex)) !== -1) {\n clientIds.splice(arrayIndex, 1);\n }\n if (clientIds.length === 0) {\n if (_globalConfig.autoActivate === true) {\n _removeMouseHandlers(elements[i]);\n }\n delete elements[i].zcClippingId;\n }\n }\n }\n }\n return this;\n };\n /**\n * The underlying implementation of `ZeroClipboard.Client.prototype.elements`.\n * @private\n */\n var _clientElements = function() {\n var meta = _clientMeta[this.id];\n return meta && meta.elements ? meta.elements.slice(0) : [];\n };\n /**\n * The underlying implementation of `ZeroClipboard.Client.prototype.destroy`.\n * @private\n */\n var _clientDestroy = function() {\n if (!_clientMeta[this.id]) {\n return;\n }\n this.unclip();\n this.off();\n delete _clientMeta[this.id];\n };\n /**\n * Inspect an Event to see if the Client (`this`) should honor it for emission.\n * @private\n */\n var _clientShouldEmit = function(event) {\n if (!(event && event.type)) {\n return false;\n }\n if (event.client && event.client !== this) {\n return false;\n }\n var meta = _clientMeta[this.id];\n var clippedEls = meta && meta.elements;\n var hasClippedEls = !!clippedEls && clippedEls.length > 0;\n var goodTarget = !event.target || hasClippedEls && clippedEls.indexOf(event.target) !== -1;\n var goodRelTarget = event.relatedTarget && hasClippedEls && clippedEls.indexOf(event.relatedTarget) !== -1;\n var goodClient = event.client && event.client === this;\n if (!meta || !(goodTarget || goodRelTarget || goodClient)) {\n return false;\n }\n return true;\n };\n /**\n * Handle the actual dispatching of events to a client instance.\n *\n * @returns `undefined`\n * @private\n */\n var _clientDispatchCallbacks = function(event) {\n var meta = _clientMeta[this.id];\n if (!(typeof event === \"object\" && event && event.type && meta)) {\n return;\n }\n var async = _shouldPerformAsync(event);\n var wildcardTypeHandlers = meta && meta.handlers[\"*\"] || [];\n var specificTypeHandlers = meta && meta.handlers[event.type] || [];\n var handlers = wildcardTypeHandlers.concat(specificTypeHandlers);\n if (handlers && handlers.length) {\n var i, len, func, context, eventCopy, originalContext = this;\n for (i = 0, len = handlers.length; i < len; i++) {\n func = handlers[i];\n context = originalContext;\n if (typeof func === \"string\" && typeof _window[func] === \"function\") {\n func = _window[func];\n }\n if (typeof func === \"object\" && func && typeof func.handleEvent === \"function\") {\n context = func;\n func = func.handleEvent;\n }\n if (typeof func === \"function\") {\n eventCopy = _extend({}, event);\n _dispatchCallback(func, context, [ eventCopy ], async);\n }\n }\n }\n };\n /**\n * Prepares the elements for clipping/unclipping.\n *\n * @returns An Array of elements.\n * @private\n */\n var _prepClip = function(elements) {\n if (typeof elements === \"string\") {\n elements = [];\n }\n return typeof elements.length !== \"number\" ? [ elements ] : elements;\n };\n /**\n * Add a `mouseover` handler function for a clipped element.\n *\n * @returns `undefined`\n * @private\n */\n var _addMouseHandlers = function(element) {\n if (!(element && element.nodeType === 1)) {\n return;\n }\n var _suppressMouseEvents = function(event) {\n if (!(event || (event = _window.event))) {\n return;\n }\n if (event._source !== \"js\") {\n event.stopImmediatePropagation();\n event.preventDefault();\n }\n delete event._source;\n };\n var _elementMouseOver = function(event) {\n if (!(event || (event = _window.event))) {\n return;\n }\n _suppressMouseEvents(event);\n ZeroClipboard.focus(element);\n };\n element.addEventListener(\"mouseover\", _elementMouseOver, false);\n element.addEventListener(\"mouseout\", _suppressMouseEvents, false);\n element.addEventListener(\"mouseenter\", _suppressMouseEvents, false);\n element.addEventListener(\"mouseleave\", _suppressMouseEvents, false);\n element.addEventListener(\"mousemove\", _suppressMouseEvents, false);\n _mouseHandlers[element.zcClippingId] = {\n mouseover: _elementMouseOver,\n mouseout: _suppressMouseEvents,\n mouseenter: _suppressMouseEvents,\n mouseleave: _suppressMouseEvents,\n mousemove: _suppressMouseEvents\n };\n };\n /**\n * Remove a `mouseover` handler function for a clipped element.\n *\n * @returns `undefined`\n * @private\n */\n var _removeMouseHandlers = function(element) {\n if (!(element && element.nodeType === 1)) {\n return;\n }\n var mouseHandlers = _mouseHandlers[element.zcClippingId];\n if (!(typeof mouseHandlers === \"object\" && mouseHandlers)) {\n return;\n }\n var key, val, mouseEvents = [ \"move\", \"leave\", \"enter\", \"out\", \"over\" ];\n for (var i = 0, len = mouseEvents.length; i < len; i++) {\n key = \"mouse\" + mouseEvents[i];\n val = mouseHandlers[key];\n if (typeof val === \"function\") {\n element.removeEventListener(key, val, false);\n }\n }\n delete _mouseHandlers[element.zcClippingId];\n };\n /**\n * Creates a new ZeroClipboard client instance.\n * Optionally, auto-`clip` an element or collection of elements.\n *\n * @constructor\n */\n ZeroClipboard._createClient = function() {\n _clientConstructor.apply(this, _args(arguments));\n };\n /**\n * Register an event listener to the client.\n *\n * @returns `this`\n */\n ZeroClipboard.prototype.on = function() {\n return _clientOn.apply(this, _args(arguments));\n };\n /**\n * Unregister an event handler from the client.\n * If no `listener` function/object is provided, it will unregister all handlers for the provided `eventType`.\n * If no `eventType` is provided, it will unregister all handlers for every event type.\n *\n * @returns `this`\n */\n ZeroClipboard.prototype.off = function() {\n return _clientOff.apply(this, _args(arguments));\n };\n /**\n * Retrieve event listeners for an `eventType` from the client.\n * If no `eventType` is provided, it will retrieve all listeners for every event type.\n *\n * @returns array of listeners for the `eventType`; if no `eventType`, then a map/hash object of listeners for all event types; or `null`\n */\n ZeroClipboard.prototype.handlers = function() {\n return _clientListeners.apply(this, _args(arguments));\n };\n /**\n * Event emission receiver from the Flash object for this client's registered JavaScript event listeners.\n *\n * @returns For the \"copy\" event, returns the Flash-friendly \"clipData\" object; otherwise `undefined`.\n */\n ZeroClipboard.prototype.emit = function() {\n return _clientEmit.apply(this, _args(arguments));\n };\n /**\n * Register clipboard actions for new element(s) to the client.\n *\n * @returns `this`\n */\n ZeroClipboard.prototype.clip = function() {\n return _clientClip.apply(this, _args(arguments));\n };\n /**\n * Unregister the clipboard actions of previously registered element(s) on the page.\n * If no elements are provided, ALL registered elements will be unregistered.\n *\n * @returns `this`\n */\n ZeroClipboard.prototype.unclip = function() {\n return _clientUnclip.apply(this, _args(arguments));\n };\n /**\n * Get all of the elements to which this client is clipped.\n *\n * @returns array of clipped elements\n */\n ZeroClipboard.prototype.elements = function() {\n return _clientElements.apply(this, _args(arguments));\n };\n /**\n * Self-destruct and clean up everything for a single client.\n * This will NOT destroy the embedded Flash object.\n *\n * @returns `undefined`\n */\n ZeroClipboard.prototype.destroy = function() {\n return _clientDestroy.apply(this, _args(arguments));\n };\n /**\n * Stores the pending plain text to inject into the clipboard.\n *\n * @returns `this`\n */\n ZeroClipboard.prototype.setText = function(text) {\n if (!_clientMeta[this.id]) {\n throw new Error(\"Attempted to set pending clipboard data from a destroyed ZeroClipboard client instance\");\n }\n ZeroClipboard.setData(\"text/plain\", text);\n return this;\n };\n /**\n * Stores the pending HTML text to inject into the clipboard.\n *\n * @returns `this`\n */\n ZeroClipboard.prototype.setHtml = function(html) {\n if (!_clientMeta[this.id]) {\n throw new Error(\"Attempted to set pending clipboard data from a destroyed ZeroClipboard client instance\");\n }\n ZeroClipboard.setData(\"text/html\", html);\n return this;\n };\n /**\n * Stores the pending rich text (RTF) to inject into the clipboard.\n *\n * @returns `this`\n */\n ZeroClipboard.prototype.setRichText = function(richText) {\n if (!_clientMeta[this.id]) {\n throw new Error(\"Attempted to set pending clipboard data from a destroyed ZeroClipboard client instance\");\n }\n ZeroClipboard.setData(\"application/rtf\", richText);\n return this;\n };\n /**\n * Stores the pending data to inject into the clipboard.\n *\n * @returns `this`\n */\n ZeroClipboard.prototype.setData = function() {\n if (!_clientMeta[this.id]) {\n throw new Error(\"Attempted to set pending clipboard data from a destroyed ZeroClipboard client instance\");\n }\n ZeroClipboard.setData.apply(this, _args(arguments));\n return this;\n };\n /**\n * Clears the pending data to inject into the clipboard.\n * If no `format` is provided, all pending data formats will be cleared.\n *\n * @returns `this`\n */\n ZeroClipboard.prototype.clearData = function() {\n if (!_clientMeta[this.id]) {\n throw new Error(\"Attempted to clear pending clipboard data from a destroyed ZeroClipboard client instance\");\n }\n ZeroClipboard.clearData.apply(this, _args(arguments));\n return this;\n };\n /**\n * Gets a copy of the pending data to inject into the clipboard.\n * If no `format` is provided, a copy of ALL pending data formats will be returned.\n *\n * @returns `String` or `Object`\n */\n ZeroClipboard.prototype.getData = function() {\n if (!_clientMeta[this.id]) {\n throw new Error(\"Attempted to get pending clipboard data from a destroyed ZeroClipboard client instance\");\n }\n return ZeroClipboard.getData.apply(this, _args(arguments));\n };\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return ZeroClipboard;\n });\n } else if (typeof module === \"object\" && module && typeof module.exports === \"object\" && module.exports) {\n module.exports = ZeroClipboard;\n } else {\n window.ZeroClipboard = ZeroClipboard;\n }\n})(function() {\n return this || window;\n}());"]} \ No newline at end of file diff --git a/resources/zeroclipboard/ZeroClipboard.swf b/resources/zeroclipboard/ZeroClipboard.swf new file mode 100644 index 0000000000000000000000000000000000000000..8bad6a3e34f1b0b055da3ee8e506fe627cf75987 GIT binary patch literal 6580 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 literal 0 HcmV?d00001 diff --git a/tasks/build-examples.js b/tasks/build-examples.js new file mode 100644 index 0000000000..97302f7efe --- /dev/null +++ b/tasks/build-examples.js @@ -0,0 +1,71 @@ +/*global Buffer */ + +var Metalsmith = require('metalsmith'); +var templates = require('metalsmith-templates'); +var marked = require('marked'); +var fs = require('fs'); +var pjson = require('../package.json'); + +var fileRegEx = /([^\/^\.]*)\.html$/; +var cleanupJSRegEx = /.*(goog\.require(.*);|.*renderer: exampleNS\..*,?)[\n]*/g; + +function main(callback) { + + function build(files) { + var file, match, str; + for (var f in files) { + file = files[f]; + match = f.match(fileRegEx); + if (match) { + if (file.title) { + if (file.docs) { + file.docs = marked(file.docs); + } + if (file.contents) { + str = marked(file.contents.toString()); + file.contents = new Buffer(str); + } + file.ol_version = pjson.version; + file.js_resource = ''; + var js = fs.readFileSync(__dirname + '/../examples_src/' + + match[1] + '.js', 'utf8'); + file.js_inline = js.replace(cleanupJSRegEx, ''); + var cssFile = __dirname + '/../examples_src/' + match[1] + '.css'; + if (fs.existsSync(cssFile)) { + file.css_resource = ''; + file.css_inline = fs.readFileSync(cssFile, 'utf-8'); + } + } + } + } + } + + + new Metalsmith('.') + .source('examples_src') + .destination('examples') + .use(build) + .use(templates({ + engine: 'handlebars', + directory: 'config/examples' + })) + .build(function(err) { + callback(err); + }); +} + + +if (require.main === module) { + main(function(err) { + if (err) { + process.stderr.write(err.message + '\n'); + process.exit(1); + } else { + process.exit(0); + } + }); +} + +module.exports = main; From 2e9869057e44524e914a037719d3c1f6222e38d1 Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Wed, 1 Apr 2015 18:19:33 +0200 Subject: [PATCH 02/42] Hide shortdesc in examples --- resources/layout.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/layout.css b/resources/layout.css index 99ea34f221..c05e5c19a7 100644 --- a/resources/layout.css +++ b/resources/layout.css @@ -15,7 +15,7 @@ body { font-family: 'Lucida Grande',Verdana,Geneva,Lucida,Arial,Helvetica,sans-serif; } -#tags, .hidden { +#tags, #shortdesc, .hidden { display: none; } From ff1ee78ddd06a3e70fd79a6c15e3f8ab969117ce Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Wed, 1 Apr 2015 18:22:56 +0200 Subject: [PATCH 03/42] Build and parse examples from examples_src/ --- .gitignore | 4 +--- {examples => examples_src}/Jugl.js | 0 {examples => examples_src}/accessible.html | 0 {examples => examples_src}/accessible.js | 0 {examples => examples_src}/animation.html | 0 {examples => examples_src}/animation.js | 0 {examples => examples_src}/arcgis-tiled.html | 0 {examples => examples_src}/arcgis-tiled.js | 0 {examples => examples_src}/attributions.html | 0 {examples => examples_src}/attributions.js | 0 {examples => examples_src}/bind-input.html | 0 {examples => examples_src}/bind-input.js | 0 {examples => examples_src}/bing-maps.html | 0 {examples => examples_src}/bing-maps.js | 0 {examples => examples_src}/box-selection.html | 0 {examples => examples_src}/box-selection.js | 0 {examples => examples_src}/brightness-contrast.html | 0 {examples => examples_src}/brightness-contrast.js | 0 {examples => examples_src}/button-title.html | 0 {examples => examples_src}/button-title.js | 0 {examples => examples_src}/canvas-tiles.html | 0 {examples => examples_src}/canvas-tiles.js | 0 {examples => examples_src}/center.html | 0 {examples => examples_src}/center.js | 0 {examples => examples_src}/cluster.html | 0 {examples => examples_src}/cluster.js | 0 {examples => examples_src}/custom-controls.html | 0 {examples => examples_src}/custom-controls.js | 0 {examples => examples_src}/d3.html | 0 {examples => examples_src}/d3.js | 0 {examples => examples_src}/data/Butterfly.png | Bin .../data/IGNWMTSCapabilities.xml | 0 .../data/WMTSCapabilities.xml | 0 {examples => examples_src}/data/arrow.png | Bin .../data/geojson/countries-110m.geojson | 0 .../data/geojson/countries.geojson | 0 .../data/geojson/line-samples.geojson | 0 .../data/geojson/point-samples.geojson | 0 .../data/geojson/polygon-samples.geojson | 0 .../data/geojson/switzerland.geojson | 0 .../data/geolocation-orientation.json | 0 .../data/geolocation_marker.png | Bin .../data/geolocation_marker_heading.png | Bin .../data/gml/topp-states-wfs.xml | 0 {examples => examples_src}/data/gpx/fells_loop.gpx | 0 {examples => examples_src}/data/icon.png | Bin .../data/igc/Clement-Latour.igc | 0 .../data/igc/Damien-de-Baenst.igc | 0 .../data/igc/Sylvain-Dhonneur.igc | 0 {examples => examples_src}/data/igc/Tom-Payne.igc | 0 .../data/igc/Ulrich-Prinz.igc | 0 {examples => examples_src}/data/kml/2012-02-10.kml | 0 .../data/kml/2012_Earthquakes_Mag5.kml | 0 {examples => examples_src}/data/kml/timezones.kml | 0 {examples => examples_src}/data/ogcsample.xml | 0 {examples => examples_src}/data/sld/countries.sld | 0 {examples => examples_src}/data/topojson/us.json | 0 .../data/topojson/world-110m.json | 0 {examples => examples_src}/device-orientation.html | 0 {examples => examples_src}/device-orientation.js | 0 .../drag-and-drop-image-vector.html | 0 .../drag-and-drop-image-vector.js | 0 {examples => examples_src}/drag-and-drop.html | 0 {examples => examples_src}/drag-and-drop.js | 0 {examples => examples_src}/drag-features.html | 0 {examples => examples_src}/drag-features.js | 0 .../drag-rotate-and-zoom.html | 0 {examples => examples_src}/drag-rotate-and-zoom.js | 0 .../draw-and-modify-features.html | 0 .../draw-and-modify-features.js | 0 {examples => examples_src}/draw-features.html | 0 {examples => examples_src}/draw-features.js | 0 {examples => examples_src}/dynamic-data.html | 0 {examples => examples_src}/dynamic-data.js | 0 {examples => examples_src}/earthquake-clusters.html | 0 {examples => examples_src}/earthquake-clusters.js | 0 {examples => examples_src}/epsg-4326.html | 0 {examples => examples_src}/epsg-4326.js | 0 {examples => examples_src}/export-map.html | 0 {examples => examples_src}/export-map.js | 0 {examples => examples_src}/fractal.html | 0 {examples => examples_src}/fractal.js | 0 .../full-screen-drag-rotate-and-zoom.html | 0 .../full-screen-drag-rotate-and-zoom.js | 0 {examples => examples_src}/full-screen.html | 0 {examples => examples_src}/full-screen.js | 0 {examples => examples_src}/geojson.html | 0 {examples => examples_src}/geojson.js | 0 .../geolocation-orientation.html | 0 .../geolocation-orientation.js | 0 {examples => examples_src}/geolocation.html | 0 {examples => examples_src}/geolocation.js | 0 .../getfeatureinfo-image.html | 0 {examples => examples_src}/getfeatureinfo-image.js | 0 {examples => examples_src}/getfeatureinfo-tile.html | 0 {examples => examples_src}/getfeatureinfo-tile.js | 0 {examples => examples_src}/gpx.html | 0 {examples => examples_src}/gpx.js | 0 {examples => examples_src}/graticule.html | 0 {examples => examples_src}/graticule.js | 0 {examples => examples_src}/heatmap-earthquakes.html | 0 {examples => examples_src}/heatmap-earthquakes.js | 0 {examples => examples_src}/hue-saturation.html | 0 {examples => examples_src}/hue-saturation.js | 0 {examples => examples_src}/icon-sprite-webgl.html | 0 {examples => examples_src}/icon-sprite-webgl.js | 0 {examples => examples_src}/icon.html | 0 {examples => examples_src}/icon.js | 0 {examples => examples_src}/igc.html | 0 {examples => examples_src}/igc.js | 0 {examples => examples_src}/image-filter.html | 0 {examples => examples_src}/image-filter.js | 0 {examples => examples_src}/image-load-events.html | 0 {examples => examples_src}/image-load-events.js | 0 {examples => examples_src}/image-vector-layer.html | 0 {examples => examples_src}/image-vector-layer.js | 0 {examples => examples_src}/index.html | 0 {examples => examples_src}/kml-earthquakes.html | 0 {examples => examples_src}/kml-earthquakes.js | 0 {examples => examples_src}/kml-timezones.html | 0 {examples => examples_src}/kml-timezones.js | 0 {examples => examples_src}/kml.html | 0 {examples => examples_src}/kml.js | 0 .../layer-clipping-webgl.html | 0 {examples => examples_src}/layer-clipping-webgl.js | 0 {examples => examples_src}/layer-clipping.html | 0 {examples => examples_src}/layer-clipping.js | 0 {examples => examples_src}/layer-extent.html | 0 {examples => examples_src}/layer-extent.js | 0 {examples => examples_src}/layer-group.html | 0 {examples => examples_src}/layer-group.js | 0 {examples => examples_src}/layer-spy.html | 0 {examples => examples_src}/layer-spy.js | 0 {examples => examples_src}/layer-swipe.html | 0 {examples => examples_src}/layer-swipe.js | 0 {examples => examples_src}/lazy-source.html | 0 {examples => examples_src}/lazy-source.js | 0 {examples => examples_src}/line-arrows.html | 0 {examples => examples_src}/line-arrows.js | 0 .../localized-openstreetmap.html | 0 .../localized-openstreetmap.js | 0 {examples => examples_src}/mapguide-untiled.html | 0 {examples => examples_src}/mapguide-untiled.js | 0 {examples => examples_src}/mapquest.html | 0 {examples => examples_src}/mapquest.js | 0 {examples => examples_src}/measure.html | 0 {examples => examples_src}/measure.js | 0 {examples => examples_src}/min-max-resolution.html | 0 {examples => examples_src}/min-max-resolution.js | 0 {examples => examples_src}/mobile-full-screen.html | 0 {examples => examples_src}/mobile-full-screen.js | 0 {examples => examples_src}/modify-features.html | 0 {examples => examples_src}/modify-features.js | 0 {examples => examples_src}/modify-test.html | 0 {examples => examples_src}/modify-test.js | 0 {examples => examples_src}/mouse-position.html | 0 {examples => examples_src}/mouse-position.js | 0 {examples => examples_src}/moveend.html | 0 {examples => examples_src}/moveend.js | 0 {examples => examples_src}/navigation-controls.html | 0 {examples => examples_src}/navigation-controls.js | 0 {examples => examples_src}/overlay.html | 0 {examples => examples_src}/overlay.js | 0 {examples => examples_src}/overviewmap-custom.html | 0 {examples => examples_src}/overviewmap-custom.js | 0 {examples => examples_src}/overviewmap.html | 0 {examples => examples_src}/overviewmap.js | 0 {examples => examples_src}/polygon-styles.html | 0 {examples => examples_src}/polygon-styles.js | 0 {examples => examples_src}/popup.html | 0 {examples => examples_src}/popup.js | 0 {examples => examples_src}/preload.html | 0 {examples => examples_src}/preload.js | 0 {examples => examples_src}/readme.md | 0 {examples => examples_src}/regularshape.html | 0 {examples => examples_src}/regularshape.js | 0 {examples => examples_src}/rotation.html | 0 {examples => examples_src}/rotation.js | 0 {examples => examples_src}/scale-line.html | 0 {examples => examples_src}/scale-line.js | 0 {examples => examples_src}/select-features.html | 0 {examples => examples_src}/select-features.js | 0 .../semi-transparent-layer.html | 0 .../semi-transparent-layer.js | 0 {examples => examples_src}/side-by-side.html | 0 {examples => examples_src}/side-by-side.js | 0 {examples => examples_src}/simple.html | 0 {examples => examples_src}/simple.js | 0 {examples => examples_src}/snap.html | 0 {examples => examples_src}/snap.js | 0 {examples => examples_src}/sphere-mollweide.html | 0 {examples => examples_src}/sphere-mollweide.js | 0 {examples => examples_src}/stamen.html | 0 {examples => examples_src}/stamen.js | 0 {examples => examples_src}/static-image.html | 0 {examples => examples_src}/static-image.js | 0 {examples => examples_src}/symbol-atlas-webgl.html | 0 {examples => examples_src}/symbol-atlas-webgl.js | 0 {examples => examples_src}/synthetic-lines.html | 0 {examples => examples_src}/synthetic-lines.js | 0 {examples => examples_src}/synthetic-points.html | 0 {examples => examples_src}/synthetic-points.js | 0 {examples => examples_src}/teleport.html | 0 {examples => examples_src}/teleport.js | 0 {examples => examples_src}/tile-load-events.html | 0 {examples => examples_src}/tile-load-events.js | 0 {examples => examples_src}/tile-vector.html | 0 {examples => examples_src}/tile-vector.js | 0 {examples => examples_src}/tilejson.html | 0 {examples => examples_src}/tilejson.js | 0 {examples => examples_src}/tileutfgrid.html | 0 {examples => examples_src}/tileutfgrid.js | 0 {examples => examples_src}/tissot.html | 0 {examples => examples_src}/tissot.js | 0 {examples => examples_src}/topojson.html | 0 {examples => examples_src}/topojson.js | 0 {examples => examples_src}/vector-labels.html | 0 {examples => examples_src}/vector-labels.js | 0 {examples => examples_src}/vector-layer.html | 0 {examples => examples_src}/vector-layer.js | 0 {examples => examples_src}/vector-osm.html | 0 {examples => examples_src}/vector-osm.js | 0 {examples => examples_src}/vector-wfs.html | 0 {examples => examples_src}/vector-wfs.js | 0 {examples => examples_src}/wkt.html | 0 {examples => examples_src}/wkt.js | 0 {examples => examples_src}/wms-capabilities.html | 0 {examples => examples_src}/wms-capabilities.js | 0 {examples => examples_src}/wms-custom-proj.html | 0 {examples => examples_src}/wms-custom-proj.js | 0 .../wms-image-custom-proj.html | 0 {examples => examples_src}/wms-image-custom-proj.js | 0 {examples => examples_src}/wms-image.html | 0 {examples => examples_src}/wms-image.js | 0 {examples => examples_src}/wms-no-proj.html | 0 {examples => examples_src}/wms-no-proj.js | 0 {examples => examples_src}/wms-tiled-wrap-180.html | 0 {examples => examples_src}/wms-tiled-wrap-180.js | 0 {examples => examples_src}/wms-tiled.html | 0 {examples => examples_src}/wms-tiled.js | 0 {examples => examples_src}/wmts-capabilities.html | 0 {examples => examples_src}/wmts-capabilities.js | 0 {examples => examples_src}/wmts-hidpi.html | 0 {examples => examples_src}/wmts-hidpi.js | 0 .../wmts-layer-from-capabilities.html | 0 .../wmts-layer-from-capabilities.js | 0 {examples => examples_src}/wmts.html | 0 {examples => examples_src}/wmts.js | 0 {examples => examples_src}/xyz-esri-4326-512.html | 0 {examples => examples_src}/xyz-esri-4326-512.js | 0 {examples => examples_src}/xyz-esri.html | 0 {examples => examples_src}/xyz-esri.js | 0 {examples => examples_src}/xyz-retina.html | 0 {examples => examples_src}/xyz-retina.js | 0 {examples => examples_src}/xyz.html | 0 {examples => examples_src}/xyz.js | 0 {examples => examples_src}/zoom-constrained.html | 0 {examples => examples_src}/zoom-constrained.js | 0 {examples => examples_src}/zoomify.html | 0 {examples => examples_src}/zoomify.js | 0 {examples => examples_src}/zoomslider.html | 0 {examples => examples_src}/zoomslider.js | 0 tasks/parse-examples.js | 2 ++ 263 files changed, 3 insertions(+), 3 deletions(-) rename {examples => examples_src}/Jugl.js (100%) rename {examples => examples_src}/accessible.html (100%) rename {examples => examples_src}/accessible.js (100%) rename {examples => examples_src}/animation.html (100%) rename {examples => examples_src}/animation.js (100%) rename {examples => examples_src}/arcgis-tiled.html (100%) rename {examples => examples_src}/arcgis-tiled.js (100%) rename {examples => examples_src}/attributions.html (100%) rename {examples => examples_src}/attributions.js (100%) rename {examples => examples_src}/bind-input.html (100%) rename {examples => examples_src}/bind-input.js (100%) rename {examples => examples_src}/bing-maps.html (100%) rename {examples => examples_src}/bing-maps.js (100%) rename {examples => examples_src}/box-selection.html (100%) rename {examples => examples_src}/box-selection.js (100%) rename {examples => examples_src}/brightness-contrast.html (100%) rename {examples => examples_src}/brightness-contrast.js (100%) rename {examples => examples_src}/button-title.html (100%) rename {examples => examples_src}/button-title.js (100%) rename {examples => examples_src}/canvas-tiles.html (100%) rename {examples => examples_src}/canvas-tiles.js (100%) rename {examples => examples_src}/center.html (100%) rename {examples => examples_src}/center.js (100%) rename {examples => examples_src}/cluster.html (100%) rename {examples => examples_src}/cluster.js (100%) rename {examples => examples_src}/custom-controls.html (100%) rename {examples => examples_src}/custom-controls.js (100%) rename {examples => examples_src}/d3.html (100%) rename {examples => examples_src}/d3.js (100%) rename {examples => examples_src}/data/Butterfly.png (100%) rename {examples => examples_src}/data/IGNWMTSCapabilities.xml (100%) rename {examples => examples_src}/data/WMTSCapabilities.xml (100%) rename {examples => examples_src}/data/arrow.png (100%) rename {examples => examples_src}/data/geojson/countries-110m.geojson (100%) rename {examples => examples_src}/data/geojson/countries.geojson (100%) rename {examples => examples_src}/data/geojson/line-samples.geojson (100%) rename {examples => examples_src}/data/geojson/point-samples.geojson (100%) rename {examples => examples_src}/data/geojson/polygon-samples.geojson (100%) rename {examples => examples_src}/data/geojson/switzerland.geojson (100%) rename {examples => examples_src}/data/geolocation-orientation.json (100%) rename {examples => examples_src}/data/geolocation_marker.png (100%) rename {examples => examples_src}/data/geolocation_marker_heading.png (100%) rename {examples => examples_src}/data/gml/topp-states-wfs.xml (100%) rename {examples => examples_src}/data/gpx/fells_loop.gpx (100%) rename {examples => examples_src}/data/icon.png (100%) rename {examples => examples_src}/data/igc/Clement-Latour.igc (100%) rename {examples => examples_src}/data/igc/Damien-de-Baenst.igc (100%) rename {examples => examples_src}/data/igc/Sylvain-Dhonneur.igc (100%) rename {examples => examples_src}/data/igc/Tom-Payne.igc (100%) rename {examples => examples_src}/data/igc/Ulrich-Prinz.igc (100%) rename {examples => examples_src}/data/kml/2012-02-10.kml (100%) rename {examples => examples_src}/data/kml/2012_Earthquakes_Mag5.kml (100%) rename {examples => examples_src}/data/kml/timezones.kml (100%) rename {examples => examples_src}/data/ogcsample.xml (100%) rename {examples => examples_src}/data/sld/countries.sld (100%) rename {examples => examples_src}/data/topojson/us.json (100%) rename {examples => examples_src}/data/topojson/world-110m.json (100%) rename {examples => examples_src}/device-orientation.html (100%) rename {examples => examples_src}/device-orientation.js (100%) rename {examples => examples_src}/drag-and-drop-image-vector.html (100%) rename {examples => examples_src}/drag-and-drop-image-vector.js (100%) rename {examples => examples_src}/drag-and-drop.html (100%) rename {examples => examples_src}/drag-and-drop.js (100%) rename {examples => examples_src}/drag-features.html (100%) rename {examples => examples_src}/drag-features.js (100%) rename {examples => examples_src}/drag-rotate-and-zoom.html (100%) rename {examples => examples_src}/drag-rotate-and-zoom.js (100%) rename {examples => examples_src}/draw-and-modify-features.html (100%) rename {examples => examples_src}/draw-and-modify-features.js (100%) rename {examples => examples_src}/draw-features.html (100%) rename {examples => examples_src}/draw-features.js (100%) rename {examples => examples_src}/dynamic-data.html (100%) rename {examples => examples_src}/dynamic-data.js (100%) rename {examples => examples_src}/earthquake-clusters.html (100%) rename {examples => examples_src}/earthquake-clusters.js (100%) rename {examples => examples_src}/epsg-4326.html (100%) rename {examples => examples_src}/epsg-4326.js (100%) rename {examples => examples_src}/export-map.html (100%) rename {examples => examples_src}/export-map.js (100%) rename {examples => examples_src}/fractal.html (100%) rename {examples => examples_src}/fractal.js (100%) rename {examples => examples_src}/full-screen-drag-rotate-and-zoom.html (100%) rename {examples => examples_src}/full-screen-drag-rotate-and-zoom.js (100%) rename {examples => examples_src}/full-screen.html (100%) rename {examples => examples_src}/full-screen.js (100%) rename {examples => examples_src}/geojson.html (100%) rename {examples => examples_src}/geojson.js (100%) rename {examples => examples_src}/geolocation-orientation.html (100%) rename {examples => examples_src}/geolocation-orientation.js (100%) rename {examples => examples_src}/geolocation.html (100%) rename {examples => examples_src}/geolocation.js (100%) rename {examples => examples_src}/getfeatureinfo-image.html (100%) rename {examples => examples_src}/getfeatureinfo-image.js (100%) rename {examples => examples_src}/getfeatureinfo-tile.html (100%) rename {examples => examples_src}/getfeatureinfo-tile.js (100%) rename {examples => examples_src}/gpx.html (100%) rename {examples => examples_src}/gpx.js (100%) rename {examples => examples_src}/graticule.html (100%) rename {examples => examples_src}/graticule.js (100%) rename {examples => examples_src}/heatmap-earthquakes.html (100%) rename {examples => examples_src}/heatmap-earthquakes.js (100%) rename {examples => examples_src}/hue-saturation.html (100%) rename {examples => examples_src}/hue-saturation.js (100%) rename {examples => examples_src}/icon-sprite-webgl.html (100%) rename {examples => examples_src}/icon-sprite-webgl.js (100%) rename {examples => examples_src}/icon.html (100%) rename {examples => examples_src}/icon.js (100%) rename {examples => examples_src}/igc.html (100%) rename {examples => examples_src}/igc.js (100%) rename {examples => examples_src}/image-filter.html (100%) rename {examples => examples_src}/image-filter.js (100%) rename {examples => examples_src}/image-load-events.html (100%) rename {examples => examples_src}/image-load-events.js (100%) rename {examples => examples_src}/image-vector-layer.html (100%) rename {examples => examples_src}/image-vector-layer.js (100%) rename {examples => examples_src}/index.html (100%) rename {examples => examples_src}/kml-earthquakes.html (100%) rename {examples => examples_src}/kml-earthquakes.js (100%) rename {examples => examples_src}/kml-timezones.html (100%) rename {examples => examples_src}/kml-timezones.js (100%) rename {examples => examples_src}/kml.html (100%) rename {examples => examples_src}/kml.js (100%) rename {examples => examples_src}/layer-clipping-webgl.html (100%) rename {examples => examples_src}/layer-clipping-webgl.js (100%) rename {examples => examples_src}/layer-clipping.html (100%) rename {examples => examples_src}/layer-clipping.js (100%) rename {examples => examples_src}/layer-extent.html (100%) rename {examples => examples_src}/layer-extent.js (100%) rename {examples => examples_src}/layer-group.html (100%) rename {examples => examples_src}/layer-group.js (100%) rename {examples => examples_src}/layer-spy.html (100%) rename {examples => examples_src}/layer-spy.js (100%) rename {examples => examples_src}/layer-swipe.html (100%) rename {examples => examples_src}/layer-swipe.js (100%) rename {examples => examples_src}/lazy-source.html (100%) rename {examples => examples_src}/lazy-source.js (100%) rename {examples => examples_src}/line-arrows.html (100%) rename {examples => examples_src}/line-arrows.js (100%) rename {examples => examples_src}/localized-openstreetmap.html (100%) rename {examples => examples_src}/localized-openstreetmap.js (100%) rename {examples => examples_src}/mapguide-untiled.html (100%) rename {examples => examples_src}/mapguide-untiled.js (100%) rename {examples => examples_src}/mapquest.html (100%) rename {examples => examples_src}/mapquest.js (100%) rename {examples => examples_src}/measure.html (100%) rename {examples => examples_src}/measure.js (100%) rename {examples => examples_src}/min-max-resolution.html (100%) rename {examples => examples_src}/min-max-resolution.js (100%) rename {examples => examples_src}/mobile-full-screen.html (100%) rename {examples => examples_src}/mobile-full-screen.js (100%) rename {examples => examples_src}/modify-features.html (100%) rename {examples => examples_src}/modify-features.js (100%) rename {examples => examples_src}/modify-test.html (100%) rename {examples => examples_src}/modify-test.js (100%) rename {examples => examples_src}/mouse-position.html (100%) rename {examples => examples_src}/mouse-position.js (100%) rename {examples => examples_src}/moveend.html (100%) rename {examples => examples_src}/moveend.js (100%) rename {examples => examples_src}/navigation-controls.html (100%) rename {examples => examples_src}/navigation-controls.js (100%) rename {examples => examples_src}/overlay.html (100%) rename {examples => examples_src}/overlay.js (100%) rename {examples => examples_src}/overviewmap-custom.html (100%) rename {examples => examples_src}/overviewmap-custom.js (100%) rename {examples => examples_src}/overviewmap.html (100%) rename {examples => examples_src}/overviewmap.js (100%) rename {examples => examples_src}/polygon-styles.html (100%) rename {examples => examples_src}/polygon-styles.js (100%) rename {examples => examples_src}/popup.html (100%) rename {examples => examples_src}/popup.js (100%) rename {examples => examples_src}/preload.html (100%) rename {examples => examples_src}/preload.js (100%) rename {examples => examples_src}/readme.md (100%) rename {examples => examples_src}/regularshape.html (100%) rename {examples => examples_src}/regularshape.js (100%) rename {examples => examples_src}/rotation.html (100%) rename {examples => examples_src}/rotation.js (100%) rename {examples => examples_src}/scale-line.html (100%) rename {examples => examples_src}/scale-line.js (100%) rename {examples => examples_src}/select-features.html (100%) rename {examples => examples_src}/select-features.js (100%) rename {examples => examples_src}/semi-transparent-layer.html (100%) rename {examples => examples_src}/semi-transparent-layer.js (100%) rename {examples => examples_src}/side-by-side.html (100%) rename {examples => examples_src}/side-by-side.js (100%) rename {examples => examples_src}/simple.html (100%) rename {examples => examples_src}/simple.js (100%) rename {examples => examples_src}/snap.html (100%) rename {examples => examples_src}/snap.js (100%) rename {examples => examples_src}/sphere-mollweide.html (100%) rename {examples => examples_src}/sphere-mollweide.js (100%) rename {examples => examples_src}/stamen.html (100%) rename {examples => examples_src}/stamen.js (100%) rename {examples => examples_src}/static-image.html (100%) rename {examples => examples_src}/static-image.js (100%) rename {examples => examples_src}/symbol-atlas-webgl.html (100%) rename {examples => examples_src}/symbol-atlas-webgl.js (100%) rename {examples => examples_src}/synthetic-lines.html (100%) rename {examples => examples_src}/synthetic-lines.js (100%) rename {examples => examples_src}/synthetic-points.html (100%) rename {examples => examples_src}/synthetic-points.js (100%) rename {examples => examples_src}/teleport.html (100%) rename {examples => examples_src}/teleport.js (100%) rename {examples => examples_src}/tile-load-events.html (100%) rename {examples => examples_src}/tile-load-events.js (100%) rename {examples => examples_src}/tile-vector.html (100%) rename {examples => examples_src}/tile-vector.js (100%) rename {examples => examples_src}/tilejson.html (100%) rename {examples => examples_src}/tilejson.js (100%) rename {examples => examples_src}/tileutfgrid.html (100%) rename {examples => examples_src}/tileutfgrid.js (100%) rename {examples => examples_src}/tissot.html (100%) rename {examples => examples_src}/tissot.js (100%) rename {examples => examples_src}/topojson.html (100%) rename {examples => examples_src}/topojson.js (100%) rename {examples => examples_src}/vector-labels.html (100%) rename {examples => examples_src}/vector-labels.js (100%) rename {examples => examples_src}/vector-layer.html (100%) rename {examples => examples_src}/vector-layer.js (100%) rename {examples => examples_src}/vector-osm.html (100%) rename {examples => examples_src}/vector-osm.js (100%) rename {examples => examples_src}/vector-wfs.html (100%) rename {examples => examples_src}/vector-wfs.js (100%) rename {examples => examples_src}/wkt.html (100%) rename {examples => examples_src}/wkt.js (100%) rename {examples => examples_src}/wms-capabilities.html (100%) rename {examples => examples_src}/wms-capabilities.js (100%) rename {examples => examples_src}/wms-custom-proj.html (100%) rename {examples => examples_src}/wms-custom-proj.js (100%) rename {examples => examples_src}/wms-image-custom-proj.html (100%) rename {examples => examples_src}/wms-image-custom-proj.js (100%) rename {examples => examples_src}/wms-image.html (100%) rename {examples => examples_src}/wms-image.js (100%) rename {examples => examples_src}/wms-no-proj.html (100%) rename {examples => examples_src}/wms-no-proj.js (100%) rename {examples => examples_src}/wms-tiled-wrap-180.html (100%) rename {examples => examples_src}/wms-tiled-wrap-180.js (100%) rename {examples => examples_src}/wms-tiled.html (100%) rename {examples => examples_src}/wms-tiled.js (100%) rename {examples => examples_src}/wmts-capabilities.html (100%) rename {examples => examples_src}/wmts-capabilities.js (100%) rename {examples => examples_src}/wmts-hidpi.html (100%) rename {examples => examples_src}/wmts-hidpi.js (100%) rename {examples => examples_src}/wmts-layer-from-capabilities.html (100%) rename {examples => examples_src}/wmts-layer-from-capabilities.js (100%) rename {examples => examples_src}/wmts.html (100%) rename {examples => examples_src}/wmts.js (100%) rename {examples => examples_src}/xyz-esri-4326-512.html (100%) rename {examples => examples_src}/xyz-esri-4326-512.js (100%) rename {examples => examples_src}/xyz-esri.html (100%) rename {examples => examples_src}/xyz-esri.js (100%) rename {examples => examples_src}/xyz-retina.html (100%) rename {examples => examples_src}/xyz-retina.js (100%) rename {examples => examples_src}/xyz.html (100%) rename {examples => examples_src}/xyz.js (100%) rename {examples => examples_src}/zoom-constrained.html (100%) rename {examples => examples_src}/zoom-constrained.js (100%) rename {examples => examples_src}/zoomify.html (100%) rename {examples => examples_src}/zoomify.js (100%) rename {examples => examples_src}/zoomslider.html (100%) rename {examples => examples_src}/zoomslider.js (100%) diff --git a/.gitignore b/.gitignore index 08d024f5e6..ed5c657ad9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,6 @@ *.pyc /build/ -/examples/*.html.png -/examples/example-list.js -/examples/example-list.xml +/examples/ /node_modules/ /dist/ /coverage/ diff --git a/examples/Jugl.js b/examples_src/Jugl.js similarity index 100% rename from examples/Jugl.js rename to examples_src/Jugl.js diff --git a/examples/accessible.html b/examples_src/accessible.html similarity index 100% rename from examples/accessible.html rename to examples_src/accessible.html diff --git a/examples/accessible.js b/examples_src/accessible.js similarity index 100% rename from examples/accessible.js rename to examples_src/accessible.js diff --git a/examples/animation.html b/examples_src/animation.html similarity index 100% rename from examples/animation.html rename to examples_src/animation.html diff --git a/examples/animation.js b/examples_src/animation.js similarity index 100% rename from examples/animation.js rename to examples_src/animation.js diff --git a/examples/arcgis-tiled.html b/examples_src/arcgis-tiled.html similarity index 100% rename from examples/arcgis-tiled.html rename to examples_src/arcgis-tiled.html diff --git a/examples/arcgis-tiled.js b/examples_src/arcgis-tiled.js similarity index 100% rename from examples/arcgis-tiled.js rename to examples_src/arcgis-tiled.js diff --git a/examples/attributions.html b/examples_src/attributions.html similarity index 100% rename from examples/attributions.html rename to examples_src/attributions.html diff --git a/examples/attributions.js b/examples_src/attributions.js similarity index 100% rename from examples/attributions.js rename to examples_src/attributions.js diff --git a/examples/bind-input.html b/examples_src/bind-input.html similarity index 100% rename from examples/bind-input.html rename to examples_src/bind-input.html diff --git a/examples/bind-input.js b/examples_src/bind-input.js similarity index 100% rename from examples/bind-input.js rename to examples_src/bind-input.js diff --git a/examples/bing-maps.html b/examples_src/bing-maps.html similarity index 100% rename from examples/bing-maps.html rename to examples_src/bing-maps.html diff --git a/examples/bing-maps.js b/examples_src/bing-maps.js similarity index 100% rename from examples/bing-maps.js rename to examples_src/bing-maps.js diff --git a/examples/box-selection.html b/examples_src/box-selection.html similarity index 100% rename from examples/box-selection.html rename to examples_src/box-selection.html diff --git a/examples/box-selection.js b/examples_src/box-selection.js similarity index 100% rename from examples/box-selection.js rename to examples_src/box-selection.js diff --git a/examples/brightness-contrast.html b/examples_src/brightness-contrast.html similarity index 100% rename from examples/brightness-contrast.html rename to examples_src/brightness-contrast.html diff --git a/examples/brightness-contrast.js b/examples_src/brightness-contrast.js similarity index 100% rename from examples/brightness-contrast.js rename to examples_src/brightness-contrast.js diff --git a/examples/button-title.html b/examples_src/button-title.html similarity index 100% rename from examples/button-title.html rename to examples_src/button-title.html diff --git a/examples/button-title.js b/examples_src/button-title.js similarity index 100% rename from examples/button-title.js rename to examples_src/button-title.js diff --git a/examples/canvas-tiles.html b/examples_src/canvas-tiles.html similarity index 100% rename from examples/canvas-tiles.html rename to examples_src/canvas-tiles.html diff --git a/examples/canvas-tiles.js b/examples_src/canvas-tiles.js similarity index 100% rename from examples/canvas-tiles.js rename to examples_src/canvas-tiles.js diff --git a/examples/center.html b/examples_src/center.html similarity index 100% rename from examples/center.html rename to examples_src/center.html diff --git a/examples/center.js b/examples_src/center.js similarity index 100% rename from examples/center.js rename to examples_src/center.js diff --git a/examples/cluster.html b/examples_src/cluster.html similarity index 100% rename from examples/cluster.html rename to examples_src/cluster.html diff --git a/examples/cluster.js b/examples_src/cluster.js similarity index 100% rename from examples/cluster.js rename to examples_src/cluster.js diff --git a/examples/custom-controls.html b/examples_src/custom-controls.html similarity index 100% rename from examples/custom-controls.html rename to examples_src/custom-controls.html diff --git a/examples/custom-controls.js b/examples_src/custom-controls.js similarity index 100% rename from examples/custom-controls.js rename to examples_src/custom-controls.js diff --git a/examples/d3.html b/examples_src/d3.html similarity index 100% rename from examples/d3.html rename to examples_src/d3.html diff --git a/examples/d3.js b/examples_src/d3.js similarity index 100% rename from examples/d3.js rename to examples_src/d3.js diff --git a/examples/data/Butterfly.png b/examples_src/data/Butterfly.png similarity index 100% rename from examples/data/Butterfly.png rename to examples_src/data/Butterfly.png diff --git a/examples/data/IGNWMTSCapabilities.xml b/examples_src/data/IGNWMTSCapabilities.xml similarity index 100% rename from examples/data/IGNWMTSCapabilities.xml rename to examples_src/data/IGNWMTSCapabilities.xml diff --git a/examples/data/WMTSCapabilities.xml b/examples_src/data/WMTSCapabilities.xml similarity index 100% rename from examples/data/WMTSCapabilities.xml rename to examples_src/data/WMTSCapabilities.xml diff --git a/examples/data/arrow.png b/examples_src/data/arrow.png similarity index 100% rename from examples/data/arrow.png rename to examples_src/data/arrow.png diff --git a/examples/data/geojson/countries-110m.geojson b/examples_src/data/geojson/countries-110m.geojson similarity index 100% rename from examples/data/geojson/countries-110m.geojson rename to examples_src/data/geojson/countries-110m.geojson diff --git a/examples/data/geojson/countries.geojson b/examples_src/data/geojson/countries.geojson similarity index 100% rename from examples/data/geojson/countries.geojson rename to examples_src/data/geojson/countries.geojson diff --git a/examples/data/geojson/line-samples.geojson b/examples_src/data/geojson/line-samples.geojson similarity index 100% rename from examples/data/geojson/line-samples.geojson rename to examples_src/data/geojson/line-samples.geojson diff --git a/examples/data/geojson/point-samples.geojson b/examples_src/data/geojson/point-samples.geojson similarity index 100% rename from examples/data/geojson/point-samples.geojson rename to examples_src/data/geojson/point-samples.geojson diff --git a/examples/data/geojson/polygon-samples.geojson b/examples_src/data/geojson/polygon-samples.geojson similarity index 100% rename from examples/data/geojson/polygon-samples.geojson rename to examples_src/data/geojson/polygon-samples.geojson diff --git a/examples/data/geojson/switzerland.geojson b/examples_src/data/geojson/switzerland.geojson similarity index 100% rename from examples/data/geojson/switzerland.geojson rename to examples_src/data/geojson/switzerland.geojson diff --git a/examples/data/geolocation-orientation.json b/examples_src/data/geolocation-orientation.json similarity index 100% rename from examples/data/geolocation-orientation.json rename to examples_src/data/geolocation-orientation.json diff --git a/examples/data/geolocation_marker.png b/examples_src/data/geolocation_marker.png similarity index 100% rename from examples/data/geolocation_marker.png rename to examples_src/data/geolocation_marker.png diff --git a/examples/data/geolocation_marker_heading.png b/examples_src/data/geolocation_marker_heading.png similarity index 100% rename from examples/data/geolocation_marker_heading.png rename to examples_src/data/geolocation_marker_heading.png diff --git a/examples/data/gml/topp-states-wfs.xml b/examples_src/data/gml/topp-states-wfs.xml similarity index 100% rename from examples/data/gml/topp-states-wfs.xml rename to examples_src/data/gml/topp-states-wfs.xml diff --git a/examples/data/gpx/fells_loop.gpx b/examples_src/data/gpx/fells_loop.gpx similarity index 100% rename from examples/data/gpx/fells_loop.gpx rename to examples_src/data/gpx/fells_loop.gpx diff --git a/examples/data/icon.png b/examples_src/data/icon.png similarity index 100% rename from examples/data/icon.png rename to examples_src/data/icon.png diff --git a/examples/data/igc/Clement-Latour.igc b/examples_src/data/igc/Clement-Latour.igc similarity index 100% rename from examples/data/igc/Clement-Latour.igc rename to examples_src/data/igc/Clement-Latour.igc diff --git a/examples/data/igc/Damien-de-Baenst.igc b/examples_src/data/igc/Damien-de-Baenst.igc similarity index 100% rename from examples/data/igc/Damien-de-Baenst.igc rename to examples_src/data/igc/Damien-de-Baenst.igc diff --git a/examples/data/igc/Sylvain-Dhonneur.igc b/examples_src/data/igc/Sylvain-Dhonneur.igc similarity index 100% rename from examples/data/igc/Sylvain-Dhonneur.igc rename to examples_src/data/igc/Sylvain-Dhonneur.igc diff --git a/examples/data/igc/Tom-Payne.igc b/examples_src/data/igc/Tom-Payne.igc similarity index 100% rename from examples/data/igc/Tom-Payne.igc rename to examples_src/data/igc/Tom-Payne.igc diff --git a/examples/data/igc/Ulrich-Prinz.igc b/examples_src/data/igc/Ulrich-Prinz.igc similarity index 100% rename from examples/data/igc/Ulrich-Prinz.igc rename to examples_src/data/igc/Ulrich-Prinz.igc diff --git a/examples/data/kml/2012-02-10.kml b/examples_src/data/kml/2012-02-10.kml similarity index 100% rename from examples/data/kml/2012-02-10.kml rename to examples_src/data/kml/2012-02-10.kml diff --git a/examples/data/kml/2012_Earthquakes_Mag5.kml b/examples_src/data/kml/2012_Earthquakes_Mag5.kml similarity index 100% rename from examples/data/kml/2012_Earthquakes_Mag5.kml rename to examples_src/data/kml/2012_Earthquakes_Mag5.kml diff --git a/examples/data/kml/timezones.kml b/examples_src/data/kml/timezones.kml similarity index 100% rename from examples/data/kml/timezones.kml rename to examples_src/data/kml/timezones.kml diff --git a/examples/data/ogcsample.xml b/examples_src/data/ogcsample.xml similarity index 100% rename from examples/data/ogcsample.xml rename to examples_src/data/ogcsample.xml diff --git a/examples/data/sld/countries.sld b/examples_src/data/sld/countries.sld similarity index 100% rename from examples/data/sld/countries.sld rename to examples_src/data/sld/countries.sld diff --git a/examples/data/topojson/us.json b/examples_src/data/topojson/us.json similarity index 100% rename from examples/data/topojson/us.json rename to examples_src/data/topojson/us.json diff --git a/examples/data/topojson/world-110m.json b/examples_src/data/topojson/world-110m.json similarity index 100% rename from examples/data/topojson/world-110m.json rename to examples_src/data/topojson/world-110m.json diff --git a/examples/device-orientation.html b/examples_src/device-orientation.html similarity index 100% rename from examples/device-orientation.html rename to examples_src/device-orientation.html diff --git a/examples/device-orientation.js b/examples_src/device-orientation.js similarity index 100% rename from examples/device-orientation.js rename to examples_src/device-orientation.js diff --git a/examples/drag-and-drop-image-vector.html b/examples_src/drag-and-drop-image-vector.html similarity index 100% rename from examples/drag-and-drop-image-vector.html rename to examples_src/drag-and-drop-image-vector.html diff --git a/examples/drag-and-drop-image-vector.js b/examples_src/drag-and-drop-image-vector.js similarity index 100% rename from examples/drag-and-drop-image-vector.js rename to examples_src/drag-and-drop-image-vector.js diff --git a/examples/drag-and-drop.html b/examples_src/drag-and-drop.html similarity index 100% rename from examples/drag-and-drop.html rename to examples_src/drag-and-drop.html diff --git a/examples/drag-and-drop.js b/examples_src/drag-and-drop.js similarity index 100% rename from examples/drag-and-drop.js rename to examples_src/drag-and-drop.js diff --git a/examples/drag-features.html b/examples_src/drag-features.html similarity index 100% rename from examples/drag-features.html rename to examples_src/drag-features.html diff --git a/examples/drag-features.js b/examples_src/drag-features.js similarity index 100% rename from examples/drag-features.js rename to examples_src/drag-features.js diff --git a/examples/drag-rotate-and-zoom.html b/examples_src/drag-rotate-and-zoom.html similarity index 100% rename from examples/drag-rotate-and-zoom.html rename to examples_src/drag-rotate-and-zoom.html diff --git a/examples/drag-rotate-and-zoom.js b/examples_src/drag-rotate-and-zoom.js similarity index 100% rename from examples/drag-rotate-and-zoom.js rename to examples_src/drag-rotate-and-zoom.js diff --git a/examples/draw-and-modify-features.html b/examples_src/draw-and-modify-features.html similarity index 100% rename from examples/draw-and-modify-features.html rename to examples_src/draw-and-modify-features.html diff --git a/examples/draw-and-modify-features.js b/examples_src/draw-and-modify-features.js similarity index 100% rename from examples/draw-and-modify-features.js rename to examples_src/draw-and-modify-features.js diff --git a/examples/draw-features.html b/examples_src/draw-features.html similarity index 100% rename from examples/draw-features.html rename to examples_src/draw-features.html diff --git a/examples/draw-features.js b/examples_src/draw-features.js similarity index 100% rename from examples/draw-features.js rename to examples_src/draw-features.js diff --git a/examples/dynamic-data.html b/examples_src/dynamic-data.html similarity index 100% rename from examples/dynamic-data.html rename to examples_src/dynamic-data.html diff --git a/examples/dynamic-data.js b/examples_src/dynamic-data.js similarity index 100% rename from examples/dynamic-data.js rename to examples_src/dynamic-data.js diff --git a/examples/earthquake-clusters.html b/examples_src/earthquake-clusters.html similarity index 100% rename from examples/earthquake-clusters.html rename to examples_src/earthquake-clusters.html diff --git a/examples/earthquake-clusters.js b/examples_src/earthquake-clusters.js similarity index 100% rename from examples/earthquake-clusters.js rename to examples_src/earthquake-clusters.js diff --git a/examples/epsg-4326.html b/examples_src/epsg-4326.html similarity index 100% rename from examples/epsg-4326.html rename to examples_src/epsg-4326.html diff --git a/examples/epsg-4326.js b/examples_src/epsg-4326.js similarity index 100% rename from examples/epsg-4326.js rename to examples_src/epsg-4326.js diff --git a/examples/export-map.html b/examples_src/export-map.html similarity index 100% rename from examples/export-map.html rename to examples_src/export-map.html diff --git a/examples/export-map.js b/examples_src/export-map.js similarity index 100% rename from examples/export-map.js rename to examples_src/export-map.js diff --git a/examples/fractal.html b/examples_src/fractal.html similarity index 100% rename from examples/fractal.html rename to examples_src/fractal.html diff --git a/examples/fractal.js b/examples_src/fractal.js similarity index 100% rename from examples/fractal.js rename to examples_src/fractal.js diff --git a/examples/full-screen-drag-rotate-and-zoom.html b/examples_src/full-screen-drag-rotate-and-zoom.html similarity index 100% rename from examples/full-screen-drag-rotate-and-zoom.html rename to examples_src/full-screen-drag-rotate-and-zoom.html diff --git a/examples/full-screen-drag-rotate-and-zoom.js b/examples_src/full-screen-drag-rotate-and-zoom.js similarity index 100% rename from examples/full-screen-drag-rotate-and-zoom.js rename to examples_src/full-screen-drag-rotate-and-zoom.js diff --git a/examples/full-screen.html b/examples_src/full-screen.html similarity index 100% rename from examples/full-screen.html rename to examples_src/full-screen.html diff --git a/examples/full-screen.js b/examples_src/full-screen.js similarity index 100% rename from examples/full-screen.js rename to examples_src/full-screen.js diff --git a/examples/geojson.html b/examples_src/geojson.html similarity index 100% rename from examples/geojson.html rename to examples_src/geojson.html diff --git a/examples/geojson.js b/examples_src/geojson.js similarity index 100% rename from examples/geojson.js rename to examples_src/geojson.js diff --git a/examples/geolocation-orientation.html b/examples_src/geolocation-orientation.html similarity index 100% rename from examples/geolocation-orientation.html rename to examples_src/geolocation-orientation.html diff --git a/examples/geolocation-orientation.js b/examples_src/geolocation-orientation.js similarity index 100% rename from examples/geolocation-orientation.js rename to examples_src/geolocation-orientation.js diff --git a/examples/geolocation.html b/examples_src/geolocation.html similarity index 100% rename from examples/geolocation.html rename to examples_src/geolocation.html diff --git a/examples/geolocation.js b/examples_src/geolocation.js similarity index 100% rename from examples/geolocation.js rename to examples_src/geolocation.js diff --git a/examples/getfeatureinfo-image.html b/examples_src/getfeatureinfo-image.html similarity index 100% rename from examples/getfeatureinfo-image.html rename to examples_src/getfeatureinfo-image.html diff --git a/examples/getfeatureinfo-image.js b/examples_src/getfeatureinfo-image.js similarity index 100% rename from examples/getfeatureinfo-image.js rename to examples_src/getfeatureinfo-image.js diff --git a/examples/getfeatureinfo-tile.html b/examples_src/getfeatureinfo-tile.html similarity index 100% rename from examples/getfeatureinfo-tile.html rename to examples_src/getfeatureinfo-tile.html diff --git a/examples/getfeatureinfo-tile.js b/examples_src/getfeatureinfo-tile.js similarity index 100% rename from examples/getfeatureinfo-tile.js rename to examples_src/getfeatureinfo-tile.js diff --git a/examples/gpx.html b/examples_src/gpx.html similarity index 100% rename from examples/gpx.html rename to examples_src/gpx.html diff --git a/examples/gpx.js b/examples_src/gpx.js similarity index 100% rename from examples/gpx.js rename to examples_src/gpx.js diff --git a/examples/graticule.html b/examples_src/graticule.html similarity index 100% rename from examples/graticule.html rename to examples_src/graticule.html diff --git a/examples/graticule.js b/examples_src/graticule.js similarity index 100% rename from examples/graticule.js rename to examples_src/graticule.js diff --git a/examples/heatmap-earthquakes.html b/examples_src/heatmap-earthquakes.html similarity index 100% rename from examples/heatmap-earthquakes.html rename to examples_src/heatmap-earthquakes.html diff --git a/examples/heatmap-earthquakes.js b/examples_src/heatmap-earthquakes.js similarity index 100% rename from examples/heatmap-earthquakes.js rename to examples_src/heatmap-earthquakes.js diff --git a/examples/hue-saturation.html b/examples_src/hue-saturation.html similarity index 100% rename from examples/hue-saturation.html rename to examples_src/hue-saturation.html diff --git a/examples/hue-saturation.js b/examples_src/hue-saturation.js similarity index 100% rename from examples/hue-saturation.js rename to examples_src/hue-saturation.js diff --git a/examples/icon-sprite-webgl.html b/examples_src/icon-sprite-webgl.html similarity index 100% rename from examples/icon-sprite-webgl.html rename to examples_src/icon-sprite-webgl.html diff --git a/examples/icon-sprite-webgl.js b/examples_src/icon-sprite-webgl.js similarity index 100% rename from examples/icon-sprite-webgl.js rename to examples_src/icon-sprite-webgl.js diff --git a/examples/icon.html b/examples_src/icon.html similarity index 100% rename from examples/icon.html rename to examples_src/icon.html diff --git a/examples/icon.js b/examples_src/icon.js similarity index 100% rename from examples/icon.js rename to examples_src/icon.js diff --git a/examples/igc.html b/examples_src/igc.html similarity index 100% rename from examples/igc.html rename to examples_src/igc.html diff --git a/examples/igc.js b/examples_src/igc.js similarity index 100% rename from examples/igc.js rename to examples_src/igc.js diff --git a/examples/image-filter.html b/examples_src/image-filter.html similarity index 100% rename from examples/image-filter.html rename to examples_src/image-filter.html diff --git a/examples/image-filter.js b/examples_src/image-filter.js similarity index 100% rename from examples/image-filter.js rename to examples_src/image-filter.js diff --git a/examples/image-load-events.html b/examples_src/image-load-events.html similarity index 100% rename from examples/image-load-events.html rename to examples_src/image-load-events.html diff --git a/examples/image-load-events.js b/examples_src/image-load-events.js similarity index 100% rename from examples/image-load-events.js rename to examples_src/image-load-events.js diff --git a/examples/image-vector-layer.html b/examples_src/image-vector-layer.html similarity index 100% rename from examples/image-vector-layer.html rename to examples_src/image-vector-layer.html diff --git a/examples/image-vector-layer.js b/examples_src/image-vector-layer.js similarity index 100% rename from examples/image-vector-layer.js rename to examples_src/image-vector-layer.js diff --git a/examples/index.html b/examples_src/index.html similarity index 100% rename from examples/index.html rename to examples_src/index.html diff --git a/examples/kml-earthquakes.html b/examples_src/kml-earthquakes.html similarity index 100% rename from examples/kml-earthquakes.html rename to examples_src/kml-earthquakes.html diff --git a/examples/kml-earthquakes.js b/examples_src/kml-earthquakes.js similarity index 100% rename from examples/kml-earthquakes.js rename to examples_src/kml-earthquakes.js diff --git a/examples/kml-timezones.html b/examples_src/kml-timezones.html similarity index 100% rename from examples/kml-timezones.html rename to examples_src/kml-timezones.html diff --git a/examples/kml-timezones.js b/examples_src/kml-timezones.js similarity index 100% rename from examples/kml-timezones.js rename to examples_src/kml-timezones.js diff --git a/examples/kml.html b/examples_src/kml.html similarity index 100% rename from examples/kml.html rename to examples_src/kml.html diff --git a/examples/kml.js b/examples_src/kml.js similarity index 100% rename from examples/kml.js rename to examples_src/kml.js diff --git a/examples/layer-clipping-webgl.html b/examples_src/layer-clipping-webgl.html similarity index 100% rename from examples/layer-clipping-webgl.html rename to examples_src/layer-clipping-webgl.html diff --git a/examples/layer-clipping-webgl.js b/examples_src/layer-clipping-webgl.js similarity index 100% rename from examples/layer-clipping-webgl.js rename to examples_src/layer-clipping-webgl.js diff --git a/examples/layer-clipping.html b/examples_src/layer-clipping.html similarity index 100% rename from examples/layer-clipping.html rename to examples_src/layer-clipping.html diff --git a/examples/layer-clipping.js b/examples_src/layer-clipping.js similarity index 100% rename from examples/layer-clipping.js rename to examples_src/layer-clipping.js diff --git a/examples/layer-extent.html b/examples_src/layer-extent.html similarity index 100% rename from examples/layer-extent.html rename to examples_src/layer-extent.html diff --git a/examples/layer-extent.js b/examples_src/layer-extent.js similarity index 100% rename from examples/layer-extent.js rename to examples_src/layer-extent.js diff --git a/examples/layer-group.html b/examples_src/layer-group.html similarity index 100% rename from examples/layer-group.html rename to examples_src/layer-group.html diff --git a/examples/layer-group.js b/examples_src/layer-group.js similarity index 100% rename from examples/layer-group.js rename to examples_src/layer-group.js diff --git a/examples/layer-spy.html b/examples_src/layer-spy.html similarity index 100% rename from examples/layer-spy.html rename to examples_src/layer-spy.html diff --git a/examples/layer-spy.js b/examples_src/layer-spy.js similarity index 100% rename from examples/layer-spy.js rename to examples_src/layer-spy.js diff --git a/examples/layer-swipe.html b/examples_src/layer-swipe.html similarity index 100% rename from examples/layer-swipe.html rename to examples_src/layer-swipe.html diff --git a/examples/layer-swipe.js b/examples_src/layer-swipe.js similarity index 100% rename from examples/layer-swipe.js rename to examples_src/layer-swipe.js diff --git a/examples/lazy-source.html b/examples_src/lazy-source.html similarity index 100% rename from examples/lazy-source.html rename to examples_src/lazy-source.html diff --git a/examples/lazy-source.js b/examples_src/lazy-source.js similarity index 100% rename from examples/lazy-source.js rename to examples_src/lazy-source.js diff --git a/examples/line-arrows.html b/examples_src/line-arrows.html similarity index 100% rename from examples/line-arrows.html rename to examples_src/line-arrows.html diff --git a/examples/line-arrows.js b/examples_src/line-arrows.js similarity index 100% rename from examples/line-arrows.js rename to examples_src/line-arrows.js diff --git a/examples/localized-openstreetmap.html b/examples_src/localized-openstreetmap.html similarity index 100% rename from examples/localized-openstreetmap.html rename to examples_src/localized-openstreetmap.html diff --git a/examples/localized-openstreetmap.js b/examples_src/localized-openstreetmap.js similarity index 100% rename from examples/localized-openstreetmap.js rename to examples_src/localized-openstreetmap.js diff --git a/examples/mapguide-untiled.html b/examples_src/mapguide-untiled.html similarity index 100% rename from examples/mapguide-untiled.html rename to examples_src/mapguide-untiled.html diff --git a/examples/mapguide-untiled.js b/examples_src/mapguide-untiled.js similarity index 100% rename from examples/mapguide-untiled.js rename to examples_src/mapguide-untiled.js diff --git a/examples/mapquest.html b/examples_src/mapquest.html similarity index 100% rename from examples/mapquest.html rename to examples_src/mapquest.html diff --git a/examples/mapquest.js b/examples_src/mapquest.js similarity index 100% rename from examples/mapquest.js rename to examples_src/mapquest.js diff --git a/examples/measure.html b/examples_src/measure.html similarity index 100% rename from examples/measure.html rename to examples_src/measure.html diff --git a/examples/measure.js b/examples_src/measure.js similarity index 100% rename from examples/measure.js rename to examples_src/measure.js diff --git a/examples/min-max-resolution.html b/examples_src/min-max-resolution.html similarity index 100% rename from examples/min-max-resolution.html rename to examples_src/min-max-resolution.html diff --git a/examples/min-max-resolution.js b/examples_src/min-max-resolution.js similarity index 100% rename from examples/min-max-resolution.js rename to examples_src/min-max-resolution.js diff --git a/examples/mobile-full-screen.html b/examples_src/mobile-full-screen.html similarity index 100% rename from examples/mobile-full-screen.html rename to examples_src/mobile-full-screen.html diff --git a/examples/mobile-full-screen.js b/examples_src/mobile-full-screen.js similarity index 100% rename from examples/mobile-full-screen.js rename to examples_src/mobile-full-screen.js diff --git a/examples/modify-features.html b/examples_src/modify-features.html similarity index 100% rename from examples/modify-features.html rename to examples_src/modify-features.html diff --git a/examples/modify-features.js b/examples_src/modify-features.js similarity index 100% rename from examples/modify-features.js rename to examples_src/modify-features.js diff --git a/examples/modify-test.html b/examples_src/modify-test.html similarity index 100% rename from examples/modify-test.html rename to examples_src/modify-test.html diff --git a/examples/modify-test.js b/examples_src/modify-test.js similarity index 100% rename from examples/modify-test.js rename to examples_src/modify-test.js diff --git a/examples/mouse-position.html b/examples_src/mouse-position.html similarity index 100% rename from examples/mouse-position.html rename to examples_src/mouse-position.html diff --git a/examples/mouse-position.js b/examples_src/mouse-position.js similarity index 100% rename from examples/mouse-position.js rename to examples_src/mouse-position.js diff --git a/examples/moveend.html b/examples_src/moveend.html similarity index 100% rename from examples/moveend.html rename to examples_src/moveend.html diff --git a/examples/moveend.js b/examples_src/moveend.js similarity index 100% rename from examples/moveend.js rename to examples_src/moveend.js diff --git a/examples/navigation-controls.html b/examples_src/navigation-controls.html similarity index 100% rename from examples/navigation-controls.html rename to examples_src/navigation-controls.html diff --git a/examples/navigation-controls.js b/examples_src/navigation-controls.js similarity index 100% rename from examples/navigation-controls.js rename to examples_src/navigation-controls.js diff --git a/examples/overlay.html b/examples_src/overlay.html similarity index 100% rename from examples/overlay.html rename to examples_src/overlay.html diff --git a/examples/overlay.js b/examples_src/overlay.js similarity index 100% rename from examples/overlay.js rename to examples_src/overlay.js diff --git a/examples/overviewmap-custom.html b/examples_src/overviewmap-custom.html similarity index 100% rename from examples/overviewmap-custom.html rename to examples_src/overviewmap-custom.html diff --git a/examples/overviewmap-custom.js b/examples_src/overviewmap-custom.js similarity index 100% rename from examples/overviewmap-custom.js rename to examples_src/overviewmap-custom.js diff --git a/examples/overviewmap.html b/examples_src/overviewmap.html similarity index 100% rename from examples/overviewmap.html rename to examples_src/overviewmap.html diff --git a/examples/overviewmap.js b/examples_src/overviewmap.js similarity index 100% rename from examples/overviewmap.js rename to examples_src/overviewmap.js diff --git a/examples/polygon-styles.html b/examples_src/polygon-styles.html similarity index 100% rename from examples/polygon-styles.html rename to examples_src/polygon-styles.html diff --git a/examples/polygon-styles.js b/examples_src/polygon-styles.js similarity index 100% rename from examples/polygon-styles.js rename to examples_src/polygon-styles.js diff --git a/examples/popup.html b/examples_src/popup.html similarity index 100% rename from examples/popup.html rename to examples_src/popup.html diff --git a/examples/popup.js b/examples_src/popup.js similarity index 100% rename from examples/popup.js rename to examples_src/popup.js diff --git a/examples/preload.html b/examples_src/preload.html similarity index 100% rename from examples/preload.html rename to examples_src/preload.html diff --git a/examples/preload.js b/examples_src/preload.js similarity index 100% rename from examples/preload.js rename to examples_src/preload.js diff --git a/examples/readme.md b/examples_src/readme.md similarity index 100% rename from examples/readme.md rename to examples_src/readme.md diff --git a/examples/regularshape.html b/examples_src/regularshape.html similarity index 100% rename from examples/regularshape.html rename to examples_src/regularshape.html diff --git a/examples/regularshape.js b/examples_src/regularshape.js similarity index 100% rename from examples/regularshape.js rename to examples_src/regularshape.js diff --git a/examples/rotation.html b/examples_src/rotation.html similarity index 100% rename from examples/rotation.html rename to examples_src/rotation.html diff --git a/examples/rotation.js b/examples_src/rotation.js similarity index 100% rename from examples/rotation.js rename to examples_src/rotation.js diff --git a/examples/scale-line.html b/examples_src/scale-line.html similarity index 100% rename from examples/scale-line.html rename to examples_src/scale-line.html diff --git a/examples/scale-line.js b/examples_src/scale-line.js similarity index 100% rename from examples/scale-line.js rename to examples_src/scale-line.js diff --git a/examples/select-features.html b/examples_src/select-features.html similarity index 100% rename from examples/select-features.html rename to examples_src/select-features.html diff --git a/examples/select-features.js b/examples_src/select-features.js similarity index 100% rename from examples/select-features.js rename to examples_src/select-features.js diff --git a/examples/semi-transparent-layer.html b/examples_src/semi-transparent-layer.html similarity index 100% rename from examples/semi-transparent-layer.html rename to examples_src/semi-transparent-layer.html diff --git a/examples/semi-transparent-layer.js b/examples_src/semi-transparent-layer.js similarity index 100% rename from examples/semi-transparent-layer.js rename to examples_src/semi-transparent-layer.js diff --git a/examples/side-by-side.html b/examples_src/side-by-side.html similarity index 100% rename from examples/side-by-side.html rename to examples_src/side-by-side.html diff --git a/examples/side-by-side.js b/examples_src/side-by-side.js similarity index 100% rename from examples/side-by-side.js rename to examples_src/side-by-side.js diff --git a/examples/simple.html b/examples_src/simple.html similarity index 100% rename from examples/simple.html rename to examples_src/simple.html diff --git a/examples/simple.js b/examples_src/simple.js similarity index 100% rename from examples/simple.js rename to examples_src/simple.js diff --git a/examples/snap.html b/examples_src/snap.html similarity index 100% rename from examples/snap.html rename to examples_src/snap.html diff --git a/examples/snap.js b/examples_src/snap.js similarity index 100% rename from examples/snap.js rename to examples_src/snap.js diff --git a/examples/sphere-mollweide.html b/examples_src/sphere-mollweide.html similarity index 100% rename from examples/sphere-mollweide.html rename to examples_src/sphere-mollweide.html diff --git a/examples/sphere-mollweide.js b/examples_src/sphere-mollweide.js similarity index 100% rename from examples/sphere-mollweide.js rename to examples_src/sphere-mollweide.js diff --git a/examples/stamen.html b/examples_src/stamen.html similarity index 100% rename from examples/stamen.html rename to examples_src/stamen.html diff --git a/examples/stamen.js b/examples_src/stamen.js similarity index 100% rename from examples/stamen.js rename to examples_src/stamen.js diff --git a/examples/static-image.html b/examples_src/static-image.html similarity index 100% rename from examples/static-image.html rename to examples_src/static-image.html diff --git a/examples/static-image.js b/examples_src/static-image.js similarity index 100% rename from examples/static-image.js rename to examples_src/static-image.js diff --git a/examples/symbol-atlas-webgl.html b/examples_src/symbol-atlas-webgl.html similarity index 100% rename from examples/symbol-atlas-webgl.html rename to examples_src/symbol-atlas-webgl.html diff --git a/examples/symbol-atlas-webgl.js b/examples_src/symbol-atlas-webgl.js similarity index 100% rename from examples/symbol-atlas-webgl.js rename to examples_src/symbol-atlas-webgl.js diff --git a/examples/synthetic-lines.html b/examples_src/synthetic-lines.html similarity index 100% rename from examples/synthetic-lines.html rename to examples_src/synthetic-lines.html diff --git a/examples/synthetic-lines.js b/examples_src/synthetic-lines.js similarity index 100% rename from examples/synthetic-lines.js rename to examples_src/synthetic-lines.js diff --git a/examples/synthetic-points.html b/examples_src/synthetic-points.html similarity index 100% rename from examples/synthetic-points.html rename to examples_src/synthetic-points.html diff --git a/examples/synthetic-points.js b/examples_src/synthetic-points.js similarity index 100% rename from examples/synthetic-points.js rename to examples_src/synthetic-points.js diff --git a/examples/teleport.html b/examples_src/teleport.html similarity index 100% rename from examples/teleport.html rename to examples_src/teleport.html diff --git a/examples/teleport.js b/examples_src/teleport.js similarity index 100% rename from examples/teleport.js rename to examples_src/teleport.js diff --git a/examples/tile-load-events.html b/examples_src/tile-load-events.html similarity index 100% rename from examples/tile-load-events.html rename to examples_src/tile-load-events.html diff --git a/examples/tile-load-events.js b/examples_src/tile-load-events.js similarity index 100% rename from examples/tile-load-events.js rename to examples_src/tile-load-events.js diff --git a/examples/tile-vector.html b/examples_src/tile-vector.html similarity index 100% rename from examples/tile-vector.html rename to examples_src/tile-vector.html diff --git a/examples/tile-vector.js b/examples_src/tile-vector.js similarity index 100% rename from examples/tile-vector.js rename to examples_src/tile-vector.js diff --git a/examples/tilejson.html b/examples_src/tilejson.html similarity index 100% rename from examples/tilejson.html rename to examples_src/tilejson.html diff --git a/examples/tilejson.js b/examples_src/tilejson.js similarity index 100% rename from examples/tilejson.js rename to examples_src/tilejson.js diff --git a/examples/tileutfgrid.html b/examples_src/tileutfgrid.html similarity index 100% rename from examples/tileutfgrid.html rename to examples_src/tileutfgrid.html diff --git a/examples/tileutfgrid.js b/examples_src/tileutfgrid.js similarity index 100% rename from examples/tileutfgrid.js rename to examples_src/tileutfgrid.js diff --git a/examples/tissot.html b/examples_src/tissot.html similarity index 100% rename from examples/tissot.html rename to examples_src/tissot.html diff --git a/examples/tissot.js b/examples_src/tissot.js similarity index 100% rename from examples/tissot.js rename to examples_src/tissot.js diff --git a/examples/topojson.html b/examples_src/topojson.html similarity index 100% rename from examples/topojson.html rename to examples_src/topojson.html diff --git a/examples/topojson.js b/examples_src/topojson.js similarity index 100% rename from examples/topojson.js rename to examples_src/topojson.js diff --git a/examples/vector-labels.html b/examples_src/vector-labels.html similarity index 100% rename from examples/vector-labels.html rename to examples_src/vector-labels.html diff --git a/examples/vector-labels.js b/examples_src/vector-labels.js similarity index 100% rename from examples/vector-labels.js rename to examples_src/vector-labels.js diff --git a/examples/vector-layer.html b/examples_src/vector-layer.html similarity index 100% rename from examples/vector-layer.html rename to examples_src/vector-layer.html diff --git a/examples/vector-layer.js b/examples_src/vector-layer.js similarity index 100% rename from examples/vector-layer.js rename to examples_src/vector-layer.js diff --git a/examples/vector-osm.html b/examples_src/vector-osm.html similarity index 100% rename from examples/vector-osm.html rename to examples_src/vector-osm.html diff --git a/examples/vector-osm.js b/examples_src/vector-osm.js similarity index 100% rename from examples/vector-osm.js rename to examples_src/vector-osm.js diff --git a/examples/vector-wfs.html b/examples_src/vector-wfs.html similarity index 100% rename from examples/vector-wfs.html rename to examples_src/vector-wfs.html diff --git a/examples/vector-wfs.js b/examples_src/vector-wfs.js similarity index 100% rename from examples/vector-wfs.js rename to examples_src/vector-wfs.js diff --git a/examples/wkt.html b/examples_src/wkt.html similarity index 100% rename from examples/wkt.html rename to examples_src/wkt.html diff --git a/examples/wkt.js b/examples_src/wkt.js similarity index 100% rename from examples/wkt.js rename to examples_src/wkt.js diff --git a/examples/wms-capabilities.html b/examples_src/wms-capabilities.html similarity index 100% rename from examples/wms-capabilities.html rename to examples_src/wms-capabilities.html diff --git a/examples/wms-capabilities.js b/examples_src/wms-capabilities.js similarity index 100% rename from examples/wms-capabilities.js rename to examples_src/wms-capabilities.js diff --git a/examples/wms-custom-proj.html b/examples_src/wms-custom-proj.html similarity index 100% rename from examples/wms-custom-proj.html rename to examples_src/wms-custom-proj.html diff --git a/examples/wms-custom-proj.js b/examples_src/wms-custom-proj.js similarity index 100% rename from examples/wms-custom-proj.js rename to examples_src/wms-custom-proj.js diff --git a/examples/wms-image-custom-proj.html b/examples_src/wms-image-custom-proj.html similarity index 100% rename from examples/wms-image-custom-proj.html rename to examples_src/wms-image-custom-proj.html diff --git a/examples/wms-image-custom-proj.js b/examples_src/wms-image-custom-proj.js similarity index 100% rename from examples/wms-image-custom-proj.js rename to examples_src/wms-image-custom-proj.js diff --git a/examples/wms-image.html b/examples_src/wms-image.html similarity index 100% rename from examples/wms-image.html rename to examples_src/wms-image.html diff --git a/examples/wms-image.js b/examples_src/wms-image.js similarity index 100% rename from examples/wms-image.js rename to examples_src/wms-image.js diff --git a/examples/wms-no-proj.html b/examples_src/wms-no-proj.html similarity index 100% rename from examples/wms-no-proj.html rename to examples_src/wms-no-proj.html diff --git a/examples/wms-no-proj.js b/examples_src/wms-no-proj.js similarity index 100% rename from examples/wms-no-proj.js rename to examples_src/wms-no-proj.js diff --git a/examples/wms-tiled-wrap-180.html b/examples_src/wms-tiled-wrap-180.html similarity index 100% rename from examples/wms-tiled-wrap-180.html rename to examples_src/wms-tiled-wrap-180.html diff --git a/examples/wms-tiled-wrap-180.js b/examples_src/wms-tiled-wrap-180.js similarity index 100% rename from examples/wms-tiled-wrap-180.js rename to examples_src/wms-tiled-wrap-180.js diff --git a/examples/wms-tiled.html b/examples_src/wms-tiled.html similarity index 100% rename from examples/wms-tiled.html rename to examples_src/wms-tiled.html diff --git a/examples/wms-tiled.js b/examples_src/wms-tiled.js similarity index 100% rename from examples/wms-tiled.js rename to examples_src/wms-tiled.js diff --git a/examples/wmts-capabilities.html b/examples_src/wmts-capabilities.html similarity index 100% rename from examples/wmts-capabilities.html rename to examples_src/wmts-capabilities.html diff --git a/examples/wmts-capabilities.js b/examples_src/wmts-capabilities.js similarity index 100% rename from examples/wmts-capabilities.js rename to examples_src/wmts-capabilities.js diff --git a/examples/wmts-hidpi.html b/examples_src/wmts-hidpi.html similarity index 100% rename from examples/wmts-hidpi.html rename to examples_src/wmts-hidpi.html diff --git a/examples/wmts-hidpi.js b/examples_src/wmts-hidpi.js similarity index 100% rename from examples/wmts-hidpi.js rename to examples_src/wmts-hidpi.js diff --git a/examples/wmts-layer-from-capabilities.html b/examples_src/wmts-layer-from-capabilities.html similarity index 100% rename from examples/wmts-layer-from-capabilities.html rename to examples_src/wmts-layer-from-capabilities.html diff --git a/examples/wmts-layer-from-capabilities.js b/examples_src/wmts-layer-from-capabilities.js similarity index 100% rename from examples/wmts-layer-from-capabilities.js rename to examples_src/wmts-layer-from-capabilities.js diff --git a/examples/wmts.html b/examples_src/wmts.html similarity index 100% rename from examples/wmts.html rename to examples_src/wmts.html diff --git a/examples/wmts.js b/examples_src/wmts.js similarity index 100% rename from examples/wmts.js rename to examples_src/wmts.js diff --git a/examples/xyz-esri-4326-512.html b/examples_src/xyz-esri-4326-512.html similarity index 100% rename from examples/xyz-esri-4326-512.html rename to examples_src/xyz-esri-4326-512.html diff --git a/examples/xyz-esri-4326-512.js b/examples_src/xyz-esri-4326-512.js similarity index 100% rename from examples/xyz-esri-4326-512.js rename to examples_src/xyz-esri-4326-512.js diff --git a/examples/xyz-esri.html b/examples_src/xyz-esri.html similarity index 100% rename from examples/xyz-esri.html rename to examples_src/xyz-esri.html diff --git a/examples/xyz-esri.js b/examples_src/xyz-esri.js similarity index 100% rename from examples/xyz-esri.js rename to examples_src/xyz-esri.js diff --git a/examples/xyz-retina.html b/examples_src/xyz-retina.html similarity index 100% rename from examples/xyz-retina.html rename to examples_src/xyz-retina.html diff --git a/examples/xyz-retina.js b/examples_src/xyz-retina.js similarity index 100% rename from examples/xyz-retina.js rename to examples_src/xyz-retina.js diff --git a/examples/xyz.html b/examples_src/xyz.html similarity index 100% rename from examples/xyz.html rename to examples_src/xyz.html diff --git a/examples/xyz.js b/examples_src/xyz.js similarity index 100% rename from examples/xyz.js rename to examples_src/xyz.js diff --git a/examples/zoom-constrained.html b/examples_src/zoom-constrained.html similarity index 100% rename from examples/zoom-constrained.html rename to examples_src/zoom-constrained.html diff --git a/examples/zoom-constrained.js b/examples_src/zoom-constrained.js similarity index 100% rename from examples/zoom-constrained.js rename to examples_src/zoom-constrained.js diff --git a/examples/zoomify.html b/examples_src/zoomify.html similarity index 100% rename from examples/zoomify.html rename to examples_src/zoomify.html diff --git a/examples/zoomify.js b/examples_src/zoomify.js similarity index 100% rename from examples/zoomify.js rename to examples_src/zoomify.js diff --git a/examples/zoomslider.html b/examples_src/zoomslider.html similarity index 100% rename from examples/zoomslider.html rename to examples_src/zoomslider.html diff --git a/examples/zoomslider.js b/examples_src/zoomslider.js similarity index 100% rename from examples/zoomslider.js rename to examples_src/zoomslider.js diff --git a/tasks/parse-examples.js b/tasks/parse-examples.js index 8315da6716..a99eea4d83 100644 --- a/tasks/parse-examples.js +++ b/tasks/parse-examples.js @@ -4,6 +4,7 @@ var path = require('path'); var async = require('async'); var Parser = require('htmlparser2').Parser; +var buildExamples = require('./build-examples'); var exampleDir = path.join(__dirname, '..', 'examples'); @@ -141,6 +142,7 @@ function writeExampleList(exampleInfos, callback) { */ function main(callback) { async.waterfall([ + buildExamples, listExamples, parseExamples, writeExampleList From e40ab58d1076d28d429df19b6037506cc85f8b19 Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Wed, 1 Apr 2015 18:23:56 +0200 Subject: [PATCH 04/42] Use template for simple.html example --- examples_src/simple.html | 64 ++++++++-------------------------------- 1 file changed, 13 insertions(+), 51 deletions(-) diff --git a/examples_src/simple.html b/examples_src/simple.html index 4f760282af..b9abd1fd95 100644 --- a/examples_src/simple.html +++ b/examples_src/simple.html @@ -1,51 +1,13 @@ - - - - - - - - - - - Simple example - - - - - -
- -
-
-
-
-
- -
- -
-

Simple example

-

Example of a simple map.

-
-

See the simple.js source to see how this is done.

-
-
simple, openstreetmap
-
- -
- -
- - - - - - - +--- +template: "example.html" +title: "Simple example" +shortdesc: "Example of a simple map." +docs: > + A simple map with customized Attribution control. +tags: "simple, openstreetmap, attribution" +--- +
+
+
+
+
From 821f31fa185bcd2270d43923dde261cda23b1ee3 Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Wed, 1 Apr 2015 18:24:22 +0200 Subject: [PATCH 05/42] Use template for custom-controls.html example --- examples_src/custom-controls.css | 7 +++ examples_src/custom-controls.html | 77 ++++++------------------------- 2 files changed, 20 insertions(+), 64 deletions(-) create mode 100644 examples_src/custom-controls.css diff --git a/examples_src/custom-controls.css b/examples_src/custom-controls.css new file mode 100644 index 0000000000..0742513f03 --- /dev/null +++ b/examples_src/custom-controls.css @@ -0,0 +1,7 @@ +.rotate-north { + top: 65px; + left: .5em; +} +.ol-touch .rotate-north { + top: 80px; +} diff --git a/examples_src/custom-controls.html b/examples_src/custom-controls.html index 5e5cfb4050..5bb376751c 100644 --- a/examples_src/custom-controls.html +++ b/examples_src/custom-controls.html @@ -1,64 +1,13 @@ - - - - - - - - - - - - ol3 custom controls example - - - - - -
- -
-
-
-
-
- -
-
-

Custom controls

-

This example shows how to create custom controls.

-
-

- This example creates a "rotate to north" button. - See the custom-controls.js - source to see how this is done. -

-
-
- custom, control -
-
-
-
- - - - - - - - +--- +template: "example.html" +title: "Custom control example" +shortdesc: "Shows how to create custom controls." +docs: > + This example creates a "rotate to north" button. +tags: "custom, control" +--- +
+
+
+
+
From dd3350c94864040f2880d79868dbeca36263898f Mon Sep 17 00:00:00 2001 From: Bart van den Eijnden Date: Wed, 1 Apr 2015 19:43:45 +0200 Subject: [PATCH 06/42] Use template for accessible.html example --- examples_src/accessible.css | 16 +++++++ examples_src/accessible.html | 87 +++++++----------------------------- 2 files changed, 31 insertions(+), 72 deletions(-) create mode 100644 examples_src/accessible.css diff --git a/examples_src/accessible.css b/examples_src/accessible.css new file mode 100644 index 0000000000..0b1c657b51 --- /dev/null +++ b/examples_src/accessible.css @@ -0,0 +1,16 @@ +a.skiplink { + position: absolute; + clip: rect(1px, 1px, 1px, 1px); + padding: 0; + border: 0; + height: 1px; + width: 1px; + overflow: hidden; +} +a.skiplink:focus { + clip: auto; + height: auto; + width: auto; + background-color: #fff; + padding: 0.3em; +} diff --git a/examples_src/accessible.html b/examples_src/accessible.html index 71e821d804..7e73c824f9 100644 --- a/examples_src/accessible.html +++ b/examples_src/accessible.html @@ -1,72 +1,15 @@ - - - - - - - - - - - Accessibility example - - - - - - -
- -
-
- -
-
-
- -
- -
-

Accessibility example

-

Example of an accessible map.

-
-

This page's map element has its tabindex attribute set to "0", that makes it focusable. To focus the map element you can either navigate to it using the "tab" key or use the skip link. When the map element is focused the + and - keys can be used to zoom in and out and the arrow keys can be used to pan.

-

When clicked the "Zoom in" and "Zoom out" buttons below the map zoom the map in and out, respectively. You can navigate to the buttons using the "tab" key, and press the "enter" key to trigger the zooming action.

-

See the accessible.js source to see how this is done.

-
-
accessibility, tabindex
-
- -
- -
- - - - - - - +--- +template: "example.html" +title: "Accessibility example" +shortdesc: "Example of an accessible map." +docs: > +

This page's map element has its tabindex attribute set to "0", that makes it focusable. To focus the map element you can either navigate to it using the "tab" key or use the skip link. When the map element is focused the + and - keys can be used to zoom in and out and the arrow keys can be used to pan.

+

When clicked the "Zoom in" and "Zoom out" buttons below the map zoom the map in and out, respectively. You can navigate to the buttons using the "tab" key, and press the "enter" key to trigger the zooming action.

+tags: "accessibility, tabindex" +--- +
+
+ +
+
+
From 8d87bd30f0f1fd1a90153db39320715e5ca4d1fb Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Thu, 2 Apr 2015 09:47:48 +0200 Subject: [PATCH 07/42] Fix typo in template --- config/examples/example.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/examples/example.html b/config/examples/example.html index 328c595cd0..f30adff4c6 100644 --- a/config/examples/example.html +++ b/config/examples/example.html @@ -61,7 +61,7 @@ <script src="https://cdnjs.cloudflare.com/ajax/libs/ol3/{{ ol_version }}/ol.js"></script> <style> {{ css_inline }} -</style< +</style> </head> <body> <div class="container-fluid"> From 943cac755b9edb18060af3ebdbef3aba7dafbc51 Mon Sep 17 00:00:00 2001 From: Bart van den Eijnden Date: Thu, 2 Apr 2015 11:27:24 +0200 Subject: [PATCH 08/42] Port over the animation, arcgis-tiled and attributions examples --- examples_src/animation.html | 92 ++++++++++------------------------ examples_src/arcgis-tiled.html | 67 ++++++------------------- examples_src/attributions.html | 66 ++++++------------------ 3 files changed, 58 insertions(+), 167 deletions(-) diff --git a/examples_src/animation.html b/examples_src/animation.html index d072983e10..aebcde69d6 100644 --- a/examples_src/animation.html +++ b/examples_src/animation.html @@ -1,65 +1,27 @@ - - - - - - - - - - - Animation example - - - - - -
- -
-
-
-
-
- -
-
- - - - - - - - - -
-
- -
- -
-

Animation example

-

Demonstrates animated pan, zoom, and rotation.

-
-

See the animation.js source to see how this is done.

-
-
animation
-
- -
- -
- - - - - - - +--- +template: "example.html" +title: "Animation example" +shortdesc: "Demonstrates animated pan, zoom, and rotation." +docs: > + This example shows how to use the beforeRender function on the Map to run one + or more animations. +tags: "animation" +--- +
+
+
+
+
+
+
+ + + + + + + + + +
+
diff --git a/examples_src/arcgis-tiled.html b/examples_src/arcgis-tiled.html index d922b78ca3..0cf5c660cd 100644 --- a/examples_src/arcgis-tiled.html +++ b/examples_src/arcgis-tiled.html @@ -1,51 +1,16 @@ - - - - - - - - - - - Tiled ArcGIS MapServer example - - - - - -
- -
-
-
-
-
- -
- -
-

Tiled ArcGIS MapServer example

-

Example of a tiled ArcGIS layer.

-
-

See the arcgis-tiled.js source to see how this is done.

-
-
arcgis, tile, tilelayer
-
- -
- -
- - - - - - - +--- +template: "example.html" +title: "Tiled ArcGIS MapServer example" +shortdesc: "Example of a tiled ArcGIS layer." +docs: > + This example shows how to use an ArcGIS REST MapService as tiles. + This source type supports Map and Image Services. For cached ArcGIS + services, better performance is available by using + ol.source.XYZ instead. +tags: arcgis, tile, tilelayer" +--- +
+
+
+
+
diff --git a/examples_src/attributions.html b/examples_src/attributions.html index 1ab192dce4..d268129d88 100644 --- a/examples_src/attributions.html +++ b/examples_src/attributions.html @@ -1,51 +1,15 @@ - - - - - - - - - - - Attributions example - - - - - -
- -
-
-
-
-
- -
- -
-

Attributions example

-

Example of a attributions visibily change on map resize, to collapse them on small maps.

-
-

See the attributions.js source to see how this is done.

-
-
attributions, openstreetmap
-
- -
- -
- - - - - - - +--- +template: "example.html" +title: "Attributions example" +shortdesc: "Example of a attributions visibily change on map resize, to collapse them on small maps." +docs: > + When the map gets too small because of a resize, the attribution will be collapsed. + This is because the collapsible option is set to true if the width + of the map gets smaller than 600 pixels. +tags: "attributions, openstreetmap" +--- +
+
+
+
+
From 7d453bc69e53d37fb2d8060efbcb4564068f51b6 Mon Sep 17 00:00:00 2001 From: Bart van den Eijnden Date: Thu, 2 Apr 2015 11:58:56 +0200 Subject: [PATCH 09/42] Port over the bind-input and bing-maps examples --- examples_src/bind-input.html | 143 +++++++++++++---------------------- examples_src/bing-maps.html | 80 +++++--------------- 2 files changed, 71 insertions(+), 152 deletions(-) diff --git a/examples_src/bind-input.html b/examples_src/bind-input.html index 341c4ddbc5..cfec65e20c 100644 --- a/examples_src/bind-input.html +++ b/examples_src/bind-input.html @@ -1,92 +1,51 @@ - - - - - - - - - - - Bind HTML input example - - - - - -
- -
-
-
-
-
- -
- -
-

Bind HTML input example

-

Demonstrates two-way binding of HTML input elements to OpenLayers objects.

-
-

See the bind-input.js source to see how this is done.

- - -
-
input, bind, openstreetmap
-
- -
- -
- Layer - - - -
- - -
- -
-
-
- View - - - - -
-
-
- -
- -
- - - - - - - +--- +template: "example.html" +title: "Bind HTML input example" +shortdesc: "Demonstrates two-way binding of HTML input elements to OpenLayers objects." +docs: > + + +tags: "custom, control" +--- +
+
+
+
+
+
+
+
+ Layer + + + +
+ +
+
+
+
+
+ View + + + + +
+
+
\ No newline at end of file diff --git a/examples_src/bing-maps.html b/examples_src/bing-maps.html index a97c1dadcb..c8fb02ddb4 100644 --- a/examples_src/bing-maps.html +++ b/examples_src/bing-maps.html @@ -1,60 +1,20 @@ - - - - - - - - - - - Bing Maps example - - - - - -
- -
-
-
- - -
-
- -
- -
-

Bing Maps example

-

Example of a Bing Maps layer.

-
-

When the Bing Maps tile service doesn't have tiles for a given resolution and region it returns "placeholder" tiles indicating that. Zoom the map beyond level 19 to see the "placeholder" tiles. If you want OpenLayers to display stretched tiles in place of "placeholder" tiles beyond zoom level 19 then set maxZoom to 19 in the options passed to ol.source.BingMaps.

-

See the bing-maps.js source to see how this is done.

-
-
bing, bing-maps
-
- -
- -
- - - - - - - +--- +template: "example.html" +title: "Bing Maps example" +shortdesc: "Example of a Bing Maps layer." +docs: > +

When the Bing Maps tile service doesn't have tiles for a given resolution and region it returns "placeholder" tiles indicating that. Zoom the map beyond level 19 to see the "placeholder" tiles. If you want OpenLayers to display stretched tiles in place of "placeholder" tiles beyond zoom level 19 then set maxZoom to 19 in the options passed to ol.source.BingMaps.

+tags: "bing, bing-maps" +--- +
+
+
+ +
+
\ No newline at end of file From f2770827082da97a92e7c82723e74e9b6063e62a Mon Sep 17 00:00:00 2001 From: Bart van den Eijnden Date: Thu, 2 Apr 2015 13:15:33 +0200 Subject: [PATCH 10/42] Port over box-selection, brightness-contrast and button-title examples --- examples_src/box-selection.html | 77 ++++++--------------- examples_src/brightness-contrast.css | 7 ++ examples_src/brightness-contrast.html | 97 +++++++-------------------- examples_src/button-title.css | 4 ++ examples_src/button-title.html | 75 ++++----------------- 5 files changed, 68 insertions(+), 192 deletions(-) create mode 100644 examples_src/brightness-contrast.css create mode 100644 examples_src/button-title.css diff --git a/examples_src/box-selection.html b/examples_src/box-selection.html index 4fd498b1b6..b727d9b35a 100644 --- a/examples_src/box-selection.html +++ b/examples_src/box-selection.html @@ -1,59 +1,20 @@ - - - - - - - - - - - Box selection example - - - -