PageRenderTime 56ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/foody.blogtamsudev.vn/public/filemanager/scripts/zeroclipboard/src/flash/ZeroClipboard.as

https://gitlab.com/ntphuc/BackendFeedy
ActionScript | 299 lines | 164 code | 48 blank | 87 comment | 20 complexity | fb49a08da32f6a68eddbbfd22eb56cc9 MD5 | raw file
  1. package {
  2. import flash.display.Stage;
  3. import flash.display.StageAlign;
  4. import flash.display.StageScaleMode;
  5. import flash.display.StageQuality;
  6. import flash.display.Sprite;
  7. import flash.events.Event;
  8. import flash.events.MouseEvent;
  9. import flash.system.Security;
  10. /**
  11. * The ZeroClipboard class creates a simple Sprite button that will put
  12. * text in the user's clipboard when clicked.
  13. */
  14. [SWF(widthPercent="100%", heightPercent="100%", backgroundColor="#FFFFFF")]
  15. public class ZeroClipboard extends Sprite {
  16. /**
  17. * Function through which JavaScript events are emitted. Accounts for scenarios
  18. * in which ZeroClipboard is used via AMD/CommonJS module loaders, too.
  19. */
  20. private var jsEmitter:String = null;
  21. /**
  22. * JavaScript proxy object.
  23. */
  24. private var jsProxy:JsProxy = null;
  25. /**
  26. * Clipboard proxy object.
  27. */
  28. private var clipboard:ClipboardInjector = null;
  29. /**
  30. * @constructor
  31. */
  32. public function ZeroClipboard() {
  33. // The JIT Compiler does not compile constructors, so ANY
  34. // cyclomatic complexity higher than 1 is discouraged.
  35. this.ctor();
  36. }
  37. /**
  38. * The real constructor.
  39. *
  40. * @return `undefined`
  41. */
  42. private function ctor(): void {
  43. // If the `stage` is available, begin!
  44. if (stage) {
  45. this.init();
  46. }
  47. else {
  48. // Otherwise, wait for the `stage`....
  49. this.addEventListener(Event.ADDED_TO_STAGE, this.init);
  50. }
  51. }
  52. /**
  53. * Initialize the class when the Stage is ready.
  54. *
  55. * @return `undefined`
  56. */
  57. private function init(): void {
  58. // Remove the event listener, if any
  59. this.removeEventListener(Event.ADDED_TO_STAGE, this.init);
  60. // Get the flashvars
  61. var flashvars:Object; // NOPMD
  62. flashvars = XssUtils.filterToFlashVars(this.loaderInfo.parameters);
  63. // Configure the SWF object's ID
  64. var swfObjectId:String = "global-zeroclipboard-flash-bridge";
  65. if (flashvars.swfObjectId && typeof flashvars.swfObjectId === "string") {
  66. var swfId = XssUtils.sanitizeString(flashvars.swfObjectId);
  67. // Validate the ID against the HTML4 spec for `ID` tokens.
  68. if (/^[A-Za-z][A-Za-z0-9_:\-\.]*$/.test(swfId)) {
  69. swfObjectId = swfId;
  70. }
  71. }
  72. // Allow the SWF object to communicate with a page on a different origin than its own (e.g. SWF served from CDN)
  73. if (flashvars.trustedOrigins && typeof flashvars.trustedOrigins === "string") {
  74. var origins:Array = XssUtils.sanitizeString(flashvars.trustedOrigins).split(",");
  75. Security.allowDomain.apply(Security, origins);
  76. }
  77. // Enable use of the fancy "Desktop" clipboard, even on Linux where it is known to suck
  78. var forceEnhancedClipboard:Boolean = false;
  79. if (flashvars.forceEnhancedClipboard === "true" || flashvars.forceEnhancedClipboard === true) {
  80. forceEnhancedClipboard = true;
  81. }
  82. this.jsEmitter =
  83. "(function(eventObj) {\n" +
  84. " var objectId = '" + swfObjectId + "',\n" +
  85. " ZC = null,\n" +
  86. " swf = null;\n" +
  87. " if (typeof ZeroClipboard === 'function' && typeof ZeroClipboard.emit === 'function') {\n" +
  88. " \nZC = ZeroClipboard;\n" +
  89. " }\n" +
  90. " else {\n" +
  91. " swf = document[objectId] || document.getElementById(objectId);\n" +
  92. " if (swf && typeof swf.ZeroClipboard === 'function' && typeof swf.ZeroClipboard.emit === 'function') {\n" +
  93. " ZC = swf.ZeroClipboard;\n" +
  94. " }\n" +
  95. " }\n" +
  96. " if (!ZC) {\n" +
  97. " throw new Error('ERROR: ZeroClipboard SWF could not locate ZeroClipboard JS object!\\n" +
  98. "Expected element ID: ' + objectId);\n" +
  99. " }\n" +
  100. " return ZC.emit(eventObj);\n" +
  101. "})";
  102. // Create an invisible "button" and transparently fill the entire Stage
  103. var button:Sprite = this.prepareUI();
  104. // Configure the clipboard injector
  105. this.clipboard = new ClipboardInjector(forceEnhancedClipboard);
  106. // Establish a communication line with JavaScript
  107. this.jsProxy = new JsProxy(swfObjectId);
  108. // Only proceed if this SWF is hosted in the browser as expected
  109. if (this.jsProxy.isComplete()) {
  110. // Add the MouseEvent listeners
  111. this.addMouseHandlers(button);
  112. // Expose the external functions
  113. this.jsProxy.addCallback(
  114. "setHandCursor",
  115. function(enabled:Boolean) {
  116. button.useHandCursor = enabled === true;
  117. }
  118. );
  119. // Signal to the browser that we are ready
  120. this.emit("ready");
  121. }
  122. else {
  123. // Signal to the browser that something is wrong
  124. this.emit("error", {
  125. name: "flash-unavailable"
  126. });
  127. }
  128. }
  129. /**
  130. * Prepare the Stage and Button.
  131. *
  132. * @return Button
  133. */
  134. private function prepareUI(): Sprite {
  135. // Set the stage!
  136. stage.align = StageAlign.TOP_LEFT;
  137. stage.scaleMode = StageScaleMode.EXACT_FIT;
  138. stage.quality = StageQuality.BEST;
  139. // Create an invisible "button" and transparently fill the entire Stage
  140. var button:Sprite = new Sprite();
  141. button.graphics.beginFill(0xFFFFFF);
  142. button.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
  143. button.alpha = 0.0;
  144. // Act like a button. This includes:
  145. // - Showing a hand cursor by default
  146. // - Receiving click events
  147. // - Receiving keypress events of space/"Enter" as click
  148. // events IF AND ONLY IF the Sprite is focused.
  149. button.buttonMode = true;
  150. // Override the hand cursor default
  151. button.useHandCursor = false;
  152. // Add the invisible "button" to the stage!
  153. this.addChild(button);
  154. // Return the button for adding event listeners
  155. return button;
  156. }
  157. /**
  158. * Clears the clipboard and sets new clipboard text. It gets this from the "_clipData"
  159. * variable on the JavaScript side. Once the text has been placed in the clipboard, it
  160. * then signals to the JavaScript that it is done.
  161. *
  162. * @return `undefined`
  163. */
  164. private function onClick(event:MouseEvent): void {
  165. var clipData:Object; // NOPMD
  166. var clipInjectSuccess:Object = {}; // NOPMD
  167. // Allow for any "UI preparation" work before the "copy" event begins
  168. this.emit("beforecopy");
  169. // Request pending clipboard data from the page
  170. clipData = this.emit("copy");
  171. // Inject all pending data into the user's clipboard
  172. clipInjectSuccess = this.clipboard.inject(clipData);
  173. // Compose and serialize a results object, send it back to the page
  174. this.emit(
  175. "aftercopy",
  176. {
  177. success: clipInjectSuccess,
  178. data: clipData
  179. }
  180. );
  181. }
  182. /**
  183. * Emit events to JavaScript.
  184. *
  185. * @return `undefined`, or the new "_clipData" object
  186. */
  187. private function emit(
  188. eventType:String,
  189. eventObj:Object = null // NOPMD
  190. ): Object { // NOPMD
  191. if (eventObj == null) {
  192. eventObj = {};
  193. }
  194. eventObj.type = eventType;
  195. var result:Object = undefined; // NOPMD
  196. if (this.jsProxy.isComplete()) {
  197. result = this.jsProxy.call(this.jsEmitter, [eventObj]);
  198. }
  199. else {
  200. this.jsProxy.send(this.jsEmitter, [eventObj]);
  201. }
  202. return result;
  203. }
  204. /**
  205. * Signals to the page that a MouseEvent occurred.
  206. *
  207. * @return `undefined`
  208. */
  209. private function onMouseEvent(event:MouseEvent): void {
  210. var evtData:Object = {}; // NOPMD
  211. // If an event is passed in, return what modifier keys are pressed, etc.
  212. if (event) {
  213. var props:Object; // NOPMD
  214. props = {
  215. "altKey": "altKey",
  216. "commandKey": "metaKey",
  217. "controlKey": "ctrlKey",
  218. "shiftKey": "shiftKey",
  219. "clickCount": "detail",
  220. "movementX": "movementX",
  221. "movementY": "movementY",
  222. "stageX": "_stageX",
  223. "stageY": "_stageY"
  224. };
  225. for (var prop in props) {
  226. if (event.hasOwnProperty(prop) && event[prop] != null) {
  227. evtData[props[prop]] = event[prop];
  228. }
  229. }
  230. evtData.type = "_" + event.type.toLowerCase();
  231. evtData._source = "swf";
  232. }
  233. this.emit(evtData.type, evtData);
  234. }
  235. /**
  236. * Add mouse event handlers to the button.
  237. *
  238. * @return `undefined`
  239. */
  240. private function addMouseHandlers(button:Sprite): Sprite {
  241. button.addEventListener(MouseEvent.MOUSE_MOVE, this.onMouseEvent);
  242. button.addEventListener(MouseEvent.MOUSE_OVER, this.onMouseEvent);
  243. button.addEventListener(MouseEvent.MOUSE_OUT, this.onMouseEvent);
  244. button.addEventListener(MouseEvent.MOUSE_DOWN, this.onMouseEvent);
  245. button.addEventListener(MouseEvent.MOUSE_UP, this.onMouseEvent);
  246. button.addEventListener(MouseEvent.CLICK, this.onClick);
  247. button.addEventListener(MouseEvent.CLICK, this.onMouseEvent);
  248. return button;
  249. }
  250. }
  251. }