Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Removed client singleton pattern.

Deprecated lots of functions related to the v2.x API; details in Issue #289.

Fixes #90.
  • Loading branch information...
commit b2ecc115b4d8adca4ce4114b4e026c736f3de62c 1 parent 2a632d6
@JamesMGreene JamesMGreene authored
View
2  Gruntfile.js
@@ -42,8 +42,8 @@ module.exports = function(grunt) {
'src/javascript/start.js',
'src/javascript/ZeroClipboard/state.js',
'src/javascript/ZeroClipboard/utils.js',
- 'src/javascript/ZeroClipboard/client.js',
'src/javascript/ZeroClipboard/flash.js',
+ 'src/javascript/ZeroClipboard/client.js',
'src/javascript/ZeroClipboard/core.js',
'src/javascript/ZeroClipboard/dom.js',
'src/javascript/ZeroClipboard/event.js',
View
2  LICENSE
@@ -1,5 +1,5 @@
The MIT License (MIT)
-Copyright (c) 2013 Jon Rohan, James M. Greene
+Copyright (c) 2014 Jon Rohan, James M. Greene
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
View
25 README.md
@@ -2,6 +2,7 @@
The ZeroClipboard library provides an easy way to copy text to the clipboard using an invisible [Adobe Flash](http://en.wikipedia.org/wiki/Adobe_Flash) movie and a [JavaScript](http://en.wikipedia.org/wiki/JavaScript) interface. The "Zero" signifies that the library is invisible and the user interface is left entirely up to you.
+
## Simple Example
``` html
@@ -35,37 +36,23 @@ See the [instructions](docs/instructions.md) for more advanced options in using
Here is a working [test page](http://zeroclipboard.org/#demo) where you can try out ZeroClipboard in your browser.
-## Testing ZeroClipboard.swf Locally
+
+## Testing ZeroClipboard Locally
To test the page [demo page](http://zeroclipboard.org/#demo) locally, clone the [website repo](https://github.com/zeroclipboard/zeroclipboard.org).
+
## Support
This library is fully compatible with Flash Player 10, which requires that the clipboard copy operation be initiated by a user click event inside the Flash movie. This is achieved by automatically floating the invisible movie on top of a [DOM](http://en.wikipedia.org/wiki/Document_Object_Model) element of your choice. Standard mouse events are even propagated out to your DOM element, so you can still have rollover and mouse down effects.
Works in IE7+ and all of the evergreen browsers.
+
## Contributing
see [CONTRIBUTING.md](CONTRIBUTING.md)
-## Known issues
-
-- Can not have different handlers for different instances of ZeroClipboard ([#90](https://github.com/zeroclipboard/zeroclipboard/issues/90))
-
-```js
-var clip1 = new ZeroClipboard(document.getElementById("copy-button-1"));
-clip1.on('complete', function() {
- console.log('Copy button 1');
-});
-var clip2 = new ZeroClipboard(document.getElementById("copy-button-2"));
-clip2.on('complete', function() {
- console.log('Copy button 2');
-});
-
-// click on copy-button-1 -> "Copy button 1"
-// click on copy-button-2 -> "Copy button 1"
-```
## Releases
@@ -73,10 +60,12 @@ Starting with version [1.1.7](https://github.com/zeroclipboard/zeroclipboard/rel
see [releases](https://github.com/zeroclipboard/zeroclipboard/releases)
+
## Roadmap
see [roadmap.md](docs/roadmap.md)
+
## Last Build
[![Build Status](https://secure.travis-ci.org/zeroclipboard/zeroclipboard.png?branch=master)](https://travis-ci.org/zeroclipboard/zeroclipboard)
View
533 ZeroClipboard.js
@@ -1,7 +1,7 @@
/*!
* 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) 2013 Jon Rohan, James M. Greene
+* Copyright (c) 2014 Jon Rohan, James M. Greene
* Licensed MIT
* http://zeroclipboard.org/
* v1.3.0-beta.1
@@ -9,15 +9,18 @@
(function() {
"use strict";
var currentElement;
- var gluedElements = [];
var flashState = {
- global: {
- noflash: null,
- wrongflash: null,
- version: "0.0.0"
- },
- clients: {}
- };
+ bridge: null,
+ version: "0.0.0",
+ noflash: null,
+ wrongflash: null,
+ ready: null
+ };
+ var _clipData = {};
+ var clientIdCounter = 0;
+ var _clientMeta = {};
+ var elementIdCounter = 0;
+ var _elementMeta = {};
var _camelizeCssPropName = function() {
var matcherRegex = /\-([a-z])/g, replacerFn = function(match, group) {
return group.toUpperCase();
@@ -49,7 +52,6 @@
return value;
};
var _elementMouseOver = function(event) {
- if (!ZeroClipboard.prototype._singleton) return;
if (!event) {
event = window.event;
}
@@ -61,7 +63,7 @@
} else if (event.srcElement) {
target = event.srcElement;
}
- ZeroClipboard.prototype._singleton.setCurrent(target);
+ ZeroClipboard.activate(target);
};
var _addEventHandler = function(element, method, func) {
if (!element || element.nodeType !== 1) {
@@ -266,9 +268,9 @@
}
}
if (!zIndex) {
- if (typeof _defaults.zIndex === "number" && _defaults.zIndex > 0) {
- zIndex = _defaults.zIndex;
- } else if (typeof _defaults.zIndex === "string" && (tmp = parseInt(_defaults.zIndex, 10)) && !isNaN(tmp) && tmp > 0) {
+ if (typeof _globalConfig.zIndex === "number" && _globalConfig.zIndex > 0) {
+ zIndex = _globalConfig.zIndex;
+ } else if (typeof _globalConfig.zIndex === "string" && (tmp = parseInt(_globalConfig.zIndex, 10)) && !isNaN(tmp) && tmp > 0) {
zIndex = tmp;
}
}
@@ -305,7 +307,7 @@
return target;
};
var _extractDomain = function(originOrUrl) {
- if (originOrUrl == null) {
+ if (originOrUrl == null || originOrUrl === "") {
return null;
}
originOrUrl = originOrUrl.replace(/^\s+|\s+$/g, "");
@@ -379,60 +381,35 @@
return "never";
};
}();
- var ZeroClipboard = function(elements, options) {
- if (elements) (ZeroClipboard.prototype._singleton || this).glue(elements);
- if (ZeroClipboard.prototype._singleton) return ZeroClipboard.prototype._singleton;
- ZeroClipboard.prototype._singleton = this;
- if (options) {
- _deprecationWarning("new ZeroClipboard(elements, options)", this.options.debug);
- }
- this.options = _extend({}, _defaults, options);
- this.handlers = {};
- if (typeof flashState.global.noflash !== "boolean") {
- flashState.global.noflash = !_detectFlashSupport();
- }
- if (!flashState.clients.hasOwnProperty(this.options.moviePath)) {
- flashState.clients[this.options.moviePath] = {
- ready: false
- };
+ var _objectKeys = function(obj) {
+ if (obj == null) {
+ return [];
}
- if (flashState.global.noflash === false) {
- _bridge();
+ if (Object.keys) {
+ return Object.keys(obj);
}
- };
- ZeroClipboard.prototype.setCurrent = function(element) {
- currentElement = element;
- _reposition.call(this);
- var titleAttr = element.getAttribute("title");
- if (titleAttr) {
- this.setTitle(titleAttr);
+ var keys = [];
+ for (var prop in obj) {
+ if (obj.hasOwnProperty(prop)) {
+ keys.push(prop);
+ }
}
- var useHandCursor = this.options.forceHandCursor === true || _getStyle(element, "cursor") === "pointer";
- _setHandCursor.call(this, useHandCursor);
- return this;
+ return keys;
};
- ZeroClipboard.prototype.setText = function(newText) {
- if (newText && newText !== "") {
- this.options.text = newText;
- if (this.ready()) this.flashBridge.setText(newText);
+ var _deleteOwnProperties = function(obj) {
+ if (obj) {
+ for (var prop in obj) {
+ if (obj.hasOwnProperty(prop)) {
+ delete obj[prop];
+ }
+ }
}
- return this;
- };
- ZeroClipboard.prototype.setTitle = function(newTitle) {
- if (newTitle && newTitle !== "") this.htmlBridge.setAttribute("title", newTitle);
- return this;
- };
- ZeroClipboard.prototype.setSize = function(width, height) {
- if (this.ready()) this.flashBridge.setSize(width, height);
- return this;
- };
- var _setHandCursor = function(enabled) {
- if (this.ready()) this.flashBridge.setHandCursor(enabled);
+ return obj;
};
var _detectFlashSupport = function() {
var hasFlash = false;
- if (typeof flashState.global.noflash === "boolean") {
- hasFlash = flashState.global.noflash === false;
+ if (typeof flashState.noflash === "boolean") {
+ hasFlash = flashState.noflash === false;
} else {
if (typeof ActiveXObject === "function") {
try {
@@ -447,42 +424,173 @@
}
return hasFlash;
};
+ function _parseFlashVersion(flashVersion) {
+ return flashVersion.replace(/,/g, ".").replace(/[^0-9\.]/g, "");
+ }
+ function _isFlashVersionSupported(flashVersion) {
+ return parseFloat(_parseFlashVersion(flashVersion)) >= 10;
+ }
+ var ZeroClipboard = function(elements, options) {
+ if (!(this instanceof ZeroClipboard)) {
+ return new ZeroClipboard(elements, options);
+ }
+ this.id = "" + clientIdCounter++;
+ _clientMeta[this.id] = {
+ instance: this,
+ elements: [],
+ handlers: {}
+ };
+ if (elements) {
+ this.glue(elements);
+ }
+ if (typeof options !== "undefined") {
+ _deprecationWarning("new ZeroClipboard(elements, options)", _globalConfig.debug);
+ ZeroClipboard.config(options);
+ }
+ this.options = ZeroClipboard.config();
+ if (typeof flashState.noflash !== "boolean") {
+ flashState.noflash = !_detectFlashSupport();
+ }
+ if (flashState.noflash === false && flashState.wrongflash !== true) {
+ if (flashState.bridge === null) {
+ flashState.wrongflash = false;
+ flashState.ready = false;
+ _bridge();
+ }
+ }
+ };
+ ZeroClipboard.prototype.setText = function(newText) {
+ if (newText && newText !== "") {
+ _clipData["text/plain"] = newText;
+ if (flashState.ready === true && flashState.bridge) {
+ flashState.bridge.setText(newText);
+ } else {}
+ }
+ return this;
+ };
+ ZeroClipboard.prototype.setSize = function(width, height) {
+ if (flashState.ready === true && flashState.bridge) {
+ flashState.bridge.setSize(width, height);
+ } else {}
+ return this;
+ };
+ var _setHandCursor = function(enabled) {
+ if (flashState.ready === true && flashState.bridge) {
+ flashState.bridge.setHandCursor(enabled);
+ } else {}
+ };
+ ZeroClipboard.prototype.destroy = function() {
+ this.unglue();
+ this.off();
+ delete _clientMeta[this.id];
+ };
+ var _getAllClients = function() {
+ var i, len, client, clients = [], clientIds = _objectKeys(_clientMeta);
+ for (i = 0, len = clientIds.length; i < len; i++) {
+ client = _clientMeta[clientIds[i]].instance;
+ if (client && client instanceof ZeroClipboard) {
+ clients.push(client);
+ }
+ }
+ return clients;
+ };
ZeroClipboard.version = "1.3.0-beta.1";
- var _defaults = {
+ var _globalConfig = {
moviePath: "ZeroClipboard.swf",
- trustedDomains: [ window.location.host ],
- text: null,
+ trustedDomains: window.location.host ? [ window.location.host ] : [],
useNoCache: true,
forceHandCursor: false,
zIndex: 999999999,
- debug: true
+ debug: true,
+ title: null
};
- ZeroClipboard.setDefaults = function(options) {
- _extend(_defaults, options);
+ ZeroClipboard.config = function(options) {
+ if (typeof options === "object" && options !== null) {
+ _extend(_globalConfig, options);
+ }
+ if (typeof options === "string" && options) {
+ if (_globalConfig.hasOwnProperty(options)) {
+ return _globalConfig[options];
+ }
+ return;
+ }
+ var copy = {};
+ for (var prop in _globalConfig) {
+ if (_globalConfig.hasOwnProperty(prop)) {
+ if (typeof _globalConfig[prop] === "object" && _globalConfig[prop] !== null) {
+ if ("length" in _globalConfig[prop]) {
+ copy[prop] = _globalConfig[prop].slice(0);
+ } else {
+ copy[prop] = _extend({}, _globalConfig[prop]);
+ }
+ } else {
+ copy[prop] = _globalConfig[prop];
+ }
+ }
+ }
+ return copy;
};
ZeroClipboard.destroy = function() {
- if (ZeroClipboard.prototype._singleton) {
- ZeroClipboard.prototype._singleton.unglue(gluedElements);
- var bridge = ZeroClipboard.prototype._singleton.htmlBridge;
- if (bridge && bridge.parentNode) {
- bridge.parentNode.removeChild(bridge);
+ ZeroClipboard.deactivate();
+ for (var clientId in _clientMeta) {
+ if (_clientMeta.hasOwnProperty(clientId) && _clientMeta[clientId]) {
+ var client = _clientMeta[clientId].instance;
+ if (client && typeof client.destroy === "function") {
+ client.destroy();
+ }
+ }
+ }
+ var htmlBridge = _getHtmlBridge(flashState.bridge);
+ if (htmlBridge && htmlBridge.parentNode) {
+ htmlBridge.parentNode.removeChild(htmlBridge);
+ flashState.ready = null;
+ flashState.bridge = null;
+ }
+ };
+ ZeroClipboard.activate = function(element) {
+ if (currentElement) {
+ _removeClass(currentElement, _globalConfig.hoverClass);
+ _removeClass(currentElement, _globalConfig.activeClass);
+ }
+ currentElement = element;
+ _addClass(element, _globalConfig.hoverClass);
+ _reposition();
+ var newTitle = _globalConfig.title || element.getAttribute("title");
+ if (newTitle) {
+ var htmlBridge = _getHtmlBridge(flashState.bridge);
+ if (htmlBridge) {
+ htmlBridge.setAttribute("title", newTitle);
}
- delete ZeroClipboard.prototype._singleton;
+ }
+ var useHandCursor = _globalConfig.forceHandCursor === true || _getStyle(element, "cursor") === "pointer";
+ _setHandCursor(useHandCursor);
+ };
+ ZeroClipboard.deactivate = function() {
+ var htmlBridge = _getHtmlBridge(flashState.bridge);
+ if (htmlBridge) {
+ htmlBridge.style.left = "0px";
+ htmlBridge.style.top = "-9999px";
+ htmlBridge.removeAttribute("title");
+ }
+ if (currentElement) {
+ _removeClass(currentElement, _globalConfig.hoverClass);
+ _removeClass(currentElement, _globalConfig.activeClass);
+ currentElement = null;
}
};
var _amdModuleId = null;
var _cjsModuleId = null;
var _bridge = function() {
var flashBridge, len;
- var client = ZeroClipboard.prototype._singleton;
var container = document.getElementById("global-zeroclipboard-html-bridge");
if (!container) {
- var opts = _extend({}, client.options);
+ var opts = ZeroClipboard.config();
opts.amdModuleId = _amdModuleId;
opts.cjsModuleId = _cjsModuleId;
- var allowScriptAccess = _determineScriptAccess(window.location.host, client.options);
+ var allowScriptAccess = _determineScriptAccess(window.location.host, _globalConfig);
var flashvars = _vars(opts);
- var html = ' <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" id="global-zeroclipboard-flash-bridge" width="100%" height="100%"> <param name="movie" value="' + client.options.moviePath + _noCache(client.options.moviePath, client.options) + '"/> <param name="allowScriptAccess" value="' + allowScriptAccess + '"/> <param name="scale" value="exactfit"/> <param name="loop" value="false"/> <param name="menu" value="false"/> <param name="quality" value="best" /> <param name="bgcolor" value="#ffffff"/> <param name="wmode" value="transparent"/> <param name="flashvars" value="' + flashvars + '"/> <embed src="' + client.options.moviePath + _noCache(client.options.moviePath, client.options) + '" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="100%" height="100%" name="global-zeroclipboard-flash-bridge" allowScriptAccess="' + allowScriptAccess + '" allowFullScreen="false" type="application/x-shockwave-flash" wmode="transparent" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="' + flashvars + '" scale="exactfit"> </embed> </object>';
+ var swfUrl = _globalConfig.moviePath + _noCache(_globalConfig.moviePath, _globalConfig);
+ var html = ' <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" id="global-zeroclipboard-flash-bridge" width="100%" height="100%"> <param name="movie" value="' + swfUrl + '"/> <param name="allowScriptAccess" value="' + allowScriptAccess + '"/> <param name="scale" value="exactfit"/> <param name="loop" value="false"/> <param name="menu" value="false"/> <param name="quality" value="best" /> <param name="bgcolor" value="#ffffff"/> <param name="wmode" value="transparent"/> <param name="flashvars" value="' + flashvars + '"/> <embed src="' + swfUrl + '" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="100%" height="100%" name="global-zeroclipboard-flash-bridge" allowScriptAccess="' + allowScriptAccess + '" allowFullScreen="false" type="application/x-shockwave-flash" wmode="transparent" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="' + flashvars + '" scale="exactfit"> </embed> </object>';
container = document.createElement("div");
container.id = "global-zeroclipboard-html-bridge";
container.setAttribute("class", "global-zeroclipboard-container");
@@ -491,140 +599,160 @@
container.style.top = "-9999px";
container.style.width = "15px";
container.style.height = "15px";
- container.style.zIndex = "" + _getSafeZIndex(client.options.zIndex);
+ container.style.zIndex = "" + _getSafeZIndex(_globalConfig.zIndex);
document.body.appendChild(container);
container.innerHTML = html;
}
- client.htmlBridge = container;
flashBridge = document["global-zeroclipboard-flash-bridge"];
if (flashBridge && (len = flashBridge.length)) {
flashBridge = flashBridge[len - 1];
}
- client.flashBridge = flashBridge || container.children[0].lastElementChild;
+ flashState.bridge = flashBridge || container.children[0].lastElementChild;
};
- ZeroClipboard.prototype.resetBridge = function() {
- if (this.htmlBridge) {
- this.htmlBridge.style.left = "0px";
- this.htmlBridge.style.top = "-9999px";
- this.htmlBridge.removeAttribute("title");
- }
- if (currentElement) {
- _removeClass(currentElement, this.options.activeClass);
- currentElement = null;
+ var _getHtmlBridge = function(flashBridge) {
+ var isFlashElement = /^object|embed$/;
+ var htmlBridge = flashBridge && flashBridge.parentNode;
+ while (htmlBridge && isFlashElement.test(htmlBridge.tagName.toLowerCase()) && htmlBridge.parentNode) {
+ htmlBridge = htmlBridge.parentNode;
}
- this.options.text = null;
- return this;
- };
- ZeroClipboard.prototype.ready = function() {
- return flashState.clients[this.options.moviePath].ready === true;
+ return htmlBridge || null;
};
var _reposition = function() {
if (currentElement) {
- var pos = _getDOMObjectPosition(currentElement, this.options.zIndex);
- this.htmlBridge.style.top = pos.top + "px";
- this.htmlBridge.style.left = pos.left + "px";
- this.htmlBridge.style.width = pos.width + "px";
- this.htmlBridge.style.height = pos.height + "px";
- this.htmlBridge.style.zIndex = pos.zIndex + 1;
- this.setSize(pos.width, pos.height);
+ var pos = _getDOMObjectPosition(currentElement, _globalConfig.zIndex);
+ var htmlBridge = _getHtmlBridge(flashState.bridge);
+ if (htmlBridge) {
+ htmlBridge.style.top = pos.top + "px";
+ htmlBridge.style.left = pos.left + "px";
+ htmlBridge.style.width = pos.width + "px";
+ htmlBridge.style.height = pos.height + "px";
+ htmlBridge.style.zIndex = pos.zIndex + 1;
+ }
+ if (flashState.ready === true && flashState.bridge) {
+ flashState.bridge.setSize(pos.width, pos.height);
+ }
}
return this;
};
ZeroClipboard.dispatch = function(eventName, args) {
if (typeof eventName === "string" && eventName) {
- var client = ZeroClipboard.prototype._singleton;
var cleanEventName = eventName.toLowerCase().replace(/^on/, "");
if (cleanEventName) {
- _receiveEvent.call(client, cleanEventName, args);
+ var clients = currentElement ? _getAllClientsGluedToElement(currentElement) : _getAllClients();
+ for (var i = 0, len = clients.length; i < len; i++) {
+ _receiveEvent.call(clients[i], cleanEventName, args);
+ }
}
}
};
ZeroClipboard.prototype.on = function(eventName, func) {
- var events = eventName.toString().split(/\s+/), added = {};
+ var events = eventName.toString().split(/\s+/), added = {}, handlers = _clientMeta[this.id] && _clientMeta[this.id].handlers;
for (var i = 0, len = events.length; i < len; i++) {
eventName = events[i].toLowerCase().replace(/^on/, "");
added[eventName] = true;
- if (!this.handlers[eventName]) {
- this.handlers[eventName] = [];
+ if (!handlers[eventName]) {
+ handlers[eventName] = [];
}
- this.handlers[eventName].push(func);
+ handlers[eventName].push(func);
}
- if (added.noflash && flashState.global.noflash) {
+ if (added.noflash && flashState.noflash) {
_receiveEvent.call(this, "onNoFlash", {});
}
- if (added.wrongflash && flashState.global.wrongflash) {
+ if (added.wrongflash && flashState.wrongflash) {
_receiveEvent.call(this, "onWrongFlash", {
- flashVersion: flashState.global.version
+ flashVersion: flashState.version
});
}
- if (added.load && flashState.clients[this.options.moviePath].ready) {
+ if (added.load && flashState.ready) {
_receiveEvent.call(this, "onLoad", {
- flashVersion: flashState.global.version
+ flashVersion: flashState.version
});
}
return this;
};
- ZeroClipboard.prototype.addEventListener = ZeroClipboard.prototype.on;
ZeroClipboard.prototype.off = function(eventName, func) {
- var i, len, handlers, foundIndex, events = eventName.toString().split(/\s+/);
- for (i = 0, len = events.length; i < len; i++) {
- eventName = events[i].toLowerCase().replace(/^on/, "");
- handlers = this.handlers[eventName];
- if (handlers && handlers.length) {
- if (func) {
- foundIndex = _inArray(func, handlers);
- while (foundIndex !== -1) {
- handlers.splice(foundIndex, 1);
- foundIndex = _inArray(func, handlers, foundIndex);
+ var i, len, foundIndex, events, perEventHandlers, handlers = _clientMeta[this.id] && _clientMeta[this.id].handlers;
+ if (arguments.length === 0) {
+ events = _objectKeys(handlers);
+ } else if (typeof eventName === "string" && eventName) {
+ events = eventName.split(/\s+/);
+ }
+ if (events && events.length) {
+ for (i = 0, len = events.length; i < len; i++) {
+ eventName = events[i].toLowerCase().replace(/^on/, "");
+ perEventHandlers = handlers[eventName];
+ if (perEventHandlers && perEventHandlers.length) {
+ if (func) {
+ foundIndex = _inArray(func, perEventHandlers);
+ while (foundIndex !== -1) {
+ perEventHandlers.splice(foundIndex, 1);
+ foundIndex = _inArray(func, perEventHandlers, foundIndex);
+ }
+ } else {
+ handlers[eventName].length = 0;
}
- } else {
- this.handlers[eventName].length = 0;
}
}
}
return this;
};
- ZeroClipboard.prototype.removeEventListener = ZeroClipboard.prototype.off;
+ ZeroClipboard.prototype.handlers = function(eventName) {
+ var prop, copy = null, handlers = _clientMeta[this.id] && _clientMeta[this.id].handlers;
+ if (handlers) {
+ if (typeof eventName === "string" && eventName) {
+ return handlers[eventName] ? handlers[eventName].slice(0) : null;
+ }
+ copy = {};
+ for (prop in handlers) {
+ if (handlers.hasOwnProperty(prop) && handlers[prop]) {
+ copy[prop] = handlers[prop].slice(0);
+ }
+ }
+ }
+ return copy;
+ };
var _receiveEvent = function(eventName, args) {
- eventName = eventName.toString().toLowerCase().replace(/^on/, "");
+ eventName = eventName.toLowerCase().replace(/^on/, "");
+ var cleanVersion = args && args.flashVersion && _parseFlashVersion(args.flashVersion) || null;
var element = currentElement;
var performCallbackAsync = true;
switch (eventName) {
case "load":
- if (args && args.flashVersion) {
- if (!_isFlashVersionSupported(args.flashVersion)) {
+ if (cleanVersion) {
+ if (!_isFlashVersionSupported(cleanVersion)) {
_receiveEvent.call(this, "onWrongFlash", {
- flashVersion: args.flashVersion
+ flashVersion: cleanVersion
});
return;
}
- flashState.clients[this.options.moviePath].ready = true;
- flashState.global.version = args.flashVersion;
+ flashState.wrongflash = false;
+ flashState.ready = true;
+ flashState.version = cleanVersion;
}
break;
case "wrongflash":
- if (args && args.flashVersion && !_isFlashVersionSupported(args.flashVersion)) {
- flashState.global.wrongflash = true;
- flashState.global.version = args.flashVersion;
+ if (cleanVersion && !_isFlashVersionSupported(cleanVersion)) {
+ flashState.wrongflash = true;
+ flashState.ready = false;
+ flashState.version = cleanVersion;
}
break;
case "mouseover":
- _addClass(element, this.options.hoverClass);
+ _addClass(element, _globalConfig.hoverClass);
break;
case "mouseout":
- _removeClass(element, this.options.hoverClass);
- this.resetBridge();
+ ZeroClipboard.deactivate();
break;
case "mousedown":
- _addClass(element, this.options.activeClass);
+ _addClass(element, _globalConfig.activeClass);
break;
case "mouseup":
- _removeClass(element, this.options.activeClass);
+ _removeClass(element, _globalConfig.activeClass);
break;
case "datarequested":
@@ -644,10 +772,10 @@
break;
case "complete":
- this.options.text = null;
+ _deleteOwnProperties(_clipData);
break;
}
- var handlers = this.handlers[eventName];
+ var handlers = _clientMeta[this.id] && _clientMeta[this.id].handlers[eventName];
if (handlers && handlers.length) {
var i, len, func;
for (i = 0, len = handlers.length; i < len; i++) {
@@ -665,52 +793,92 @@
elements = _prepGlue(elements);
for (var i = 0; i < elements.length; i++) {
if (elements.hasOwnProperty(i) && elements[i] && elements[i].nodeType === 1) {
+ if (!elements[i].zcClippingId) {
+ elements[i].zcClippingId = "zcClippingId_" + elementIdCounter++;
+ _elementMeta[elements[i].zcClippingId] = [ this.id ];
+ _addEventHandler(elements[i], "mouseover", _elementMouseOver);
+ } else if (_inArray(this.id, _elementMeta[elements[i].zcClippingId]) === -1) {
+ _elementMeta[elements[i].zcClippingId].push(this.id);
+ }
+ var gluedElements = _clientMeta[this.id].elements;
if (_inArray(elements[i], gluedElements) === -1) {
gluedElements.push(elements[i]);
- _addEventHandler(elements[i], "mouseover", _elementMouseOver);
}
}
}
return this;
};
ZeroClipboard.prototype.unglue = function(elements) {
- elements = _prepGlue(elements);
- for (var i = 0; i < elements.length; i++) {
- if (elements.hasOwnProperty(i) && elements[i] && elements[i].nodeType === 1) {
- _removeEventHandler(elements[i], "mouseover", _elementMouseOver);
- var arrayIndex = _inArray(elements[i], gluedElements);
- if (arrayIndex !== -1) {
- gluedElements.splice(arrayIndex, 1);
+ var meta = _clientMeta[this.id];
+ if (meta) {
+ if (typeof elements === "undefined") {
+ elements = meta.elements.slice(0);
+ }
+ elements = _prepGlue(elements);
+ for (var i = 0; i < elements.length; i++) {
+ if (elements.hasOwnProperty(i) && elements[i] && elements[i].nodeType === 1) {
+ var gluedElements = meta.elements;
+ var arrayIndex = 0;
+ while ((arrayIndex = _inArray(elements[i], gluedElements, arrayIndex)) !== -1) {
+ gluedElements.splice(arrayIndex, 1);
+ }
+ var clientIds = _elementMeta[elements[i].zcClippingId];
+ if (clientIds) {
+ arrayIndex = 0;
+ while ((arrayIndex = _inArray(this.id, clientIds, arrayIndex)) !== -1) {
+ clientIds.splice(arrayIndex, 1);
+ }
+ if (clientIds.length === 0) {
+ _removeEventHandler(elements[i], "mouseover", _elementMouseOver);
+ delete elements[i].zcClippingId;
+ }
+ }
}
}
}
return this;
};
- function _isFlashVersionSupported(flashVersion) {
- return parseFloat(flashVersion.replace(/,/g, ".").replace(/[^0-9\.]/g, "")) >= 10;
- }
- _defaults.hoverClass = "zeroclipboard-is-hover";
- _defaults.activeClass = "zeroclipboard-is-active";
- _defaults.trustedOrigins = null;
- _defaults.allowScriptAccess = null;
+ ZeroClipboard.prototype.elements = function() {
+ var meta = _clientMeta[this.id];
+ return meta && meta.elements ? meta.elements.slice(0) : [];
+ };
+ var _getAllClientsGluedToElement = function(element) {
+ var elementMetaId, clientIds, i, len, client, clients = [];
+ if (element && element.nodeType === 1 && (elementMetaId = element.zcClippingId) && _elementMeta.hasOwnProperty(elementMetaId)) {
+ clientIds = _elementMeta[elementMetaId];
+ if (clientIds && clientIds.length) {
+ for (i = 0, len = clientIds.length; i < len; i++) {
+ client = _clientMeta[clientIds[i]].instance;
+ if (client && client instanceof ZeroClipboard) {
+ clients.push(client);
+ }
+ }
+ }
+ }
+ return clients;
+ };
+ _globalConfig.hoverClass = "zeroclipboard-is-hover";
+ _globalConfig.activeClass = "zeroclipboard-is-active";
+ _globalConfig.trustedOrigins = null;
+ _globalConfig.allowScriptAccess = null;
ZeroClipboard.detectFlashSupport = function() {
- var debugEnabled = ZeroClipboard.prototype._singleton && ZeroClipboard.prototype._singleton.options.debug || _defaults.debug;
+ var debugEnabled = _globalConfig.debug;
_deprecationWarning("ZeroClipboard.detectFlashSupport", debugEnabled);
return _detectFlashSupport();
};
ZeroClipboard.prototype.setHandCursor = function(enabled) {
- _deprecationWarning("ZeroClipboard.prototype.setHandCursor", this.options.debug);
+ _deprecationWarning("ZeroClipboard.prototype.setHandCursor", _globalConfig.debug);
enabled = typeof enabled === "boolean" ? enabled : !!enabled;
- _setHandCursor.call(this, enabled);
- this.options.forceHandCursor = enabled;
+ _setHandCursor(enabled);
+ _globalConfig.forceHandCursor = enabled;
return this;
};
ZeroClipboard.prototype.reposition = function() {
- _deprecationWarning("ZeroClipboard.prototype.reposition", this.options.debug);
- return _reposition.call(this);
+ _deprecationWarning("ZeroClipboard.prototype.reposition", _globalConfig.debug);
+ return _reposition();
};
ZeroClipboard.prototype.receiveEvent = function(eventName, args) {
- _deprecationWarning("ZeroClipboard.prototype.receiveEvent", this.options.debug);
+ _deprecationWarning("ZeroClipboard.prototype.receiveEvent", _globalConfig.debug);
if (typeof eventName === "string" && eventName) {
var cleanEventName = eventName.toLowerCase().replace(/^on/, "");
if (cleanEventName) {
@@ -718,6 +886,43 @@
}
}
};
+ ZeroClipboard.prototype.setCurrent = function(element) {
+ _deprecationWarning("ZeroClipboard.prototype.setCurrent", _globalConfig.debug);
+ ZeroClipboard.activate(element);
+ return this;
+ };
+ ZeroClipboard.prototype.resetBridge = function() {
+ _deprecationWarning("ZeroClipboard.prototype.resetBridge", _globalConfig.debug);
+ ZeroClipboard.deactivate();
+ return this;
+ };
+ ZeroClipboard.prototype.setTitle = function(newTitle) {
+ _deprecationWarning("ZeroClipboard.prototype.setTitle", _globalConfig.debug);
+ newTitle = newTitle || _globalConfig.title || currentElement && currentElement.getAttribute("title");
+ if (newTitle) {
+ var htmlBridge = _getHtmlBridge(flashState.bridge);
+ if (htmlBridge) {
+ htmlBridge.setAttribute("title", newTitle);
+ }
+ }
+ return this;
+ };
+ ZeroClipboard.setDefaults = function(options) {
+ _deprecationWarning("ZeroClipboard.setDefaults", _globalConfig.debug);
+ ZeroClipboard.config(options);
+ };
+ ZeroClipboard.prototype.addEventListener = function() {
+ _deprecationWarning("ZeroClipboard.prototype.addEventListener", _globalConfig.debug);
+ return this.on.apply(this, [].slice.call(arguments, 0));
+ };
+ ZeroClipboard.prototype.removeEventListener = function() {
+ _deprecationWarning("ZeroClipboard.prototype.removeEventListener", _globalConfig.debug);
+ return this.off.apply(this, [].slice.call(arguments, 0));
+ };
+ ZeroClipboard.prototype.ready = function() {
+ _deprecationWarning("ZeroClipboard.prototype.ready", _globalConfig.debug);
+ return flashState.ready === true;
+ };
if (typeof define === "function" && define.amd) {
define([ "require", "exports", "module" ], function(require, exports, module) {
_amdModuleId = module && module.id || null;
View
4 ZeroClipboard.min.js
@@ -1,9 +1,9 @@
/*!
* 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) 2013 Jon Rohan, James M. Greene
+* Copyright (c) 2014 Jon Rohan, James M. Greene
* Licensed MIT
* http://zeroclipboard.org/
* v1.3.0-beta.1
*/
-!function(){"use strict";function a(a){return parseFloat(a.replace(/,/g,".").replace(/[^0-9\.]/g,""))>=10}var b,c=[],d={global:{noflash:null,wrongflash:null,version:"0.0.0"},clients:{}},e=function(){var a=/\-([a-z])/g,b=function(a,b){return b.toUpperCase()};return function(c){return c.replace(a,b)}}(),f=function(a,b){var c,d,f;return window.getComputedStyle?c=window.getComputedStyle(a,null).getPropertyValue(b):(d=e(b),c=a.currentStyle?a.currentStyle[d]:a.style[d]),"cursor"!==b||c&&"auto"!==c||(f=a.tagName.toLowerCase(),"a"!==f)?c:"pointer"},g=function(a){if(x.prototype._singleton){a||(a=window.event);var b;this!==window?b=this:a.target?b=a.target:a.srcElement&&(b=a.srcElement),x.prototype._singleton.setCurrent(b)}},h=function(a,b,c){a&&1===a.nodeType&&(a.addEventListener?a.addEventListener(b,c,!1):a.attachEvent&&a.attachEvent("on"+b,c))},i=function(a,b,c){a&&1===a.nodeType&&(a.removeEventListener?a.removeEventListener(b,c,!1):a.detachEvent&&a.detachEvent("on"+b,c))},j=function(a,b){if(!a||1!==a.nodeType)return a;if(a.classList)return a.classList.contains(b)||a.classList.add(b),a;if(b&&"string"==typeof b){var c=(b||"").split(/\s+/);if(1===a.nodeType)if(a.className){for(var d=" "+a.className+" ",e=a.className,f=0,g=c.length;g>f;f++)d.indexOf(" "+c[f]+" ")<0&&(e+=" "+c[f]);a.className=e.replace(/^\s+|\s+$/g,"")}else a.className=b}return a},k=function(a,b){if(!a||1!==a.nodeType)return a;if(a.classList)return a.classList.contains(b)&&a.classList.remove(b),a;if(b&&"string"==typeof b||void 0===b){var c=(b||"").split(/\s+/);if(1===a.nodeType&&a.className)if(b){for(var d=(" "+a.className+" ").replace(/[\n\t]/g," "),e=0,f=c.length;f>e;e++)d=d.replace(" "+c[e]+" "," ");a.className=d.replace(/^\s+|\s+$/g,"")}else a.className=""}return a},l=function(){var a,b,c,d=1;return"function"==typeof document.body.getBoundingClientRect&&(a=document.body.getBoundingClientRect(),b=a.right-a.left,c=document.body.offsetWidth,d=Math.round(b/c*100)/100),d},m=function(a,b){var c={left:0,top:0,width:0,height:0,zIndex:s(b)-1};if(a.getBoundingClientRect){var d,e,f,g=a.getBoundingClientRect();"pageXOffset"in window&&"pageYOffset"in window?(d=window.pageXOffset,e=window.pageYOffset):(f=l(),d=Math.round(document.documentElement.scrollLeft/f),e=Math.round(document.documentElement.scrollTop/f));var h=document.documentElement.clientLeft||0,i=document.documentElement.clientTop||0;c.left=g.left+d-h,c.top=g.top+e-i,c.width="width"in g?g.width:g.right-g.left,c.height="height"in g?g.height:g.bottom-g.top}return c},n=function(a,b){var c=!(b&&b.useNoCache===!1);return c?(-1===a.indexOf("?")?"?":"&")+"nocache="+(new Date).getTime():""},o=function(a){var b,c,d,e=[],f=[],g=[];if(a.trustedOrigins&&("string"==typeof a.trustedOrigins?f.push(a.trustedOrigins):"object"==typeof a.trustedOrigins&&"length"in a.trustedOrigins&&(f=f.concat(a.trustedOrigins))),a.trustedDomains&&("string"==typeof a.trustedDomains?f.push(a.trustedDomains):"object"==typeof a.trustedDomains&&"length"in a.trustedDomains&&(f=f.concat(a.trustedDomains))),f.length)for(b=0,c=f.length;c>b;b++)if(f.hasOwnProperty(b)&&f[b]&&"string"==typeof f[b]){if(d=v(f[b]),!d)continue;if("*"===d){g=[d];break}g.push.apply(g,[d,"//"+d,window.location.protocol+"//"+d])}return g.length&&e.push("trustedOrigins="+encodeURIComponent(g.join(","))),"string"==typeof a.amdModuleId&&a.amdModuleId&&e.push("amdModuleId="+encodeURIComponent(a.amdModuleId)),"string"==typeof a.cjsModuleId&&a.cjsModuleId&&e.push("cjsModuleId="+encodeURIComponent(a.cjsModuleId)),e.join("&")},p=function(a,b,c){if("function"==typeof b.indexOf)return b.indexOf(a,c);var d,e=b.length;for("undefined"==typeof c?c=0:0>c&&(c=e+c),d=c;e>d;d++)if(b.hasOwnProperty(d)&&b[d]===a)return d;return-1},q=function(a){if("string"==typeof a)throw new TypeError("ZeroClipboard doesn't accept query strings.");return a.length?a:[a]},r=function(a,b,c,d,e){e?window.setTimeout(function(){a.call(b,c,d)},0):a.call(b,c,d)},s=function(a){var b,c;return a&&("number"==typeof a&&a>0?b=a:"string"==typeof a&&(c=parseInt(a,10))&&!isNaN(c)&&c>0&&(b=c)),b||("number"==typeof A.zIndex&&A.zIndex>0?b=A.zIndex:"string"==typeof A.zIndex&&(c=parseInt(A.zIndex,10))&&!isNaN(c)&&c>0&&(b=c)),b||0},t=function(a,b){if(a&&b!==!1&&"undefined"!=typeof console&&console&&(console.warn||console.log)){var c="`"+a+"` is deprecated. See docs for more info:\n https://github.com/zeroclipboard/zeroclipboard/blob/master/docs/instructions.md#deprecations";console.warn?console.warn(c):console.log(c)}},u=function(){var a,b,c,d,e,f,g=arguments[0]||{};for(a=1,b=arguments.length;b>a;a++)if(null!=(c=arguments[a]))for(d in c)if(c.hasOwnProperty(d)){if(e=g[d],f=c[d],g===f)continue;void 0!==f&&(g[d]=f)}return g},v=function(a){if(null==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},w=function(){var a=function(a,b){var c,d,e;if(null!=a&&"*"!==b[0]&&("string"==typeof a&&(a=[a]),"object"==typeof a&&"length"in a))for(c=0,d=a.length;d>c;c++)if(a.hasOwnProperty(c)&&(e=v(a[c]))){if("*"===e){b.length=0,b.push("*");break}-1===p(e,b)&&b.push(e)}},b={always:"always",samedomain:"sameDomain",never:"never"};return function(c,d){var e,f=d.allowScriptAccess;if("string"==typeof f&&(e=f.toLowerCase())&&/^always|samedomain|never$/.test(e))return b[e];var g=v(d.moviePath);null===g&&(g=c);var h=[];a(d.trustedOrigins,h),a(d.trustedDomains,h);var i=h.length;if(i>0){if(1===i&&"*"===h[0])return"always";if(-1!==p(c,h))return 1===i&&c===g?"sameDomain":"always"}return"never"}}(),x=function(a,b){return a&&(x.prototype._singleton||this).glue(a),x.prototype._singleton?x.prototype._singleton:(x.prototype._singleton=this,b&&t("new ZeroClipboard(elements, options)",this.options.debug),this.options=u({},A,b),this.handlers={},"boolean"!=typeof d.global.noflash&&(d.global.noflash=!z()),d.clients.hasOwnProperty(this.options.moviePath)||(d.clients[this.options.moviePath]={ready:!1}),d.global.noflash===!1&&D(),void 0)};x.prototype.setCurrent=function(a){b=a,E.call(this);var c=a.getAttribute("title");c&&this.setTitle(c);var d=this.options.forceHandCursor===!0||"pointer"===f(a,"cursor");return y.call(this,d),this},x.prototype.setText=function(a){return a&&""!==a&&(this.options.text=a,this.ready()&&this.flashBridge.setText(a)),this},x.prototype.setTitle=function(a){return a&&""!==a&&this.htmlBridge.setAttribute("title",a),this},x.prototype.setSize=function(a,b){return this.ready()&&this.flashBridge.setSize(a,b),this};var y=function(a){this.ready()&&this.flashBridge.setHandCursor(a)},z=function(){var a=!1;if("boolean"==typeof d.global.noflash)a=d.global.noflash===!1;else{if("function"==typeof ActiveXObject)try{new ActiveXObject("ShockwaveFlash.ShockwaveFlash")&&(a=!0)}catch(b){}!a&&navigator.mimeTypes["application/x-shockwave-flash"]&&(a=!0)}return a};x.version="1.3.0-beta.1";var A={moviePath:"ZeroClipboard.swf",trustedDomains:[window.location.host],text:null,useNoCache:!0,forceHandCursor:!1,zIndex:999999999,debug:!0};x.setDefaults=function(a){u(A,a)},x.destroy=function(){if(x.prototype._singleton){x.prototype._singleton.unglue(c);var a=x.prototype._singleton.htmlBridge;a&&a.parentNode&&a.parentNode.removeChild(a),delete x.prototype._singleton}};var B=null,C=null,D=function(){var a,b,c=x.prototype._singleton,d=document.getElementById("global-zeroclipboard-html-bridge");if(!d){var e=u({},c.options);e.amdModuleId=B,e.cjsModuleId=C;var f=w(window.location.host,c.options),g=o(e),h=' <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" id="global-zeroclipboard-flash-bridge" width="100%" height="100%"> <param name="movie" value="'+c.options.moviePath+n(c.options.moviePath,c.options)+'"/> <param name="allowScriptAccess" value="'+f+'"/> <param name="scale" value="exactfit"/> <param name="loop" value="false"/> <param name="menu" value="false"/> <param name="quality" value="best" /> <param name="bgcolor" value="#ffffff"/> <param name="wmode" value="transparent"/> <param name="flashvars" value="'+g+'"/> <embed src="'+c.options.moviePath+n(c.options.moviePath,c.options)+'" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="100%" height="100%" name="global-zeroclipboard-flash-bridge" allowScriptAccess="'+f+'" allowFullScreen="false" type="application/x-shockwave-flash" wmode="transparent" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="'+g+'" scale="exactfit"> </embed> </object>';d=document.createElement("div"),d.id="global-zeroclipboard-html-bridge",d.setAttribute("class","global-zeroclipboard-container"),d.style.position="absolute",d.style.left="0px",d.style.top="-9999px",d.style.width="15px",d.style.height="15px",d.style.zIndex=""+s(c.options.zIndex),document.body.appendChild(d),d.innerHTML=h}c.htmlBridge=d,a=document["global-zeroclipboard-flash-bridge"],a&&(b=a.length)&&(a=a[b-1]),c.flashBridge=a||d.children[0].lastElementChild};x.prototype.resetBridge=function(){return this.htmlBridge&&(this.htmlBridge.style.left="0px",this.htmlBridge.style.top="-9999px",this.htmlBridge.removeAttribute("title")),b&&(k(b,this.options.activeClass),b=null),this.options.text=null,this},x.prototype.ready=function(){return d.clients[this.options.moviePath].ready===!0};var E=function(){if(b){var a=m(b,this.options.zIndex);this.htmlBridge.style.top=a.top+"px",this.htmlBridge.style.left=a.left+"px",this.htmlBridge.style.width=a.width+"px",this.htmlBridge.style.height=a.height+"px",this.htmlBridge.style.zIndex=a.zIndex+1,this.setSize(a.width,a.height)}return this};x.dispatch=function(a,b){if("string"==typeof a&&a){var c=x.prototype._singleton,d=a.toLowerCase().replace(/^on/,"");d&&F.call(c,d,b)}},x.prototype.on=function(a,b){for(var c=a.toString().split(/\s+/),e={},f=0,g=c.length;g>f;f++)a=c[f].toLowerCase().replace(/^on/,""),e[a]=!0,this.handlers[a]||(this.handlers[a]=[]),this.handlers[a].push(b);return e.noflash&&d.global.noflash&&F.call(this,"onNoFlash",{}),e.wrongflash&&d.global.wrongflash&&F.call(this,"onWrongFlash",{flashVersion:d.global.version}),e.load&&d.clients[this.options.moviePath].ready&&F.call(this,"onLoad",{flashVersion:d.global.version}),this},x.prototype.addEventListener=x.prototype.on,x.prototype.off=function(a,b){var c,d,e,f,g=a.toString().split(/\s+/);for(c=0,d=g.length;d>c;c++)if(a=g[c].toLowerCase().replace(/^on/,""),e=this.handlers[a],e&&e.length)if(b)for(f=p(b,e);-1!==f;)e.splice(f,1),f=p(b,e,f);else this.handlers[a].length=0;return this},x.prototype.removeEventListener=x.prototype.off;var F=function(c,e){c=c.toString().toLowerCase().replace(/^on/,"");var f=b,g=!0;switch(c){case"load":if(e&&e.flashVersion){if(!a(e.flashVersion))return F.call(this,"onWrongFlash",{flashVersion:e.flashVersion}),void 0;d.clients[this.options.moviePath].ready=!0,d.global.version=e.flashVersion}break;case"wrongflash":e&&e.flashVersion&&!a(e.flashVersion)&&(d.global.wrongflash=!0,d.global.version=e.flashVersion);break;case"mouseover":j(f,this.options.hoverClass);break;case"mouseout":k(f,this.options.hoverClass),this.resetBridge();break;case"mousedown":j(f,this.options.activeClass);break;case"mouseup":k(f,this.options.activeClass);break;case"datarequested":var h=f.getAttribute("data-clipboard-target"),i=h?document.getElementById(h):null;if(i){var l=i.value||i.textContent||i.innerText;l&&this.setText(l)}else{var m=f.getAttribute("data-clipboard-text");m&&this.setText(m)}g=!1;break;case"complete":this.options.text=null}var n=this.handlers[c];if(n&&n.length){var o,p,q;for(o=0,p=n.length;p>o;o++)q=n[o],"string"==typeof q&&"function"==typeof window[q]&&(q=window[q]),"function"==typeof q&&r(q,f,this,e,g)}};x.prototype.glue=function(a){a=q(a);for(var b=0;b<a.length;b++)a.hasOwnProperty(b)&&a[b]&&1===a[b].nodeType&&-1===p(a[b],c)&&(c.push(a[b]),h(a[b],"mouseover",g));return this},x.prototype.unglue=function(a){a=q(a);for(var b=0;b<a.length;b++)if(a.hasOwnProperty(b)&&a[b]&&1===a[b].nodeType){i(a[b],"mouseover",g);var d=p(a[b],c);-1!==d&&c.splice(d,1)}return this},A.hoverClass="zeroclipboard-is-hover",A.activeClass="zeroclipboard-is-active",A.trustedOrigins=null,A.allowScriptAccess=null,x.detectFlashSupport=function(){var a=x.prototype._singleton&&x.prototype._singleton.options.debug||A.debug;return t("ZeroClipboard.detectFlashSupport",a),z()},x.prototype.setHandCursor=function(a){return t("ZeroClipboard.prototype.setHandCursor",this.options.debug),a="boolean"==typeof a?a:!!a,y.call(this,a),this.options.forceHandCursor=a,this},x.prototype.reposition=function(){return t("ZeroClipboard.prototype.reposition",this.options.debug),E.call(this)},x.prototype.receiveEvent=function(a,b){if(t("ZeroClipboard.prototype.receiveEvent",this.options.debug),"string"==typeof a&&a){var c=a.toLowerCase().replace(/^on/,"");c&&F.call(this,c,b)}},"function"==typeof define&&define.amd?define(["require","exports","module"],function(a,b,c){return B=c&&c.id||null,x}):"object"==typeof module&&module&&"object"==typeof module.exports&&module.exports?(C=module.id||null,module.exports=x):window.ZeroClipboard=x}();
+!function(){"use strict";function a(a){return a.replace(/,/g,".").replace(/[^0-9\.]/g,"")}function b(b){return parseFloat(a(b))>=10}var c,d={bridge:null,version:"0.0.0",noflash:null,wrongflash:null,ready:null},e={},f=0,g={},h=0,i={},j=function(){var a=/\-([a-z])/g,b=function(a,b){return b.toUpperCase()};return function(c){return c.replace(a,b)}}(),k=function(a,b){var c,d,e;return window.getComputedStyle?c=window.getComputedStyle(a,null).getPropertyValue(b):(d=j(b),c=a.currentStyle?a.currentStyle[d]:a.style[d]),"cursor"!==b||c&&"auto"!==c||(e=a.tagName.toLowerCase(),"a"!==e)?c:"pointer"},l=function(a){a||(a=window.event);var b;this!==window?b=this:a.target?b=a.target:a.srcElement&&(b=a.srcElement),F.activate(b)},m=function(a,b,c){a&&1===a.nodeType&&(a.addEventListener?a.addEventListener(b,c,!1):a.attachEvent&&a.attachEvent("on"+b,c))},n=function(a,b,c){a&&1===a.nodeType&&(a.removeEventListener?a.removeEventListener(b,c,!1):a.detachEvent&&a.detachEvent("on"+b,c))},o=function(a,b){if(!a||1!==a.nodeType)return a;if(a.classList)return a.classList.contains(b)||a.classList.add(b),a;if(b&&"string"==typeof b){var c=(b||"").split(/\s+/);if(1===a.nodeType)if(a.className){for(var d=" "+a.className+" ",e=a.className,f=0,g=c.length;g>f;f++)d.indexOf(" "+c[f]+" ")<0&&(e+=" "+c[f]);a.className=e.replace(/^\s+|\s+$/g,"")}else a.className=b}return a},p=function(a,b){if(!a||1!==a.nodeType)return a;if(a.classList)return a.classList.contains(b)&&a.classList.remove(b),a;if(b&&"string"==typeof b||void 0===b){var c=(b||"").split(/\s+/);if(1===a.nodeType&&a.className)if(b){for(var d=(" "+a.className+" ").replace(/[\n\t]/g," "),e=0,f=c.length;f>e;e++)d=d.replace(" "+c[e]+" "," ");a.className=d.replace(/^\s+|\s+$/g,"")}else a.className=""}return a},q=function(){var a,b,c,d=1;return"function"==typeof document.body.getBoundingClientRect&&(a=document.body.getBoundingClientRect(),b=a.right-a.left,c=document.body.offsetWidth,d=Math.round(b/c*100)/100),d},r=function(a,b){var c={left:0,top:0,width:0,height:0,zIndex:x(b)-1};if(a.getBoundingClientRect){var d,e,f,g=a.getBoundingClientRect();"pageXOffset"in window&&"pageYOffset"in window?(d=window.pageXOffset,e=window.pageYOffset):(f=q(),d=Math.round(document.documentElement.scrollLeft/f),e=Math.round(document.documentElement.scrollTop/f));var h=document.documentElement.clientLeft||0,i=document.documentElement.clientTop||0;c.left=g.left+d-h,c.top=g.top+e-i,c.width="width"in g?g.width:g.right-g.left,c.height="height"in g?g.height:g.bottom-g.top}return c},s=function(a,b){var c=!(b&&b.useNoCache===!1);return c?(-1===a.indexOf("?")?"?":"&")+"nocache="+(new Date).getTime():""},t=function(a){var b,c,d,e=[],f=[],g=[];if(a.trustedOrigins&&("string"==typeof a.trustedOrigins?f.push(a.trustedOrigins):"object"==typeof a.trustedOrigins&&"length"in a.trustedOrigins&&(f=f.concat(a.trustedOrigins))),a.trustedDomains&&("string"==typeof a.trustedDomains?f.push(a.trustedDomains):"object"==typeof a.trustedDomains&&"length"in a.trustedDomains&&(f=f.concat(a.trustedDomains))),f.length)for(b=0,c=f.length;c>b;b++)if(f.hasOwnProperty(b)&&f[b]&&"string"==typeof f[b]){if(d=A(f[b]),!d)continue;if("*"===d){g=[d];break}g.push.apply(g,[d,"//"+d,window.location.protocol+"//"+d])}return g.length&&e.push("trustedOrigins="+encodeURIComponent(g.join(","))),"string"==typeof a.amdModuleId&&a.amdModuleId&&e.push("amdModuleId="+encodeURIComponent(a.amdModuleId)),"string"==typeof a.cjsModuleId&&a.cjsModuleId&&e.push("cjsModuleId="+encodeURIComponent(a.cjsModuleId)),e.join("&")},u=function(a,b,c){if("function"==typeof b.indexOf)return b.indexOf(a,c);var d,e=b.length;for("undefined"==typeof c?c=0:0>c&&(c=e+c),d=c;e>d;d++)if(b.hasOwnProperty(d)&&b[d]===a)return d;return-1},v=function(a){if("string"==typeof a)throw new TypeError("ZeroClipboard doesn't accept query strings.");return a.length?a:[a]},w=function(a,b,c,d,e){e?window.setTimeout(function(){a.call(b,c,d)},0):a.call(b,c,d)},x=function(a){var b,c;return a&&("number"==typeof a&&a>0?b=a:"string"==typeof a&&(c=parseInt(a,10))&&!isNaN(c)&&c>0&&(b=c)),b||("number"==typeof I.zIndex&&I.zIndex>0?b=I.zIndex:"string"==typeof I.zIndex&&(c=parseInt(I.zIndex,10))&&!isNaN(c)&&c>0&&(b=c)),b||0},y=function(a,b){if(a&&b!==!1&&"undefined"!=typeof console&&console&&(console.warn||console.log)){var c="`"+a+"` is deprecated. See docs for more info:\n https://github.com/zeroclipboard/zeroclipboard/blob/master/docs/instructions.md#deprecations";console.warn?console.warn(c):console.log(c)}},z=function(){var a,b,c,d,e,f,g=arguments[0]||{};for(a=1,b=arguments.length;b>a;a++)if(null!=(c=arguments[a]))for(d in c)if(c.hasOwnProperty(d)){if(e=g[d],f=c[d],g===f)continue;void 0!==f&&(g[d]=f)}return g},A=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},B=function(){var a=function(a,b){var c,d,e;if(null!=a&&"*"!==b[0]&&("string"==typeof a&&(a=[a]),"object"==typeof a&&"length"in a))for(c=0,d=a.length;d>c;c++)if(a.hasOwnProperty(c)&&(e=A(a[c]))){if("*"===e){b.length=0,b.push("*");break}-1===u(e,b)&&b.push(e)}},b={always:"always",samedomain:"sameDomain",never:"never"};return function(c,d){var e,f=d.allowScriptAccess;if("string"==typeof f&&(e=f.toLowerCase())&&/^always|samedomain|never$/.test(e))return b[e];var g=A(d.moviePath);null===g&&(g=c);var h=[];a(d.trustedOrigins,h),a(d.trustedDomains,h);var i=h.length;if(i>0){if(1===i&&"*"===h[0])return"always";if(-1!==u(c,h))return 1===i&&c===g?"sameDomain":"always"}return"never"}}(),C=function(a){if(null==a)return[];if(Object.keys)return Object.keys(a);var b=[];for(var c in a)a.hasOwnProperty(c)&&b.push(c);return b},D=function(a){if(a)for(var b in a)a.hasOwnProperty(b)&&delete a[b];return a},E=function(){var a=!1;if("boolean"==typeof d.noflash)a=d.noflash===!1;else{if("function"==typeof ActiveXObject)try{new ActiveXObject("ShockwaveFlash.ShockwaveFlash")&&(a=!0)}catch(b){}!a&&navigator.mimeTypes["application/x-shockwave-flash"]&&(a=!0)}return a},F=function(a,b){return this instanceof F?(this.id=""+f++,g[this.id]={instance:this,elements:[],handlers:{}},a&&this.glue(a),"undefined"!=typeof b&&(y("new ZeroClipboard(elements, options)",I.debug),F.config(b)),this.options=F.config(),"boolean"!=typeof d.noflash&&(d.noflash=!E()),d.noflash===!1&&d.wrongflash!==!0&&null===d.bridge&&(d.wrongflash=!1,d.ready=!1,L()),void 0):new F(a,b)};F.prototype.setText=function(a){return a&&""!==a&&(e["text/plain"]=a,d.ready===!0&&d.bridge&&d.bridge.setText(a)),this},F.prototype.setSize=function(a,b){return d.ready===!0&&d.bridge&&d.bridge.setSize(a,b),this};var G=function(a){d.ready===!0&&d.bridge&&d.bridge.setHandCursor(a)};F.prototype.destroy=function(){this.unglue(),this.off(),delete g[this.id]};var H=function(){var a,b,c,d=[],e=C(g);for(a=0,b=e.length;b>a;a++)c=g[e[a]].instance,c&&c instanceof F&&d.push(c);return d};F.version="1.3.0-beta.1";var I={moviePath:"ZeroClipboard.swf",trustedDomains:window.location.host?[window.location.host]:[],useNoCache:!0,forceHandCursor:!1,zIndex:999999999,debug:!0,title:null};F.config=function(a){"object"==typeof a&&null!==a&&z(I,a);{if("string"!=typeof a||!a){var b={};for(var c in I)I.hasOwnProperty(c)&&(b[c]="object"==typeof I[c]&&null!==I[c]?"length"in I[c]?I[c].slice(0):z({},I[c]):I[c]);return b}if(I.hasOwnProperty(a))return I[a]}},F.destroy=function(){F.deactivate();for(var a in g)if(g.hasOwnProperty(a)&&g[a]){var b=g[a].instance;b&&"function"==typeof b.destroy&&b.destroy()}var c=M(d.bridge);c&&c.parentNode&&(c.parentNode.removeChild(c),d.ready=null,d.bridge=null)},F.activate=function(a){c&&(p(c,I.hoverClass),p(c,I.activeClass)),c=a,o(a,I.hoverClass),N();var b=I.title||a.getAttribute("title");if(b){var e=M(d.bridge);e&&e.setAttribute("title",b)}var f=I.forceHandCursor===!0||"pointer"===k(a,"cursor");G(f)},F.deactivate=function(){var a=M(d.bridge);a&&(a.style.left="0px",a.style.top="-9999px",a.removeAttribute("title")),c&&(p(c,I.hoverClass),p(c,I.activeClass),c=null)};var J=null,K=null,L=function(){var a,b,c=document.getElementById("global-zeroclipboard-html-bridge");if(!c){var e=F.config();e.amdModuleId=J,e.cjsModuleId=K;var f=B(window.location.host,I),g=t(e),h=I.moviePath+s(I.moviePath,I),i=' <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" id="global-zeroclipboard-flash-bridge" width="100%" height="100%"> <param name="movie" value="'+h+'"/> <param name="allowScriptAccess" value="'+f+'"/> <param name="scale" value="exactfit"/> <param name="loop" value="false"/> <param name="menu" value="false"/> <param name="quality" value="best" /> <param name="bgcolor" value="#ffffff"/> <param name="wmode" value="transparent"/> <param name="flashvars" value="'+g+'"/> <embed src="'+h+'" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="100%" height="100%" name="global-zeroclipboard-flash-bridge" allowScriptAccess="'+f+'" allowFullScreen="false" type="application/x-shockwave-flash" wmode="transparent" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="'+g+'" scale="exactfit"> </embed> </object>';c=document.createElement("div"),c.id="global-zeroclipboard-html-bridge",c.setAttribute("class","global-zeroclipboard-container"),c.style.position="absolute",c.style.left="0px",c.style.top="-9999px",c.style.width="15px",c.style.height="15px",c.style.zIndex=""+x(I.zIndex),document.body.appendChild(c),c.innerHTML=i}a=document["global-zeroclipboard-flash-bridge"],a&&(b=a.length)&&(a=a[b-1]),d.bridge=a||c.children[0].lastElementChild},M=function(a){for(var b=/^object|embed$/,c=a&&a.parentNode;c&&b.test(c.tagName.toLowerCase())&&c.parentNode;)c=c.parentNode;return c||null},N=function(){if(c){var a=r(c,I.zIndex),b=M(d.bridge);b&&(b.style.top=a.top+"px",b.style.left=a.left+"px",b.style.width=a.width+"px",b.style.height=a.height+"px",b.style.zIndex=a.zIndex+1),d.ready===!0&&d.bridge&&d.bridge.setSize(a.width,a.height)}return this};F.dispatch=function(a,b){if("string"==typeof a&&a){var d=a.toLowerCase().replace(/^on/,"");if(d)for(var e=c?P(c):H(),f=0,g=e.length;g>f;f++)O.call(e[f],d,b)}},F.prototype.on=function(a,b){for(var c=a.toString().split(/\s+/),e={},f=g[this.id]&&g[this.id].handlers,h=0,i=c.length;i>h;h++)a=c[h].toLowerCase().replace(/^on/,""),e[a]=!0,f[a]||(f[a]=[]),f[a].push(b);return e.noflash&&d.noflash&&O.call(this,"onNoFlash",{}),e.wrongflash&&d.wrongflash&&O.call(this,"onWrongFlash",{flashVersion:d.version}),e.load&&d.ready&&O.call(this,"onLoad",{flashVersion:d.version}),this},F.prototype.off=function(a,b){var c,d,e,f,h,i=g[this.id]&&g[this.id].handlers;if(0===arguments.length?f=C(i):"string"==typeof a&&a&&(f=a.split(/\s+/)),f&&f.length)for(c=0,d=f.length;d>c;c++)if(a=f[c].toLowerCase().replace(/^on/,""),h=i[a],h&&h.length)if(b)for(e=u(b,h);-1!==e;)h.splice(e,1),e=u(b,h,e);else i[a].length=0;return this},F.prototype.handlers=function(a){var b,c=null,d=g[this.id]&&g[this.id].handlers;if(d){if("string"==typeof a&&a)return d[a]?d[a].slice(0):null;c={};for(b in d)d.hasOwnProperty(b)&&d[b]&&(c[b]=d[b].slice(0))}return c};var O=function(f,h){f=f.toLowerCase().replace(/^on/,"");var i=h&&h.flashVersion&&a(h.flashVersion)||null,j=c,k=!0;switch(f){case"load":if(i){if(!b(i))return O.call(this,"onWrongFlash",{flashVersion:i}),void 0;d.wrongflash=!1,d.ready=!0,d.version=i}break;case"wrongflash":i&&!b(i)&&(d.wrongflash=!0,d.ready=!1,d.version=i);break;case"mouseover":o(j,I.hoverClass);break;case"mouseout":F.deactivate();break;case"mousedown":o(j,I.activeClass);break;case"mouseup":p(j,I.activeClass);break;case"datarequested":var l=j.getAttribute("data-clipboard-target"),m=l?document.getElementById(l):null;if(m){var n=m.value||m.textContent||m.innerText;n&&this.setText(n)}else{var q=j.getAttribute("data-clipboard-text");q&&this.setText(q)}k=!1;break;case"complete":D(e)}var r=g[this.id]&&g[this.id].handlers[f];if(r&&r.length){var s,t,u;for(s=0,t=r.length;t>s;s++)u=r[s],"string"==typeof u&&"function"==typeof window[u]&&(u=window[u]),"function"==typeof u&&w(u,j,this,h,k)}};F.prototype.glue=function(a){a=v(a);for(var b=0;b<a.length;b++)if(a.hasOwnProperty(b)&&a[b]&&1===a[b].nodeType){a[b].zcClippingId?-1===u(this.id,i[a[b].zcClippingId])&&i[a[b].zcClippingId].push(this.id):(a[b].zcClippingId="zcClippingId_"+h++,i[a[b].zcClippingId]=[this.id],m(a[b],"mouseover",l));var c=g[this.id].elements;-1===u(a[b],c)&&c.push(a[b])}return this},F.prototype.unglue=function(a){var b=g[this.id];if(b){"undefined"==typeof a&&(a=b.elements.slice(0)),a=v(a);for(var c=0;c<a.length;c++)if(a.hasOwnProperty(c)&&a[c]&&1===a[c].nodeType){for(var d=b.elements,e=0;-1!==(e=u(a[c],d,e));)d.splice(e,1);var f=i[a[c].zcClippingId];if(f){for(e=0;-1!==(e=u(this.id,f,e));)f.splice(e,1);0===f.length&&(n(a[c],"mouseover",l),delete a[c].zcClippingId)}}}return this},F.prototype.elements=function(){var a=g[this.id];return a&&a.elements?a.elements.slice(0):[]};var P=function(a){var b,c,d,e,f,h=[];if(a&&1===a.nodeType&&(b=a.zcClippingId)&&i.hasOwnProperty(b)&&(c=i[b],c&&c.length))for(d=0,e=c.length;e>d;d++)f=g[c[d]].instance,f&&f instanceof F&&h.push(f);return h};I.hoverClass="zeroclipboard-is-hover",I.activeClass="zeroclipboard-is-active",I.trustedOrigins=null,I.allowScriptAccess=null,F.detectFlashSupport=function(){var a=I.debug;return y("ZeroClipboard.detectFlashSupport",a),E()},F.prototype.setHandCursor=function(a){return y("ZeroClipboard.prototype.setHandCursor",I.debug),a="boolean"==typeof a?a:!!a,G(a),I.forceHandCursor=a,this},F.prototype.reposition=function(){return y("ZeroClipboard.prototype.reposition",I.debug),N()},F.prototype.receiveEvent=function(a,b){if(y("ZeroClipboard.prototype.receiveEvent",I.debug),"string"==typeof a&&a){var c=a.toLowerCase().replace(/^on/,"");c&&O.call(this,c,b)}},F.prototype.setCurrent=function(a){return y("ZeroClipboard.prototype.setCurrent",I.debug),F.activate(a),this},F.prototype.resetBridge=function(){return y("ZeroClipboard.prototype.resetBridge",I.debug),F.deactivate(),this},F.prototype.setTitle=function(a){if(y("ZeroClipboard.prototype.setTitle",I.debug),a=a||I.title||c&&c.getAttribute("title")){var b=M(d.bridge);b&&b.setAttribute("title",a)}return this},F.setDefaults=function(a){y("ZeroClipboard.setDefaults",I.debug),F.config(a)},F.prototype.addEventListener=function(){return y("ZeroClipboard.prototype.addEventListener",I.debug),this.on.apply(this,[].slice.call(arguments,0))},F.prototype.removeEventListener=function(){return y("ZeroClipboard.prototype.removeEventListener",I.debug),this.off.apply(this,[].slice.call(arguments,0))},F.prototype.ready=function(){return y("ZeroClipboard.prototype.ready",I.debug),d.ready===!0},"function"==typeof define&&define.amd?define(["require","exports","module"],function(a,b,c){return J=c&&c.id||null,F}):"object"==typeof module&&module&&"object"==typeof module.exports&&module.exports?(K=module.id||null,module.exports=F):window.ZeroClipboard=F}();
View
BIN  ZeroClipboard.swf
Binary file not shown
View
2  composer.json
@@ -1,7 +1,7 @@
{
"name": "zeroclipboard/zeroclipboard",
"description": "The ZeroClipboard library provides an easy way to copy text to the clipboard using an invisible Adobe Flash movie and a JavaScript interface.",
- "version": "1.3.0-beta.1",
+ "version": "1.3.0-beta.1",
"type": "library",
"keywords": ["flash","clipboard","copy","cut","paste","zclip","clip","clippy"],
"license": "MIT",
View
129 docs/instructions.md
@@ -35,23 +35,23 @@ directory as your web page, then it will work out of the box. However, if the S
to set the URL like this (place this code _after_ the script tag):
```js
-ZeroClipboard.setDefaults( { moviePath: 'http://YOURSERVER/path/ZeroClipboard.swf' } );
+ZeroClipboard.config( { moviePath: 'http://YOURSERVER/path/ZeroClipboard.swf' } );
```
## Clients
-Now you are ready to create one or more _Clients_. A client is a single instance of the clipboard library on the page,
+Now you are ready to create one or more _clients_. A client is a single instance of the clipboard library on the page,
linked to one or more DOM elements. Here is how to create a client instance:
```js
-var clip = new ZeroClipboard();
+var client = new ZeroClipboard();
```
-You can also include an element or array of elements in the new client. * This example uses jQuery to find the button.
+You can also include an element or array of elements in the new client. _**This example uses jQuery to find the button._
```js
-var clip = new ZeroClipboard($("#my-button"));
+var client = new ZeroClipboard($("#my-button"));
```
Next, you can set some options.
@@ -81,16 +81,21 @@ var _defaults = {
// Debug enabled: send `console` messages with deprecation warnings, etc.
debug: true,
+ // Sets the title of the `div` encapsulating the Flash object
+ title: null,
+
+
/** @deprecated */
- // The class used to hover over the object
+ // The class used to indicate that a glued element is being hovered over
hoverClass: "zeroclipboard-is-hover",
/** @deprecated */
- // The class used to set object active
+ // The class used to indicate that a glued element is active (is being clicked)
activeClass: "zeroclipboard-is-active",
/** @deprecated */
- // [Deprecated] SWF inbound scripting policy: page origins that the SWF should trust. (single string or array of strings)
+ // DEPRECATED!!! Use `trustedDomains` instead!
+ // SWF inbound scripting policy: page origins that the SWF should trust. (single string or array of strings)
trustedOrigins: null,
/** @deprecated */
@@ -99,14 +104,14 @@ var _defaults = {
};
```
-You can override the defaults by making a call like `ZeroClipboard.setDefaults({ moviePath: "new/path" });` before you create any clients.
+You can override the defaults by making a call like `ZeroClipboard.config({ moviePath: "new/path" });` before you create any clients.
You can also set the options when creating a new client by passing an optional "options" object, e.g.
```js
-var clip = new ZeroClipboard($("#d_clip_button"), { moviePath: "new/path" });`
+var client = new ZeroClipboard($("#d_clip_button"), { moviePath: "new/path" });`
```
-However, this per-client options overriding is deprecated as of v1.3.0.
+However, this per-client options overriding is deprecated as of v1.3.0 and will be removed in v2.0.0.
Whenever possible, we recommend that you change the defaults rather than changing options per client. This works out
better in most situations as:
@@ -169,10 +174,10 @@ If you find yourself in this situation (as in [Issue #170](https://github.com/ze
Setting the clipboard text can be done in 4 ways:
-1. Add a `dataRequested` event handler in which you call `clip.setText` to set the appropriate text. This event is triggered every time ZeroClipboard tries to inject into the clipboard. Example:
+1. Add a `dataRequested` event handler in which you call `client.setText` to set the appropriate text. This event is triggered every time ZeroClipboard tries to inject into the clipboard. Example:
```js
- clip.on( 'dataRequested', function (client, args) {
+ client.on( 'dataRequested', function (client, args) {
client.setText( "Copy me!" );
});
```
@@ -203,14 +208,14 @@ Setting the clipboard text can be done in 4 ways:
<button id="my-button" data-clipboard-text="Copy me!">Copy to Clipboard</button>
```
-4. Set the text via `clip.setText` property. You can call this function at any time; when the page first loads, or later like in a `dataRequested` event handler. Example:
+4. Set the text via `client.setText` property. You can call this function at any time; when the page first loads, or later like in a `dataRequested` event handler. Example:
```js
- clip.setText( "Copy me!" );
+ client.setText( "Copy me!" );
```
- The important caveat of using `clip.setText` is that the text it sets is **transient** and _will only be used for a single copy operation_. As such, we do not particularly
- recommend using `clip.setText` other than inside of a `dataRequested` event handler; however, the API will not prevent you from using it in other ways.
+ The important caveat of using `client.setText` is that the text it sets is **transient** and _will only be used for a single copy operation_. As such, we do not particularly
+ recommend using `client.setText` other than inside of a `dataRequested` event handler; however, the API will not prevent you from using it in other ways.
### Gluing
@@ -221,10 +226,10 @@ The Flash movie receives the click event and copies the text to the clipboard.
To glue elements, you must pass an element, or array of elements to the glue function.
-Here is how to glue your clip library instance to a DOM element:
+Here is how to glue your client library instance to a DOM element:
```js
-clip.glue( document.getElementById('d_clip_button') );
+client.glue( document.getElementById('d_clip_button') );
```
You can pass in a reference to the actual DOM element object itself or an array of DOM objects. The rest all happens automatically -- the movie is created, all your options set, and it is floated above the element, awaiting clicks from the user.
@@ -239,7 +244,7 @@ You can pass in a reference to the actual DOM element object itself or an array
And the code:
```js
-var clip = new ZeroClipboard( $("button#my-button") );
+var client = new ZeroClipboard( $("button#my-button") );
```
@@ -269,7 +274,7 @@ These classes are for a DOM element with an ID: "d_clip_button". The "zeroclipb
The clipboard library allows you set a number of different event handlers. These are all set by calling the `on()` method, as in this example:
```js
-clip.on( 'load', my_load_handler );
+client.on( 'load', my_load_handler );
```
The first argument is the name of the event, and the second is a reference to your function. The function may be passed by name (string) or an actual reference to the function object
@@ -279,7 +284,7 @@ Your custom function will be passed at least one argument -- a reference to the
Event handlers can be removed by calling the `off()` method, which has the same method signature as `on()`:
```js
-clip.off( 'load', my_load_handler );
+client.off( 'load', my_load_handler );
```
@@ -288,7 +293,7 @@ clip.off( 'load', my_load_handler );
The `load` event is fired when the Flash movie completes loading and is ready for action. Please note that you don't need to listen for this event to set options -- those are automatically passed to the movie if you call them before it loads. Example use:
```js
-clip.on( 'load', function ( client, args ) {
+client.on( 'load', function ( client, args ) {
alert( "movie has loaded" );
});
```
@@ -308,7 +313,7 @@ The handler is passed these options to the `args`
The `mouseover` event is fired when the user's mouse pointer enters the Flash movie. You can use this to simulate a rollover effect on your DOM element, however see *CSS Effects* for an easier way to do this. Example use:
```js
-clip.on( 'mouseover', function ( client, args ) {
+client.on( 'mouseover', function ( client, args ) {
alert( "mouse is over movie" );
});
```
@@ -334,7 +339,7 @@ The handler is passed these options to the `args`
The `mouseout` event is fired when the user's mouse pointer leaves the Flash movie. You can use this to simulate a rollover effect on your DOM element, however see *CSS Effects* for an easier way to do this. Example use:
```js
-clip.on( 'mouseout', function ( client, args ) {
+client.on( 'mouseout', function ( client, args ) {
alert( "mouse has left movie" );
} );
```
@@ -360,7 +365,7 @@ The handler is passed these options to the `args`
The `mousedown` event is fired when the user clicks on the Flash movie. Please note that this does not guarantee that the user will release the mouse button while still over the movie (i.e. resulting in a click). You can use this to simulate a click effect on your DOM element, however see *CSS Effects* for an easier way to do this. Example use:
```js
-clip.on( 'mousedown', function ( client, args ) {
+client.on( 'mousedown', function ( client, args ) {
alert( "mouse button is down" );
} );
```
@@ -386,7 +391,7 @@ The handler is passed these options to the `args`
The `mouseup` event is fired when the user releases the mouse button (having first pressed the mouse button while hovering over the movie). Please note that this does not guarantee that the mouse cursor is still over the movie (i.e. resulting in a click). You can use this to simulate a click effect on your DOM element, however see *CSS Effects* for an easier way to do this. Example use:
```js
-clip.on( 'mouseup', function ( client, args ) {
+client.on( 'mouseup', function ( client, args ) {
alert( "mouse button is up" );
} );
```
@@ -412,7 +417,7 @@ The handler is passed these options to the `args`
The `complete` event is fired when the text is successfully copied to the clipboard. Example use:
```js
-clip.on( 'complete', function ( client, args ) {
+client.on( 'complete', function ( client, args ) {
alert("Copied text to clipboard: " + args.text );
} );
```
@@ -440,7 +445,7 @@ The handler is passed these options to the `args`
The `noflash` event is fired when the user doesn't have flash installed on their system
```js
-clip.on( 'noflash', function ( client, args ) {
+client.on( 'noflash', function ( client, args ) {
alert("You don't support flash");
} );
```
@@ -460,7 +465,7 @@ The handler is passed these options to the `args`
The `wrongflash` event is fired when the user has the wrong version of flash. ZeroClipboard supports version 10 and up.
```js
-clip.on( 'wrongflash', function ( client, args ) {
+client.on( 'wrongflash', function ( client, args ) {
alert("Your flash is too old " + args.flashVersion);
} );
```
@@ -477,11 +482,11 @@ The handler is passed these options to the `args`
#### dataRequested
-On mousedown, the flash object will check and see if the `clipText` has been set. If it hasn't, then it will fire off a `dataRequested` event. If the html object has `data-clipboard-text` or `data-clipboard-target` then ZeroClipboard will take care of getting the data. However if it hasn't been set, then it will be up to you to `clip.setText` from that method. Which will complete the loop.
+On mousedown, the Flash object will check and see if the clipboard text has been set. If it hasn't, then it will fire off a `dataRequested` event. If the html object has `data-clipboard-text` or `data-clipboard-target` then ZeroClipboard will take care of getting the data. However if it hasn't been set, then it will be up to you to `client.setText` from that method. Which will complete the loop.
```js
-clip.on( 'dataRequested', function ( client, args ) {
- clip.setText( 'Copied to clipboard.' );
+client.on( 'dataRequested', function ( client, args ) {
+ client.setText( 'Copied to clipboard.' );
} );
```
@@ -512,7 +517,7 @@ Here is a quick example using as few calls as possible:
<script type="text/javascript" src="ZeroClipboard.js"></script>
<script type="text/javascript">
- var clip = new ZeroClipboard( document.getElementById('d_clip_button') );
+ var client = new ZeroClipboard( document.getElementById('d_clip_button') );
</script>
</body>
</html>
@@ -546,31 +551,30 @@ Here is a complete example which exercises every option and event handler:
<div id="d_clip_button" data-clipboard-text="Copy Me!">Copy To Clipboard</div>
<script type="text/javascript">
- var clip = new ZeroClipboard( $('#d_clip_button') );
+ var client = new ZeroClipboard( $('#d_clip_button') );
- clip.on( 'load', function(client) {
+ client.on( 'load', function(client) {
// alert( "movie is loaded" );
- } );
-
- clip.on( 'complete', function(client, args) {
- alert("Copied text to clipboard: " + args.text );
- } );
- clip.on( 'mouseover', function(client) {
- // alert("mouse over");
- } );
+ client.on( 'complete', function(client, args) {
+ alert("Copied text to clipboard: " + args.text );
+ } );
- clip.on( 'mouseout', function(client) {
- // alert("mouse out");
- } );
+ client.on( 'mouseover', function(client) {
+ // alert("mouse over");
+ } );
- clip.on( 'mousedown', function(client) {
+ client.on( 'mouseout', function(client) {
+ // alert("mouse out");
+ } );
- // alert("mouse down");
- } );
+ client.on( 'mousedown', function(client) {
+ // alert("mouse down");
+ } );
- clip.on( 'mouseup', function(client) {
- // alert("mouse up");
+ client.on( 'mouseup', function(client) {
+ // alert("mouse up");
+ } );
} );
</script>
@@ -608,7 +612,7 @@ decisions of how _your_ site should handle each of these situations.
this transformation by utilizing the `dataRequested` event handler, e.g.
```js
- clip.on('dataRequested', function(client, args) {
+ client.on('dataRequested', function(client, args) {
var text = document.getElementById('yourTextArea').value;
var windowsText = text.replace(/\n/g, '\r\n');
client.setText(windowsText);
@@ -622,7 +626,7 @@ decisions of how _your_ site should handle each of these situations.
By default, ZeroClipboard will issue deprecation warnings to the developer `console`. To disable this, set the
following option:
```js
-ZeroClipboard.setDefaults({ debug: false });`
+ZeroClipboard.config({ debug: false });`
```
The current list of deprecations includes:
@@ -645,3 +649,20 @@ The current list of deprecations includes:
- `new ZeroClipboard(elements, options)` &rarr; as of [v1.3.0], removing in [v2.0.0]
- Most options actually have a global effect rather than a per-client effect, so we are removing the ability to
customize options per-client to help avoid confusion. The constructor `new ZeroClipboard(elements)` will remain.
+ - `ZeroClipboard.prototype.addEventListener` &rarr; as of [v1.3.0], removing in [v2.0.0]
+ - Use `ZeroClipboard.prototype.on` instead!
+ - `ZeroClipboard.prototype.removeEventListener` &rarr; as of [v1.3.0], removing in [v2.0.0]
+ - Use `ZeroClipboard.prototype.off` instead!
+ - `ZeroClipboard.prototype.setCurrent` &rarr; as of [v1.3.0], removing in [v2.0.0]
+ - Use `ZeroClipboard.activate` instead!
+ - `ZeroClipboard.prototype.resetBridge` &rarr; as of [v1.3.0], removing in [v2.0.0]
+ - Use `ZeroClipboard.deactivate` instead!
+ - `ZeroClipboard.prototype.setTitle` &rarr; as of [v1.3.0], removing in [v2.0.0]
+ - Use the `title` config option instead!
+ - `ZeroClipboard.setDefaults` &rarr; as of [v1.3.0], removing in [v2.0.0]
+ - Use `ZeroClipboard.config` instead!
+ - `ZeroClipboard#handlers` &rarr; as of [v1.3.0], removed in [v1.3.0]
+ - Use the `ZeroClipboard.prototype.handlers` method instead!
+ - `ZeroClipboard.prototype.ready` &rarr; as of [v1.3.0], removing in [v2.0.0]
+ - For v1.x, use the `ZeroClipboard.prototype.on("load", ...);` instead!
+ - For v2.x, use the `ZeroClipboard.prototype.on("ready", ...);` instead!
View
162 src/javascript/ZeroClipboard/client.js
@@ -5,115 +5,143 @@
*/
var ZeroClipboard = function (elements, /** @deprecated */ options) {
- // If the elements exist glue
- if (elements) (ZeroClipboard.prototype._singleton || this).glue(elements);
+ // Ensure the constructor is invoked with the `new` keyword, even if the user forgets it
+ if (!(this instanceof ZeroClipboard)) {
+ return new ZeroClipboard(elements, options);
+ }
- // If there's a client already, return the singleton
- if (ZeroClipboard.prototype._singleton) return ZeroClipboard.prototype._singleton;
+ // Assign an ID to the client instance
+ this.id = "" + (clientIdCounter++);
- ZeroClipboard.prototype._singleton = this;
+ // Create the meta information store for this client
+ _clientMeta[this.id] = {
+ instance: this,
+ elements: [],
+ handlers: {}
+ };
- // Warn about use of deprecated constructor signature
- if (options) {
- _deprecationWarning("new ZeroClipboard(elements, options)", this.options.debug);
+ // If the elements argument exists, glue it
+ if (elements) {
+ this.glue(elements);
}
- // Set and override the defaults
- this.options = _extend({}, _defaults, options);
+ // Warn about use of deprecated constructor signature
+ if (typeof options !== "undefined") {
+ _deprecationWarning("new ZeroClipboard(elements, options)", _globalConfig.debug);
+
+ // Set and override the defaults
+ ZeroClipboard.config(options);
+ }
- // event handlers
- this.handlers = {};
+ /** @deprecated in [v1.3.0], slated for removal in [v2.0.0]. See docs for more info. */
+ this.options = ZeroClipboard.config();
// Flash status
- if (typeof flashState.global.noflash !== "boolean") {
- flashState.global.noflash = !_detectFlashSupport();
- }
- if (!flashState.clients.hasOwnProperty(this.options.moviePath)) {
- flashState.clients[this.options.moviePath] = {
- ready: false
- };
+ if (typeof flashState.noflash !== "boolean") {
+ flashState.noflash = !_detectFlashSupport();
}
// Setup the Flash <-> JavaScript bridge
- if (flashState.global.noflash === false) {
- _bridge();
+ if (flashState.noflash === false && flashState.wrongflash !== true) {
+ if (flashState.bridge === null) {
+ flashState.wrongflash = false;
+ flashState.ready = false;
+ _bridge();
+ }
}
-
};
/*
- * Sets the current html object that the flash object should overlay.
- * This will put the global flash object on top of the current object and set
- * the text and title from the html object.
+ * Sends a signal to the Flash object to set the clipboard text.
*
* returns object instance
*/
-ZeroClipboard.prototype.setCurrent = function (element) {
-
- // What element is current
- currentElement = element;
-
- _reposition.call(this);
-
- // If the dom element has a title
- var titleAttr = element.getAttribute("title");
- if (titleAttr) {
- this.setTitle(titleAttr);
+ZeroClipboard.prototype.setText = function (newText) {
+ if (newText && newText !== "") {
+ _clipData["text/plain"] = newText;
+ if (flashState.ready === true && flashState.bridge) {
+ flashState.bridge.setText(newText);
+ }
+ else {
+ //
+ // TODO: Fix Issue #295?
+ //
+ }
}
-
- // If the element has a pointer style, set to hand cursor
- var useHandCursor = this.options.forceHandCursor === true || _getStyle(element, "cursor") === "pointer";
- // Update the hand cursor state without updating the `forceHandCursor` option
- _setHandCursor.call(this, useHandCursor);
-
return this;
};
+
/*
- * Sends a signal to the flash object to set the clipboard text.
+ * Sends a signal to the Flash object to change the stage size/dimensions.
*
* returns object instance
*/
-ZeroClipboard.prototype.setText = function (newText) {
- if (newText && newText !== "") {
- this.options.text = newText;
- if (this.ready()) this.flashBridge.setText(newText);
+ZeroClipboard.prototype.setSize = function (width, height) {
+ if (flashState.ready === true && flashState.bridge) {
+ flashState.bridge.setSize(width, height);
+ }
+ else {
+ //
+ // TODO: ???
+ //
}
-
return this;
};
+
/*
- * Adds a title="" attribute to the htmlBridge to give it tooltip capabiities
+ * @private
*
- * returns object instance
+ * Sends a signal to the Flash object to display the hand cursor if true.
+ * Does NOT update the value of the `forceHandCursor` option.
+ *
+ * returns nothing
*/
-ZeroClipboard.prototype.setTitle = function (newTitle) {
- if (newTitle && newTitle !== "") this.htmlBridge.setAttribute("title", newTitle);
-
- return this;
+var _setHandCursor = function (enabled) {
+ if (flashState.ready === true && flashState.bridge) {
+ flashState.bridge.setHandCursor(enabled);
+ }
+ else {
+ //
+ // TODO: ???
+ //
+ }
};
+
/*
- * Sends a signal to the flash object to change the stage size.
+ * Self-destruction and clean up everything for a single client.
*
- * returns object instance
+ * returns nothing
*/
-ZeroClipboard.prototype.setSize = function (width, height) {
- if (this.ready()) this.flashBridge.setSize(width, height);
+ZeroClipboard.prototype.destroy = function () {
+ // unglue all the elements
+ this.unglue();
- return this;
+ // Remove all event handlers
+ this.off();
+
+ // Delete the client's metadata store
+ delete _clientMeta[this.id];
};
+
/*
- * @private
+ * Get all clients.
*
- * Sends a signal to the flash object to display the hand cursor if true.
- * Does NOT update the value of the `forceHandCursor` option.
- *
- * returns nothing
+ * returns array of clients
*/
-var _setHandCursor = function (enabled) {
- if (this.ready()) this.flashBridge.setHandCursor(enabled);
-};
+var _getAllClients = function () {
+ var i, len, client,
+ clients = [],
+ clientIds = _objectKeys(_clientMeta);
+ for (i = 0, len = clientIds.length; i < len; i++) {
+ client = _clientMeta[clientIds[i]].instance;
+ if (client && client instanceof ZeroClipboard) {
+ clients.push(client);
+ }
+ }
+ return clients;
+};
View
154 src/javascript/ZeroClipboard/core.js
@@ -1,46 +1,154 @@
ZeroClipboard.version = "<%= version %>";
// ZeroClipboard options defaults
-var _defaults = {
- moviePath: "ZeroClipboard.swf", // URL to movie
- trustedDomains: [window.location.host], // Page domains that the SWF should trust (single string or array of strings)
+var _globalConfig = {
+ // URL to movie
+ moviePath: "ZeroClipboard.swf",
- /** @private */
- text: null, // The text to be copied
+ // SWF inbound scripting policy: page domains that the SWF should trust. (single string or array of strings)
+ trustedDomains: window.location.host ? [window.location.host] : [],
- useNoCache: true, // Include a nocache query parameter on requests for the SWF
- forceHandCursor: false, // Forcibly set the hand cursor ("pointer") for all glued elements
- zIndex: 999999999, // The z-index used by the Flash object. Max value (32-bit): 2147483647
- debug: true // Debug enabled: send `console` messages with deprecation warnings, etc.
+ // Include a nocache query parameter on requests for the SWF
+ useNoCache: true,
+
+ // Forcibly set the hand cursor ("pointer") for all glued elements
+ forceHandCursor: false,
+
+ // The z-index used by the Flash object. Max value (32-bit): 2147483647
+ zIndex: 999999999,
+
+ // Debug enabled: send `console` messages with deprecation warnings, etc.
+ debug: true,
+
+ // Sets the title of the `div` encapsulating the Flash object
+ title: null
};
+
/*
- * Set defaults.
+ * Update or get a copy of the ZeroClipboard global configuration.
*
- * returns nothing
+ * returns a copy of the updated configuration
*/
-ZeroClipboard.setDefaults = function (options) {
- _extend(_defaults, options);
+ZeroClipboard.config = function (options) {
+ if (typeof options === "object" && options !== null) {
+ _extend(_globalConfig, options);
+ }
+ if (typeof options === "string" && options) {
+ if (_globalConfig.hasOwnProperty(options)) {
+ return _globalConfig[options];
+ }
+ // else `return undefined;`
+ return;
+ }
+ // Make a deep copy of the config object
+ var copy = {};
+ for (var prop in _globalConfig) {
+ if (_globalConfig.hasOwnProperty(prop)) {
+ if (typeof _globalConfig[prop] === "object" && _globalConfig[prop] !== null) {
+ if ("length" in _globalConfig[prop]) {
+ copy[prop] = _globalConfig[prop].slice(0);
+ }
+ else {
+ copy[prop] = _extend({}, _globalConfig[prop]);
+ }
+ }
+ else {
+ copy[prop] = _globalConfig[prop];
+ }
+ }
+ }
+ return copy;
};
+
/*
* Self-destruction and clean up everything
*
* returns nothing
*/
ZeroClipboard.destroy = function () {
- // If there is an existing singleton
- if (ZeroClipboard.prototype._singleton) {
- // unglue all the elements
- ZeroClipboard.prototype._singleton.unglue(gluedElements);
+ // Deactivate the active element, if any
+ ZeroClipboard.deactivate();
- var bridge = ZeroClipboard.prototype._singleton.htmlBridge;
+ // Invoke `destroy` on each client instance
+ for (var clientId in _clientMeta) {
+ if (_clientMeta.hasOwnProperty(clientId) && _clientMeta[clientId]) {
+ var client = _clientMeta[clientId].instance;
+ if (client && typeof client.destroy === "function") {
+ client.destroy();
+ }
+ }
+ }
- // remove the bridge
- if (bridge && bridge.parentNode) {
- bridge.parentNode.removeChild(bridge);
+ // Remove the Flash bridge
+ var htmlBridge = _getHtmlBridge(flashState.bridge);
+ if (htmlBridge && htmlBridge.parentNode) {
+ htmlBridge.parentNode.removeChild(htmlBridge);
+ flashState.ready = null;
+ flashState.bridge = null;
+ }
+};
+
+
+/*
+ * 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 nothing
+ */
+ZeroClipboard.activate = function(element) {
+ // "Ignore" the currently active element
+ if (currentElement) {
+ _removeClass(currentElement, _globalConfig.hoverClass);
+ _removeClass(currentElement, _globalConfig.activeClass);
+ }
+
+ // Mark the element as currently activated
+ currentElement = element;
+
+ // Add the hover class
+ _addClass(element, _globalConfig.hoverClass);
+
+ // Move the Flash object
+ _reposition();
+
+ // If the element has a title, mimic it
+ var newTitle = _globalConfig.title || element.getAttribute("title");
+ if (newTitle) {
+ var htmlBridge = _getHtmlBridge(flashState.bridge);
+ if (htmlBridge) {
+ htmlBridge.setAttribute("title", newTitle);
}
+ }
+
+ // If the element has a pointer style, set to hand cursor
+ var useHandCursor = _globalConfig.forceHandCursor === true || _getStyle(element, "cursor") === "pointer";
+ // Update the hand cursor state without updating the `forceHandCursor` option
+ _setHandCursor(useHandCursor);
+};
+
+
+/*
+ * 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 nothing
+ */
+ZeroClipboard.deactivate = function() {
+ // Hide the Flash object off-screen
+ var htmlBridge = _getHtmlBridge(flashState.bridge);
+ if (htmlBridge) {
+ htmlBridge.style.left = "0px";
+ htmlBridge.style.top = "-9999px";
+ htmlBridge.removeAttribute("title");
+ }
- // delete the client object
- delete ZeroClipboard.prototype._singleton;
+ // "Ignore" the currently active element
+ if (currentElement) {
+ _removeClass(currentElement, _globalConfig.hoverClass);
+ _removeClass(currentElement, _globalConfig.activeClass);
+ currentElement = null;
}
};
View
127 src/javascript/ZeroClipboard/deprecated.js
@@ -5,7 +5,7 @@
*
* Originally from "core.js"
*/
-_defaults.hoverClass = "zeroclipboard-is-hover";
+_globalConfig.hoverClass = "zeroclipboard-is-hover";
/*
@@ -15,7 +15,7 @@ _defaults.hoverClass = "zeroclipboard-is-hover";
*
* Originally from "core.js"
*/
-_defaults.activeClass = "zeroclipboard-is-active";
+_globalConfig.activeClass = "zeroclipboard-is-active";
/*
@@ -25,7 +25,7 @@ _defaults.activeClass = "zeroclipboard-is-active";
*
* Originally from "core.js"
*/
-_defaults.trustedOrigins = null;
+_globalConfig.trustedOrigins = null;
/*
@@ -35,7 +35,7 @@ _defaults.trustedOrigins = null;
*
* Originally from "core.js"
*/
-_defaults.allowScriptAccess = null;
+_globalConfig.allowScriptAccess = null;
/*
@@ -48,7 +48,7 @@ _defaults.allowScriptAccess = null;
* Originally from "core.js", then "flash.js"
*/
ZeroClipboard.detectFlashSupport = function () {
- var debugEnabled = (ZeroClipboard.prototype._singleton && ZeroClipboard.prototype._singleton.options.debug) || _defaults.debug;
+ var debugEnabled = _globalConfig.debug;
_deprecationWarning("ZeroClipboard.detectFlashSupport", debugEnabled);
return _detectFlashSupport();
};
@@ -63,10 +63,10 @@ ZeroClipboard.detectFlashSupport = function () {
* returns object instance
*/
ZeroClipboard.prototype.setHandCursor = function (enabled) {
- _deprecationWarning("ZeroClipboard.prototype.setHandCursor", this.options.debug);
+ _deprecationWarning("ZeroClipboard.prototype.setHandCursor", _globalConfig.debug);
enabled = typeof enabled === "boolean" ? enabled : !!enabled;
- _setHandCursor.call(this, enabled);
- this.options.forceHandCursor = enabled;
+ _setHandCursor(enabled);
+ _globalConfig.forceHandCursor = enabled;
return this;
};
@@ -80,8 +80,8 @@ ZeroClipboard.prototype.setHandCursor = function (enabled) {
* returns object instance
*/
ZeroClipboard.prototype.reposition = function () {
- _deprecationWarning("ZeroClipboard.prototype.reposition", this.options.debug);
- return _reposition.call(this);
+ _deprecationWarning("ZeroClipboard.prototype.reposition", _globalConfig.debug);
+ return _reposition();
};
@@ -94,7 +94,7 @@ ZeroClipboard.prototype.reposition = function () {
* returns nothing
*/
ZeroClipboard.prototype.receiveEvent = function (eventName, args) {
- _deprecationWarning("ZeroClipboard.prototype.receiveEvent", this.options.debug);
+ _deprecationWarning("ZeroClipboard.prototype.receiveEvent", _globalConfig.debug);
if (typeof eventName === "string" && eventName) {
// Sanitize the event name
var cleanEventName = eventName.toLowerCase().replace(/^on/, "");
@@ -104,4 +104,109 @@ ZeroClipboard.prototype.receiveEvent = function (eventName, args) {
_receiveEvent.call(this, cleanEventName, args);
}
}
+};
+
+
+/*
+ * @deprecated in [v1.3.0], slated for removal in [v2.0.0]. See docs for alternatives.
+ *
+ * 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 object instance
+ */
+ZeroClipboard.prototype.setCurrent = function (element) {
+ _deprecationWarning("ZeroClipboard.prototype.setCurrent", _globalConfig.debug);
+ ZeroClipboard.activate(element);
+ return this;
+};
+
+
+/*
+ * @deprecated in [v1.3.0], slated for removal in [v2.0.0]. See docs for alternatives.
+ *
+ * Reset the html bridge to be hidden off screen and not have title or text.
+ *
+ * returns object instance
+ */
+ZeroClipboard.prototype.resetBridge = function () {
+ _deprecationWarning("ZeroClipboard.prototype.resetBridge", _globalConfig.debug);
+ ZeroClipboard.deactivate();
+ return this;
+};
+
+
+/*
+ * @deprecated in [v1.3.0], slated for removal in [v2.0.0]. See docs for alternatives.
+ *
+ * Adds a title="..." attribute to the htmlBridge to give it tooltip capabilities
+ *
+ * returns object instance
+ */
+ZeroClipboard.prototype.setTitle = function (newTitle) {
+ _deprecationWarning("ZeroClipboard.prototype.setTitle", _globalConfig.debug);
+ // If the element has a title, mimic it
+ newTitle = newTitle || _globalConfig.title || (currentElement && currentElement.getAttribute("title"));
+ if (newTitle) {
+ var htmlBridge = _getHtmlBridge(flashState.bridge);
+ if (htmlBridge) {
+ htmlBridge.setAttribute("title", newTitle);
+ }
+ }
+
+ return this;
+};
+
+
+/*
+ * @deprecated in [v1.3.0], slated for removal in [v2.0.0]. See docs for alternatives.
+ *
+ * Set defaults.
+ *
+ * returns nothing
+ */
+ZeroClipboard.setDefaults = function (options) {
+ _deprecationWarning("ZeroClipboard.setDefaults", _globalConfig.debug);
+ ZeroClipboard.config(options);
+};
+
+
+/*
+ * @deprecated in [v1.3.0], slated for removal in [v2.0.0]. See docs for alternatives.
+ *
+ * An original API method name, now only an alias for `on`.
+ *
+ * returns object instance
+ */
+ZeroClipboard.prototype.addEventListener = function() {
+ _deprecationWarning("ZeroClipboard.prototype.addEventListener", _globalConfig.debug);
+ return this.on.apply(this, [].slice.call(arguments, 0));
+};
+
+
+/*
+ * @deprecated in [v1.3.0], slated for removal in [v2.0.0]. See docs for alternatives.
+ *
+ * An original API method name, now only an alias for `off`.
+ *
+ * returns object instance
+ */
+ZeroClipboard.prototype.removeEventListener = function() {
+ _deprecationWarning("ZeroClipboard.prototype.removeEventListener", _globalConfig.debug);
+ return this.off.apply(this, [].slice.call(arguments, 0));
+};
+
+
+/*
+ * @deprecated in [v1.3.0], slated for removal in [v2.0.0]. See docs for more info.
+ *
+ * Helper function to determine if the Flash bridge is ready. Gets this info from
+ * a per-bridge status tracker.
+ *
+ * returns true if the Flash bridge is ready
+ */
+ZeroClipboard.prototype.ready = function () {
+ _deprecationWarning("ZeroClipboard.prototype.ready", _globalConfig.debug);
+ return flashState.ready === true;
};
View
72 src/javascript/ZeroClipboard/dom.js
@@ -11,26 +11,27 @@ var _cjsModuleId = null;
*/
var _bridge = function () {
var flashBridge, len;
- var client = ZeroClipboard.prototype._singleton;
+
// try and find the current global bridge
var container = document.getElementById("global-zeroclipboard-html-bridge");
if (!container) {
- // Create a copy of the `client.options` object to avoid exposing
+ // Get a copy of the `_globalConfig` object to avoid exposing
// the `amdModuleId` and `cjsModuleId` settings
- var opts = _extend({}, client.options);
+ var opts = ZeroClipboard.config();
// Set these last to override them just in case any [v1.2.0-beta.1] users
// are still passing them in to [v1.2.0-beta.2] (or higher)
opts.amdModuleId = _amdModuleId;
opts.cjsModuleId = _cjsModuleId;
// Set `allowScriptAccess` based on `trustedDomains` and `window.location.host` vs. `moviePath`
- var allowScriptAccess = _determineScriptAccess(window.location.host, client.options);
+ var allowScriptAccess = _determineScriptAccess(window.location.host, _globalConfig);
var flashvars = _vars(opts);
+ var swfUrl = _globalConfig.moviePath + _noCache(_globalConfig.moviePath, _globalConfig);
var html = "\
<object classid=\"clsid:d27cdb6e-ae6d-11cf-96b8-444553540000\" id=\"global-zeroclipboard-flash-bridge\" width=\"100%\" height=\"100%\"> \
- <param name=\"movie\" value=\"" + client.options.moviePath + _noCache(client.options.moviePath, client.options) + "\"/> \
+ <param name=\"movie\" value=\"" + swfUrl + "\"/> \
<param name=\"allowScriptAccess\" value=\"" + allowScriptAccess + "\"/> \
<param name=\"scale\" value=\"exactfit\"/> \
<param name=\"loop\" value=\"false\"/> \
@@ -39,7 +40,7 @@ var _bridge = function () {
<param name=\"bgcolor\" value=\"#ffffff\"/> \
<param name=\"wmode\" value=\"transparent\"/> \
<param name=\"flashvars\" value=\"" + flashvars + "\"/> \
- <embed src=\"" + client.options.moviePath + _noCache(client.options.moviePath, client.options) + "\" \
+ <embed src=\"" + swfUrl + "\" \
loop=\"false\" menu=\"false\" \
quality=\"best\" bgcolor=\"#ffffff\" \
width=\"100%\" height=\"100%\" \
@@ -62,7 +63,7 @@ var _bridge = function () {
container.style.top = "-9999px";
container.style.width = "15px";
container.style.height = "15px";
- container.style.zIndex = "" + _getSafeZIndex(client.options.zIndex);
+ container.style.zIndex = "" + _getSafeZIndex(_globalConfig.zIndex);
// NOTE: Fixes https://github.com/zeroclipboard/zeroclipboard/issues/204
// Although many web developers will tell you that the following 2 lines should be switched to
@@ -72,45 +73,27 @@ var _bridge = function () {
document.body.appendChild(container);
container.innerHTML = html;
}
-
- client.htmlBridge = container;
flashBridge = document["global-zeroclipboard-flash-bridge"];
if (flashBridge && (len = flashBridge.length)) {
flashBridge = flashBridge[len - 1];
}
- client.flashBridge = flashBridge || container.children[0].lastElementChild;
+ flashState.bridge = flashBridge || container.children[0].lastElementChild;
};
/*
- * Reset the html bridge to be hidden off screen and not have title or text.
- *
- * returns object instance
+ * Get the HTML element container that wraps the Flash bridge object/element.
+ * @private
*/
-ZeroClipboard.prototype.resetBridge = function () {
- if (this.htmlBridge) {
- this.htmlBridge.style.left = "0px";
- this.htmlBridge.style.top = "-9999px";
- this.htmlBridge.removeAttribute("title");
+var _getHtmlBridge = function(flashBridge) {
+ var isFlashElement = /^object|embed$/;
+ var htmlBridge = flashBridge && flashBridge.parentNode;
+ while (htmlBridge && isFlashElement.test(htmlBridge.tagName.toLowerCase()) && htmlBridge.parentNode) {
+ htmlBridge = htmlBridge.parentNode;
}
- if (currentElement) {
- _removeClass(currentElement, this.options.activeClass);
- currentElement = null;
- }
- this.options.text = null;
-
- return this;
+ return htmlBridge || null;
};
-/*
- * Helper function to determine if the Flash bridge is ready. Gets this info from
- * a per-bridge status tracker.
- *
- * returns true if the Flash bridge is ready
- */
-ZeroClipboard.prototype.ready = function () {
- return flashState.clients[this.options.moviePath].ready === true;
-};
/*
* Reposition the Flash object to cover the current element being hovered over.
@@ -121,16 +104,21 @@ var _reposition = function () {
// If there is no `currentElement`, skip it
if (currentElement) {
- var pos = _getDOMObjectPosition(currentElement, this.options.zIndex);
+ var pos = _getDOMObjectPosition(currentElement, _globalConfig.zIndex);
// new css
- this.htmlBridge.style.top = pos.top + "px";
- this.htmlBridge.style.left = pos.left + "px";
- this.htmlBridge.style.width = pos.width + "px";
- this.htmlBridge.style.height = pos.height + "px";
- this.htmlBridge.style.zIndex = pos.zIndex + 1;
-
- this.setSize(pos.width, pos.height);
+ var htmlBridge = _getHtmlBridge(flashState.bridge);
+ if (htmlBridge) {
+ htmlBridge.style.top = pos.top + "px";
+ htmlBridge.style.left = pos.left + "px";
+ htmlBridge.style.width = pos.width + "px";
+ htmlBridge.style.height = pos.height + "px";
+ htmlBridge.style.zIndex = pos.zIndex + 1;
+ }
+
+ if (flashState.ready === true && flashState.bridge) {
+ flashState.bridge.setSize(pos.width, pos.height);
+ }
}
return this;
View
244 src/javascript/ZeroClipboard/event.js
@@ -5,141 +5,181 @@
*/
ZeroClipboard.dispatch = function (eventName, args) {
if (typeof eventName === "string" && eventName) {
- // TODO: Update this to get an array of clients that have been glued to the `currentElement`
- var client = ZeroClipboard.prototype._singleton;
-
// Sanitize the event name
var cleanEventName = eventName.toLowerCase().replace(/^on/, "");
- // receive event from Flash movie, send to client
+ // Receive event from Flash movie, forward to clients
if (cleanEventName) {
- _receiveEvent.call(client, cleanEventName, args);
+ // Get an array of clients that have been glued to the `currentElement`, or
+ // get ALL clients if no `currentElement` (e.g. for the global Flash events like "load", etc.)
+ var clients = currentElement ? _getAllClientsGluedToElement(currentElement) : _getAllClients();
+ for (var i = 0, len = clients.length; i < len; i++) {
+ _receiveEvent.call(clients[i], cleanEventName, args);
+ }
}
}
};
/*
- * Add an event to the client.
+ * Add an event handler to the client.
*
* returns object instance
*/
ZeroClipboard.prototype.on = function (eventName, func) {
- // add user event listener for event
+ // add user event handler for event
var events = eventName.toString().split(/\s+/),
- added = {};
+ added = {},
+ handlers = _clientMeta[this.id] && _clientMeta[this.id].handlers;
for (var i = 0, len = events.length; i < len; i++) {
eventName = events[i].toLowerCase().replace(/^on/, '');
added[eventName] = true;
- if (!this.handlers[eventName]) {
- this.handlers[eventName] = [];
+ if (!handlers[eventName]) {
+ handlers[eventName] = [];
}
- this.handlers[eventName].push(func);
+ handlers[eventName].push(func);
}
// The following events must be memorized and fired immediately if relevant as they only occur
// once per Flash object load.
// If we don't have Flash, tell an adult
- if (added.noflash && flashState.global.noflash) {
+ if (added.noflash && flashState.noflash) {
_receiveEvent.call(this, "onNoFlash", {});
}
// If we have old Flash,
- if (added.wrongflash && flashState.global.wrongflash) {
+ if (added.wrongflash && flashState.wrongflash) {
_receiveEvent.call(this, "onWrongFlash", {
- flashVersion: flashState.global.version
+ flashVersion: flashState.version
});
}
// If the SWF was already loaded, we're à gogo!
- if (added.load && flashState.clients[this.options.moviePath].ready) {
+ if (added.load && flashState.ready) {
_receiveEvent.call(this, "onLoad", {
- flashVersion: flashState.global.version
+ flashVersion: flashState.version
});
}
return this;
};
-// shortcut to old stuff
-ZeroClipboard.prototype.addEventListener = ZeroClipboard.prototype.on;
/*