1 |
/* Compile using: mxmlc --target-player=10.0.0 ZeroClipboard.as */ |
2 |
package { |
3 |
import flash.display.Stage; |
4 |
import flash.display.Sprite; |
5 |
import flash.display.LoaderInfo; |
6 |
import flash.display.StageScaleMode; |
7 |
import flash.events.*; |
8 |
import flash.display.StageAlign; |
9 |
import flash.display.StageScaleMode; |
10 |
import flash.external.ExternalInterface; |
11 |
import flash.system.Security; |
12 |
import flash.utils.*; |
13 |
import flash.system.System; |
14 |
import flash.net.FileReference; |
15 |
import flash.net.FileFilter; |
16 |
|
17 |
public class ZeroClipboard extends Sprite { |
18 |
|
19 |
private var domId:String = ''; |
20 |
private var button:Sprite; |
21 |
private var clipText:String = 'blank'; |
22 |
private var fileName:String = ''; |
23 |
private var action:String = 'copy'; |
24 |
private var incBom:Boolean = true; |
25 |
private var charSet:String = 'utf8'; |
26 |
|
27 |
|
28 |
public function ZeroClipboard() { |
29 |
// constructor, setup event listeners and external interfaces |
30 |
stage.scaleMode = StageScaleMode.EXACT_FIT; |
31 |
flash.system.Security.allowDomain("*"); |
32 |
|
33 |
// import flashvars |
34 |
var flashvars:Object = LoaderInfo( this.root.loaderInfo ).parameters; |
35 |
domId = flashvars.id; |
36 |
|
37 |
// invisible button covers entire stage |
38 |
button = new Sprite(); |
39 |
button.buttonMode = true; |
40 |
button.useHandCursor = true; |
41 |
button.graphics.beginFill(0x00FF00); |
42 |
button.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight); |
43 |
button.alpha = 0.0; |
44 |
addChild(button); |
45 |
|
46 |
button.addEventListener(MouseEvent.CLICK, clickHandler); |
47 |
button.addEventListener(MouseEvent.MOUSE_OVER, function(event:Event):void { |
48 |
ExternalInterface.call( 'ZeroClipboard_TableTools.dispatch', domId, 'mouseOver', null ); |
49 |
} ); |
50 |
button.addEventListener(MouseEvent.MOUSE_OUT, function(event:Event):void { |
51 |
ExternalInterface.call( 'ZeroClipboard_TableTools.dispatch', domId, 'mouseOut', null ); |
52 |
} ); |
53 |
button.addEventListener(MouseEvent.MOUSE_DOWN, function(event:Event):void { |
54 |
ExternalInterface.call( 'ZeroClipboard_TableTools.dispatch', domId, 'mouseDown', null ); |
55 |
} ); |
56 |
button.addEventListener(MouseEvent.MOUSE_UP, function(event:Event):void { |
57 |
ExternalInterface.call( 'ZeroClipboard_TableTools.dispatch', domId, 'mouseUp', null ); |
58 |
} ); |
59 |
|
60 |
// External functions - readd whenever the stage is made active for IE |
61 |
addCallbacks(); |
62 |
stage.addEventListener(Event.ACTIVATE, addCallbacks); |
63 |
|
64 |
// signal to the browser that we are ready |
65 |
ExternalInterface.call( 'ZeroClipboard_TableTools.dispatch', domId, 'load', null ); |
66 |
} |
67 |
|
68 |
public function addCallbacks (evt:Event = null):void { |
69 |
ExternalInterface.addCallback("setHandCursor", setHandCursor); |
70 |
ExternalInterface.addCallback("clearText", clearText); |
71 |
ExternalInterface.addCallback("setText", setText); |
72 |
ExternalInterface.addCallback("appendText", appendText); |
73 |
ExternalInterface.addCallback("setFileName", setFileName); |
74 |
ExternalInterface.addCallback("setAction", setAction); |
75 |
ExternalInterface.addCallback("setCharSet", setCharSet); |
76 |
ExternalInterface.addCallback("setBomInc", setBomInc); |
77 |
} |
78 |
|
79 |
|
80 |
public function setCharSet(newCharSet:String):void { |
81 |
if ( newCharSet == 'UTF16LE' ) { |
82 |
charSet = newCharSet; |
83 |
} else { |
84 |
charSet = 'UTF8'; |
85 |
} |
86 |
} |
87 |
|
88 |
public function setBomInc(newBomInc:Boolean):void { |
89 |
incBom = newBomInc; |
90 |
} |
91 |
|
92 |
public function clearText():void { |
93 |
clipText = ''; |
94 |
} |
95 |
|
96 |
public function appendText(newText:String):void { |
97 |
clipText += newText; |
98 |
} |
99 |
|
100 |
public function setText(newText:String):void { |
101 |
clipText = newText; |
102 |
} |
103 |
|
104 |
public function setFileName(newFileName:String):void { |
105 |
fileName = newFileName; |
106 |
} |
107 |
|
108 |
public function setAction(newAction:String):void { |
109 |
action = newAction; |
110 |
} |
111 |
|
112 |
public function setHandCursor(enabled:Boolean):void { |
113 |
// control whether the hand cursor is shown on rollover (true) |
114 |
// or the default arrow cursor (false) |
115 |
button.useHandCursor = enabled; |
116 |
} |
117 |
|
118 |
|
119 |
private function clickHandler(event:Event):void { |
120 |
var fileRef:FileReference = new FileReference(); |
121 |
fileRef.addEventListener(Event.COMPLETE, saveComplete); |
122 |
|
123 |
if ( action == "save" ) { |
124 |
/* Save as a file */ |
125 |
if ( charSet == 'UTF16LE' ) { |
126 |
fileRef.save( strToUTF16LE(clipText), fileName ); |
127 |
} else { |
128 |
fileRef.save( strToUTF8(clipText), fileName ); |
129 |
} |
130 |
} else if ( action == "pdf" ) { |
131 |
fileRef.save( "This instance of ZeroClipboard is not configured for PDF export. "+ |
132 |
"Please use the PDF export version.", fileName+".txt" ); |
133 |
} else { |
134 |
/* Copy the text to the clipboard. Note charset and BOM have no effect here */ |
135 |
System.setClipboard( clipText ); |
136 |
ExternalInterface.call( 'ZeroClipboard_TableTools.dispatch', domId, 'complete', clipText ); |
137 |
} |
138 |
} |
139 |
|
140 |
|
141 |
private function saveComplete(event:Event):void { |
142 |
ExternalInterface.call( 'ZeroClipboard_TableTools.dispatch', domId, 'complete', clipText ); |
143 |
} |
144 |
|
145 |
|
146 |
private function getProp( prop:String, opts:Array ):String |
147 |
{ |
148 |
var i:int, iLen:int; |
149 |
for ( i=0, iLen=opts.length ; i<iLen ; i++ ) |
150 |
{ |
151 |
if ( opts[i].indexOf( prop+":" ) != -1 ) |
152 |
{ |
153 |
return opts[i].replace( prop+":", "" ); |
154 |
} |
155 |
} |
156 |
return ""; |
157 |
} |
158 |
|
159 |
|
160 |
/* |
161 |
* Function: strToUTF8 |
162 |
* Purpose: Convert a string to the output utf-8 |
163 |
* Returns: ByteArray |
164 |
* Inputs: String |
165 |
*/ |
166 |
private function strToUTF8( str:String ):ByteArray { |
167 |
var utf8:ByteArray = new ByteArray(); |
168 |
|
169 |
/* BOM first */ |
170 |
if ( incBom ) { |
171 |
utf8.writeByte( 0xEF ); |
172 |
utf8.writeByte( 0xBB ); |
173 |
utf8.writeByte( 0xBF ); |
174 |
} |
175 |
utf8.writeUTFBytes( str ); |
176 |
|
177 |
return utf8; |
178 |
} |
179 |
|
180 |
|
181 |
/* |
182 |
* Function: strToUTF16LE |
183 |
* Purpose: Convert a string to the output utf-16 |
184 |
* Returns: ByteArray |
185 |
* Inputs: String |
186 |
* Notes: The fact that this function is needed is a little annoying. Basically, strings in |
187 |
* AS3 are UTF-16 (with surrogate pairs and everything), but characters which take up less |
188 |
* than 8 bytes appear to be stored as only 8 bytes. This function effective adds the |
189 |
* padding required, and the BOM |
190 |
*/ |
191 |
private function strToUTF16LE( str:String ):ByteArray { |
192 |
var utf16:ByteArray = new ByteArray(); |
193 |
var iChar:uint; |
194 |
var i:uint=0, iLen:uint = str.length; |
195 |
|
196 |
/* BOM first */ |
197 |
if ( incBom ) { |
198 |
utf16.writeByte( 0xFF ); |
199 |
utf16.writeByte( 0xFE ); |
200 |
} |
201 |
|
202 |
while ( i < iLen ) { |
203 |
iChar = str.charCodeAt(i); |
204 |
|
205 |
if ( iChar < 0xFF ) { |
206 |
/* one byte char */ |
207 |
utf16.writeByte( iChar ); |
208 |
utf16.writeByte( 0 ); |
209 |
} else { |
210 |
/* two byte char */ |
211 |
utf16.writeByte( iChar & 0x00FF ); |
212 |
utf16.writeByte( iChar >> 8 ); |
213 |
} |
214 |
|
215 |
i++; |
216 |
} |
217 |
|
218 |
return utf16; |
219 |
} |
220 |
} |
221 |
} |