debian/0000775000000000000000000000000012031305773007171 5ustar debian/copyright0000664000000000000000000000544711773177557011161 0ustar Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ upstream-Name: Yahoo! User Interface Toolkit V3 Upstream-Contact: Yahoo! Inc. http://groups.yahoo.com/group/ydn-javascript/ Source: http://developer.yahoo.com/yui3/ Files: * Copyright: (C) 2006-2012 Yahoo! Inc. License: BSD Files: docs/api/assets/vendor/prettify/* Copyright: mikesamuel@gmail.com License: Apache2.0 Files: docs/assets/panel/vendor/prettify/* Copyright: mikesamuel@gmail.com License: Apache2.0 Files: docs/assets/vendor/prettify/* Copyright: mikesamuel@gmail.com License: Apache2.0 Files: debian/* Copyright: (C) 2007-2012 Jaldhar H. Vyas License: BSD License: BSD 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. License: Apache2.0 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at . http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. . On a Debian GNU/Linux system, a copy of the Apache License can be found at /usr/share/common-licenses/Apache-2.0 debian/changelog0000664000000000000000000000166012031305773011046 0ustar yui3 (3.5.1-1ubuntu3) quantal; urgency=low * Downgrade the javascript-common recommendation to a suggestion for all binary packages. -- Matthias Klose Fri, 28 Sep 2012 13:36:31 +0200 yui3 (3.5.1-1ubuntu2) quantal; urgency=low * debian/control: Drop Recommends on javascript-common to Suggests as it is not in main. -- Andres Rodriguez Tue, 11 Sep 2012 15:00:22 -0400 yui3 (3.5.1-1ubuntu1) quantal; urgency=low * Do not build the *.swf files to not pull various dependencies that we do not want in main. - debian/control: Drop Build-Dep on swftools. - debian/rules: Do not build swf files. * debian/watch: Remove dfsg mangler option. -- Andres Rodriguez Tue, 03 Jul 2012 15:53:28 -0400 yui3 (3.5.1-1) unstable; urgency=low * Initial upload. (Closes: #554431) -- Jaldhar H. Vyas Thu, 28 Jun 2012 23:08:48 -0400 debian/source/0000775000000000000000000000000011773177557010514 5ustar debian/source/format0000664000000000000000000000001411773177557011722 0ustar 3.0 (quilt) debian/libjs-yui3-min.lintian-overrides0000664000000000000000000000006311773177557015346 0ustar libjs-yui3-min binary: embedded-javascript-library debian/compat0000664000000000000000000000000211773177557010412 0ustar 7 debian/libjs-yui3-common.install0000664000000000000000000000004411773177557014062 0ustar build/* /usr/share/javascript/yui3 debian/README.Debian-source0000664000000000000000000000031411773177557012551 0ustar Upstream distributes a zip archive, so you need to repackage it to .tar.gz: uscan --repack --rename Afterwards import the new upstream tarball: git-import-orig --pristine-tar ../yui3_3.1.0.orig.tar.gz debian/control0000664000000000000000000000545412031305670010600 0ustar Source: yui3 Section: web Priority: optional Maintainer: Ubuntu Developers XSBC-Original-Maintainer: Debian Javascript Maintainers Uploaders: Jaldhar H. Vyas Build-Depends: debhelper (>= 7.0.50~) Standards-Version: 3.9.3 Homepage: http://developer.yahoo.com/yui/3/ Vcs-Browser: http://git.debian.org/?p=pkg-javascript/yui3.git Vcs-Git: git://git.debian.org/git/pkg-javascript/yui3.git DM-Upload-Allowed: yes Package: libjs-yui3-common Section: web Architecture: all Depends: ${misc:Depends} Suggests: javascript-common Description: Yahoo User Interface Library v3 (common files) A collection of JavaScript and CSS resources that make it easier to build richly interactive applications in web browsers. The library currently includes: . * utility classes for animation, browser history, AJAX, cookies, caching drag and drop. safe cross-site data retrieval, dynamic script/css loading, image loading, selectors, JSON, internationalization, DOM and browser events, and more. * many user interface widgets. * Cascading stylesheets for browser-independent grids and fonts. . This package contains images, css files and other assets which are used by the min, debug, and full packages. Package: libjs-yui3-debug Section: web Architecture: all Depends: libjs-yui3-common, ${misc:Depends} Suggests: javascript-common Description: Yahoo User Interface Library v3 (debug files) A collection of JavaScript and CSS resources that make it easier to build richly interactive applications in web browsers. . This package contains versions of the javascript files suitable for debugging. Package: libjs-yui3-doc Section: doc Architecture: all Depends: ${misc:Depends}, libjs-yui3-min (= ${binary:Version}) Description: Documentation and examples for the Yahoo User Interface Library v3 This package contains documentation for the Yahoo User Interface JavaScript library version 3. Package: libjs-yui3-full Section: web Architecture: all Depends: libjs-yui3-common, ${misc:Depends} Suggests: javascript-common Description: Yahoo User Interface Library v3 (full, uncompressed files) A collection of JavaScript and CSS resources that make it easier to build richly interactive applications in web browsers. . This package contains the full, unobfuscated and uncompressed, versions of the javascript files. Package: libjs-yui3-min Section: web Architecture: all Depends: libjs-yui3-common, ${misc:Depends} Suggests: javascript-common Description: Yahoo User Interface Library v3 (minified files) A collection of JavaScript and CSS resources that make it easier to build richly interactive applications in web browsers. . This package contains versions of the javascript files which have been minified for efficiency. debian/libjs-yui3-common.dirs0000664000000000000000000000003311773177557013353 0ustar /usr/share/javascript/yui3 debian/watch0000664000000000000000000000014711774646664010250 0ustar version=3 http://yuilibrary.com/download/yui3/ \ http://yui.zenfs.com/releases/yui3/yui_([\d\.]*).zip debian/libjs-yui3-min.dirs0000664000000000000000000000003311773177557012646 0ustar /usr/share/javascript/yui3 debian/libjs-yui3-debug.dirs0000664000000000000000000000003311773177557013151 0ustar /usr/share/javascript/yui3 debian/libjs-yui3-doc.docs0000664000000000000000000000003211773177557012616 0ustar api/ releasenotes/ docs/* debian/libjs-yui3-doc.doc-base.yui3-api0000664000000000000000000000043511773177557015011 0ustar Document: yui3-api Title: YUI API documentation Author: Yahoo! Inc. Abstract: Explains how to use the Yahoo! User Interface Library v3 in your own web sites. Section: Programming Format: HTML Index: /usr/share/doc/libjs-yui3-doc/index.html Files: /usr/share/doc/libjs-yui3-doc/*.html debian/libjs-yui3-full.dirs0000664000000000000000000000003311773177557013025 0ustar /usr/share/javascript/yui3 debian/patches/0000775000000000000000000000000011773225332010624 5ustar debian/patches/as-src.patch0000664000000000000000000030713611773223612013046 0ustar From: Jaldhar H. Vyas Date: Thu Jun 28 21:43:38 EDT 2012 Subject: as-src Description: ActionScript source for the flash files included in the package. Origin: https://github.com/yui/yui3.git (yui-3.5.1 branch) --- create mode 100644 src/io/as/com/yui/util/io.as create mode 100644 src/uploader-deprecated/as/Uploader.as create mode 100644 src/uploader-deprecated/as/com/yahoo/util/YUIBridge.as create mode 100644 src/uploader/as/File.as create mode 100644 src/uploader/as/FlashUploader.as create mode 100644 src/uploader/as/Uploader.as create mode 100644 src/uploader/as/com/yahoo/util/YUIBridge.as diff --git a/src/io/as/com/yui/util/io.as b/src/io/as/com/yui/util/io.as new file mode 100644 index 0000000..9614d7e --- /dev/null +++ b/src/io/as/com/yui/util/io.as @@ -0,0 +1,179 @@ +package com.yui.util +{ + import flash.display.Sprite; + import flash.events.Event; + import flash.events.IOErrorEvent; + import flash.events.SecurityErrorEvent; + import flash.events.TimerEvent; + import flash.events.IEventDispatcher; + import flash.net.URLRequest; + import flash.net.URLRequestMethod; + import flash.net.URLRequestHeader; + import flash.net.URLLoader; + import flash.net.URLVariables; + import flash.utils.Timer; + import flash.external.ExternalInterface; + + public class io extends Sprite + { + private var httpComplete:Function; + private var httpError:Function; + private var httpTimeout:Function; + private var loaderMap:Object = {}; + private var vars:Object = root.loaderInfo.parameters; + + public function io() { + ExternalInterface.addCallback("send", send); + ExternalInterface.addCallback("abort", abort); + ExternalInterface.addCallback("isInProgress", isInProgress); + ExternalInterface.call('YUI.applyTo', vars.yid, 'io.xdrReady', [vars.yid, vars.uid]); + } + + public function send(uri:String, cfg:Object):void { + var loader:URLLoader = new URLLoader(), + request:URLRequest = new URLRequest(uri), + o:Object = { id: cfg.id, uid: cfg.uid }, + timer:Timer, + k:String, + p:String; + + for (p in cfg) { + switch (p) { + case "method": + if(cfg.method === 'POST') { + request.method = URLRequestMethod.POST; + } + break; + case "data": + if (cfg.method === 'POST') { + request.data = cfg.data; + } + else { + for (k in cfg.data) { + request.data = new URLVariables(k + "=" + cfg.data[k]); + } + } + break; + case "headers": + setRequestHeaders(request, cfg.headers); + break; + case "timeout": + timer = new Timer(cfg.timeout, 1); + break; + } + } + + loaderMap[cfg.id] = { c:loader, readyState: 0, t:timer }; + defineListeners(o, timer); + addListeners(loader, timer); + loader.load(request); + start(o, timer); + } + + private function defineListeners(o:Object, timer:Timer):void { + httpComplete = function(e:Event):void { success(e, o, timer); }; + httpError = function(e:Event):void { failure(e, o, timer); }; + if (timer) { + httpTimeout = function(e:TimerEvent):void { timeout(e, o.id); }; + } + } + + private function addListeners(loader:IEventDispatcher, timer:IEventDispatcher):void { + loader.addEventListener(Event.COMPLETE, httpComplete); + loader.addEventListener(IOErrorEvent.IO_ERROR, httpError); + loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, httpError); + if (timer) { + timer.addEventListener(TimerEvent.TIMER_COMPLETE, httpTimeout); + } + } + + private function removeListeners(id:uint):void { + loaderMap[id].c.removeEventListener(Event.COMPLETE, httpComplete); + loaderMap[id].c.removeEventListener(IOErrorEvent.IO_ERROR, httpError); + loaderMap[id].c.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, httpError); + if (loaderMap[id].t) { + loaderMap[id].t.removeEventListener(TimerEvent.TIMER_COMPLETE, httpTimeout); + } + } + + private function start(o:Object, timer:Timer):void { + if (timer) { + timer.start(); + } + loaderMap[o.id].readyState = 2; + dispatch(['start', o, null]); + } + + private function success(e:Event, o:Object, timer:Timer):void { + o.c = { responseText: encodeURI(e.target.data) }; + loaderMap[o.id].readyState = 4; + if (timer && timer.running) { + timer.stop(); + } + + dispatch(['success', o]); + destroy(o.id); + } + + private function failure(e:Event, o:Object, timer:Timer):void { + loaderMap[o.id].readyState = 4; + if (timer && timer.running) { + timer.stop(); + } + + if (e is IOErrorEvent) { + o.c = { status: 0, statusText: e.type }; + } + else if (e is SecurityErrorEvent) { + o.c = { status: 0, statusText: 'Security Violation.' }; + } + + dispatch([e is TimerEvent ? 'timeout' : 'failure', o]); + destroy(o.id); + } + + public function abort(id:uint):void { + loaderMap[id].c.close(); + if (loaderMap[id].t && loaderMap[id].t.running) { + loaderMap[id].t.stop(); + } + + dispatch(['abort', { id: id }]); + destroy(id); + } + + public function isInProgress(id:uint):Boolean { + if (loaderMap[id]) { + return loaderMap[id].readyState !== 4; + } + else { + return false; + } + } + + private function timeout(e:TimerEvent, id:uint):void { + loaderMap[id].c.close(); + dispatch(['timeout', { id: id }]); + destroy(id); + } + + private function destroy(id:uint):void { + removeListeners(id); + delete loaderMap[id]; + } + + private function dispatch(a:Object):void { + ExternalInterface.call('YUI.applyTo', vars.yid, 'io.xdrResponse', a); + } + + private function setRequestHeaders(request:URLRequest, headers:Object):void { + var header:URLRequestHeader, + prop:String; + + for (prop in headers) { + header = new URLRequestHeader(prop, headers[prop]); + request.requestHeaders.push(header); + } + } + } +} \ No newline at end of file diff --git a/src/uploader-deprecated/as/Uploader.as b/src/uploader-deprecated/as/Uploader.as new file mode 100644 index 0000000..2d1f7fd --- /dev/null +++ b/src/uploader-deprecated/as/Uploader.as @@ -0,0 +1,980 @@ +package + +{ + + import com.yahoo.util.YUIBridge; + + import flash.display.Loader; + import flash.display.Sprite; + import flash.display.StageAlign; + import flash.display.StageScaleMode; + import flash.events.DataEvent; + import flash.events.Event; + import flash.events.FocusEvent; + import flash.events.HTTPStatusEvent; + import flash.events.IOErrorEvent; + import flash.events.KeyboardEvent; + import flash.events.MouseEvent; + import flash.events.ProgressEvent; + import flash.events.SecurityErrorEvent; + import flash.external.ExternalInterface; + import flash.net.FileFilter; + import flash.net.FileReference; + import flash.net.FileReferenceList; + import flash.net.URLRequest; + import flash.net.URLVariables; + import flash.ui.Keyboard; + import flash.utils.Dictionary; + + + + [SWF(backgroundColor=0xFFFFFF)] + + /** + * The base Uploader class for YUI's Flash-based file uploader. + * + * @author Allen Rabinovich + */ + + public class Uploader extends Sprite { + + //-------------------------------------- + // Constructor + //-------------------------------------- + + public function Uploader() + { + super(); + yuiBridge = new YUIBridge(this.stage); + logMessage("Initializing uploader..."); + initializeComponent(); + } + + //-------------------------------------------------------------------------- + // + // Variables + // + //-------------------------------------------------------------------------- + + private var allowMultiple:Boolean = false; + private var allowLog:Boolean = false; + private var filterArray:Array; + + private var fileDataList:Object; + private var fileRefList:Object; + private var fileIDList:Dictionary; + private var fileIDCounter:Number; + private var filesToUpload:Array; + + private var singleFile:FileReference; + private var multipleFiles:FileReferenceList; + + public var yuiBridge:YUIBridge; + + /** + * Determines how many files will be uploaded simultaneously + * + * @see setSimUploadLimit + * @langversion 3.0 + * @playerversion Flash 9.0.28.0 + */ + public var simultaneousUploadLimit:Number = 2; + + // Track the number of current upload threads + private var currentUploadThreads:Number = 0; + + // How the uploader is rendered, either "button" or "transparent" + private var renderType:String; + + // The Sprite containing the rendered UI. + private var buttonSprite:Sprite = new Sprite(); + + // The skin for the button, if "button" renderType is used. + private var buttonSkin:Loader = new Loader(); + + // Height and width for the button + private var buttonHeight:Number; + private var buttonWidth:Number; + + //-------------------------------------- + // Public Methods + //-------------------------------------- + + /** + * Sets the number of simultaneous file uploads possible. + * The maximum is 5. + * @param numberOfUploads Number of simultaneous uploads, no fewer than 1 + * and no larger than 5. + */ + public function setSimUploadLimit (simUploadLimit:int) : void { + if (simUploadLimit <= 1) { + this.simultaneousUploadLimit = 1; + logMessage("Simultaneous upload limit has been set to 1"); + } + else if (simUploadLimit >= 5) { + this.simultaneousUploadLimit = 5; + logMessage("Simultaneous upload limit has been set to 5"); + } + else { + this.simultaneousUploadLimit = simUploadLimit; + logMessage("Simultaneous upload limit has been set to " + simUploadLimit); + } + } + + + /** + * Sets a list of file type filters for the "Open File(s)" dialog. + * + * @param newFilterArray An array of sets of key-value pairs of the form + * {extensions: extensionString, description: descriptionString, macType: macTypeString [optional]} + * The extension string is a semicolon-delimited list of elements of the form "*.xxx", + * e.g. "*.jpg;*.gif;*.png". + */ + public function setFileFilters(newFilterArray:Array) : void { + filterArray = processFileFilterObjects(newFilterArray); + + if (allowLog) { + var logString:String = "File filters have been set to the following: \n"; + for each (var ff:FileFilter in filterArray) { + logString += ff.extension + ": " + ff.description + "\n"; + } + logMessage(logString); + } + } + + /** + * Sets a flag allowing logging in Flash trace and Yahoo logger. + * + * @param allowLogging Whether to allow log messages. + * + */ + public function setAllowLogging(allowLogging:Boolean) : void { + if (this.allowLog != allowLogging) { + logMessage("Logging has been turned " + (allowLogging ? "on." : "off.")); + this.allowLog = allowLogging; + } + } + + /** + * Sets a flag allowing multiple file selection in the "Browse" dialog. + * + * @param allowMultiple Whether to allow multiple file selection. + * + */ + public function setAllowMultipleFiles(allowMultipleFiles:Boolean) : void { + this.allowMultiple = allowMultipleFiles; + logMessage("Multiple file upload has been turned " + (allowMultiple ? "on." : "off.")); + } + + + /** + * Triggers a prompt for the user to browse their file system to select + * files to be uploaded. + * + * @param allowMultiple Whether to allow the user to select more than + * one file + * + * @param filterArray An array of filter objects, each with + * description, and extensions properties which + * determine which files the user is allowed to select + */ + + private function browse(allowMultiple:Boolean = false, filterArray:Array = null):void { + + if(!allowMultiple) { + logMessage("Starting to browse for a single file...") + singleFile = new FileReference(); + singleFile.addEventListener(Event.SELECT, singleFileSelected); + + if(filterArray) { + singleFile.browse(filterArray); + } + else { + singleFile.browse(); + } + } + + else { + + logMessage("Starting to browse for multiple files...") + multipleFiles = new FileReferenceList(); + multipleFiles.addEventListener(Event.SELECT, multipleFilesSelected); + + if(filterArray) { + multipleFiles.browse(filterArray); + } + + else { + multipleFiles.browse(); + } + + } + + } + + + /** + * Removes the file from the set to be uploaded + * + * @param fileID The ID of the file to be removed + */ + + public function removeFile(fileID:String):Object { + + logMessage("Removing file " + fileID); + + delete fileDataList[fileID]; + delete fileRefList[fileID]; + + logMessage("Returning new file list: " + fileDataList); + return fileDataList; + } + + public function enable () : void { + if (renderType == "button") { + this.addEventListener(MouseEvent.ROLL_OVER, buttonMouseOver); + this.addEventListener(MouseEvent.ROLL_OUT, buttonMouseOut); + this.addEventListener(MouseEvent.MOUSE_DOWN, buttonMouseDown); + this.addEventListener(MouseEvent.MOUSE_UP, buttonMouseUp); + this.addEventListener(MouseEvent.CLICK, handleMouseClick); + buttonSkin.y = 0; + } + else { + this.addEventListener(MouseEvent.CLICK, handleMouseClick); + this.addEventListener(MouseEvent.CLICK, transparentClick); + + this.addEventListener(MouseEvent.MOUSE_DOWN, transparentDown); + this.addEventListener(MouseEvent.MOUSE_UP, transparentUp); + this.addEventListener(MouseEvent.ROLL_OVER, transparentRollOver); + this.addEventListener(MouseEvent.ROLL_OUT, transparentRollOut); + } + + logMessage("Uploader UI has been enabled."); + } + + public function disable () : void { + if (renderType == "button") { + this.removeEventListener(MouseEvent.ROLL_OVER, buttonMouseOver); + this.removeEventListener(MouseEvent.ROLL_OUT, buttonMouseOut); + this.removeEventListener(MouseEvent.MOUSE_DOWN, buttonMouseDown); + this.removeEventListener(MouseEvent.MOUSE_UP, buttonMouseUp); + this.removeEventListener(MouseEvent.CLICK, handleMouseClick); + buttonSkin.y = -3*buttonHeight; + } + else { + this.removeEventListener(MouseEvent.CLICK, handleMouseClick); + this.removeEventListener(MouseEvent.CLICK, transparentClick); + + this.removeEventListener(MouseEvent.MOUSE_DOWN, transparentDown); + this.removeEventListener(MouseEvent.MOUSE_UP, transparentUp); + this.removeEventListener(MouseEvent.ROLL_OVER, transparentRollOver); + this.removeEventListener(MouseEvent.ROLL_OUT, transparentRollOut); + } + + logMessage("Uploader UI has been disabled."); + } + + /** + * Clears the set of files that had been selected for upload + */ + + public function clearFileList():Boolean { + + filesToUpload = []; + fileDataList = new Object(); + fileRefList = new Object(); + fileIDList = new Dictionary(); + fileIDCounter = 0; + + logMessage("The file list has been cleared."); + + return true; + } + + + + /** + * Uploads a file corresponding to a specified ID to a specified path where a script handles writing to the server. + * + * @param fileID The ID of the file to be uploaded + * @param url The path to the serverside script + * @param method The HTTP submission method. Possible values are "GET" and "POST" + * @param vars An object containing variables to be sent along with the request + * @param fieldName The field name that precedes the file data in the upload POST operation. + * The uploadDataFieldName value must be non-null and a non-empty String. + * @param headers An object containing variables that should be set as headers in the POST request. The following header names + * cannot be used: + * + * Accept-Charset, Accept-Encoding, Accept-Ranges, Age, Allow, Allowed, Authorization, Charge-To, Connect, Connection, + * Content-Length, Content-Location, Content-Range, Cookie, Date, Delete, ETag, Expect, Get, Head, Host, Keep-Alive, + * Last-Modified, Location, Max-Forwards, Options, Post, Proxy-Authenticate, Proxy-Authorization, Proxy-Connection, + * Public, Put, Range, Referer, Request-Range, Retry-After, Server, TE, Trace, Trailer, Transfer-Encoding, Upgrade, + * URI, User-Agent, Vary, Via, Warning, WWW-Authenticate, x-flash-version. + * + */ + + public function upload(fileID:String, url:String, method:String = "GET", vars:Object = null, fieldName:String = "Filedata"):void { + + // null checking in the params is not working correctly + filesToUpload = []; + + if(isEmptyString(method)) { + method = "GET"; + } + + if(isEmptyString(fieldName)) { + fieldName = "Filedata"; + } + + var request:URLRequest = formURLRequest(url, method, vars); + var fr:FileReference = fileRefList[fileID]; + + this.currentUploadThreads++; + fr.upload(request,fieldName); + + logMessage("Starting the upload of file " + fileID); + } + + /** + * Uploads the specified files to a specified path where a script handles writing to the server. + * + * @param fileIDs The IDs of the files to be uploaded + * @param url The path to the serverside script + * @param method The HTTP submission method. Possible values are "GET" and "POST" + * @param vars An object containing data to be sent along with the request + * @param fieldName The field name that precedes the file data in the upload POST operation. The uploadDataFieldName value must be non-null and a non-empty String. + */ + + public function uploadThese(fileIDs:Array, url:String, method:String = "GET", vars:Object = null, fieldName:String = "Filedata"):void { + if(isEmptyString(method)) { + method = "GET"; + } + + if(isEmptyString(fieldName)) { + fieldName = "Filedata"; + } + + var request:URLRequest = formURLRequest(url, method, vars); + + for each(var fileID:String in fileIDs) { + queueForUpload(fileRefList[fileID], request, fieldName); + } + + processQueue(); + } + + /** + * Uploads all files to a specified path where a script handles writing to the server. + * + * @param fileID The ID of the file to be uploaded + * @param url The path to the serverside script + * @param method The HTTP submission method. Possible values are "GET" and "POST" + * @param vars An object containing data to be sent along with the request + * @param fieldName The field name that precedes the file data in the upload POST operation. The uploadDataFieldName value must be non-null and a non-empty String. + * @param headers An object containing variables that should be set as headers in the POST request. The following header names + * cannot be used: + * + * Accept-Charset, Accept-Encoding, Accept-Ranges, Age, Allow, Allowed, Authorization, Charge-To, Connect, Connection, + * Content-Length, Content-Location, Content-Range, Cookie, Date, Delete, ETag, Expect, Get, Head, Host, Keep-Alive, + * Last-Modified, Location, Max-Forwards, Options, Post, Proxy-Authenticate, Proxy-Authorization, Proxy-Connection, + * Public, Put, Range, Referer, Request-Range, Retry-After, Server, TE, Trace, Trailer, Transfer-Encoding, Upgrade, + * URI, User-Agent, Vary, Via, Warning, WWW-Authenticate, x-flash-version. + * + */ + + public function uploadAll(url:String, method:String = "GET", vars:Object = null, fieldName:String = "Filedata", headers:Object = null):void { + if(isEmptyString(method)) { + method = "GET"; + } + + if(isEmptyString(fieldName)) { + fieldName = "Filedata"; + } + + var request:URLRequest = formURLRequest(url, method, vars); + + filesToUpload = []; + + // sort files in the order that they were given to us + var fileIds:Array = []; + for (var fileId:String in fileRefList) { + fileIds.push(parseInt(fileId.substr(4))); + } + fileIds.sort(Array.NUMERIC); + for each(var fileId2:int in fileIds) { + queueForUpload(fileRefList["file"+fileId2], request, fieldName); + } + + processQueue(); + } + + /** + * Cancels either an upload of the file corresponding to a given fileID, or in the absence of the specified fileID, all active files being uploaded. + * + * @param fileID The ID of the file to be uploaded + */ + + public function cancel(fileID:String = null):void { + + logMessage("Canceling upload of " + fileID?fileID:"all files."); + + if (fileID == null) { // cancel all files + for each (var item:FileReference in fileRefList) { + item.cancel(); + } + this.currentUploadThreads = 0; + filesToUpload = []; + } + + else { // cancel specified file + var fr:FileReference = fileRefList[fileID]; + if (this.currentUploadThreads > 0) + this.currentUploadThreads--; + fr.cancel(); + } + + } + + + + /* + Events + ------------------------------- + mouseDown - fires when the mouse button is pressed over uploader + mouseUp - fires when the mouse button is released over uploader + rollOver - fires when the mouse rolls over the uploader + rollOut - fires when the mouse rolls out of the uploader + click - fires when the uploader is clicked + fileSelect - fires when the user selects one or more files (after browse is called). Passes the array of currently selected files (if prior browse calls were made and clearFileList hasn't been called, all files the user has ever selected will be returned), along with all information available about them (name, size, type, creationDate, modificationDate, creator). + uploadStart - fires when a file starts uploading. Passes a file id for identifying the file. + uploadProgress - fires when a file upload reports progress. Passes the file id, as well as bytesUploaded and bytesTotal for the given file. + uploadComplete - fires when a file upload is completed successfully and passes the corresponding file id. + uploadCompleteData - fires when data is received from the server after upload and passes the corresponding file id and the said data. + uploadError - fires when an error occurs during download. Passes the id of the file that was being uploaded and an error type. + */ + + private function transparentDown (event:MouseEvent) : void { + logMessage("Dispatching mousedown event."); + var newEvent:Object = new Object(); + newEvent.type = "mousedown"; + yuiBridge.sendEvent(newEvent); + } + + private function transparentUp (event:MouseEvent) : void { + logMessage("Dispatching mouseup event."); + var newEvent:Object = new Object(); + newEvent.type = "mouseup"; + yuiBridge.sendEvent(newEvent); + } + + private function transparentRollOver (event:MouseEvent) : void { + logMessage("Dispatching mouseenter event."); + var newEvent:Object = new Object(); + newEvent.type = "mouseenter"; + yuiBridge.sendEvent(newEvent); + } + + private function transparentRollOut (event:MouseEvent) : void { + logMessage("Dispatching mouseleave event."); + var newEvent:Object = new Object(); + newEvent.type = "mouseleave"; + yuiBridge.sendEvent(newEvent); + } + + private function transparentClick (event:MouseEvent) : void { + logMessage("Dispatching click event."); + var newEvent:Object = new Object(); + newEvent.type = "click"; + yuiBridge.sendEvent(newEvent); + } + + + private function uploadStart (event:Event) : void { + logMessage("Dispatching uploadstart event for " + fileIDList[event.target]); + var newEvent:Object = new Object(); + newEvent.id = fileIDList[event.target]; + newEvent.type = "uploadstart"; + yuiBridge.sendEvent(newEvent); + } + + + + private function uploadProgress (event:ProgressEvent) : void { + logMessage("Dispatching uploadprogress event for " + fileIDList[event.target] + ": " + event.bytesLoaded.toString() + " / " + event.bytesTotal.toString()); + var newEvent:Object = new Object(); + newEvent.id = fileIDList[event.target]; + newEvent.bytesLoaded = event.bytesLoaded; + newEvent.bytesTotal = event.bytesTotal; + newEvent.type = "uploadprogress" + yuiBridge.sendEvent(newEvent); + } + + + + private function uploadComplete (event:Event) : void { + logMessage("Dispatching uploadcomplete event for " + fileIDList[event.target]); + var newEvent:Object = new Object(); + newEvent.id = fileIDList[event.target]; + newEvent.type = "uploadcomplete" + yuiBridge.sendEvent(newEvent); + + this.currentUploadThreads--; + // get next off of queue: + processQueue(); + } + + + + private function uploadCompleteData (event:DataEvent) : void { + logMessage("Dispatching uploadcompletedata event for " + fileIDList[event.target] + ": "); + logMessage("Received the following data: " + event.data); + var newEvent:Object = new Object(); + newEvent.id = fileIDList[event.target]; + newEvent.data = event.data; + newEvent.type = "uploadcompletedata" + yuiBridge.sendEvent(newEvent); + } + + private function uploadCancel (event:Event) : void { + logMessage("Dispatching uploadcancel event for " + fileIDList[event.target]); + var newEvent:Object = new Object(); + newEvent.id = fileIDList[event.target]; + newEvent.type = "uploadcancel"; + yuiBridge.sendEvent(newEvent); + } + + + + private function uploadError (event:Event) : void { + var newEvent:Object = {}; + + if (event is HTTPStatusEvent) { + var myev:HTTPStatusEvent = event as HTTPStatusEvent; + newEvent.status = myev.status; + logMessage("HTTP status error for " + fileIDList[event.target] + ": " + myev.status); + } + + else if (event is IOErrorEvent) { + newEvent.status = event.toString(); + logMessage("IO error for " + fileIDList[event.target] + ". Likely causes are problems with Internet connection or server misconfiguration."); + } + + else if (event is SecurityErrorEvent) { + newEvent.status = event.toString(); + logMessage("Security error for " + fileIDList[event.target]); + } + logMessage ("Dispatching error event for " + fileIDList[event.target]); + newEvent.type = "uploaderror"; + newEvent.id = fileIDList[event.target]; + + yuiBridge.sendEvent(newEvent); + + // get next off of queue: + processQueue(); + } + + + + // Fired when the user selects a single file + private function singleFileSelected(event:Event):void { + this.clearFileList(); + addFile(event.target as FileReference); + processSelection(); + } + + + + // Fired when the user selects multiple files + private function multipleFilesSelected(event:Event):void { + var currentFRL:FileReferenceList = multipleFiles; + for each (var currentFR:FileReference in currentFRL.fileList) { + addFile(currentFR); + } + processSelection(); + } + + private function renderAsButton (buttonSkinSprite:String) : void { + + logMessage("Rendering uploader as button..."); + buttonSkin.load(new URLRequest(buttonSkinSprite)); + var _this:Uploader = this; + + var initLoader:Function = function (event:Event) : void { + buttonSprite.addChild(buttonSkin); + + buttonHeight = buttonSkin.height/4; + buttonWidth = buttonSkin.width; + var buttonMask:Sprite = new Sprite(); + buttonMask.graphics.beginFill(0x000000,1); + buttonMask.graphics.drawRect(0,0,buttonWidth,buttonHeight); + buttonMask.graphics.endFill(); + _this.addChild(buttonMask); + buttonSprite.mask = buttonMask; + + var buttonStageResize:Function = function (evt:Event = null) : void { + buttonSprite.width = _this.stage.stageWidth; + buttonSprite.height = _this.stage.stageHeight*4; + buttonMask.width = _this.stage.stageWidth; + buttonMask.height = _this.stage.stageHeight; + }; + + buttonStageResize(); + + _this.stage.scaleMode = StageScaleMode.NO_SCALE; + _this.stage.align = StageAlign.TOP_LEFT; + _this.stage.tabChildren = false; + + _this.stage.addEventListener(Event.RESIZE, buttonStageResize); + + _this.addEventListener(MouseEvent.ROLL_OVER, buttonMouseOver); + _this.addEventListener(MouseEvent.ROLL_OUT, buttonMouseOut); + _this.addEventListener(MouseEvent.MOUSE_DOWN, buttonMouseDown); + _this.addEventListener(MouseEvent.MOUSE_UP, buttonMouseUp); + _this.addEventListener(MouseEvent.CLICK, handleMouseClick); + + _this.stage.addEventListener(KeyboardEvent.KEY_DOWN, handleKeyDown); + _this.stage.addEventListener(KeyboardEvent.KEY_UP, handleKeyUp); + + + _this.addChild(buttonSprite); + } + + var errorLoader:Function = function (event:IOErrorEvent) : void { + renderAsTransparent(); + } + + buttonSkin.contentLoaderInfo.addEventListener(Event.COMPLETE, initLoader); + buttonSkin.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, errorLoader); + + } + + private function buttonMouseOver (event:MouseEvent) : void { + buttonSkin.y = -1*buttonHeight; + } + + private function buttonMouseOut (event:MouseEvent) : void { + buttonSkin.y = 0; + } + + private function buttonMouseDown (event:MouseEvent) : void { + buttonSkin.y = -2*buttonHeight; + } + + private function buttonMouseUp (event:MouseEvent) : void { + buttonSkin.y = 0; + } + + private function renderAsTransparent () : void { + + logMessage("Rendering uploader as transparent overlay."); + + function transparentStageResize (evt:Event) : void { + buttonSprite.width = buttonSprite.stage.stageWidth; + buttonSprite.height = buttonSprite.stage.stageHeight; + } + + buttonSprite.graphics.beginFill(0xffffff, 0); + buttonSprite.graphics.drawRect(0,0,5,5); + buttonSprite.width = this.stage.stageWidth; + buttonSprite.height = this.stage.stageHeight; + buttonSprite.graphics.endFill(); + this.stage.scaleMode = StageScaleMode.NO_SCALE; + this.stage.align = StageAlign.TOP_LEFT; + this.stage.tabChildren = false; + + this.stage.addEventListener(Event.RESIZE, transparentStageResize); + + this.addEventListener(MouseEvent.CLICK, handleMouseClick); + this.addEventListener(MouseEvent.CLICK, transparentClick); + + this.addEventListener(MouseEvent.MOUSE_DOWN, transparentDown); + this.addEventListener(MouseEvent.MOUSE_UP, transparentUp); + this.addEventListener(MouseEvent.ROLL_OVER, transparentRollOver); + this.addEventListener(MouseEvent.ROLL_OUT, transparentRollOut); + + this.buttonMode = true; + this.useHandCursor = true; + this.addChild(buttonSprite); + } + + private function handleKeyDown (evt:KeyboardEvent) : void { + if (evt.keyCode == Keyboard.ENTER || evt.keyCode == Keyboard.SPACE) { + logMessage("Keyboard 'Enter' or 'Space' down."); + buttonSkin.y = -2*buttonHeight; + } + } + + private function handleKeyUp (evt:KeyboardEvent) : void { + if (evt.keyCode == Keyboard.ENTER || evt.keyCode == Keyboard.SPACE) { + buttonSkin.y = 0; + logMessage("Keyboard 'Enter' or 'Space' up."); + logMessage("Keyboard 'Enter' or 'Space' detected, launching 'Open File' dialog."); + this.browse(this.allowMultiple, this.filterArray); + } + } + + private function handleFocusIn (evt:FocusEvent) : void { + logMessage("Focus is on the Uploader."); + } + + private function handleFocusOut (evt:FocusEvent) : void { + logMessage("Focus is out on the Uploader."); + } + + + private function handleMouseClick (evt:MouseEvent) : void { + logMessage("Mouse click detected, launching 'Open File' dialog."); + this.browse(this.allowMultiple, this.filterArray); + } + + //-------------------------------------------------------------------------- + // + // Overridden Properties + // + //-------------------------------------------------------------------------- + + /** + * @private + * Initializes the component and enables communication with JavaScript + * + * @param parent A container that the PopUpManager uses to place the Menu + * control in. The Menu control may not actually be parented by this object. + * + * @param xmlDataProvider The data provider for the Menu control. + * @see #dataProvider + * + * @return An instance of the Menu class. + * + * @see #popUpMenu() + * @see com.yahoo.astra.fl.data.XMLDataProvider + */ + + protected function initializeComponent():void { + + logMessage("Initializing uploader..."); + var btnSkinURL:String; + btnSkinURL = yuiBridge.flashvars["buttonSkin"]; + logMessage("Button skin: " + btnSkinURL); + + if (btnSkinURL != null) { + logMessage("Starting to render as button..."); + this.renderType = "button"; + this.renderAsButton(btnSkinURL); + } + else { + this.renderType = "transparent"; + this.renderAsTransparent(); + } + + + yuiBridge.addCallbacks ({removeFile:removeFile, clearFileList:clearFileList, upload:upload,uploadThese:uploadThese,uploadAll:uploadAll,cancel:cancel,setAllowLogging:setAllowLogging,setAllowMultipleFiles:setAllowMultipleFiles,setSimUploadLimit:setSimUploadLimit,setFileFilters:setFileFilters,enable:enable, disable:disable}); + // removeFile (fileID:String = null) + // Removes one or all files from the upload queue + // ExternalInterface.addCallback("removeFile", removeFile); + + // clearFileList (): Boolean + // Clears the list of files to be uploaded. + // ExternalInterface.addCallback("clearFileList", clearFileList); + + // upload(fileID:String, url:String, method:String = "GET", vars:Object = null, fieldName:String = "Filedata") + // Uploads the specified file in a specified POST variable, attaching other variables using the specified method + // ExternalInterface.addCallback("upload", upload); + + //ExternalInterface.addCallback("uploadThese", uploadThese); + + // uploadAll(url:String, method:String = "GET", vars:Object = null, fieldName:String = "Filedata") + // Uploads all files in the queue, using simultaneousUploads. + //ExternalInterface.addCallback("uploadAll", uploadAll); + + // cancel (fileID:String = null) + // Cancels the specified file upload; or all, if no id is specified + //ExternalInterface.addCallback("cancel", cancel); + + // setAllowLoging (allowLogging:Boolean = false) + // Allows log outputs to be produced. + //ExternalInterface.addCallback("setAllowLogging", setAllowLogging); + + // setAllowMultipleFiles (allowMultiple:Boolean = false) + // Allows multiple file selection + //ExternalInterface.addCallback("setAllowMultipleFiles", this.setAllowMultipleFiles); + + // setSimUploadLimit(simUpload:int = [2,5]) + // Sets the number of simultaneous uploads allowed when automatically managing queue. + //ExternalInterface.addCallback("setSimUploadLimit", this.setSimUploadLimit); + + // setFileFilters(fileFilters:Array) + // Sets file filters for file selection. + //ExternalInterface.addCallback("setFileFilters", this.setFileFilters); + + // enable() + // Enables Uploader UI + //ExternalInterface.addCallback("enable", enable); + + // disable() + // Disables Uploader UI + //ExternalInterface.addCallback("disable", disable); + + // Initialize properties. + fileDataList = new Object(); + fileRefList = new Object(); + fileIDList = new Dictionary(); + singleFile = new FileReference(); + multipleFiles = new FileReferenceList(); + + fileIDCounter = 0; + + filesToUpload = []; + + } + + + + //-------------------------------------- + // Private Methods + //-------------------------------------- + + /** + * @private + * Formats objects containing extensions of files to be filtered into formal FileFilter objects + */ + + private function processFileFilterObjects(filtersArray:Array) : Array { + + // TODO: Should we have an 'allowedExtensions' property that the JS user accesses directly? Potential here for typos ('extension' instead of 'extensions') as well as a misunderstanding of the nature of the expected array + // TODO: Description not showing (testing on OS X PPC player) + for (var i:int = 0; i < filtersArray.length; i++) { + filtersArray[i] = new FileFilter(filtersArray[i].description, filtersArray[i].extensions, filtersArray[i].macType); + } + + return filtersArray; + } + + /** + * @private + * Outputs the files selected to an output panel and triggers a 'fileSelect' event. + */ + + private function processSelection():void { + + var dstring:String = ""; + dstring += "Files Selected: \n"; + + for each (var item:Object in fileDataList) { + dstring += item.name + "\n "; + } + + logMessage(dstring); + + var newEvent:Object = new Object(); + newEvent.fileList = fileDataList; + newEvent.type = "fileselect" + + yuiBridge.sendEvent(newEvent); + } + + + + /** + * @private + * Adds a file reference object to the internal queue and assigns listeners to its events + */ + + private function addFile(fr:FileReference):void { + + var fileID:String = "file" + fileIDCounter; + var fileName:String = fr.name; + var fileCDate:Date = fr.creationDate; + var fileMDate:Date = fr.modificationDate; + var fileSize:Number = fr.size; + fileIDCounter++; + + fileDataList[fileID] = {id: fileID, name: fileName, cDate: fileCDate, mDate: fileMDate, size: fileSize};//, type: fileType, creator: fileCreator}; + + fr.addEventListener(Event.OPEN, uploadStart); + fr.addEventListener(ProgressEvent.PROGRESS, uploadProgress); + fr.addEventListener(Event.COMPLETE, uploadComplete); + fr.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, uploadCompleteData); + fr.addEventListener(HTTPStatusEvent.HTTP_STATUS, uploadError); + fr.addEventListener(IOErrorEvent.IO_ERROR, uploadError); + fr.addEventListener(SecurityErrorEvent.SECURITY_ERROR, uploadError); + fr.addEventListener(Event.CANCEL,uploadCancel); + + fileRefList[fileID] = fr; + fileIDList[fr] = fileID; + } + + /** + * @private + * Queues a file for upload + */ + private function queueForUpload(fr:FileReference, request:URLRequest, fieldName:String):void { + filesToUpload.push( {fr:fr, request:request, fieldName:fieldName }); + } + + /** + * @private + * Uploads the next file in the upload queue. + */ + + private function processQueue():void { + while (this.currentUploadThreads < this.simultaneousUploadLimit && filesToUpload.length > 0) { + var objToUpload:Object = filesToUpload.shift(); + var fr:FileReference = objToUpload.fr; + var request:URLRequest = objToUpload.request; + var fieldName:String = objToUpload.fieldName; + logMessage("Starting upload for " + objToUpload.id); + fr.upload(request,fieldName); + this.currentUploadThreads++; + } + } + + /** + * @private + * Creates a URLRequest object from a url, and optionally includes an HTTP request method and additional variables to be sent + */ + + private function formURLRequest(url:String, method:String = "GET", vars:Object = null):URLRequest { + + var request:URLRequest = new URLRequest(); + request.url = url; + request.method = method; + request.data = new URLVariables(); + + + for (var itemName:String in vars) { + request.data[itemName] = vars[itemName]; + } + + + return request; + } + + /** + * @private + * Determines whether an object is equivalent to an empty string + */ + + private function isEmptyString(toCheck:*):Boolean { + + if( toCheck == "null" || + toCheck == "" || + toCheck == null ) { + + return true; + } + + else { + return false; + } + } + + private function logMessage (message:String) : void { + if (this.allowLog) { + trace(message); + } + } + + } + +} + diff --git a/src/uploader-deprecated/as/com/yahoo/util/YUIBridge.as b/src/uploader-deprecated/as/com/yahoo/util/YUIBridge.as new file mode 100644 index 0000000..44dd270 --- /dev/null +++ b/src/uploader-deprecated/as/com/yahoo/util/YUIBridge.as @@ -0,0 +1,111 @@ +package com.yahoo.util + { + import flash.display.Stage; + import flash.external.ExternalInterface; + import flash.utils.getDefinitionByName; + import flash.system.Security; + + public class YUIBridge extends Object + { + public var flashvars:Object; + private var _jsHandler:String; + private var _swfID:String; + private var _yId:String; + + private var _stage:Stage; + + private var _instances:Object = {}; + + public function YUIBridge(stage:Stage) + { + _stage = stage; + flashvars = _stage.loaderInfo.parameters; + + if (flashvars["yId"] && flashvars["YUIBridgeCallback"] && flashvars["YUISwfId"] && ExternalInterface.available) { + _jsHandler = flashvars["YUIBridgeCallback"]; + _swfID = flashvars["YUISwfId"]; + _yId = flashvars["yId"]; + } + + if(flashvars.hasOwnProperty("allowedDomain")) + { + Security.allowDomain(flashvars.allowedDomain); + } + + ExternalInterface.addCallback("createInstance", createInstance); + ExternalInterface.addCallback("exposeMethod", exposeMethod); + ExternalInterface.addCallback("getProperty", getProperty); + ExternalInterface.addCallback("setProperty", setProperty); + + } + + public function createInstance(instanceId:String, className:String, constructorArguments:Array = null) : void { + + constructorArguments == null ? constructorArguments = [] : constructorArguments = constructorArguments; + + var cA:Array = constructorArguments; + var classReference:Class = getDefinitionByName(className) as Class; + + var instance:Object; + + switch (cA.length) { + case 1: instance = new classReference(cA[0]); + case 2: instance = new classReference(cA[0], cA[1]); + case 3: instance = new classReference(cA[0], cA[1], cA[2]); + case 4: instance = new classReference(cA[0], cA[1], cA[2], cA[3]); + case 5: instance = new classReference(cA[0], cA[1], cA[2], cA[3], cA[4]); + case 6: instance = new classReference(cA[0], cA[1], cA[2], cA[3], cA[4], cA[5]); + case 7: instance = new classReference(cA[0], cA[1], cA[2], cA[3], cA[4], cA[5], cA[6]); + case 8: instance = new classReference(cA[0], cA[1], cA[2], cA[3], cA[4], cA[5], cA[6], cA[7]); + case 9: instance = new classReference(cA[0], cA[1], cA[2], cA[3], cA[4], cA[5], cA[6], cA[7], cA[8]); + case 10: instance = new classReference(cA[0], cA[1], cA[2], cA[3], cA[4], cA[5], cA[6], cA[7], cA[8], cA[9]); + case 11: instance = new classReference(cA[0], cA[1], cA[2], cA[3], cA[4], cA[5], cA[6], cA[7], cA[8], cA[9], cA[10]); + case 12: instance = new classReference(cA[0], cA[1], cA[2], cA[3], cA[4], cA[5], cA[6], cA[7], cA[8], cA[9], cA[10], cA[11]); + case 13: instance = new classReference(cA[0], cA[1], cA[2], cA[3], cA[4], cA[5], cA[6], cA[7], cA[8], cA[9], cA[10], cA[11], cA[12]); + default: instance = new classReference(); + } + + _instances[instanceId] = instance; + } + + public function exposeMethod(instanceId:String, methodName:String, exposedName:String = "") : void { + exposedName == "" ? exposedName = methodName : exposedName = exposedName; + + if (_instances[instanceId] && ExternalInterface.available) { + ExternalInterface.addCallback(exposedName, _instances[instanceId][methodName]); + } + } + + public function getProperty (instanceId:String, propertyName:String) : Object { + if (_instances[instanceId] && _instances[instanceId].hasOwnProperty(propertyName)) { + return _instances[instanceId][propertyName]; + } + else { + return null; + } + } + + public function setProperty (instanceId:String, propertyName:String, propertyValue:Object) : void { + if (_instances[instanceId] && _instances[instanceId].hasOwnProperty(propertyName)) { + _instances[instanceId][propertyName] = propertyValue; + } + } + + public function addCallbacks (callbacks:Object) : void { + if (ExternalInterface.available) { + for (var callback:String in callbacks) { + trace("Added callback for " + callback + ", function " + callbacks[callback]); + ExternalInterface.addCallback(callback, callbacks[callback]); + } + sendEvent({type:"swfReady"}); + } + } + + public function sendEvent (evt:Object) : void { + if (ExternalInterface.available) { + ExternalInterface.call("YUI.applyTo", _yId, _jsHandler, [_swfID, evt]); + } + + } + } + } diff --git a/src/uploader/as/File.as b/src/uploader/as/File.as new file mode 100644 index 0000000..51a4cc6 --- /dev/null +++ b/src/uploader/as/File.as @@ -0,0 +1,56 @@ +package + +{ + + import flash.events.EventDispatcher; + import flash.events.DataEvent; + import flash.events.Event; + import flash.events.FocusEvent; + import flash.events.HTTPStatusEvent; + import flash.events.IOErrorEvent; + import flash.events.ProgressEvent; + import flash.events.SecurityErrorEvent; + import flash.net.FileReference; + + + /** + * The base FlashUploader class for YUI 3.5 FlashUploader. + * + * @author Allen Rabinovich + */ + + public class File extends EventDispatcher { + + //-------------------------------------- + // Constructor + //-------------------------------------- + + public function File(newFile:FileReference) + { + var now : Date = new Date(); + this.fileId = "fileyui_" + now.getTime() + "_" + idCounter; + this.fileReference = newFile; + File.idCounter+=1; + + this.fileReference.addEventListener(Event.OPEN, this.fileEventHandler); + this.fileReference.addEventListener(ProgressEvent.PROGRESS, this.fileEventHandler); + this.fileReference.addEventListener(Event.COMPLETE, this.fileEventHandler); + this.fileReference.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, this.fileEventHandler); + this.fileReference.addEventListener(HTTPStatusEvent.HTTP_STATUS, this.fileEventHandler); + this.fileReference.addEventListener(IOErrorEvent.IO_ERROR, this.fileEventHandler); + this.fileReference.addEventListener(SecurityErrorEvent.SECURITY_ERROR, this.fileEventHandler); + this.fileReference.addEventListener(Event.CANCEL, this.fileEventHandler); + } + + private function fileEventHandler (event:Event) : void { + this.dispatchEvent(event); + } + + public var fileId:String = ""; + public var fileReference:FileReference; + private static var idCounter:uint = 0; + + // cancel, complete, httpStatus, ioError, open, progress, securityError, select, uploadCompleteData + } + +} \ No newline at end of file diff --git a/src/uploader/as/FlashUploader.as b/src/uploader/as/FlashUploader.as new file mode 100644 index 0000000..61a3576 --- /dev/null +++ b/src/uploader/as/FlashUploader.as @@ -0,0 +1,517 @@ +package + +{ + + import com.yahoo.util.YUIBridge; + + import flash.display.Loader; + import flash.display.DisplayObject; + import flash.display.Sprite; + import flash.display.StageAlign; + import flash.display.StageScaleMode; + import flash.events.DataEvent; + import flash.events.Event; + import flash.events.HTTPStatusEvent; + import flash.events.IOErrorEvent; + import flash.events.KeyboardEvent; + import flash.events.MouseEvent; + import flash.events.ProgressEvent; + import flash.events.SecurityErrorEvent; + import flash.external.ExternalInterface; + import flash.net.FileFilter; + import flash.net.FileReference; + import flash.net.FileReferenceList; + import flash.net.URLRequest; + import flash.net.URLVariables; + import flash.ui.Keyboard; + import flash.utils.Dictionary; + import flash.utils.setTimeout; + import flash.filters.GlowFilter; + import flash.accessibility.*; + + [SWF(backgroundColor=0xFFFFFF)] + + /** + * The base FlashUploader class for YUI 3.5 FlashUploader. + * + * @class FlashUploader + * @author Allen Rabinovich + * + */ + + public class FlashUploader extends Sprite { + + /** + * Instantiates FlashUploader + * @constructor + */ + public function FlashUploader() + { + + fileList = {}; + filesInProgress = {}; + singleFile = new FileReference(); + multipleFiles = new FileReferenceList(); + + yuiBridge = new YUIBridge(this.stage); + yuiBridge.addCallbacks ({clearFileList:clearFileList, upload:upload,cancel:cancel,setAllowMultipleFiles:setAllowMultipleFiles,setSimUploadLimit:setSimUploadLimit,setFileFilters:setFileFilters,enable:enable, disable:disable}); + + var _accProps:AccessibilityProperties = new AccessibilityProperties(); + _accProps.silent = false; + _accProps.name = "Select Files button"; + _accProps.description = "Select Files button"; + + this.accessibilityProperties = _accProps; + + // setTimeout(updateAccessibility, 2000); + + // this.log("Accactive? " + Accessibility.active); + if(Accessibility.active) { + Accessibility.updateProperties(); + } + + this.renderAsTransparent(); + } + + private function updateAccessibility():void { + + } + + + private function log (msg: String) : void { + this.yuiBridge.sendEvent({type:"trace", message: msg}); + } + + + private function transparentStageResize (evt:Event) : void { + buttonSprite.width = buttonSprite.stage.stageWidth; + buttonSprite.height = buttonSprite.stage.stageHeight; + } + + private function keyboardEventHandler (evt : KeyboardEvent) : void { + // trace("key received: " + evt.keyCode); + this.log("Key pressed " + evt.keyCode); + this.log("Shift key " + evt.shiftKey); + this.log("Target " + evt.target); + this.log("In focus: " + this.stage.focus); + switch (evt.keyCode) { + case 9: + if (evt.shiftKey) { + // trace("tabback"); + this.yuiBridge.sendEvent({type:"tabback"}); + } + else { + // trace("tabforward"); + this.yuiBridge.sendEvent({type:"tabforward"}); + } + break; + case 32: + case 13: + if (this.enabled) { + this.handleMouseClick(new MouseEvent("mousevent")); + } + break; + } + } + + + private function renderAsTransparent () : void { + + buttonSprite.graphics.beginFill(0xffffff, 0); + buttonSprite.graphics.drawRect(0,0,5,5); + buttonSprite.width = this.stage.stageWidth; + buttonSprite.height = this.stage.stageHeight; + buttonSprite.graphics.endFill(); + buttonSprite.tabEnabled = false; + + this.stage.scaleMode = StageScaleMode.NO_SCALE; + this.stage.align = StageAlign.TOP_LEFT; + this.stage.tabChildren = false; + + this.stage.addEventListener(Event.RESIZE, this.transparentStageResize); + this.stage.addEventListener(KeyboardEvent.KEY_DOWN, this.keyboardEventHandler); + // trace("3.0"); + + this.buttonMode = true; + this.useHandCursor = true; + this.tabEnabled = false; + this.enable(); + + this.addChild(buttonSprite); + } + + + //-------------------------------------------------------------------------- + // + // Variables and setters + // + //-------------------------------------------------------------------------- + + private var buttonSprite:Sprite = new Sprite(); + + private var enabled:Boolean = true; + + private var allowMultiple:Boolean = false; + private var filterArray:Array; + + private var fileList:Object; + private var filesInProgress:Object; + + private var singleFile:FileReference; + private var multipleFiles:FileReferenceList; + + private var yuiBridge:YUIBridge; + + private var simultaneousUploadLimit:Number = 2; + + public function setSimUploadLimit (simUploadLimit:int) : void { + this.simultaneousUploadLimit = simUploadLimit; + } + + + public function setFileFilters (filtersArray:Array) : void { + + for (var i:int = 0; i < filtersArray.length; i++) { + filtersArray[i] = new FileFilter(filtersArray[i].description, + filtersArray[i].extensions, + filtersArray[i].macType); + } + + this.filterArray = filtersArray; + } + + public function setAllowMultipleFiles (allowMultipleFiles:Boolean) : void { + this.allowMultiple = allowMultipleFiles; + //yuiBridge.log("setAllowMultipleFiles has been called, and the allowMultiple value is now " + this.allowMultiple); + } + + + // Browse for single or multiple files, with or without a filter array. + + private function browse (allowMultiple:Boolean = false, filterArray:Array = null):void { + + if(!allowMultiple) { + singleFile = new FileReference(); + singleFile.addEventListener(Event.SELECT, singleFileSelected); + + if(filterArray) { + singleFile.browse(filterArray); + } + else { + singleFile.browse(); + } + + } + + else { + + multipleFiles = new FileReferenceList(); + multipleFiles.addEventListener(Event.SELECT, multipleFilesSelected); + + if(filterArray) { + multipleFiles.browse(filterArray); + } + + else { + multipleFiles.browse(); + } + + } + + } + + + // Enable or disable the button + + public function enable () : void { + this.enabled = true; + this.addEventListener(MouseEvent.CLICK, handleMouseClick); + + this.addEventListener(MouseEvent.MOUSE_DOWN, handleMouseDown); + this.addEventListener(MouseEvent.MOUSE_UP, handleMouseUp); + this.stage.addEventListener(MouseEvent.MOUSE_UP, handleMouseUp); + this.addEventListener(MouseEvent.ROLL_OVER, handleRollOver); + this.addEventListener(MouseEvent.ROLL_OUT, handleRollOut); + } + + public function disable () : void { + this.enabled = false; + this.removeEventListener(MouseEvent.CLICK, handleMouseClick); + + this.removeEventListener(MouseEvent.MOUSE_DOWN, handleMouseDown); + this.removeEventListener(MouseEvent.MOUSE_UP, handleMouseUp); + this.stage.removeEventListener(MouseEvent.MOUSE_UP, handleMouseUp); + this.removeEventListener(MouseEvent.ROLL_OVER, handleRollOver); + this.removeEventListener(MouseEvent.ROLL_OUT, handleRollOut); + } + + /** + * Clears the set of files that had been selected for upload + */ + + public function clearFileList():void { + + this.fileList = {}; + + } + + + + public function upload(fileID:String, url:String, vars:Object = null, fieldName:String = "Filedata"):void { + + this.log("upload has been called"); + if(isEmptyString(fieldName)) { + fieldName = "Filedata"; + } + + this.log("The url is " + url); + var request:URLRequest = formURLRequest(url, "POST", vars); + + + var file:File = this.fileList[fileID]; + + this.log("Got the file with id " + file.fileId); + + var fr:FileReference = file.fileReference; + + fr.upload(request, fieldName); + this.filesInProgress[fileID] = file; + } + + + public function cancel(fileID:String = null):void { + + if (fileID == null) { // cancel all files + for each (var item:File in this.filesInProgress) { + item.fileReference.cancel(); + } + + this.filesInProgress = {}; + } + + else { + var fr:File = filesInProgress[fileID]; + if (fr) { + fr.fileReference.cancel(); + } + + delete filesInProgress[fileID]; + } + + } + + + // Interactive mouse events + + private function handleMouseClick (evt:*) : void { + this.browse(this.allowMultiple, this.filterArray); + var newEvent:Object = new Object(); + this.log("mouseclick"); + newEvent.type = "click"; + yuiBridge.sendEvent(newEvent); + } + + + private function handleMouseDown (event:MouseEvent) : void { + var newEvent:Object = new Object(); + this.log("mousedown"); + newEvent.type = "mousedown"; + yuiBridge.sendEvent(newEvent); + } + + private function handleMouseUp (event:*) : void { + var newEvent:Object = new Object(); + this.log("mouseup"); + newEvent.type = "mouseup"; + yuiBridge.sendEvent(newEvent); + } + + private function handleRollOver (event:MouseEvent) : void { + var newEvent:Object = new Object(); + this.log("rollover"); + newEvent.type = "mouseenter"; + yuiBridge.sendEvent(newEvent); + } + + private function handleRollOut (event:MouseEvent) : void { + var newEvent:Object = new Object(); + this.log("rollout"); + newEvent.type = "mouseleave"; + yuiBridge.sendEvent(newEvent); + } + + + private function uploadStart (event:Event) : void { + var newEvent:Object = new Object(); + this.log("START fired for: " + event.target.fileId); + newEvent.id = event.target.fileId; + newEvent.type = "uploadstart"; + yuiBridge.sendEvent(newEvent); + } + + + private function uploadProgress (event:ProgressEvent) : void { + var newEvent:Object = new Object(); + this.log("PROGRESS fired for: " + event.target.fileReference.name + ":::" + event.bytesLoaded + ":::" + event.bytesTotal); + newEvent.id = event.target.fileId; + newEvent.bytesLoaded = event.bytesLoaded; + newEvent.bytesTotal = event.bytesTotal; + newEvent.type = "uploadprogress"; + yuiBridge.sendEvent(newEvent); + } + + + private function uploadComplete (event:Event) : void { + var newEvent:Object = new Object(); + this.log("COMPLETE fired for: " + event.target.fileId); + newEvent.id = event.target.fileId; + newEvent.type = "uploadcomplete"; + yuiBridge.sendEvent(newEvent); + } + + + private function uploadCompleteData (event:DataEvent) : void { + var newEvent:Object = new Object(); + this.log("COMPLETEDATA fired for: " + event.target.fileId); + newEvent.id = event.target.fileId; + newEvent.data = event.data; + newEvent.type = "uploadcompletedata"; + yuiBridge.sendEvent(newEvent); + } + + private function uploadCancel (event:Event) : void { + var newEvent:Object = new Object(); + this.log("CANCEL fired for: " + event.target.fileId); + newEvent.id = event.target.fileId; + newEvent.type = "uploadcancel"; + yuiBridge.sendEvent(newEvent); + } + + + private function uploadError (event:Event) : void { + var newEvent:Object = new Object(); + this.log("ERROR has fired for: " + event.target.fileId); + this.log("The event type is " + event.type); + if (event is IOErrorEvent) { + this.log("The event text is " + (event as IOErrorEvent).text); + newEvent.source="io"; + newEvent.message = (event as IOErrorEvent).text; + } + else if (event is HTTPStatusEvent) { + this.log("The event status is " + (event as HTTPStatusEvent).status); + newEvent.source="http"; + newEvent.message = (event as HTTPStatusEvent).status; + } + for (var itemName:String in event) { + newEvent[itemName] = event[itemName]; + this.log("Error details / " + itemName + ": " + event[itemName]); + } + + newEvent.id = event.target.fileId; + yuiBridge.sendEvent(newEvent); + } + + + // Fired when the user selects a single file + private function singleFileSelected(event:Event):void { + this.clearFileList(); + var newFile:File = addFile(event.target as FileReference); + processSelection(new Array(newFile)); + } + + + + // Fired when the user selects multiple files + private function multipleFilesSelected(event:Event):void { + var currentFRL:FileReferenceList = event.target as FileReferenceList; + var addedFiles:Array = []; + for each (var currentFR:FileReference in currentFRL.fileList) { + addedFiles.push(addFile(currentFR)); + } + processSelection(addedFiles); + } + + + /** + * @private + * Outputs the files selected to an output panel and triggers a 'fileSelect' event. + */ + + private function processSelection(selectedFiles : Array):void { + + var newEvent:Object = new Object(); + newEvent.fileList = selectedFiles; + newEvent.type = "fileselect"; + + yuiBridge.sendEvent(newEvent); + } + + + + /** + * @private + * Adds a file reference object to the internal queue and assigns listeners to its events + */ + + private function addFile(fr:FileReference) : File { + + var newFile:File = new File(fr); + + newFile.addEventListener(Event.OPEN, uploadStart); + newFile.addEventListener(ProgressEvent.PROGRESS, uploadProgress); + newFile.addEventListener(Event.COMPLETE, uploadComplete); + newFile.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, uploadCompleteData); + newFile.addEventListener(HTTPStatusEvent.HTTP_STATUS, uploadError); + newFile.addEventListener(IOErrorEvent.IO_ERROR, uploadError); + newFile.addEventListener(SecurityErrorEvent.SECURITY_ERROR, uploadError); + newFile.addEventListener(Event.CANCEL,uploadCancel); + + fileList[newFile.fileId] = newFile; + + return newFile; + } + + /** + * @private + * Creates a URLRequest object from a url, and optionally includes an HTTP request method and additional variables to be sent + */ + + private function formURLRequest(url:String, method:String = "GET", vars:Object = null):URLRequest { + + var request:URLRequest = new URLRequest(); + request.url = url; + request.method = method; + request.data = new URLVariables(); + + + for (var itemName:String in vars) { + request.data[itemName] = vars[itemName]; + } + + + return request; + } + + /** + * @private + * Determines whether an object is equivalent to an empty string + */ + + private function isEmptyString(toCheck:*):Boolean { + + if( toCheck == "null" || + toCheck == "" || + toCheck == null ) { + + return true; + } + + else { + return false; + } + } + + } + +} + diff --git a/src/uploader/as/Uploader.as b/src/uploader/as/Uploader.as new file mode 100644 index 0000000..2d1f7fd --- /dev/null +++ b/src/uploader/as/Uploader.as @@ -0,0 +1,980 @@ +package + +{ + + import com.yahoo.util.YUIBridge; + + import flash.display.Loader; + import flash.display.Sprite; + import flash.display.StageAlign; + import flash.display.StageScaleMode; + import flash.events.DataEvent; + import flash.events.Event; + import flash.events.FocusEvent; + import flash.events.HTTPStatusEvent; + import flash.events.IOErrorEvent; + import flash.events.KeyboardEvent; + import flash.events.MouseEvent; + import flash.events.ProgressEvent; + import flash.events.SecurityErrorEvent; + import flash.external.ExternalInterface; + import flash.net.FileFilter; + import flash.net.FileReference; + import flash.net.FileReferenceList; + import flash.net.URLRequest; + import flash.net.URLVariables; + import flash.ui.Keyboard; + import flash.utils.Dictionary; + + + + [SWF(backgroundColor=0xFFFFFF)] + + /** + * The base Uploader class for YUI's Flash-based file uploader. + * + * @author Allen Rabinovich + */ + + public class Uploader extends Sprite { + + //-------------------------------------- + // Constructor + //-------------------------------------- + + public function Uploader() + { + super(); + yuiBridge = new YUIBridge(this.stage); + logMessage("Initializing uploader..."); + initializeComponent(); + } + + //-------------------------------------------------------------------------- + // + // Variables + // + //-------------------------------------------------------------------------- + + private var allowMultiple:Boolean = false; + private var allowLog:Boolean = false; + private var filterArray:Array; + + private var fileDataList:Object; + private var fileRefList:Object; + private var fileIDList:Dictionary; + private var fileIDCounter:Number; + private var filesToUpload:Array; + + private var singleFile:FileReference; + private var multipleFiles:FileReferenceList; + + public var yuiBridge:YUIBridge; + + /** + * Determines how many files will be uploaded simultaneously + * + * @see setSimUploadLimit + * @langversion 3.0 + * @playerversion Flash 9.0.28.0 + */ + public var simultaneousUploadLimit:Number = 2; + + // Track the number of current upload threads + private var currentUploadThreads:Number = 0; + + // How the uploader is rendered, either "button" or "transparent" + private var renderType:String; + + // The Sprite containing the rendered UI. + private var buttonSprite:Sprite = new Sprite(); + + // The skin for the button, if "button" renderType is used. + private var buttonSkin:Loader = new Loader(); + + // Height and width for the button + private var buttonHeight:Number; + private var buttonWidth:Number; + + //-------------------------------------- + // Public Methods + //-------------------------------------- + + /** + * Sets the number of simultaneous file uploads possible. + * The maximum is 5. + * @param numberOfUploads Number of simultaneous uploads, no fewer than 1 + * and no larger than 5. + */ + public function setSimUploadLimit (simUploadLimit:int) : void { + if (simUploadLimit <= 1) { + this.simultaneousUploadLimit = 1; + logMessage("Simultaneous upload limit has been set to 1"); + } + else if (simUploadLimit >= 5) { + this.simultaneousUploadLimit = 5; + logMessage("Simultaneous upload limit has been set to 5"); + } + else { + this.simultaneousUploadLimit = simUploadLimit; + logMessage("Simultaneous upload limit has been set to " + simUploadLimit); + } + } + + + /** + * Sets a list of file type filters for the "Open File(s)" dialog. + * + * @param newFilterArray An array of sets of key-value pairs of the form + * {extensions: extensionString, description: descriptionString, macType: macTypeString [optional]} + * The extension string is a semicolon-delimited list of elements of the form "*.xxx", + * e.g. "*.jpg;*.gif;*.png". + */ + public function setFileFilters(newFilterArray:Array) : void { + filterArray = processFileFilterObjects(newFilterArray); + + if (allowLog) { + var logString:String = "File filters have been set to the following: \n"; + for each (var ff:FileFilter in filterArray) { + logString += ff.extension + ": " + ff.description + "\n"; + } + logMessage(logString); + } + } + + /** + * Sets a flag allowing logging in Flash trace and Yahoo logger. + * + * @param allowLogging Whether to allow log messages. + * + */ + public function setAllowLogging(allowLogging:Boolean) : void { + if (this.allowLog != allowLogging) { + logMessage("Logging has been turned " + (allowLogging ? "on." : "off.")); + this.allowLog = allowLogging; + } + } + + /** + * Sets a flag allowing multiple file selection in the "Browse" dialog. + * + * @param allowMultiple Whether to allow multiple file selection. + * + */ + public function setAllowMultipleFiles(allowMultipleFiles:Boolean) : void { + this.allowMultiple = allowMultipleFiles; + logMessage("Multiple file upload has been turned " + (allowMultiple ? "on." : "off.")); + } + + + /** + * Triggers a prompt for the user to browse their file system to select + * files to be uploaded. + * + * @param allowMultiple Whether to allow the user to select more than + * one file + * + * @param filterArray An array of filter objects, each with + * description, and extensions properties which + * determine which files the user is allowed to select + */ + + private function browse(allowMultiple:Boolean = false, filterArray:Array = null):void { + + if(!allowMultiple) { + logMessage("Starting to browse for a single file...") + singleFile = new FileReference(); + singleFile.addEventListener(Event.SELECT, singleFileSelected); + + if(filterArray) { + singleFile.browse(filterArray); + } + else { + singleFile.browse(); + } + } + + else { + + logMessage("Starting to browse for multiple files...") + multipleFiles = new FileReferenceList(); + multipleFiles.addEventListener(Event.SELECT, multipleFilesSelected); + + if(filterArray) { + multipleFiles.browse(filterArray); + } + + else { + multipleFiles.browse(); + } + + } + + } + + + /** + * Removes the file from the set to be uploaded + * + * @param fileID The ID of the file to be removed + */ + + public function removeFile(fileID:String):Object { + + logMessage("Removing file " + fileID); + + delete fileDataList[fileID]; + delete fileRefList[fileID]; + + logMessage("Returning new file list: " + fileDataList); + return fileDataList; + } + + public function enable () : void { + if (renderType == "button") { + this.addEventListener(MouseEvent.ROLL_OVER, buttonMouseOver); + this.addEventListener(MouseEvent.ROLL_OUT, buttonMouseOut); + this.addEventListener(MouseEvent.MOUSE_DOWN, buttonMouseDown); + this.addEventListener(MouseEvent.MOUSE_UP, buttonMouseUp); + this.addEventListener(MouseEvent.CLICK, handleMouseClick); + buttonSkin.y = 0; + } + else { + this.addEventListener(MouseEvent.CLICK, handleMouseClick); + this.addEventListener(MouseEvent.CLICK, transparentClick); + + this.addEventListener(MouseEvent.MOUSE_DOWN, transparentDown); + this.addEventListener(MouseEvent.MOUSE_UP, transparentUp); + this.addEventListener(MouseEvent.ROLL_OVER, transparentRollOver); + this.addEventListener(MouseEvent.ROLL_OUT, transparentRollOut); + } + + logMessage("Uploader UI has been enabled."); + } + + public function disable () : void { + if (renderType == "button") { + this.removeEventListener(MouseEvent.ROLL_OVER, buttonMouseOver); + this.removeEventListener(MouseEvent.ROLL_OUT, buttonMouseOut); + this.removeEventListener(MouseEvent.MOUSE_DOWN, buttonMouseDown); + this.removeEventListener(MouseEvent.MOUSE_UP, buttonMouseUp); + this.removeEventListener(MouseEvent.CLICK, handleMouseClick); + buttonSkin.y = -3*buttonHeight; + } + else { + this.removeEventListener(MouseEvent.CLICK, handleMouseClick); + this.removeEventListener(MouseEvent.CLICK, transparentClick); + + this.removeEventListener(MouseEvent.MOUSE_DOWN, transparentDown); + this.removeEventListener(MouseEvent.MOUSE_UP, transparentUp); + this.removeEventListener(MouseEvent.ROLL_OVER, transparentRollOver); + this.removeEventListener(MouseEvent.ROLL_OUT, transparentRollOut); + } + + logMessage("Uploader UI has been disabled."); + } + + /** + * Clears the set of files that had been selected for upload + */ + + public function clearFileList():Boolean { + + filesToUpload = []; + fileDataList = new Object(); + fileRefList = new Object(); + fileIDList = new Dictionary(); + fileIDCounter = 0; + + logMessage("The file list has been cleared."); + + return true; + } + + + + /** + * Uploads a file corresponding to a specified ID to a specified path where a script handles writing to the server. + * + * @param fileID The ID of the file to be uploaded + * @param url The path to the serverside script + * @param method The HTTP submission method. Possible values are "GET" and "POST" + * @param vars An object containing variables to be sent along with the request + * @param fieldName The field name that precedes the file data in the upload POST operation. + * The uploadDataFieldName value must be non-null and a non-empty String. + * @param headers An object containing variables that should be set as headers in the POST request. The following header names + * cannot be used: + * + * Accept-Charset, Accept-Encoding, Accept-Ranges, Age, Allow, Allowed, Authorization, Charge-To, Connect, Connection, + * Content-Length, Content-Location, Content-Range, Cookie, Date, Delete, ETag, Expect, Get, Head, Host, Keep-Alive, + * Last-Modified, Location, Max-Forwards, Options, Post, Proxy-Authenticate, Proxy-Authorization, Proxy-Connection, + * Public, Put, Range, Referer, Request-Range, Retry-After, Server, TE, Trace, Trailer, Transfer-Encoding, Upgrade, + * URI, User-Agent, Vary, Via, Warning, WWW-Authenticate, x-flash-version. + * + */ + + public function upload(fileID:String, url:String, method:String = "GET", vars:Object = null, fieldName:String = "Filedata"):void { + + // null checking in the params is not working correctly + filesToUpload = []; + + if(isEmptyString(method)) { + method = "GET"; + } + + if(isEmptyString(fieldName)) { + fieldName = "Filedata"; + } + + var request:URLRequest = formURLRequest(url, method, vars); + var fr:FileReference = fileRefList[fileID]; + + this.currentUploadThreads++; + fr.upload(request,fieldName); + + logMessage("Starting the upload of file " + fileID); + } + + /** + * Uploads the specified files to a specified path where a script handles writing to the server. + * + * @param fileIDs The IDs of the files to be uploaded + * @param url The path to the serverside script + * @param method The HTTP submission method. Possible values are "GET" and "POST" + * @param vars An object containing data to be sent along with the request + * @param fieldName The field name that precedes the file data in the upload POST operation. The uploadDataFieldName value must be non-null and a non-empty String. + */ + + public function uploadThese(fileIDs:Array, url:String, method:String = "GET", vars:Object = null, fieldName:String = "Filedata"):void { + if(isEmptyString(method)) { + method = "GET"; + } + + if(isEmptyString(fieldName)) { + fieldName = "Filedata"; + } + + var request:URLRequest = formURLRequest(url, method, vars); + + for each(var fileID:String in fileIDs) { + queueForUpload(fileRefList[fileID], request, fieldName); + } + + processQueue(); + } + + /** + * Uploads all files to a specified path where a script handles writing to the server. + * + * @param fileID The ID of the file to be uploaded + * @param url The path to the serverside script + * @param method The HTTP submission method. Possible values are "GET" and "POST" + * @param vars An object containing data to be sent along with the request + * @param fieldName The field name that precedes the file data in the upload POST operation. The uploadDataFieldName value must be non-null and a non-empty String. + * @param headers An object containing variables that should be set as headers in the POST request. The following header names + * cannot be used: + * + * Accept-Charset, Accept-Encoding, Accept-Ranges, Age, Allow, Allowed, Authorization, Charge-To, Connect, Connection, + * Content-Length, Content-Location, Content-Range, Cookie, Date, Delete, ETag, Expect, Get, Head, Host, Keep-Alive, + * Last-Modified, Location, Max-Forwards, Options, Post, Proxy-Authenticate, Proxy-Authorization, Proxy-Connection, + * Public, Put, Range, Referer, Request-Range, Retry-After, Server, TE, Trace, Trailer, Transfer-Encoding, Upgrade, + * URI, User-Agent, Vary, Via, Warning, WWW-Authenticate, x-flash-version. + * + */ + + public function uploadAll(url:String, method:String = "GET", vars:Object = null, fieldName:String = "Filedata", headers:Object = null):void { + if(isEmptyString(method)) { + method = "GET"; + } + + if(isEmptyString(fieldName)) { + fieldName = "Filedata"; + } + + var request:URLRequest = formURLRequest(url, method, vars); + + filesToUpload = []; + + // sort files in the order that they were given to us + var fileIds:Array = []; + for (var fileId:String in fileRefList) { + fileIds.push(parseInt(fileId.substr(4))); + } + fileIds.sort(Array.NUMERIC); + for each(var fileId2:int in fileIds) { + queueForUpload(fileRefList["file"+fileId2], request, fieldName); + } + + processQueue(); + } + + /** + * Cancels either an upload of the file corresponding to a given fileID, or in the absence of the specified fileID, all active files being uploaded. + * + * @param fileID The ID of the file to be uploaded + */ + + public function cancel(fileID:String = null):void { + + logMessage("Canceling upload of " + fileID?fileID:"all files."); + + if (fileID == null) { // cancel all files + for each (var item:FileReference in fileRefList) { + item.cancel(); + } + this.currentUploadThreads = 0; + filesToUpload = []; + } + + else { // cancel specified file + var fr:FileReference = fileRefList[fileID]; + if (this.currentUploadThreads > 0) + this.currentUploadThreads--; + fr.cancel(); + } + + } + + + + /* + Events + ------------------------------- + mouseDown - fires when the mouse button is pressed over uploader + mouseUp - fires when the mouse button is released over uploader + rollOver - fires when the mouse rolls over the uploader + rollOut - fires when the mouse rolls out of the uploader + click - fires when the uploader is clicked + fileSelect - fires when the user selects one or more files (after browse is called). Passes the array of currently selected files (if prior browse calls were made and clearFileList hasn't been called, all files the user has ever selected will be returned), along with all information available about them (name, size, type, creationDate, modificationDate, creator). + uploadStart - fires when a file starts uploading. Passes a file id for identifying the file. + uploadProgress - fires when a file upload reports progress. Passes the file id, as well as bytesUploaded and bytesTotal for the given file. + uploadComplete - fires when a file upload is completed successfully and passes the corresponding file id. + uploadCompleteData - fires when data is received from the server after upload and passes the corresponding file id and the said data. + uploadError - fires when an error occurs during download. Passes the id of the file that was being uploaded and an error type. + */ + + private function transparentDown (event:MouseEvent) : void { + logMessage("Dispatching mousedown event."); + var newEvent:Object = new Object(); + newEvent.type = "mousedown"; + yuiBridge.sendEvent(newEvent); + } + + private function transparentUp (event:MouseEvent) : void { + logMessage("Dispatching mouseup event."); + var newEvent:Object = new Object(); + newEvent.type = "mouseup"; + yuiBridge.sendEvent(newEvent); + } + + private function transparentRollOver (event:MouseEvent) : void { + logMessage("Dispatching mouseenter event."); + var newEvent:Object = new Object(); + newEvent.type = "mouseenter"; + yuiBridge.sendEvent(newEvent); + } + + private function transparentRollOut (event:MouseEvent) : void { + logMessage("Dispatching mouseleave event."); + var newEvent:Object = new Object(); + newEvent.type = "mouseleave"; + yuiBridge.sendEvent(newEvent); + } + + private function transparentClick (event:MouseEvent) : void { + logMessage("Dispatching click event."); + var newEvent:Object = new Object(); + newEvent.type = "click"; + yuiBridge.sendEvent(newEvent); + } + + + private function uploadStart (event:Event) : void { + logMessage("Dispatching uploadstart event for " + fileIDList[event.target]); + var newEvent:Object = new Object(); + newEvent.id = fileIDList[event.target]; + newEvent.type = "uploadstart"; + yuiBridge.sendEvent(newEvent); + } + + + + private function uploadProgress (event:ProgressEvent) : void { + logMessage("Dispatching uploadprogress event for " + fileIDList[event.target] + ": " + event.bytesLoaded.toString() + " / " + event.bytesTotal.toString()); + var newEvent:Object = new Object(); + newEvent.id = fileIDList[event.target]; + newEvent.bytesLoaded = event.bytesLoaded; + newEvent.bytesTotal = event.bytesTotal; + newEvent.type = "uploadprogress" + yuiBridge.sendEvent(newEvent); + } + + + + private function uploadComplete (event:Event) : void { + logMessage("Dispatching uploadcomplete event for " + fileIDList[event.target]); + var newEvent:Object = new Object(); + newEvent.id = fileIDList[event.target]; + newEvent.type = "uploadcomplete" + yuiBridge.sendEvent(newEvent); + + this.currentUploadThreads--; + // get next off of queue: + processQueue(); + } + + + + private function uploadCompleteData (event:DataEvent) : void { + logMessage("Dispatching uploadcompletedata event for " + fileIDList[event.target] + ": "); + logMessage("Received the following data: " + event.data); + var newEvent:Object = new Object(); + newEvent.id = fileIDList[event.target]; + newEvent.data = event.data; + newEvent.type = "uploadcompletedata" + yuiBridge.sendEvent(newEvent); + } + + private function uploadCancel (event:Event) : void { + logMessage("Dispatching uploadcancel event for " + fileIDList[event.target]); + var newEvent:Object = new Object(); + newEvent.id = fileIDList[event.target]; + newEvent.type = "uploadcancel"; + yuiBridge.sendEvent(newEvent); + } + + + + private function uploadError (event:Event) : void { + var newEvent:Object = {}; + + if (event is HTTPStatusEvent) { + var myev:HTTPStatusEvent = event as HTTPStatusEvent; + newEvent.status = myev.status; + logMessage("HTTP status error for " + fileIDList[event.target] + ": " + myev.status); + } + + else if (event is IOErrorEvent) { + newEvent.status = event.toString(); + logMessage("IO error for " + fileIDList[event.target] + ". Likely causes are problems with Internet connection or server misconfiguration."); + } + + else if (event is SecurityErrorEvent) { + newEvent.status = event.toString(); + logMessage("Security error for " + fileIDList[event.target]); + } + logMessage ("Dispatching error event for " + fileIDList[event.target]); + newEvent.type = "uploaderror"; + newEvent.id = fileIDList[event.target]; + + yuiBridge.sendEvent(newEvent); + + // get next off of queue: + processQueue(); + } + + + + // Fired when the user selects a single file + private function singleFileSelected(event:Event):void { + this.clearFileList(); + addFile(event.target as FileReference); + processSelection(); + } + + + + // Fired when the user selects multiple files + private function multipleFilesSelected(event:Event):void { + var currentFRL:FileReferenceList = multipleFiles; + for each (var currentFR:FileReference in currentFRL.fileList) { + addFile(currentFR); + } + processSelection(); + } + + private function renderAsButton (buttonSkinSprite:String) : void { + + logMessage("Rendering uploader as button..."); + buttonSkin.load(new URLRequest(buttonSkinSprite)); + var _this:Uploader = this; + + var initLoader:Function = function (event:Event) : void { + buttonSprite.addChild(buttonSkin); + + buttonHeight = buttonSkin.height/4; + buttonWidth = buttonSkin.width; + var buttonMask:Sprite = new Sprite(); + buttonMask.graphics.beginFill(0x000000,1); + buttonMask.graphics.drawRect(0,0,buttonWidth,buttonHeight); + buttonMask.graphics.endFill(); + _this.addChild(buttonMask); + buttonSprite.mask = buttonMask; + + var buttonStageResize:Function = function (evt:Event = null) : void { + buttonSprite.width = _this.stage.stageWidth; + buttonSprite.height = _this.stage.stageHeight*4; + buttonMask.width = _this.stage.stageWidth; + buttonMask.height = _this.stage.stageHeight; + }; + + buttonStageResize(); + + _this.stage.scaleMode = StageScaleMode.NO_SCALE; + _this.stage.align = StageAlign.TOP_LEFT; + _this.stage.tabChildren = false; + + _this.stage.addEventListener(Event.RESIZE, buttonStageResize); + + _this.addEventListener(MouseEvent.ROLL_OVER, buttonMouseOver); + _this.addEventListener(MouseEvent.ROLL_OUT, buttonMouseOut); + _this.addEventListener(MouseEvent.MOUSE_DOWN, buttonMouseDown); + _this.addEventListener(MouseEvent.MOUSE_UP, buttonMouseUp); + _this.addEventListener(MouseEvent.CLICK, handleMouseClick); + + _this.stage.addEventListener(KeyboardEvent.KEY_DOWN, handleKeyDown); + _this.stage.addEventListener(KeyboardEvent.KEY_UP, handleKeyUp); + + + _this.addChild(buttonSprite); + } + + var errorLoader:Function = function (event:IOErrorEvent) : void { + renderAsTransparent(); + } + + buttonSkin.contentLoaderInfo.addEventListener(Event.COMPLETE, initLoader); + buttonSkin.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, errorLoader); + + } + + private function buttonMouseOver (event:MouseEvent) : void { + buttonSkin.y = -1*buttonHeight; + } + + private function buttonMouseOut (event:MouseEvent) : void { + buttonSkin.y = 0; + } + + private function buttonMouseDown (event:MouseEvent) : void { + buttonSkin.y = -2*buttonHeight; + } + + private function buttonMouseUp (event:MouseEvent) : void { + buttonSkin.y = 0; + } + + private function renderAsTransparent () : void { + + logMessage("Rendering uploader as transparent overlay."); + + function transparentStageResize (evt:Event) : void { + buttonSprite.width = buttonSprite.stage.stageWidth; + buttonSprite.height = buttonSprite.stage.stageHeight; + } + + buttonSprite.graphics.beginFill(0xffffff, 0); + buttonSprite.graphics.drawRect(0,0,5,5); + buttonSprite.width = this.stage.stageWidth; + buttonSprite.height = this.stage.stageHeight; + buttonSprite.graphics.endFill(); + this.stage.scaleMode = StageScaleMode.NO_SCALE; + this.stage.align = StageAlign.TOP_LEFT; + this.stage.tabChildren = false; + + this.stage.addEventListener(Event.RESIZE, transparentStageResize); + + this.addEventListener(MouseEvent.CLICK, handleMouseClick); + this.addEventListener(MouseEvent.CLICK, transparentClick); + + this.addEventListener(MouseEvent.MOUSE_DOWN, transparentDown); + this.addEventListener(MouseEvent.MOUSE_UP, transparentUp); + this.addEventListener(MouseEvent.ROLL_OVER, transparentRollOver); + this.addEventListener(MouseEvent.ROLL_OUT, transparentRollOut); + + this.buttonMode = true; + this.useHandCursor = true; + this.addChild(buttonSprite); + } + + private function handleKeyDown (evt:KeyboardEvent) : void { + if (evt.keyCode == Keyboard.ENTER || evt.keyCode == Keyboard.SPACE) { + logMessage("Keyboard 'Enter' or 'Space' down."); + buttonSkin.y = -2*buttonHeight; + } + } + + private function handleKeyUp (evt:KeyboardEvent) : void { + if (evt.keyCode == Keyboard.ENTER || evt.keyCode == Keyboard.SPACE) { + buttonSkin.y = 0; + logMessage("Keyboard 'Enter' or 'Space' up."); + logMessage("Keyboard 'Enter' or 'Space' detected, launching 'Open File' dialog."); + this.browse(this.allowMultiple, this.filterArray); + } + } + + private function handleFocusIn (evt:FocusEvent) : void { + logMessage("Focus is on the Uploader."); + } + + private function handleFocusOut (evt:FocusEvent) : void { + logMessage("Focus is out on the Uploader."); + } + + + private function handleMouseClick (evt:MouseEvent) : void { + logMessage("Mouse click detected, launching 'Open File' dialog."); + this.browse(this.allowMultiple, this.filterArray); + } + + //-------------------------------------------------------------------------- + // + // Overridden Properties + // + //-------------------------------------------------------------------------- + + /** + * @private + * Initializes the component and enables communication with JavaScript + * + * @param parent A container that the PopUpManager uses to place the Menu + * control in. The Menu control may not actually be parented by this object. + * + * @param xmlDataProvider The data provider for the Menu control. + * @see #dataProvider + * + * @return An instance of the Menu class. + * + * @see #popUpMenu() + * @see com.yahoo.astra.fl.data.XMLDataProvider + */ + + protected function initializeComponent():void { + + logMessage("Initializing uploader..."); + var btnSkinURL:String; + btnSkinURL = yuiBridge.flashvars["buttonSkin"]; + logMessage("Button skin: " + btnSkinURL); + + if (btnSkinURL != null) { + logMessage("Starting to render as button..."); + this.renderType = "button"; + this.renderAsButton(btnSkinURL); + } + else { + this.renderType = "transparent"; + this.renderAsTransparent(); + } + + + yuiBridge.addCallbacks ({removeFile:removeFile, clearFileList:clearFileList, upload:upload,uploadThese:uploadThese,uploadAll:uploadAll,cancel:cancel,setAllowLogging:setAllowLogging,setAllowMultipleFiles:setAllowMultipleFiles,setSimUploadLimit:setSimUploadLimit,setFileFilters:setFileFilters,enable:enable, disable:disable}); + // removeFile (fileID:String = null) + // Removes one or all files from the upload queue + // ExternalInterface.addCallback("removeFile", removeFile); + + // clearFileList (): Boolean + // Clears the list of files to be uploaded. + // ExternalInterface.addCallback("clearFileList", clearFileList); + + // upload(fileID:String, url:String, method:String = "GET", vars:Object = null, fieldName:String = "Filedata") + // Uploads the specified file in a specified POST variable, attaching other variables using the specified method + // ExternalInterface.addCallback("upload", upload); + + //ExternalInterface.addCallback("uploadThese", uploadThese); + + // uploadAll(url:String, method:String = "GET", vars:Object = null, fieldName:String = "Filedata") + // Uploads all files in the queue, using simultaneousUploads. + //ExternalInterface.addCallback("uploadAll", uploadAll); + + // cancel (fileID:String = null) + // Cancels the specified file upload; or all, if no id is specified + //ExternalInterface.addCallback("cancel", cancel); + + // setAllowLoging (allowLogging:Boolean = false) + // Allows log outputs to be produced. + //ExternalInterface.addCallback("setAllowLogging", setAllowLogging); + + // setAllowMultipleFiles (allowMultiple:Boolean = false) + // Allows multiple file selection + //ExternalInterface.addCallback("setAllowMultipleFiles", this.setAllowMultipleFiles); + + // setSimUploadLimit(simUpload:int = [2,5]) + // Sets the number of simultaneous uploads allowed when automatically managing queue. + //ExternalInterface.addCallback("setSimUploadLimit", this.setSimUploadLimit); + + // setFileFilters(fileFilters:Array) + // Sets file filters for file selection. + //ExternalInterface.addCallback("setFileFilters", this.setFileFilters); + + // enable() + // Enables Uploader UI + //ExternalInterface.addCallback("enable", enable); + + // disable() + // Disables Uploader UI + //ExternalInterface.addCallback("disable", disable); + + // Initialize properties. + fileDataList = new Object(); + fileRefList = new Object(); + fileIDList = new Dictionary(); + singleFile = new FileReference(); + multipleFiles = new FileReferenceList(); + + fileIDCounter = 0; + + filesToUpload = []; + + } + + + + //-------------------------------------- + // Private Methods + //-------------------------------------- + + /** + * @private + * Formats objects containing extensions of files to be filtered into formal FileFilter objects + */ + + private function processFileFilterObjects(filtersArray:Array) : Array { + + // TODO: Should we have an 'allowedExtensions' property that the JS user accesses directly? Potential here for typos ('extension' instead of 'extensions') as well as a misunderstanding of the nature of the expected array + // TODO: Description not showing (testing on OS X PPC player) + for (var i:int = 0; i < filtersArray.length; i++) { + filtersArray[i] = new FileFilter(filtersArray[i].description, filtersArray[i].extensions, filtersArray[i].macType); + } + + return filtersArray; + } + + /** + * @private + * Outputs the files selected to an output panel and triggers a 'fileSelect' event. + */ + + private function processSelection():void { + + var dstring:String = ""; + dstring += "Files Selected: \n"; + + for each (var item:Object in fileDataList) { + dstring += item.name + "\n "; + } + + logMessage(dstring); + + var newEvent:Object = new Object(); + newEvent.fileList = fileDataList; + newEvent.type = "fileselect" + + yuiBridge.sendEvent(newEvent); + } + + + + /** + * @private + * Adds a file reference object to the internal queue and assigns listeners to its events + */ + + private function addFile(fr:FileReference):void { + + var fileID:String = "file" + fileIDCounter; + var fileName:String = fr.name; + var fileCDate:Date = fr.creationDate; + var fileMDate:Date = fr.modificationDate; + var fileSize:Number = fr.size; + fileIDCounter++; + + fileDataList[fileID] = {id: fileID, name: fileName, cDate: fileCDate, mDate: fileMDate, size: fileSize};//, type: fileType, creator: fileCreator}; + + fr.addEventListener(Event.OPEN, uploadStart); + fr.addEventListener(ProgressEvent.PROGRESS, uploadProgress); + fr.addEventListener(Event.COMPLETE, uploadComplete); + fr.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, uploadCompleteData); + fr.addEventListener(HTTPStatusEvent.HTTP_STATUS, uploadError); + fr.addEventListener(IOErrorEvent.IO_ERROR, uploadError); + fr.addEventListener(SecurityErrorEvent.SECURITY_ERROR, uploadError); + fr.addEventListener(Event.CANCEL,uploadCancel); + + fileRefList[fileID] = fr; + fileIDList[fr] = fileID; + } + + /** + * @private + * Queues a file for upload + */ + private function queueForUpload(fr:FileReference, request:URLRequest, fieldName:String):void { + filesToUpload.push( {fr:fr, request:request, fieldName:fieldName }); + } + + /** + * @private + * Uploads the next file in the upload queue. + */ + + private function processQueue():void { + while (this.currentUploadThreads < this.simultaneousUploadLimit && filesToUpload.length > 0) { + var objToUpload:Object = filesToUpload.shift(); + var fr:FileReference = objToUpload.fr; + var request:URLRequest = objToUpload.request; + var fieldName:String = objToUpload.fieldName; + logMessage("Starting upload for " + objToUpload.id); + fr.upload(request,fieldName); + this.currentUploadThreads++; + } + } + + /** + * @private + * Creates a URLRequest object from a url, and optionally includes an HTTP request method and additional variables to be sent + */ + + private function formURLRequest(url:String, method:String = "GET", vars:Object = null):URLRequest { + + var request:URLRequest = new URLRequest(); + request.url = url; + request.method = method; + request.data = new URLVariables(); + + + for (var itemName:String in vars) { + request.data[itemName] = vars[itemName]; + } + + + return request; + } + + /** + * @private + * Determines whether an object is equivalent to an empty string + */ + + private function isEmptyString(toCheck:*):Boolean { + + if( toCheck == "null" || + toCheck == "" || + toCheck == null ) { + + return true; + } + + else { + return false; + } + } + + private function logMessage (message:String) : void { + if (this.allowLog) { + trace(message); + } + } + + } + +} + diff --git a/src/uploader/as/com/yahoo/util/YUIBridge.as b/src/uploader/as/com/yahoo/util/YUIBridge.as new file mode 100644 index 0000000..869f319 --- /dev/null +++ b/src/uploader/as/com/yahoo/util/YUIBridge.as @@ -0,0 +1,117 @@ +package com.yahoo.util + { + import flash.display.Stage; + import flash.external.ExternalInterface; + import flash.utils.getDefinitionByName; + import flash.system.Security; + + public class YUIBridge extends Object + { + public var flashvars:Object; + private var _jsHandler:String; + private var _swfID:String; + private var _yId:String; + + private var _stage:Stage; + + private var _instances:Object = {}; + + public function YUIBridge(stage:Stage) + { + _stage = stage; + flashvars = _stage.loaderInfo.parameters; + + if (flashvars["yId"] && flashvars["YUIBridgeCallback"] && flashvars["YUISwfId"] && ExternalInterface.available) { + _jsHandler = flashvars["YUIBridgeCallback"]; + _swfID = flashvars["YUISwfId"]; + _yId = flashvars["yId"]; + } + + if(flashvars.hasOwnProperty("allowedDomain")) + { + Security.allowDomain(flashvars.allowedDomain); + } + + ExternalInterface.addCallback("createInstance", createInstance); + ExternalInterface.addCallback("exposeMethod", exposeMethod); + ExternalInterface.addCallback("getProperty", getProperty); + ExternalInterface.addCallback("setProperty", setProperty); + + } + + public function createInstance(instanceId:String, className:String, constructorArguments:Array = null) : void { + + constructorArguments == null ? constructorArguments = [] : constructorArguments = constructorArguments; + + var cA:Array = constructorArguments; + var classReference:Class = getDefinitionByName(className) as Class; + + var instance:Object; + + switch (cA.length) { + case 1: instance = new classReference(cA[0]); + case 2: instance = new classReference(cA[0], cA[1]); + case 3: instance = new classReference(cA[0], cA[1], cA[2]); + case 4: instance = new classReference(cA[0], cA[1], cA[2], cA[3]); + case 5: instance = new classReference(cA[0], cA[1], cA[2], cA[3], cA[4]); + case 6: instance = new classReference(cA[0], cA[1], cA[2], cA[3], cA[4], cA[5]); + case 7: instance = new classReference(cA[0], cA[1], cA[2], cA[3], cA[4], cA[5], cA[6]); + case 8: instance = new classReference(cA[0], cA[1], cA[2], cA[3], cA[4], cA[5], cA[6], cA[7]); + case 9: instance = new classReference(cA[0], cA[1], cA[2], cA[3], cA[4], cA[5], cA[6], cA[7], cA[8]); + case 10: instance = new classReference(cA[0], cA[1], cA[2], cA[3], cA[4], cA[5], cA[6], cA[7], cA[8], cA[9]); + case 11: instance = new classReference(cA[0], cA[1], cA[2], cA[3], cA[4], cA[5], cA[6], cA[7], cA[8], cA[9], cA[10]); + case 12: instance = new classReference(cA[0], cA[1], cA[2], cA[3], cA[4], cA[5], cA[6], cA[7], cA[8], cA[9], cA[10], cA[11]); + case 13: instance = new classReference(cA[0], cA[1], cA[2], cA[3], cA[4], cA[5], cA[6], cA[7], cA[8], cA[9], cA[10], cA[11], cA[12]); + default: instance = new classReference(); + } + + _instances[instanceId] = instance; + } + + public function exposeMethod(instanceId:String, methodName:String, exposedName:String = "") : void { + exposedName == "" ? exposedName = methodName : exposedName = exposedName; + + if (_instances[instanceId] && ExternalInterface.available) { + ExternalInterface.addCallback(exposedName, _instances[instanceId][methodName]); + } + } + + public function getProperty (instanceId:String, propertyName:String) : Object { + if (_instances[instanceId] && _instances[instanceId].hasOwnProperty(propertyName)) { + return _instances[instanceId][propertyName]; + } + else { + return null; + } + } + + public function setProperty (instanceId:String, propertyName:String, propertyValue:Object) : void { + if (_instances[instanceId] && _instances[instanceId].hasOwnProperty(propertyName)) { + _instances[instanceId][propertyName] = propertyValue; + } + } + + public function addCallbacks (callbacks:Object) : void { + if (ExternalInterface.available) { + for (var callback:String in callbacks) { + trace("Added callback for " + callback + ", function " + callbacks[callback]); + ExternalInterface.addCallback(callback, callbacks[callback]); + } + sendEvent({type:"swfReady"}); + } + } + + public function sendEvent (evt:Object) : void { + if (ExternalInterface.available) { + ExternalInterface.call("YUI.applyTo", _yId, _jsHandler, [_swfID, evt]); + } + + } + + public function log (message : String) : void { + if (ExternalInterface.available) { + ExternalInterface.call("console.log", message); + } + } + } + } debian/patches/series0000664000000000000000000000001511773225332012035 0ustar as-src.patch debian/libjs-yui3-common.README.Debian0000664000000000000000000000152211773223612014514 0ustar YUI3 for Debian --------------- * The upstream docs and api references from the upstream docs/, releasenotes/ and api/ directories can be found in the libjs-yui3-doc package. * The library files themselves (from the build/ and assets/ directories upstream) are split into four packages: libjs-yui3 contains the full unobfuscated source for the javascript files. libjs-yui3-min contains minified versions of the javascript files. libjs-yui3-debug contains debug versions of the javascript files. libjs-yui3-common contains the assets and the rest of the files. The library files are installed into /usr/share/javascript/yui3. In order to make use of them in your html, use the URL /javascript/yui3/. -- Jaldhar H. Vyas Thu Jun 28 23:19:02 EDT 2012 debian/rules0000775000000000000000000000332611774646502010270 0ustar #!/usr/bin/make -f %: dh $@ override_dh_install: dh_install # Adjusting file locations find debian/libjs-yui3-common/usr/share/javascript/yui3 -name "*.html" | \ xargs perl -pi -e 's#\Q../../../../assets\E#/javascript/yui3/assets#g;' find debian/libjs-yui3-common/usr/share/javascript/yui3 -name "*.html" | \ xargs perl -pi -e 's#\Q../../build\E#/javascript/yui3#g;' cd debian/libjs-yui3-common && for i in `find . -name "*-debug.js" -print`; do \ install -D -m0644 "$$i" ../libjs-yui3-debug/"$$i" ; \ rm -rf "$$i" ; \ done cd debian/libjs-yui3-common && for i in `find . -name "*-min.js" -print`; do \ install -D -m0644 "$$i" ../libjs-yui3-min/"$$i" ; \ rm -rf "$$i" ; \ done cd debian/libjs-yui3-common && for i in `find . -name "*.js" -print`; do \ install -D -m0644 "$$i" ../libjs-yui3-full/"$$i" ; \ rm -rf "$$i" ; \ done cd debian/libjs-yui3-common && find . -type d -empty | xargs rmdir override_dh_clean: dh_clean -find . -name "*.swf" | xargs rm override_dh_compress: dh_compress -i -X.js -X-js -X.json -X.php override_dh_installchangelogs: # workaround for a problem with non-changelog files being detected which I haven't time to investigate yet. dh_installchangelogs --exclude=docs override_dh_installdocs: dh_installdocs --exclude=COPYING # Adjusting file locations find debian/libjs-yui3-doc/usr/share/doc/libjs-yui3-doc -name "*.html" | \ xargs perl -pi -e 's#\Q../../build\E#/javascript/yui3#g;' find debian/libjs-yui3-doc/usr/share/doc/libjs-yui3-doc -name "*.html" | \ xargs perl -pi -e 's#\Q../build\E#/javascript/yui3#g;' find debian/libjs-yui3-doc/usr/share/javascript/yui3 -name "*.html" | \ xargs perl -pi -e 's#\Q../assets\E#/javascript/yui3/assets#g;' debian/libjs-yui3-doc.README.Debian0000664000000000000000000000067111773177557014015 0ustar File Locations/URLs ------------------- * The documentation in the upstream docs/ directory is in: /usr/share/doc/libjs-yui3-doc/ You can access it at http://localhost/doc/libjs-yui3-doc/ * The documentation in the upstream api/ directory is in: /usr/share/doc/libjs-yui3-doc/api You can access it at http://localhost/doc/libjs-yui3-doc/api -- Jaldhar H. Vyas Thu, 28 Jun 2012 16:21:00 -0400