Permalink
Browse files

Final pre-v2.x deprecations.

Fixes #289.
  • Loading branch information...
1 parent 598bd91 commit ec3ef0f80662d97665ebd030660c288d151c6f83 @JamesMGreene JamesMGreene committed Jan 23, 2014
View
@@ -17,11 +17,11 @@ The ZeroClipboard library provides an easy way to copy text to the clipboard usi
``` js
// main.js
-var clip = new ZeroClipboard( document.getElementById("copy-button"), {
+var client = new ZeroClipboard( document.getElementById("copy-button"), {
moviePath: "/path/to/ZeroClipboard.swf"
} );
-clip.on( "load", function(client) {
+client.on( "load", function(client) {
// alert( "movie is loaded" );
client.on( "complete", function(client, args) {
View
@@ -670,17 +670,6 @@
}
return this;
};
- ZeroClipboard.dispatch = function(eventName, args) {
- if (typeof eventName === "string" && eventName) {
- var cleanEventName = eventName.toLowerCase().replace(/^on/, "");
- if (cleanEventName) {
- var clients = currentElement ? _getAllClientsClippedToElement(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 i, len, events, added = {}, handlers = _clientMeta[this.id] && _clientMeta[this.id].handlers;
if (typeof eventName === "string" && eventName) {
@@ -764,76 +753,6 @@
}
return copy;
};
- var _receiveEvent = function(eventName, args) {
- 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 (cleanVersion) {
- if (!_isFlashVersionSupported(cleanVersion)) {
- _receiveEvent.call(this, "onWrongFlash", {
- flashVersion: cleanVersion
- });
- return;
- }
- flashState.outdated = false;
- flashState.ready = true;
- flashState.version = cleanVersion;
- }
- break;
-
- case "wrongflash":
- if (cleanVersion && !_isFlashVersionSupported(cleanVersion)) {
- flashState.outdated = true;
- flashState.ready = false;
- flashState.version = cleanVersion;
- }
- break;
-
- case "mouseover":
- _addClass(element, _globalConfig.hoverClass);
- break;
-
- case "mouseout":
- if (_globalConfig.autoActivate === true) {
- ZeroClipboard.deactivate();
- }
- break;
-
- case "mousedown":
- _addClass(element, _globalConfig.activeClass);
- break;
-
- case "mouseup":
- _removeClass(element, _globalConfig.activeClass);
- break;
-
- case "datarequested":
- var targetId = element.getAttribute("data-clipboard-target"), targetEl = !targetId ? null : document.getElementById(targetId);
- if (targetEl) {
- var textContent = targetEl.value || targetEl.textContent || targetEl.innerText;
- if (textContent) {
- this.setText(textContent);
- }
- } else {
- var defaultText = element.getAttribute("data-clipboard-text");
- if (defaultText) {
- this.setText(defaultText);
- }
- }
- performCallbackAsync = false;
- break;
-
- case "complete":
- _deleteOwnProperties(_clipData);
- break;
- }
- var context = element;
- var eventArgs = [ this, args ];
- return _dispatchClientCallbacks.call(this, eventName, context, eventArgs, performCallbackAsync);
- };
var _dispatchClientCallbacks = function(eventName, context, args, async) {
var handlers = _clientMeta[this.id] && _clientMeta[this.id].handlers[eventName];
if (handlers && handlers.length) {
@@ -939,6 +858,17 @@
_deprecationWarning("ZeroClipboard.detectFlashSupport", _globalConfig.debug);
return _detectFlashSupport();
};
+ ZeroClipboard.dispatch = function(eventName, args) {
+ if (typeof eventName === "string" && eventName) {
+ var cleanEventName = eventName.toLowerCase().replace(/^on/, "");
+ if (cleanEventName) {
+ var clients = currentElement ? _getAllClientsClippedToElement(currentElement) : _getAllClients();
+ for (var i = 0, len = clients.length; i < len; i++) {
+ _receiveEvent.call(clients[i], cleanEventName, args);
+ }
+ }
+ }
+ };
ZeroClipboard.prototype.setHandCursor = function(enabled) {
_deprecationWarning("ZeroClipboard.prototype.setHandCursor", _globalConfig.debug);
enabled = typeof enabled === "boolean" ? enabled : !!enabled;
@@ -996,6 +926,76 @@
_deprecationWarning("ZeroClipboard.prototype.ready", _globalConfig.debug);
return flashState.ready === true;
};
+ var _receiveEvent = function(eventName, args) {
+ 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 (cleanVersion) {
+ if (!_isFlashVersionSupported(cleanVersion)) {
+ _receiveEvent.call(this, "onWrongFlash", {
+ flashVersion: cleanVersion
+ });
+ return;
+ }
+ flashState.outdated = false;
+ flashState.ready = true;
+ flashState.version = cleanVersion;
+ }
+ break;
+
+ case "wrongflash":
+ if (cleanVersion && !_isFlashVersionSupported(cleanVersion)) {
+ flashState.outdated = true;
+ flashState.ready = false;
+ flashState.version = cleanVersion;
+ }
+ break;
+
+ case "mouseover":
+ _addClass(element, _globalConfig.hoverClass);
+ break;
+
+ case "mouseout":
+ if (_globalConfig.autoActivate === true) {
+ ZeroClipboard.deactivate();
+ }
+ break;
+
+ case "mousedown":
+ _addClass(element, _globalConfig.activeClass);
+ break;
+
+ case "mouseup":
+ _removeClass(element, _globalConfig.activeClass);
+ break;
+
+ case "datarequested":
+ var targetId = element.getAttribute("data-clipboard-target"), targetEl = !targetId ? null : document.getElementById(targetId);
+ if (targetEl) {
+ var textContent = targetEl.value || targetEl.textContent || targetEl.innerText;
+ if (textContent) {
+ this.setText(textContent);
+ }
+ } else {
+ var defaultText = element.getAttribute("data-clipboard-text");
+ if (defaultText) {
+ this.setText(defaultText);
+ }
+ }
+ performCallbackAsync = false;
+ break;
+
+ case "complete":
+ _deleteOwnProperties(_clipData);
+ break;
+ }
+ var context = element;
+ var eventArgs = [ this, args ];
+ return _dispatchClientCallbacks.call(this, eventName, context, eventArgs, performCallbackAsync);
+ };
if (typeof define === "function" && define.amd) {
define([ "require", "exports", "module" ], function(require, exports, module) {
_amdModuleId = module && module.id || null;
View

Large diffs are not rendered by default.

Oops, something went wrong.
View
@@ -726,4 +726,10 @@ The current list of deprecations includes:
- Use the `cacheBust` config option instead!
- The `moviePath` config option &rarr; as of [v1.3.0], removing in [v2.0.0]
- Use the `swfPath` config option instead!
- - For v1.3.x usage, do: `ZeroClipboard.config({ moviePath: ZeroClipboard.config("swfPath") });`
+ - For v1.3.x usage, do: `ZeroClipboard.config({ moviePath: ZeroClipboard.config("swfPath") });`
+ - `ZeroClipboard.dispatch` &rarr; as of [v1.3.0], removing in [v2.0.0]
+ - Use `ZeroClipboard.emit` instead!
+ - All v1.x event names &rarr; as of [v1.3.0], removing in [v2.0.0]
+ - Use the [v2.x event names](https://gist.github.com/JamesMGreene/7886534#events) instead!
+ - The v1.x event model &rarr; as of [v1.3.0], removing in [v2.0.0]
+ - Use the [v2.x event model (based on the DOM event model)](https://gist.github.com/JamesMGreene/7886534#event-handler-format) instead!
View
@@ -11,3 +11,6 @@ In a perfect world we wouldn't need ZeroClipboard, and the browsers would just t
## Flash tests
We want to setup a unit test suite for the Flash file. See Issue [#43](https://github.com/zeroclipboard/zeroclipboard/issues/43).
+## Mostly new API in v2.0.0
+Most of the API will be redesigned for v2.0.0 (as we did not design the v1.x API but rather inherited it.
+Feedback on the [https://gist.github.com/JamesMGreene/7886534](ZeroClipboard v2.0.0 API draft) is welcomed!
View
@@ -1,6 +1,6 @@
### ZeroClipboard Security
-We try our best to keep ZeroClipboard secure but there are some rules that you should follow to keep your site safe.
+We try our best to keep ZeroClipboard secure but there are some rules that you should consider following to keep your site safe.
#### Rules
@@ -9,14 +9,18 @@ Basically, if an attacker gets access to the main window/global object via an XS
2. The `ZeroClipboard.prototype` object itself is not globally accessible.
3. No `ZeroClipboard` instances are globally accessible.
4. No callback functions for dispatched ZeroClipboard events are globally accessible.
- 5. If a variable is used to set the path to the SWF via `ZeroClipboard#setDefaults`, that variable must not be globally accessible.
+ 5. If a variable is used to set the path to the SWF via `ZeroClipboard#config`, that variable must not be globally accessible.
+ 6. The DOM is not accessible (due to built-in support for `data-clipboard-text` and `data-clipboard-target` attributes).
+
#### Examples
1. Having `ZeroClipboard` instances globally accessible (versus encapsulated in a closure). This allows an attacker to manually call a client's `setText` method and inject their own text.
2. As with all globally accessible functions in JavaScript, any globally accessible callback functions (hooked to events) can be overridden by an attacker. This isn't terribly dangerous but could be annoying.
3. Overriding any of the `ZeroClipboard` or `ZeroClipboard.prototype` properties or methods, if globally accessible.
+ 4. Adding `data-clipboard-text` or `data-clipboard-target` attributes to every element in the DOM.
+
### Responsible Disclosure
-If you find any security holes, please submit a pull request, or file an issue. We will be very appreciative.
+If you find any security holes that you believe can be patched, please submit a pull request or file an issue. We will be very appreciative!
@@ -73,6 +73,33 @@ ZeroClipboard.detectFlashSupport = function () {
};
+/*
+ * @deprecated in [v1.3.0], slated for removal in [v2.0.0]. See docs for alternatives.
+ *
+ * Bridge from the Flash object back to the JavaScript
+ *
+ * returns nothing
+ *
+ * Originally from "event.js"
+ */
+ZeroClipboard.dispatch = function (eventName, args) {
+ if (typeof eventName === "string" && eventName) {
+ // Sanitize the event name
+ var cleanEventName = eventName.toLowerCase().replace(/^on/, "");
+
+ // Receive event from Flash movie, forward to clients
+ if (cleanEventName) {
+ // 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 ? _getAllClientsClippedToElement(currentElement) : _getAllClients();
+ for (var i = 0, len = clients.length; i < len; i++) {
+ _receiveEvent.call(clients[i], cleanEventName, args);
+ }
+ }
+ }
+};
+
+
/*
* @deprecated in [v1.2.0], slated for removal in [v2.0.0]. See docs for alternatives.
*
@@ -228,4 +255,99 @@ ZeroClipboard.prototype.removeEventListener = function() {
ZeroClipboard.prototype.ready = function () {
_deprecationWarning("ZeroClipboard.prototype.ready", _globalConfig.debug);
return flashState.ready === true;
+};
+
+
+/*
+ * @deprecated in [v1.3.0], slated for removal in [v2.0.0].
+ * @private
+ *
+ * Receive an event from Flash for a specific element/client.
+ *
+ * returns object instance
+ *
+ * Originally from "event.js"
+ */
+var _receiveEvent = function (eventName, args) {
+ eventName = eventName.toLowerCase().replace(/^on/, '');
+
+ var cleanVersion = (args && args.flashVersion && _parseFlashVersion(args.flashVersion)) || null;
+ var element = currentElement;
+ var performCallbackAsync = true;
+
+ // special behavior for certain events
+ switch (eventName) {
+ case 'load':
+ if (cleanVersion) {
+ // If the Flash version is less than 10, throw event.
+ if (!_isFlashVersionSupported(cleanVersion)) {
+ _receiveEvent.call(this, "onWrongFlash", { flashVersion: cleanVersion });
+ return;
+ }
+ flashState.outdated = false;
+ flashState.ready = true;
+ flashState.version = cleanVersion;
+ }
+ break;
+
+ case 'wrongflash':
+ if (cleanVersion && !_isFlashVersionSupported(cleanVersion)) {
+ flashState.outdated = true;
+ flashState.ready = false;
+ flashState.version = cleanVersion;
+ }
+ break;
+
+ // NOTE: This `mouseover` event is coming from Flash, not DOM/JS
+ case 'mouseover':
+ _addClass(element, _globalConfig.hoverClass);
+ break;
+
+ // NOTE: This `mouseout` event is coming from Flash, not DOM/JS
+ case 'mouseout':
+ if (_globalConfig.autoActivate === true) {
+ ZeroClipboard.deactivate();
+ }
+ break;
+
+ // NOTE: This `mousedown` event is coming from Flash, not DOM/JS
+ case 'mousedown':
+ _addClass(element, _globalConfig.activeClass);
+ break;
+
+ // NOTE: This `mouseup` event is coming from Flash, not DOM/JS
+ case 'mouseup':
+ _removeClass(element, _globalConfig.activeClass);
+ break;
+
+ case 'datarequested':
+ var targetId = element.getAttribute('data-clipboard-target'),
+ targetEl = !targetId ? null : document.getElementById(targetId);
+ if (targetEl) {
+ var textContent = targetEl.value || targetEl.textContent || targetEl.innerText;
+ if (textContent) {
+ this.setText(textContent);
+ }
+ }
+ else {
+ var defaultText = element.getAttribute('data-clipboard-text');
+ if (defaultText) {
+ this.setText(defaultText);
+ }
+ }
+
+ // This callback cannot be performed asynchronously as it would prevent the
+ // user from being able to call `.setText` successfully before the pending
+ // clipboard injection associated with this event fires.
+ performCallbackAsync = false;
+ break;
+
+ case 'complete':
+ _deleteOwnProperties(_clipData);
+ break;
+ } // switch eventName
+
+ var context = element;
+ var eventArgs = [this, args];
+ return _dispatchClientCallbacks.call(this, eventName, context, eventArgs, performCallbackAsync);
};
Oops, something went wrong.

0 comments on commit ec3ef0f

Please sign in to comment.