Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 6 commits
  • 6 files changed
  • 0 comments
  • 1 contributor
6 README
... ... @@ -0,0 +1,6 @@
  1 +The ClipBoard class is designed to be a node plugin and a wrapper over the flash movie
  2 +to copy text contents to the OS clipboard. The class will place the flash movie below the given
  3 +node so that a user action can trigger the copy of contents to the OS clip board using
  4 +Flash's System.setClipboard method. Starting from flash 10, the clipboard can be set only
  5 +off a user initiated event. So the JS class shall only set the string to be copied and will
  6 +allow the flash movie's event to capture the user action and set the clipboard contents.
1  assets/ClipBoardCopy.as
... ... @@ -0,0 +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]); } } }
BIN  assets/ClipBoardCopy.fla
Binary file not shown
32 js/gallery-clipboard-debug.js
@@ -35,6 +35,22 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
@@ -108,22 +124,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2  js/gallery-clipboard-min.js
... ... @@ -1 +1 @@
32 js/gallery-clipboard.js
@@ -35,6 +35,22 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
@@ -108,22 +124,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

No commit comments for this range

Something went wrong with that request. Please try again.