Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

added support for global namespace and updated the flash movie

  • Loading branch information...
commit 22705ff77906c966ec7b4ff250d5843380eada71 1 parent 5318b52
Subramanyan Murali authored
2  assets/ClipBoardCopy.as
... ... @@ -1 +1 @@
1   -/* Copyright (c) 2011, Yahoo! Inc. All rights reserved. Redistribution and use of this software in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Yahoo! Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission of Yahoo! Inc. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * The class to set the OS clipboard contents with a value passed * in through a Javascript interface. Since the flash movie can * set the clipboard only when the user action is actually trapped * by the flash movie, this flash movie has to be placed below the * the mouse pointer or the focus node where the user will initiate the copy operation * @class ClipBoardCopy * @author Subramanyan Murali */ package { import flash.display.Stage; import flash.display.Sprite; import flash.display.LoaderInfo; import flash.display.StageScaleMode; import flash.display.StageAlign; import flash.ui.Keyboard; import flash.system.Security; import flash.system.System; import flash.external.ExternalInterface; import flash.events.*; import flash.utils.*; public class ClipBoardCopy extends Sprite { public static const DOMAIN:String = "*"; public static const EXT_FN:String = "ClipBoard.passThrough"; public static const ENTER:String = "enter"; public static const ERROR_MSG:String = "error"; public static const EVENT_MSG:String = "event"; public static const LOAD_MSG:String = "load"; private var CURRENT_TRAN:String = ''; private var control:Sprite; private var id:String = ''; private var extFn:String = ''; private var copyString:String = ''; private var eventCache:Object = {}; private var NS:String = ''; public function ClipBoardCopy() { stage.scaleMode = StageScaleMode.EXACT_FIT; /* Setup the configuration parameters using the flashvars */ var info = this.root.loaderInfo, config:Object = LoaderInfo( info ).parameters, domain = config.domain?config.domain:DOMAIN, loadUrl = info.loaderURL, dimen:Object = {width:config.width?config.width:100, height:config.height?config.height:100}; /* Setup the list of domains to allow */ flash.system.Security.allowDomain(domain); id = config.id; extFn = config.fn?config.fn:EXT_FN; NS = config.ns?config.ns+":":NS; /* Set up the control that will accept the user events */ control = new Sprite(); control.buttonMode = true; control.useHandCursor = true; control.graphics.beginFill(0xCCFF00); control.graphics.drawRect(0, 0, dimen.width, dimen.height); control.alpha = 0.0; addChild(control); control.addEventListener("mouseOver", function(event:Event){ control.buttonMode = true; control.useHandCursor = true; }); /* Set up the external interface */ setupExternalInterface({"copy" : copyText, "setupEvents" : setupEvents, "removeEvents" : removeEvents }); callExternal(LOAD_MSG, {"loadUrl" : loadUrl, "domain" : domain, "id" : id, "dimensions" :dimen, "NS" : NS, "interface" : ["copy", "setupEvents", "removeEvents"]}); } /** * Method to set the private copyString value to the given value * @method copyText * @param val {String} The value to be set * @param tran {String} The current transaction * @return {Boolean} TRUE if success, FALSE if fail */ public function copyText(val, tran) { callExternal("test", {v:val, t:tran}); try { copyString = val; CURRENT_TRAN = tran; } catch (errObj:Error) { callExternal(ERROR_MSG, { "error" : errObj.message, "id" : id, "fn" : "copy" }); } } /** * Method to set up additional events that have to be tracked by the flash movie * and handed off to the Javascript interface * This method accepts an object with String key value pairs, where the key represents * the event that has to be attached in the flash movie on the control and the value * represents the function name that has to be called on the javascript interface * @method setupEvents * @param e {Object} the event object, e.g { keyUp : { cb : "callKeyUp", docopy: true} } * @returns {Boolean} TRUE if success, FALSE if error */ public function setupEvents(json:Object) { try { for (var ev:String in json) { if(eventCache[ev]) return true; /* Event already set, do not assign again */ createCallBack(ev, json[ev].docopy); } } catch (errObj:Error) { callExternal(ERROR_MSG, { "error" : errObj.message, "id" : id, "fn" : "setupEvents" }); } } /** * Method to remove all the attached events. Every event added using the setUpEvents method * will be maintained in an event cache and when this method is called, all the * events will be removed * @method removeEvents * @returns {Boolean} TRUE if success, FALSE if failure */ public function removeEvents(a) { try { var flag = false, evc:Object = {}; if(a.length != 0) { for(var i=0,n=a.length;i<n;i++) { if(eventCache[a[i]]) { evc[a[i]] = eventCache[a[i]]; } } } else { evc = eventCache; } for (var ev:String in evc){ if(ev == ENTER) control.removeEventListener(KeyboardEvent.KEY_DOWN, evc[ev]); else control.removeEventListener(ev, evc[ev]); delete eventCache[ev]; flag = true; } return flag; } catch (errObj:Error) { callExternal(ERROR_MSG, { "error" : errObj.message, "id" : id, "fn" : "removeEvents" }); } } /** * Private method to assign a callback to the events. this method * is created so that the correct events are attached when the * events object is looped through in closure * @method createCallBack * @private * @param ev {String} The event name * @param fn {String} name of the external function */ private function createCallBack(ev:String, cp:Boolean) { var func:Function, evt:String = ev, obj:Object = {}; if(ev == ENTER) { evt = KeyboardEvent.KEY_DOWN; func = function(event:KeyboardEvent) { if (event.keyCode == Keyboard.ENTER) { obj.type = ENTER; eventHandler(obj, cp, event); } }; } else { evt = ev; func = function(event:Event):void { obj.type = event.type; eventHandler(obj, cp, event); }; } eventCache[ev] = func; control.addEventListener(evt, func); } /** * Method to call the external interface function with the given * event name and the arguments * @method callExternal * @param fn {String} The function name that identifies the action * @param args {Object} the arguments that need to be passed to the function * @returns {Boolean} TRUE if success, FALSE if error * @private */ private function callExternal(fn:String, args:Object) { if(fn) { args["transaction"] = CURRENT_TRAN; ExternalInterface.call(extFn, NS+fn, args ); return true; } return false; } /** * Method that is attached to the handler event to trigger off the copy * This method expects that the copyString is already set by calling * the copyText * @method eventHandler * @param o {Object} The custom event object * @param cp {Boolean} Whether to set clipboard on the event or not * @param event {Event} The event object * @private * @returns {Void} */ private function eventHandler(o:Object, cp:Boolean, event:Event):void { var obj = { "id" : id, "event" :o.type}; if(cp) { System.setClipboard( copyString ); obj.clipboard = copyString; } callExternal(EVENT_MSG, obj); } /** * Method to set up the external interface apis * @method setupExternalInterface * @param o {Object} the interface object * @private */ private function setupExternalInterface(o:Object) { for(var i:String in o) ExternalInterface.addCallback(i, o[i]); } } }
  1 +/* Copyright (c) 2011, Yahoo! Inc. All rights reserved. Redistribution and use of this software in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Yahoo! Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission of Yahoo! Inc. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * The class to set the OS clipboard contents with a value passed * in through a Javascript interface. Since the flash movie can * set the clipboard only when the user action is actually trapped * by the flash movie, this flash movie has to be placed below the * the mouse pointer or the focus node where the user will initiate the copy operation * @class ClipBoardCopy * @author Subramanyan Murali */ /* Date Generated : Sept 1, 2011 */ package { import flash.display.Stage; import flash.display.Sprite; import flash.display.LoaderInfo; import flash.display.StageScaleMode; import flash.display.StageAlign; import flash.ui.Keyboard; import flash.system.Security; import flash.system.System; import flash.external.ExternalInterface; import flash.events.*; import flash.utils.*; public class ClipBoardCopy extends Sprite { public static const DOMAIN:String = "*.yahoo.com"; public static const EXT_FN:String = "ClipBoard.passThrough"; public static const ENTER:String = "enter"; public static const ERROR_MSG:String = "error"; public static const EVENT_MSG:String = "event"; public static const LOAD_MSG:String = "load"; private var CURRENT_TRAN:String = ''; private var control:Sprite; private var id:String = ''; private var extFn:String = ''; private var copyString:String = ''; private var eventCache:Object = {}; private var NS:String = ''; public function ClipBoardCopy() { stage.scaleMode = StageScaleMode.EXACT_FIT; /* Setup the configuration parameters using the flashvars */ var info = this.root.loaderInfo, config:Object = LoaderInfo( info ).parameters, domain = config.domain?config.domain:DOMAIN, loadUrl = info.loaderURL, dimen:Object = {width:config.width?config.width:100, height:config.height?config.height:100}; /* Setup the list of domains to allow */ flash.system.Security.allowDomain(domain); id = config.id; extFn = config.fn?config.fn:EXT_FN; NS = config.ns?config.ns+":":NS; /* Set up the control that will accept the user events */ control = new Sprite(); control.buttonMode = true; control.useHandCursor = true; control.graphics.beginFill(0xCCFF00); control.graphics.drawRect(0, 0, dimen.width, dimen.height); control.alpha = 0.0; addChild(control); control.addEventListener("mouseOver", function(event:Event){ control.buttonMode = true; control.useHandCursor = true; }); /* Set up the external interface */ setupExternalInterface({"copy" : copyText, "setupEvents" : setupEvents, "removeEvents" : removeEvents }); callExternal(LOAD_MSG, {"loadUrl" : loadUrl, "domain" : domain, "id" : id, "dimensions" :dimen, "NS" : NS, "interface" : ["copy", "setupEvents", "removeEvents"]}); } /** * Method to set the private copyString value to the given value * @method copyText * @param val {String} The value to be set * @param tran {String} The current transaction * @return {Boolean} TRUE if success, FALSE if fail */ public function copyText(val, tran) { try { copyString = val; CURRENT_TRAN = tran; } catch (errObj:Error) { callExternal(ERROR_MSG, { "error" : errObj.message, "id" : id, "fn" : "copy" }); } } /** * Method to set up additional events that have to be tracked by the flash movie * and handed off to the Javascript interface * This method accepts an object with String key value pairs, where the key represents * the event that has to be attached in the flash movie on the control and the value * represents the function name that has to be called on the javascript interface * @method setupEvents * @param e {Object} the event object, e.g { keyUp : { cb : "callKeyUp", docopy: true} } * @returns {Boolean} TRUE if success, FALSE if error */ public function setupEvents(json:Object) { try { for (var ev:String in json) { if(eventCache[ev]) return true; /* Event already set, do not assign again */ createCallBack(ev, json[ev].docopy); } } catch (errObj:Error) { callExternal(ERROR_MSG, { "error" : errObj.message, "id" : id, "fn" : "setupEvents" }); } } /** * Method to remove all the attached events. Every event added using the setUpEvents method * will be maintained in an event cache and when this method is called, all the * events will be removed * @method removeEvents * @returns {Boolean} TRUE if success, FALSE if failure */ public function removeEvents(a) { try { var flag = false, evc:Object = {}; if(a.length != 0) { for(var i=0,n=a.length;i<n;i++) { if(eventCache[a[i]]) { evc[a[i]] = eventCache[a[i]]; } } } else { evc = eventCache; } for (var ev:String in evc){ if(ev == ENTER) control.removeEventListener(KeyboardEvent.KEY_DOWN, evc[ev]); else control.removeEventListener(ev, evc[ev]); delete eventCache[ev]; flag = true; } return flag; } catch (errObj:Error) { callExternal(ERROR_MSG, { "error" : errObj.message, "id" : id, "fn" : "removeEvents" }); } } /** * Private method to assign a callback to the events. this method * is created so that the correct events are attached when the * events object is looped through in closure * @method createCallBack * @private * @param ev {String} The event name * @param fn {String} name of the external function */ private function createCallBack(ev:String, cp:Boolean) { var func:Function, evt:String = ev, obj:Object = {}; if(ev == ENTER) { evt = KeyboardEvent.KEY_DOWN; func = function(event:KeyboardEvent) { if (event.keyCode == Keyboard.ENTER) { obj.type = ENTER; eventHandler(obj, cp, event); } }; } else { evt = ev; func = function(event:Event):void { obj.type = event.type; eventHandler(obj, cp, event); }; } eventCache[ev] = func; control.addEventListener(evt, func); } /** * Method to call the external interface function with the given * event name and the arguments * @method callExternal * @param fn {String} The function name that identifies the action * @param args {Object} the arguments that need to be passed to the function * @returns {Boolean} TRUE if success, FALSE if error * @private */ private function callExternal(fn:String, args:Object) { if(fn) { args["transaction"] = CURRENT_TRAN; ExternalInterface.call(extFn, NS+fn, args ); return true; } return false; } /** * Method that is attached to the handler event to trigger off the copy * This method expects that the copyString is already set by calling * the copyText * @method eventHandler * @param o {Object} The custom event object * @param cp {Boolean} Whether to set clipboard on the event or not * @param event {Event} The event object * @private * @returns {Void} */ private function eventHandler(o:Object, cp:Boolean, event:Event):void { var obj = { "id" : id, "event" :o.type}; if(cp) { System.setClipboard( copyString ); obj.clipboard = copyString; } callExternal(EVENT_MSG, obj); } /** * Method to set up the external interface apis * @method setupExternalInterface * @param o {Object} the interface object * @private */ private function setupExternalInterface(o:Object) { for(var i:String in o) ExternalInterface.addCallback(i, o[i]); } } }
BIN  assets/ClipBoardCopy.swf
Binary file not shown
8 demo/demo_1.html
@@ -92,6 +92,14 @@ <h1 id='title'>Flash clipboard copy demo</h1>
92 92 var node1 = Y.one(".b1"),
93 93 node2 = Y.one(".b2");
94 94
  95 + /* Make sure that the flash interface callback is within a known global name space */
  96 + window.My = {
  97 + Global : {
  98 + foo : "bar"
  99 + }
  100 + };
  101 + Y.ClipBoard.setCallBackGlobal( "My.Global" );
  102 +
95 103 /* Set up Copy on Node 1 */
96 104 node1.plug(Y.ClipBoard, {
97 105 page : Y.one(".container"),
35 js/gallery-clipboard.js
@@ -89,10 +89,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -127,7 +127,24 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -164,7 +181,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -195,7 +215,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -210,8 +230,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

0 comments on commit 22705ff

Please sign in to comment.
Something went wrong with that request. Please try again.