[Pkg-javascript-commits] [SCM] Yahoo! User Interface Toolkit (yui) branch, master, updated. debian/2.8.1-1-10-g9fa2f48

Jaldhar H. Vyas jaldhar at debian.org
Fri Jun 29 21:18:09 UTC 2012


The following commit has been merged in the master branch:
commit 682de95f6c39acd8dff4b5b27c993e2791387ffe
Author: Jaldhar H. Vyas <jaldhar at debian.org>
Date:   Fri Jun 29 07:43:18 2012 -0400

    Updated Debian packaging.

diff --git a/debian/changelog b/debian/changelog
index 0db9984..9f4b278 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+yui (2.9.0-1) unstable; urgency=low
+
+  * New upstream version.
+
+ -- Jaldhar H. Vyas <jaldhar at debian.org>  Fri, 29 Jun 2012 02:20:10 -0400
+
 yui (2.8.2r1-1) unstable; urgency=low
 
   * New upstream version.
diff --git a/debian/control b/debian/control
index 387a808..c4fa3e5 100644
--- a/debian/control
+++ b/debian/control
@@ -4,8 +4,8 @@ Priority: optional
 Maintainer: Debian Javascript Maintainers <pkg-javascript-devel at lists.alioth.debian.org>
 Uploaders: Jaldhar H. Vyas <jaldhar at debian.org>,
            Marcelo Jorge Vieira (metal) <metal at debian.org>
-Build-Depends: debhelper (>= 7)
-Standards-Version: 3.9.1
+Build-Depends: debhelper (>= 7.0.50~), swftools
+Standards-Version: 3.9.3
 Homepage: http://developer.yahoo.com/yui/
 Vcs-Browser: http://git.debian.org/?p=pkg-javascript/yui.git
 Vcs-Git: git://git.debian.org/git/pkg-javascript/yui.git
@@ -23,9 +23,9 @@ Description: Yahoo User Interface Library
   * utility classes for animation, browser history, AJAX, cookies, 
     drag and drop. safe cross-site data retrieval, dynamic script/css loading,
     image loading, selectors, JSON, resizing elements, DOM and browser events.
-  * Autocomplete, button, calendar, carousel, charts, color picker,
-    data table, file upload, image crop, menu, paginator, layout manager,
-    rich text editor, slider, tabview and treeview controls and a container
+  * Autocomplete, button, calendar, carousel, color picker,data table,
+    file upload, image crop, menu, paginator, layout manager, rich text editor,
+    slider, tabview and treeview controls and a container
     control that can be used for tooltips, panels, dialog boxes etc.
   * A logging framework.
   * A profiler
diff --git a/debian/patches/as-src.patch b/debian/patches/as-src.patch
new file mode 100644
index 0000000..8cbe5cb
--- /dev/null
+++ b/debian/patches/as-src.patch
@@ -0,0 +1,2455 @@
+From: Jaldhar H. Vyas <jaldhar at debian.org>
+Date: Thu Jun 29 06:43:38 EDT 2012
+Subject: as-src
+
+Description: ActionScript source for the flash files included in the package.
+Origin: https://github.com/yui/yui2.git (master branch)
+---
+ create mode 100755 src/connection/as/com/yui/util/connection.as
+ create mode 100755 src/swfstore/as/SWFStore.as
+ create mode 100755 src/swfstore/as/com/yahoo/util/YUIBridge.as
+ create mode 100755 src/uploader/as/Uploader.as
+ create mode 100755 src/uploader/as/com/yahoo/yui/YUIAdapter.as
+
+diff --git a/src/connection/as/com/yui/util/connection.as b/src/connection/as/com/yui/util/connection.as
+new file mode 100755
+index 0000000..a93b89c
+--- /dev/null
++++ b/src/connection/as/com/yui/util/connection.as
+@@ -0,0 +1,162 @@
++package com.yui.util
++{
++	import flash.display.Sprite;
++	import flash.events.Event;
++	import flash.events.IOErrorEvent;
++	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 connection extends Sprite
++	{
++		private var httpComplete:Function;
++		private var httpError:Function;
++		private var httpTimeout:Function;
++		private var loaderMap:Object = {};
++		private var yId:String;
++		private var handler:String = 'YAHOO.util.Connect.handleXdrResponse';
++
++		public function connection() {
++			ExternalInterface.addCallback("send", send);
++			ExternalInterface.addCallback("abort", abort);
++			ExternalInterface.addCallback("isCallInProgress", isCallInProgress);
++			ExternalInterface.call('YAHOO.util.Connect.xdrReady');
++		}
++
++		public function send(uri:String, cb:Object, id:uint):void {
++			var loader:URLLoader = new URLLoader(),
++				request:URLRequest = new URLRequest(uri),
++				timer:Timer,
++				prop:String;
++
++			for (prop in cb) {
++				switch (prop) {
++					case "method":
++						if(cb.method === 'POST') {
++							request.method = URLRequestMethod.POST;
++						}
++						break;
++					case "data":
++						request.data = cb.data;
++						break;
++					case "timeout":
++						timer = new Timer(cb.timeout, 1);
++						break;
++				}
++			}
++
++			loaderMap[id] = { c:loader, readyState: 0, t:timer };
++			defineListeners(id, timer);
++			addListeners(loader, timer);
++			loader.load(request);
++			start(id);
++
++			if (timer) {
++				timer.start();
++			}
++		}
++
++		private function defineListeners(id:uint, timer:Timer):void {
++			httpComplete = function(e:Event):void { success(e, id, timer); };
++			httpError = function(e:IOErrorEvent):void { failure(e, id, timer); };
++
++			if (timer) {
++				httpTimeout = function(e:TimerEvent):void { abort(id); };
++			}
++		}
++
++		private function addListeners(loader:IEventDispatcher, timer:IEventDispatcher):void  {
++			loader.addEventListener(Event.COMPLETE, httpComplete);
++			loader.addEventListener(IOErrorEvent.IO_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);
++
++			if (loaderMap[id].t) {
++				loaderMap[id].t.removeEventListener(TimerEvent.TIMER_COMPLETE, httpTimeout);
++			}
++		}
++
++		private function start(id:uint):void {
++			var response:Object = { tId: id, statusText: 'xdr:start' };
++
++			loaderMap[id].readyState = 2;
++			ExternalInterface.call(handler, response);
++		}
++
++		private function success(e:Event, id:uint, timer:Timer):void {
++			var data:String = encodeURI(e.target.data),
++				response:Object = {
++					tId: id,
++					statusText: 'xdr:success',
++					responseText: data
++				};
++
++			loaderMap[id].readyState = 4;
++
++			if (timer && timer.running) {
++				timer.stop();
++			}
++
++			ExternalInterface.call(handler, response);
++			destroy(id);
++		}
++
++		private function failure(e:Event, id:uint, timer:Timer):void {
++			var data:String,
++				response:Object = { tId: id, statusText: 'xdr:error' };
++
++			loaderMap[id].readyState = 4;
++
++			if (e is IOErrorEvent) {
++				response.responseText = encodeURI(e.target.data);
++			}
++
++			if (timer && timer.running) {
++				timer.stop();
++			}
++
++			ExternalInterface.call(handler, response);
++			destroy(id);
++		}
++
++		public function abort(id:uint):void {
++			var response:Object = { tId: id, statusText: 'xdr:abort' };
++
++			loaderMap[id].c.close();
++
++			if (loaderMap[id].t && loaderMap[id].t.running) {
++				loaderMap[id].t.stop();
++			}
++
++			ExternalInterface.call(handler, response);
++			destroy(id);
++		}
++
++		public function isCallInProgress(id:uint):Boolean {
++			if (loaderMap[id]) {
++				return loaderMap[id].readyState !== 4;
++			}
++			else {
++				return false;
++			}
++		}
++
++		private function destroy(id:uint):void {
++			removeListeners(id);
++			delete loaderMap[id];
++		}
++	}
++}
+\ No newline at end of file
+diff --git a/src/swfstore/as/SWFStore.as b/src/swfstore/as/SWFStore.as
+new file mode 100755
+index 0000000..e7758de
+--- /dev/null
++++ b/src/swfstore/as/SWFStore.as
+@@ -0,0 +1,949 @@
++package  
++{
++	import com.yahoo.util.YUIBridge;
++	
++	import flash.display.Sprite;
++	import flash.events.Event;
++	import flash.events.IOErrorEvent;
++	import flash.events.SecurityErrorEvent;
++	import flash.events.NetStatusEvent;
++	import flash.external.ExternalInterface;
++	import flash.net.SharedObject;
++	import flash.net.SharedObjectFlushStatus;
++	import flash.net.URLLoader;
++	import flash.net.URLRequest;
++	import flash.system.Security;
++	import flash.system.SecurityPanel;
++	import flash.utils.ByteArray;
++
++	//We set width/height is set here to be large enough to display the settings panel in Flash Player
++	//It will typically be shrunk to 0 x 0 via the embed code
++	[SWF(width=215, height=138)]
++
++	/**
++	 * A wrapper for Flash SharedObjects to allow them to be used in JavaScript.
++	 * 
++	 * @author Alaric Cole
++	 */
++	public class SWFStore extends Sprite
++	{
++	    
++	    //--------------------------------------------------------------------------
++	    //
++	    //  Private Variables
++	    //
++	    //--------------------------------------------------------------------------
++	    
++	    
++		/**
++	     * The Shared Object instance in which to store entries.
++	     * @private
++	     * @fucktown
++	     */
++		private var _sharedObject:SharedObject;
++		
++		
++		/**
++	     * An object used to temporarily store entries.
++	     * @private
++	     */
++		private var _archive:Object;
++	
++		/**
++	     * Storage for useCompression getter/setter
++	     * @private
++	     */	    
++	    private var _useCompression:Boolean;
++	    
++		/**
++	     * Storage for shareData getter/setter
++	     * @private
++	     */		    
++	    private var _shareData:Boolean;
++	    //--------------------------------------------------------------------------
++	    //
++	    //  Static Variables
++	    //
++	    //--------------------------------------------------------------------------
++	    
++		/**
++		 * The minimum width required to be able to display the settings panel within the SWF
++		 * 
++		 */	
++		public static var MINIMUM_WIDTH:Number = 215;
++	
++		/**
++		 * The minimum height required to be able to display the settings panel within the SWF
++		 * 
++		 */	
++		public static var MINIMUM_HEIGHT:Number = 138;
++		
++		/**
++		* @private
++		* Initialization flag
++		*/
++		private var _initialized:Boolean;
++				
++		/**
++		* @private
++		* Whitelist xml path  
++		*/
++		private var _whitelistFileName:String = "storage-whitelist.xml";
++		
++		/**
++		* @private
++		* YUI Embedding framework
++		*/
++		private var yuibridge:YUIBridge;
++		
++		//--------------------------------------
++		//  Constructor
++		//--------------------------------------
++		
++		/**
++		 * Creates a store, which can be used to set and get information on a
++		 * user's local machine. This is typically invoked through the YUI JS API.
++		 * 
++		 * 
++		 * <p>If multiple SWF files need access to the same store, 
++		 * or if the SWF file that creates a store will later be moved, 
++		 * the value of this parameter affects how accessible the store will be.</p> 
++		 * <p>For example, if you create a store with localPath set to the default value
++		 * (the full path to the SWF file), no other SWF file can access that shared object. 
++		 * If you later move the original SWF file to another location, 
++		 * not even that SWF file can access the data already stored.</p>
++		 * <p>To avoid inadvertently restricting access to a store, set this parameter. 
++		 * The most permissive approach is to set localPath to <code>/ </code> (forward slash), 
++		 * which makes the store available to all SWF files in the domain, 
++		 * but increases the likelihood of name conflicts with other stores in the domain. 
++		 * A more restrictive approach is to append localPath with folder names 
++		 * that are in the full path to the SWF file. Note that not just any folder path
++		 * can be placed here, but only those that are in the path of the SWF. 
++		 * For instance, if the SWF is located at company.com/products/mail/mail.swf,
++		 * the available options for localPath would be "/products/mail/", 
++		 * "/products/", or "/".</p>
++		 * 
++		 */
++		public function SWFStore() 
++		{
++			loadWhitelist();
++			
++			var callbacks:Object = {};
++			callbacks.getValueOf = getValueOf;
++			callbacks.getItems = getItems;
++			callbacks.getValueAt = getValueAt;
++			callbacks.getNameAt = getNameAt;
++			callbacks.getLength = getLength;
++			callbacks.getModificationDate = getModificationDate;
++			callbacks.calculateCurrentSize = calculateCurrentSize;
++			callbacks.setItem = setItem;
++			callbacks.removeItem = removeItem;    
++			callbacks.removeItemAt = removeItemAt;
++			callbacks.clear = clear;
++			callbacks.setSize = setSize;
++			callbacks.displaySettings = displaySettings;
++			callbacks.getTypeOf = getTypeOf;
++			callbacks.getTypeAt = getTypeAt;
++			callbacks.setUseCompression = setUseCompression;
++			callbacks.getUseCompression = getUseCompression;
++			callbacks.setShareData = setShareData;
++			callbacks.getShareData = getShareData;
++			callbacks.setShareData = setShareData;
++			callbacks.hasAdequateDimensions = hasAdequateDimensions;
++			    
++			yuibridge = new YUIBridge(stage);
++			yuibridge.addCallbacks(callbacks);
++			
++
++		}
++
++		
++		//--------------------------------------------------------------------------
++		// 
++		// Properties
++		//
++		//--------------------------------------------------------------------------
++		
++ 		/**
++		* 
++		* Whether or not compression is used
++		*/
++ 		public function getUseCompression():Boolean
++ 		{
++ 			return _useCompression;
++ 			
++ 		}
++ 		
++  		/**
++		* Whether or not to use compression
++		*/		
++ 		public function setUseCompression(value:Boolean):void
++ 		{
++ 			_useCompression = value; 
++ 			
++ 			//if we're not already compressed, this setting should force current data to be compressed
++			if( !(_sharedObject.data.archive is ByteArray) && value)
++			{
++				var bytes:ByteArray = new ByteArray();
++	  			bytes.writeObject(_archive);   
++	  			bytes.compress();    
++	  			_sharedObject.data.archive = bytes;
++	  			_sharedObject.flush();
++			}
++ 			
++ 		}
++ 
++  		/**
++		* 
++		* Whether or not to data is being shared among different browsers
++		*/
++ 		public function getShareData():Boolean
++ 		{
++ 			return _useCompression;
++ 		}
++  		/**
++		* 
++		* Whether or not to share data among different browsers
++		*/				
++ 		public function setShareData(value:Boolean):void
++ 		{
++ 			_shareData = value;
++ 			initializeSharedObject();
++ 		}
++ 		
++ 		//--------------------------------------------------------------------------
++		// 
++		// Public Methods
++		//
++		//--------------------------------------------------------------------------
++		
++	   /**
++	    * Saves data to local storage. It returns "true" if the storage succeeded; "false" if the user
++		* has denied storage on their machine or if the current limit is too low.
++		* <p>The size limit for the passed parameters is ~40Kb.</p>
++		*  
++	    * @param item The data to store
++	    * @param location The name of the "cookie" or store 
++		* @return Boolean Whether or not the save was successful
++	    *  
++	    */   
++	    public function setItem(location:String, item:* ):Boolean
++	    {        
++	    	var oldValue:Object = null;
++	    	var info:String;
++	    	
++ 			//check to see if this has already been added
++			if(_archive.storage.hasOwnProperty(location))
++			{
++				//entry already exists with this value, ignore
++				if(_archive.storage[location] == item) return false;
++				
++				else //it's there but has a different value
++				{
++					oldValue = getValueOf(location);
++					_archive.storage[location] = item;
++					info = "update";
++				} 
++			}
++			 
++			else //doesn't exist, create and index it
++			{ 
++				info = "add";
++				  
++				_archive.storage[location] = item;
++				_archive.hash.push(location);
++				
++			}
++			   
++			//write it immediately
++	    	var result:Boolean = save(location, info, oldValue, item);
++			if(!result) 
++			{
++				//return archive to its original state, as this did not propagate to the SharedObject
++				switch(info)
++				{
++					case "update":
++					_archive.storage[location] = oldValue;
++					break;
++					
++					case "add":
++					delete _archive.storage[location];
++					_archive.hash.pop();
++					break;
++					
++				}
++			} 
++	    	return result;
++	    }
++   
++   
++	    /**
++	    * Returns the value of the key in local storage, if any. This corresponds to the 
++	    * HTML5 spec getItem(key).
++	    * <p>Note: to return an item at a specific index, use the helper function</p>:
++	    * <code>getValueAt(index)</code>
++	    * 
++	    * @param location The name of the "cookie" or key
++		* @return The data
++	    * @see getValueAt
++	    */
++	    public function getValueOf(location:String):*
++	    {
++	    	if(_archive.storage.hasOwnProperty(location)) 
++	    	{
++	      		return _archive.storage[location];
++	    	}
++	    	
++	    	return null;
++	    }
++	    
++	    /**
++	    * Returns the value of the key in local storage, if any, at the specified index.
++	    * Corresponds to the key(n) method in the HTML5 spec.
++	    * 
++	    * @param index The index of the "cookie" or store
++		* @return The value stored
++	    * 
++	    */ 
++	    public function getValueAt(index:int):*
++	    {   
++	    	var keyname:String = getNameAt(index);
++	    	
++	    	if(!keyname) return null;
++	    	
++	    	var value:Object = _archive.storage[keyname];
++	    	
++	    	if(!value) return null;
++	    	
++	    	return value;
++	    } 
++	    
++	    /**
++	    * Returns the data type of of the storage. 
++	    *     
++	    * <p>May be one of the following types:
++	    * <ul>
++	    * <li>boolean</li>
++	    * <li>function</li>
++	    * <li>number</li>
++	    * <li>object</li>
++	    * <li>string</li>
++	    * <li>number</li>
++	    * <li>xml</li>
++	    * </ul>
++	    * </p>
++	    * 
++	    * @param location The name of the "cookie" or store
++		* @return The data type.
++	    * 
++	    */ 
++	    public function getTypeOf(location:String):String
++	    {
++	    	if(_archive.storage.hasOwnProperty(location)) 
++	    	{
++	      		return typeof _archive.storage[location];
++	    	}
++	    	
++	    	return null;
++	    }
++	    
++	    /**
++	    * Returns the data type of of the storage. 
++	    * 
++	    * @param index The index of the "cookie" or store
++		* @return The data type.
++		* @see getTypeOf
++	    * 
++	    */ 
++	    public function getTypeAt(index:int):String
++	    {
++	    	return typeof getValueAt(index);
++	    }
++	    	    
++	    /**
++	    * Returns the key name in storage, if any, at the specified index.
++	    * 
++	    * @param index The index of the "cookie" or store
++		* @return The data
++	    * 
++	    */
++	    public function getNameAt(index:int):String
++	    {   
++	    	var keyname:String = _archive.hash[index];
++	    	
++	    	if(!keyname) return null;
++	    	
++	    	return keyname;
++	    } 
++	    
++	   /**
++	    * Returns the number of keys in storage.
++	    * 
++		* @return The number of keys
++	    * 
++	    */
++	    public function getLength():int
++	    { 
++    	    	return _archive.hash.length;
++	    }
++	      
++	    /**
++	    * Returns the storage object as an Array of name/value pairs.
++	    * 
++	    * 
++		* @return The storage dictionary as an Array
++	    * 
++	    */
++	    public function getItems():Array
++	    {     
++	    	var len:int = getLength();
++	    	var array:Array = [];
++	    	
++	    	for (var i:uint = 0; i < len; i++)
++	    	{        
++	    		array.push(_archive.storage[ _archive.hash[i] ] );
++	    	}  
++	    	return array;
++	    	
++	    }
++	    
++	   /**
++	    * Removes the data in local storage at the specified location, if any.
++	    * 
++	    * @param location The name of the "cookie" or store
++		* @return Whether the remove was successful
++	    * 
++	    */
++	    public function removeItem(location:String):Boolean
++	    {     
++	    	var index: int = getIndexOf(location);
++	    	var oldValue:Object = _archive.storage[location];
++	    	
++	    	delete _archive.storage[location];
++	    	
++	    	_archive.hash.splice(index, 1);
++	    	  
++	    	var result:Boolean = save(location, "delete", oldValue, null, index);
++	    	
++	    	return result;
++	    }
++
++	   /**
++	    * Removes the data in local storage at the specified location, if any.
++	    * 
++	    * @param location The name of the "cookie" or store
++		* @return Whether the remove was successful
++	    * 
++	    */
++	    public function removeItemAt(index:int):Boolean
++	    {
++	    	var oldValue:Object = getValueAt(index);
++	    	var location:String = getNameAt(index);
++	    	 
++	    	delete _archive.storage[location];
++	    	    
++	    	_archive.hash.splice(index, 1);
++	    	
++	    	var result:Boolean = save(location, "delete", oldValue, null, index);
++	    	 
++	    	return result;
++	    }
++	    
++	   /**
++	    * Removes all data in local storage for this domain.
++	    * <p>Be careful when using this method, as it may 
++	    * remove stored information that is used by other applications
++	    * in this domain </p>
++	    * 
++		* @return Whether the clear was successful
++	    * 
++	    */
++	    public function clear():Boolean
++	    {
++	    	_sharedObject.clear();
++	    	_archive = {storage:{}, hash:[]};
++	    	var evt:Object = {type: "save"};           
++	    	
++			yuibridge.sendEvent(evt);
++	    	return true;
++	    }
++	    
++	    
++	    /**
++	     * Gets the amount of space taken by the current store. Note that this value is 
++	     * calculated as requested, so large datasets could result in reduced performance.
++	     * @return the size of the store in KB
++	     */
++		public function calculateCurrentSize():uint
++		{
++			var sz:uint = _sharedObject.size;
++			return sz;
++		}
++		
++		/**
++		* This method requests more storage if the amount is above the current limit (typically ~100KB). 
++		* The request dialog has to be displayed within the Flash player itself
++		* so the SWF it is called from must be visible and at least 215px x 138px in size.
++		* 
++		* Since this is a "per domain" setting, you can
++		* use this method on a SWF in a separate page, such as a settings page, 
++		* if the width/height of the compiled SWF is not large enough to fit this dialog. 
++		* 
++		* @param value The size, in KB
++		*/
++		public function setSize(value:int):String
++		{
++			var status:String;
++			
++			status = _sharedObject.flush(value * 1024);
++			//on error, attempt to resize div?
++			
++			return status;
++		}
++
++		/**
++		 * Displays the settings dialog to allow the user to configure
++		 * storage settings manually. If the SWF height and width are smaller than
++		 * what is allowable to display the local settings panel,
++		 * an error message will be sent to JavaScript.
++		 */
++		public function displaySettings():void
++		{
++			var evt:Object;    
++			if( hasAdequateDimensions() )
++			{
++				evt = {type: "openingDialog"};
++				yuibridge.sendEvent(evt);
++
++				Security.showSettings(SecurityPanel.LOCAL_STORAGE);
++			}
++			else
++			{
++				
++				evt = {type: "inadequateDimensions", message: "The current size of the SWF is too small to display " + 
++						"the settings panel. Please increase the available width and height to 215px x 138px or larger."};
++				yuibridge.sendEvent(evt);
++			}
++
++		}
++		
++	
++	    /**
++	     * Gets the timestamp of the last store. This value is automatically set when 
++	     * data is stored.
++	     * @return A Date object
++	     */
++		public function getModificationDate():Date
++		{
++			var lastDate:Date =  new Date(_sharedObject.data.modificationDate);
++			
++			return lastDate;
++			
++		}
++		
++
++		
++    
++		//--------------------------------------
++		//  Private Methods
++		//--------------------------------------
++		
++		/**
++		 * @private
++		 * Gets the index of the item at the specified location
++		 * @param location The name of the key
++		 */		
++		private function getIndexOf(location:String):int 
++		{
++			return _archive.hash.indexOf(location);
++		}
++		
++		/**
++		 * @private
++		 * Loads the whitlist XML file
++		 * 
++		 */		
++		private function loadWhitelist():void 
++		{
++			var whitelistLoader:URLLoader = new URLLoader();
++			whitelistLoader.addEventListener(Event.COMPLETE, onComplete);
++			whitelistLoader.addEventListener(IOErrorEvent.IO_ERROR, onError);
++			whitelistLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError);
++		
++			//don't use a relative path, use the swf's loaded path
++			//to prevent crossdomain or base param workarounds
++		
++			var fullPath:String = loaderInfo.url;
++    		
++			//remove trailing slashes
++			var parentPath:String;
++			
++			var hasTrailingSlash:Boolean = fullPath.charAt(fullPath.length - 1) == "/";
++			if(hasTrailingSlash) fullPath = fullPath.slice(0, -1);
++			
++			//now get the path before the final slash (something like "/swffile.swf")
++     		parentPath = fullPath.slice(0,fullPath.lastIndexOf("/"));
++    		 
++			var localpath:String = parentPath + "/" + _whitelistFileName;
++			whitelistLoader.load(new URLRequest(localpath));	
++		}
++		
++		/**
++		 * @private
++		 * Parses the config xml data and populates path array
++		 * 
++		 */
++		private function onComplete (event:Event) : void 
++		{
++			 
++			var contentXML:XML;
++			try
++			{
++				 contentXML = new XML(event.target.data);
++			}
++			catch(error:TypeError)
++			{
++				yuibridge.sendEvent({type:"error", message:error.message});
++			}
++			
++			var valid:Boolean;
++			
++			var pageURL:String = ExternalInterface.call("function(){return window.location.href;}");
++			 
++			for  each (var path:XML in contentXML["allow-access-from"] ) 
++			{
++				var url:String = path. at url;
++				
++				if(pathMatches(pageURL, url))
++				{
++					valid = true;
++					break; 
++				} 
++			}
++	
++			
++			if(valid) initializeSharedObject();
++			
++			//not a valid whitelist, dispatch error
++			else 
++			{
++				var evt:Object = {type: "securityError", message: "Security Error: the whitelist does not allow access to storage from this location" };
++						
++					yuibridge.sendEvent(evt);
++			}	
++		}
++
++
++		private function pathMatches(page:String, path:String):Boolean
++		{
++			//remove the protocol when matching domains, because protocols are not to be specified in the whitelist				
++			/* var protocolPattern: RegExp = new RegExp("(http|https|file)\:\/\/");
++    		var pathWithoutProtocol:String = url.replace(protocolPattern, "");
++    		
++    		var pageURLWithoutProtocol:String = url.replace(pageURL, ""); */
++    		
++    		//ExternalInterface.call("alert('this page's url: " + page + "/nproposed url: " + path + "')");
++				
++	    		
++			if(page.indexOf(path) > -1)
++			{
++				//if the loading page's url contains the whitelisted url as a substring, pass it
++				return true;
++			}
++			
++			else return false;
++		}
++		/**
++		 * @private
++		 * Dispatches an IOErrorEvent
++		 * 
++		 */
++		private function onError(event:IOErrorEvent) : void 
++		{
++			//trace("no whitelist file");
++			
++			//try matching the url, a default action since no whitelist was specified
++			
++			performURLMatch();
++		}
++		
++		/**
++		 * @private
++		 * Dispatches a SecurityErrorEvent
++		 * 
++		 */
++		private function onSecurityError(event:SecurityErrorEvent) : void 
++		{
++			var evt:Object = {type: "securityError", message: event.text };
++					
++				yuibridge.sendEvent(evt);
++		}
++		
++		/**
++		 * Expands a path with shorthands to url
++		 * 
++		 * @param path	Path with shorthands
++		 * @return      Path with shorthands expanded
++		 */
++		public function getPath (path:String) : String {
++			var newPath:String = path.replace(/%(.*)%/, getPath);
++			return newPath; 
++		}
++		
++		private function performURLMatch():void
++		{
++			try 
++			{
++				//check that page url is the same as the swf's url //host gives main domain? 
++				//ExternalInterface.call("function(){alert(window.location.href)}"); 
++				var currentURL:String = ExternalInterface.call("function(){return window.location.href;}");
++				if(currentURL.indexOf("?") > -1)
++				{
++					currentURL = currentURL.slice(0,currentURL.indexOf("?"));
++				} 
++			      
++			    currentURL = currentURL.slice(0,currentURL.lastIndexOf("/"));
++			    					
++				var loadedURL:String = loaderInfo.url;
++				if(loadedURL.indexOf("?") > -1)
++				{
++					loadedURL = loadedURL.slice(0,loadedURL.indexOf("?"));	
++				}   
++				loadedURL = loadedURL.slice(0,loadedURL.lastIndexOf("/"));
++				
++				var currentURL_ESC:String = unescape(currentURL) ;
++				var loadedURL_ESC:String = unescape(loadedURL) 
++				
++				if(currentURL_ESC == loadedURL_ESC )
++				{ 
++					initializeSharedObject();
++ 					 
++				}
++				 else 
++				{	
++					var evt:Object = {type: "securityError", message: "The domain of the page must match the SWF's domain.\nPage's URL: " +
++						currentURL + "\n" + "SWF's URL: " + loadedURL};
++						
++					yuibridge.sendEvent(evt);
++				}  
++			} 
++			
++			catch(e:Error)
++			{
++				yuibridge.sendEvent(e);
++			}
++
++		}
++		protected function initializeSharedObject():void
++		{
++			var allowedDomain:String = loaderInfo.parameters.allowedDomain || null;
++			
++			if(allowedDomain)
++			{
++				//allows "cross-scripting" of html container and swf
++				Security.allowDomain(allowedDomain);
++			}
++			
++			else
++			{
++				var evt:Object = {type: "securityError", message: "The domain of the page does not have appropriate permissions.\nPage's URL: "};
++				yuibridge.sendEvent(evt);
++			}
++			
++			var localPath:String = null;//loaderInfo.parameters.localPath || null;
++			   
++			var browser:String = loaderInfo.parameters.browser || "other";
++			
++			if(!_initialized)
++			{
++				_shareData = loaderInfo.parameters.shareData == "true";
++  				_useCompression = loaderInfo.parameters.useCompression == "true";
++			}
++			
++			var loc:String = "DataStore_" + (_shareData?"":browser);
++ 			_sharedObject = SharedObject.getLocal(loc, localPath); 
++ 			
++ 			_sharedObject.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus);
++ 				
++ 			//initialize 
++ 			if(!_sharedObject.data.hasOwnProperty("archive")) 
++ 			{
++   				_archive = {storage:{}, hash:[]};
++ 			}
++ 			else    
++ 			{
++ 				 //if compression is detected to be in use, we must decompress it first
++ 				if(_sharedObject.data.archive is ByteArray)
++ 				{ 
++ 					//remember that sharedobjects are flushed automatically when the page destroys the SWF.
++ 					var tempBytes:ByteArray = _sharedObject.data.archive as ByteArray;
++ 					
++ 					//make a clone of the current shared object
++ 					var bytes:ByteArray = new ByteArray();
++ 					tempBytes.readBytes(bytes, 0, tempBytes.length);
++ 					
++ 					//NOTE: there may be a way to read the first few bytes and determine if it is compressed
++ 					
++ 					try
++ 					{
++ 						bytes.uncompress();
++ 					}
++ 					catch(error:Error)
++ 					{
++ 						//there's an error decompressing
++ 						yuibridge.sendEvent({type: "error", message:error.message});
++ 					}
++ 					
++ 					_archive = bytes.readObject();
++ 				} 
++ 				else
++ 				{
++ 					_archive = _sharedObject.data.archive;
++ 				}
++ 				
++ 			}
++ 			
++ 			//if(!_initialized)
++ 			{
++ 				_initialized = true;
++ 				//once initialization is complete, let JS know 
++ 				yuibridge.sendEvent({type:"contentReady"});
++ 			}
++ 			
++		}
++	
++
++	    /**
++	    * @private
++	    * Returns the key/value pair in storage, if any, at the specified index.
++	    * Similar to get key() in HTML5
++	    * @param index The index of the "cookie" or store
++		* @return The data
++	    * 
++	    */
++	    protected function getKeyValueAt(index:int):Object
++	    {   
++	    	return getItems()[index];
++	    } 	  
++	  
++	  
++		/** 
++		* @private
++		* Writes the store to disk. While this will be called by Flash
++		* whenever the application is closed, calling it immediately after
++		* new information allows that info to be instantly available.
++		*
++	    * @return Whether or not the save was successful
++		*/
++		protected function save( location:String = null, info:String = "add", oldValue:Object = null, newValue:Object = null, index:int = -1):Boolean
++	    {     
++	        var evt:Object = {};
++	        var type:String = "save";
++	         
++	        //set the time modified  UTC
++	        if(newValue) 
++	        {
++	        	setTime(new Date().getTime());
++	        }   
++	        
++	       if(_useCompression)
++	        {
++		        var bytes:ByteArray = new ByteArray();
++	  			bytes.writeObject(_archive);   
++	  			bytes.compress();    
++	  			_sharedObject.data.archive = bytes;
++	        }
++	        else _sharedObject.data.archive = _archive;
++	         
++	    	var result:String;
++	 		
++			try
++			{
++				result = _sharedObject.flush();
++	    	}
++			catch(e:Error)
++			{
++				//event will be throw further down
++			}
++	    	//return status
++	    	if(result == SharedObjectFlushStatus.FLUSHED)
++	    	{
++	    		//there may be future issues here with 40k+ storage, because due to the HTML5 spec,
++	    		//old and new values must be sent back--for a 40k update, this means sending 80k back in the event
++	    		evt.type = type;
++	    		evt.info = info;
++	    		evt.key = location;
++	    		evt.oldValue = oldValue;
++	    		evt.newValue = newValue;
++				evt.index = index;
++				yuibridge.sendEvent(evt);
++	    		return true;
++	    	}
++			if(result == SharedObjectFlushStatus.PENDING)
++	    	{
++	    		//let JS know theres going to be a dialog
++	    		evt = {type: "pending"};
++				yuibridge.sendEvent(evt);
++	    		return false;
++	    	} 
++	    	 
++	    	else
++	    	{
++	    		evt = {type: "error", message:"Unable to save. Client-side storage has been disabled for this domain. To enable, display the Flash settings panel and set a storage amount."};
++				yuibridge.sendEvent(evt);
++	    		return false;
++	    		
++	    	} 
++	    	return false;
++	    }
++	    
++	    /**
++		* @private
++		* Sets the date modified for the store, based on the user's clock.
++		* 
++		* @param value The time to set, as a Number.
++	    * 
++		*/
++		protected function setTime(value:Number):void
++		{
++			_sharedObject.data.modificationDate = value;
++		}
++	    
++		/**
++		* @private
++		* Called when a larger shared object size is requested
++	    * @param the NetStatusEvent object.
++		*/
++		protected function onNetStatus(event:NetStatusEvent):void
++		{
++			 
++			var evt:Object;
++			if(event.info.level =="error")
++			{           
++				//this is most likely the result of maxing out storage for the domain. There's no way to tell for certain
++				evt = {type: "quotaExceededError", info:"NetStatus Error: " + event.info.code,
++					message: "Storage capacity requested exceeds available amount."}; 
++					 
++				yuibridge.sendEvent(evt); 
++			}
++			else
++			{
++				//this is normally executed when additional storage is requested and allowed by the user
++				evt = {type: "success"};
++				yuibridge.sendEvent(evt);
++			}
++			
++		}    
++
++		/**
++		* 
++		* Helper function to determine if SWF visible area is large enough to fit 
++		* the settings panel
++	    * @return Boolean Whether or not the area is large enough.
++		*/
++		public function hasAdequateDimensions():Boolean
++		{
++			return (stage.stageHeight >= MINIMUM_HEIGHT) && (stage.stageWidth >= MINIMUM_WIDTH);
++		}
++	}
++}
+diff --git a/src/swfstore/as/com/yahoo/util/YUIBridge.as b/src/swfstore/as/com/yahoo/util/YUIBridge.as
+new file mode 100755
+index 0000000..e532d42
+--- /dev/null
++++ b/src/swfstore/as/com/yahoo/util/YUIBridge.as
+@@ -0,0 +1,45 @@
++	package com.yahoo.util
++	{
++		import flash.display.Stage;
++		import flash.external.ExternalInterface;
++		
++		public class YUIBridge extends Object
++		{
++			private var _stage:Stage;
++			public var flashvars:Object;
++			private var _jsHandler:String;
++			private var _swfID:String;
++	
++			public function YUIBridge(stage:Stage)
++			{
++				_stage = stage;
++				flashvars = _stage.loaderInfo.parameters;
++				if (flashvars["YUIBridgeCallback"] && flashvars["YUISwfId"] && ExternalInterface.available) {
++					_jsHandler = flashvars["YUIBridgeCallback"];
++					var jsCheck:RegExp = /^[A-Za-z0-9.]*$/g;
++					if (!jsCheck.test(_jsHandler)) {
++				 		_jsHandler = "";
++					}
++
++					_swfID = flashvars["YUISwfId"];
++				}
++			}
++			
++			public function addCallbacks (callbacks:Object) : void {
++				if (ExternalInterface.available) {
++					for (var callback:String in callbacks) {
++	 					ExternalInterface.addCallback(callback, callbacks[callback]);
++	 					trace("Added callback for " + callbacks[callback] + " named " + callback);
++	 				}
++	 				sendEvent({type:"swfReady"});
++	 			}
++			}
++	
++			public function sendEvent (evt:Object) : void {
++				if (ExternalInterface.available) {
++				trace("Sending event " + evt.type);
++				ExternalInterface.call(_jsHandler, _swfID, evt);
++				}
++			}		
++		}
++	}
+\ No newline at end of file
+diff --git a/src/uploader/as/Uploader.as b/src/uploader/as/Uploader.as
+new file mode 100755
+index 0000000..dd9b0af
+--- /dev/null
++++ b/src/uploader/as/Uploader.as
+@@ -0,0 +1,988 @@
++package
++
++{
++
++	import com.yahoo.yui.YUIAdapter;
++	
++	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 YUIAdapter {
++
++	//--------------------------------------
++	//  Constructor
++	//--------------------------------------
++
++		public function Uploader()
++		{
++			super();
++		}
++
++
++	    //--------------------------------------------------------------------------
++	    //
++	    //  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 actualLimit:Number;
++
++		private var singleFile:FileReference;
++		private var multipleFiles:FileReferenceList;
++		
++		
++		/**
++		 * 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;
++		 	}
++		 	else if (simUploadLimit >= 5) {
++		 		this.simultaneousUploadLimit = 5;
++		 	}
++		 	else {
++		 		this.simultaneousUploadLimit = 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 {
++			this.allowLog = allowLogging;
++			logMessage("Logging has been turned " + (allowLog ? "on." : "off."));
++		}
++		
++		/**
++	     *  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 <code>
++	     *  description</code>, and <code>extensions</code> properties which
++		 *  determine which files the user is allowed to select
++	     */
++
++		private function browse(allowMultiple:Boolean = false, filterArray:Array = null):void {
++
++			if(!allowMultiple) {
++				logMessage("Browsing for a single file.")
++				singleFile = new FileReference();
++				singleFile.addEventListener(Event.SELECT, singleFileSelected);
++
++				if(filterArray) {
++					singleFile.browse(filterArray);
++				}
++				else {
++					singleFile.browse();
++				}
++			}
++
++			else {
++
++				logMessage("Browsing for one or more 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 {
++
++			// TODO: Do we need to remove the item from filesToUpload also?
++            cancel(fileID);
++
++			delete fileDataList[fileID];
++			delete fileRefList[fileID];
++
++			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 {
++
++			// TODO: Remove event listeners (or weak references?)
++
++			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: 
++	     *  <code>
++	     *  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.
++	     *  </code>
++	     */
++
++		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);
++		}
++
++		/**
++		 *  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: 
++	     *  <code>
++	     *  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.
++	     * </code>
++	     */
++
++		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);
++			}
++			
++			if (filesToUpload.length < this.simultaneousUploadLimit) {
++						this.actualLimit = filesToUpload.length;
++			} else {
++				this.actualLimit = this.simultaneousUploadLimit;
++			}
++				
++			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");
++			
++			if (fileID == null) { // cancel all files
++				for each (var item:FileReference in fileRefList) {
++					item.cancel();
++				}
++				this.currentUploadThreads = 0;
++				filesToUpload = [];
++			} 
++
++			else if (fileRefList[fileID] != null) { // 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("Mouse down on the uploader.");
++			var newEvent:Object = new Object();
++			newEvent.type = "mouseDown";
++			super.dispatchEventToJavaScript(newEvent);
++		}
++
++		private function transparentUp (event:MouseEvent) : void {
++			logMessage("Mouse up on the uploader.");
++			var newEvent:Object = new Object();
++			newEvent.type = "mouseUp";
++			super.dispatchEventToJavaScript(newEvent);
++		}
++
++		private function transparentRollOver (event:MouseEvent) : void {
++			logMessage("Mouse rolled over the uploader.");
++			var newEvent:Object = new Object();
++			newEvent.type = "rollOver";
++			super.dispatchEventToJavaScript(newEvent);
++		}
++		
++		private function transparentRollOut (event:MouseEvent) : void {
++			logMessage("Mouse rolled out the uploader.");
++			var newEvent:Object = new Object();
++			newEvent.type = "rollOut";
++			super.dispatchEventToJavaScript(newEvent);
++		}
++		
++		private function transparentClick (event:MouseEvent) : void {
++			logMessage("Mouse clicked on the uploader.");
++			var newEvent:Object = new Object();
++			newEvent.type = "click";
++			super.dispatchEventToJavaScript(newEvent);
++		}
++		
++		
++		private function uploadStart (event:Event) : void {
++			logMessage("Started upload for " + fileIDList[event.target]);
++			var newEvent:Object = new Object();
++			newEvent.id = fileIDList[event.target];
++			newEvent.type = "uploadStart";
++            super.dispatchEventToJavaScript(newEvent);
++		}
++
++
++
++		private function uploadProgress (event:ProgressEvent) : void {
++			logMessage("Progress 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"
++			super.dispatchEventToJavaScript(newEvent);
++		}
++
++
++
++		private function uploadComplete (event:Event) : void {
++			logMessage("Upload complete for " + fileIDList[event.target]);
++			var newEvent:Object = new Object();
++			newEvent.id = fileIDList[event.target];
++			newEvent.type = "uploadComplete"
++			super.dispatchEventToJavaScript(newEvent);
++
++			if (this.currentUploadThreads > 0)
++				this.currentUploadThreads--;
++			// get next off of queue:
++			processQueue();
++		}
++
++
++
++		private function uploadCompleteData (event:DataEvent) : void {
++			logMessage("Got data back for " + fileIDList[event.target] + ": ");
++			logMessage(event.data);
++			var newEvent:Object = new Object();
++			newEvent.id = fileIDList[event.target];
++			newEvent.data = event.data;
++			newEvent.type = "uploadCompleteData"
++			super.dispatchEventToJavaScript(newEvent);
++		}
++		
++		private function uploadCancel (event:Event) : void {			
++			logMessage("Canceled upload for " + fileIDList[event.target]);
++			var newEvent:Object = new Object();
++			newEvent.id = fileIDList[event.target];
++			newEvent.type = "uploadCancel";
++			super.dispatchEventToJavaScript(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]);
++			}
++			
++			if (this.currentUploadThreads > 0)
++				this.currentUploadThreads--;
++
++			newEvent.type = "uploadError";
++			newEvent.id = fileIDList[event.target];
++
++			super.dispatchEventToJavaScript(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) {
++				if (currentFR.size > 0) {
++				    addFile(currentFR);
++			    }
++			}			
++			processSelection();
++		}
++		
++		private function renderAsButton (buttonSkinSprite:String) : void {
++		
++			
++			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;
++				
++				function buttonStageResize (evt:Event) : void {
++		 		buttonSprite.width = buttonSprite.stage.stageWidth;
++		 		buttonSprite.height = buttonSprite.stage.stageHeight*4;
++		 		buttonMask.width = _this.stage.stageWidth;
++		 		buttonMask.height = _this.stage.stageHeight;
++		 		};
++		 	
++				buttonSprite.width = _this.stage.stageWidth;
++				buttonSprite.height = _this.stage.stageHeight*4;
++				buttonMask.width = _this.stage.stageWidth;
++				buttonMask.height = _this.stage.stageHeight;
++				
++				_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 {
++		 	
++		 	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
++	     */
++
++		override protected function initializeComponent():void {
++
++			super.initializeComponent();
++			var btnSkinURL:String;
++			btnSkinURL = this.stage.loaderInfo.parameters["buttonSkin"];
++			
++			if (btnSkinURL != null) {
++				this.renderType = "button";
++				this.renderAsButton(btnSkinURL);
++			}
++			else {
++				this.renderType = "transparent";	
++				this.renderAsTransparent();
++			}			
++		 	
++		 	// 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"
++
++			super.dispatchEventToJavaScript(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.actualLimit && filesToUpload.length > 0) {
++				var objToUpload:Object = filesToUpload.shift();
++				var fr:FileReference = objToUpload.fr;
++				var request:URLRequest = objToUpload.request;
++				var fieldName:String = objToUpload.fieldName;
++
++				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);
++				ExternalInterface.call("YAHOO.log", message);
++			}
++		}
++
++	}
++
++}
++
+diff --git a/src/uploader/as/com/yahoo/yui/YUIAdapter.as b/src/uploader/as/com/yahoo/yui/YUIAdapter.as
+new file mode 100755
+index 0000000..0d6fc5d
+--- /dev/null
++++ b/src/uploader/as/com/yahoo/yui/YUIAdapter.as
+@@ -0,0 +1,265 @@
++package com.yahoo.yui
++{
++	import flash.accessibility.AccessibilityProperties;
++	import flash.display.DisplayObject;
++	import flash.display.Sprite;
++	import flash.display.StageAlign;
++	import flash.display.StageScaleMode;
++	import flash.errors.IOError;
++	import flash.events.Event;
++	import flash.external.ExternalInterface;
++	import flash.system.Security;
++	import flash.text.TextField;
++	import flash.text.TextFieldAutoSize;
++	import flash.text.TextFormat;
++
++	public class YUIAdapter extends Sprite
++	{
++		
++	//--------------------------------------
++	//  Constructor
++	//--------------------------------------
++	
++		/**
++		 * Constructor.
++		 */
++		public function YUIAdapter()
++		{
++			if(this.stage)
++			{
++				this.stage.addEventListener(Event.RESIZE, stageResizeHandler);
++				this.stage.scaleMode = StageScaleMode.NO_SCALE;
++				this.stage.align = StageAlign.TOP_LEFT;
++			}
++			
++			super();
++			
++			try
++			{
++				//show error popups
++				ExternalInterface.marshallExceptions = true;
++			}
++			catch(error:Error)
++			{
++				//do nothing, we're in a flash player that properly displays exceptions
++			}
++			
++			this._errorText = new TextField();
++			this._errorText.defaultTextFormat = new TextFormat("_sans", 10, 0xff0000);
++			this._errorText.wordWrap = true;
++			this._errorText.autoSize = TextFieldAutoSize.LEFT;
++			this._errorText.selectable = false;
++			this._errorText.mouseEnabled = false;
++			this.addChild(this._errorText);
++			
++			this.addEventListener(Event.ADDED, addedHandler);
++			
++			if(ExternalInterface.available)
++			{
++				this.initializeComponent();
++				var swfReady:Object = {type: "swfReady"};
++				this.dispatchEventToJavaScript(swfReady);
++			}
++			else
++			{
++				throw new IOError("Flash YUIComponent cannot communicate with JavaScript content.");
++			}
++			
++
++		}
++		
++	//--------------------------------------
++	//  Properties
++	//--------------------------------------
++	
++		/**
++		 * The element id that references the SWF in the HTML.
++		 */
++		protected var elementID:String;
++		
++		/**
++		 * The globally accessible JavaScript function that accepts events through ExternalInterface.
++		 */
++		protected var javaScriptEventHandler:String;
++		
++		/**
++		 * The reference to the Flash component.
++		 */
++		private var _component:DisplayObject;
++		
++		/**
++		 * @private
++		 */
++		protected function get component():DisplayObject
++		{
++			return this._component;
++		}
++		
++		/**
++		 * @private
++		 */
++		protected function set component(value:DisplayObject):void
++		{
++			this._component = value;
++			this.refreshComponentSize();
++		}
++		
++		/**
++		 * @private
++		 * For errors that cannot be passed to JavaScript.
++		 * (ONLY SecurityErrors when ExternalInterface is not available!)
++		 */
++		private var _errorText:TextField;
++		
++		/**
++		 * @private
++		 * Alternative text for assistive technology.
++		 */
++		private var _altText:String;
++		
++	//--------------------------------------
++	//  Public Methods
++	//--------------------------------------
++		
++		/**
++		 * Gets the alternative text for assistive technology.
++		 */
++		public function getAltText():String
++		{
++			return this._altText;
++		}
++		
++		/**
++		 * Sets the alternative text for assistive technology.
++		 */
++		public function setAltText(value:String):void
++		{
++			this._altText = value;
++			var accProps:AccessibilityProperties = new AccessibilityProperties();
++			accProps.name = this._altText;
++			accProps.forceSimple = true;
++			accProps.noAutoLabeling = true;
++			this.component.accessibilityProperties = accProps;
++		}
++		
++	//--------------------------------------
++	//  Protected Methods
++	//--------------------------------------
++		
++		/**
++		 * To be overridden by subclasses to add ExternalInterface callbacks.
++		 */
++		protected function initializeComponent():void
++		{	
++			this.elementID = this.loaderInfo.parameters.YUISwfId;
++
++			this.javaScriptEventHandler = this.loaderInfo.parameters.YUIBridgeCallback;
++			var jsCheck:RegExp = /^[A-Za-z0-9.]*$/g;
++			if (!jsCheck.test(this.javaScriptEventHandler)) {
++				this.javaScriptEventHandler = "";
++			}
++
++
++			
++			var allowedDomain:String = this.loaderInfo.parameters.allowedDomain;
++			if(allowedDomain)
++			{
++				Security.allowDomain(allowedDomain);
++				this.log("allowing: " + allowedDomain);
++			}
++			
++			try
++			{
++				ExternalInterface.addCallback("getAltText", getAltText);
++				ExternalInterface.addCallback("setAltText", setAltText);
++			}
++			catch(error:SecurityError)
++			{
++				//do nothing. it will be caught somewhere else.
++			}
++		}
++		
++		/**
++		 * Sends a log message to the YUI Logger.
++		 */
++		protected function log(message:Object, category:String = null):void
++		{
++			if(message == null) message = "";
++			this.dispatchEventToJavaScript({type: "log", message: message.toString(), category: category});
++		}
++		
++		protected function showFatalError(message:Object):void
++		{
++			if(!message) message = "";
++			if(this._errorText)
++			{
++				this._errorText.appendText(message.toString());
++				//scroll to the new error if needed
++				this._errorText.scrollV = this._errorText.maxScrollV;
++				this._errorText.mouseEnabled = true;
++				this._errorText.selectable = true;
++			}
++		}
++		
++		/**
++		 * @private
++		 *
++		 * Dispatches an event object to the JavaScript wrapper element.
++		 */
++		protected function dispatchEventToJavaScript(event:Object):void
++		{
++			try
++			{
++				if(ExternalInterface.available) ExternalInterface.call(this.javaScriptEventHandler, this.elementID, event);
++			}
++			catch(error:Error)
++			{
++				if(error is SecurityError)
++				{
++					this.showFatalError("Warning: Cannot establish communication between YUI Charts and JavaScript. YUI Charts must be served from HTTP and cannot be viewed locally with file:/// protocol unless location is trusted by Flash Player.\n\nFor more information see:\nhttp://www.adobe.com/products/flashplayer/articles/localcontent/\n\n");
++				}
++			}
++		}
++
++		/**
++		 * @private
++		 * 
++		 * The size of the SWF/stage is dependant on the container it is in.
++		 * The visual component will resize to match the stage size.
++		 */
++		protected function stageResizeHandler(event:Event):void
++		{
++			this.refreshComponentSize();
++			
++			if(this._errorText)
++			{
++				this._errorText.width = this.stage.stageWidth;
++				this._errorText.height = this.stage.stageHeight;
++			}
++			
++			this.log("resize (width: " + this.stage.stageWidth + ", height: " + this.stage.stageHeight + ")", LoggerCategory.INFO);
++		}
++		
++		/**
++		 * @private
++		 */
++		protected function refreshComponentSize():void
++		{
++			if(this.component)
++			{
++				this.component.x = this.component.y = 0;
++				this.component.width = this.stage.stageWidth;
++				this.component.height = this.stage.stageHeight;
++			}
++		}
++		
++		/**
++		 * @private
++		 * ensures that errorText is always on top!
++		 */
++		protected function addedHandler(event:Event):void
++		{
++			this.setChildIndex(this._errorText, this.numChildren - 1);
++		}
++	}
++}
+\ No newline at end of file
diff --git a/debian/patches/series b/debian/patches/series
new file mode 100644
index 0000000..647d160
--- /dev/null
+++ b/debian/patches/series
@@ -0,0 +1 @@
+as-src.patch
diff --git a/debian/rules b/debian/rules
index b02e839..7c5b2d6 100755
--- a/debian/rules
+++ b/debian/rules
@@ -1,28 +1,49 @@
 #!/usr/bin/make -f
 
-clean:
-	dh_testdir
-	dh_testroot
+%:
+	dh $@
 
-	dh_clean
+override_dh_install:
+	dh_install
 
-build:
+	# Adjusting file locations
 
-install:
+	find debian/libjs-yui/usr/share/javascript/yui -name "*.html" | \
+	xargs perl -pi -e 's#\Q../../../../assets\E#/javascript/yui/assets#g;'
 
-binary: binary-indep
+	find debian/libjs-yui/usr/share/javascript/yui -name "*.html" | \
+	xargs perl -pi -e 's#\Q../../build\E#/javascript/yui#g;'
+
+	# creating flash files
+
+	cd src/connection/as && \
+	as3compile com/yui/util/connection.as -M connection -R -o connection.swf && \
+	mv connection.swf ../../../build/connection
+
+	cd src/uploader/as && \
+	as3compile Uploader.as -M Uploader -R -o uploader.swf && \
+	cp uploader.swf ../../../examples/uploader/assets && \
+	mv uploader.swf ../../../build/uploader/assets
+          
+	cd src/swfstore/as && \
+	as3compile SWFStore.as -M SWFStore -R -o swfstore.swf && \
+	cp  swfstore.swf ../../../examples/storage && \
+	cp  swfstore.swf ../../../examples/swfstore && \
+	mv swfstore.swf ../../../build/swfstore
+
+override_dh_clean:
+	dh_clean
+	-find build -name "*.swf" | xargs rm
+	-find examples -name "*.swf" | xargs rm
 
-binary-arch:
+override_dh_compress:
+	dh_compress -i -X.js -X-js -X.json -X.php
 
-binary-indep:
-	dh_testdir -i
-	dh_testroot -i
-	dh_installchangelogs -i
-	dh_installdocs -i
-	dh_installexamples -i
-	dh_install -i 
+override_dh_installdocs:
+	dh_installdocs
 
 	# Adjusting file locations
+
 	find debian/libjs-yui-doc/usr/share/doc/libjs-yui-doc/examples -name "*.html" | \
 	xargs perl -pi -e 's#\Q../../../../assets\E#/javascript/yui/assets#g;'
 
@@ -40,19 +61,3 @@ binary-indep:
 
 	find debian/libjs-yui-doc/usr/share/doc/libjs-yui-doc/examples -name "*.html" | \
 	xargs perl -pi -e 's#\Q../../docs#/doc/libjs-yui-doc\E#g;'
-
-	find debian/libjs-yui/usr/share/javascript/yui -name "*.html" | \
-	xargs perl -pi -e 's#\Q../../../../assets\E#/javascript/yui/assets#g;'
-
-	find debian/libjs-yui/usr/share/javascript/yui -name "*.html" | \
-	xargs perl -pi -e 's#\Q../../build\E#/javascript/yui#g;'
-
-	dh_lintian -i
-	dh_compress -i -X.js -X-js -X.json -X.php
-	dh_fixperms -i
-	dh_installdeb -i
-	dh_gencontrol -i
-	dh_md5sums -i
-	dh_builddeb -i
-
-.PHONY: clean build install binary binary-arch binary-indep
diff --git a/debian/source/format b/debian/source/format
new file mode 100644
index 0000000..163aaf8
--- /dev/null
+++ b/debian/source/format
@@ -0,0 +1 @@
+3.0 (quilt)
diff --git a/debian/watch b/debian/watch
index 893efe4..9bc0e9a 100644
--- a/debian/watch
+++ b/debian/watch
@@ -1,2 +1,3 @@
 version=3
-http://yuilibrary.com/downloads/ .*yui2/yui_(.*).zip
+http://yuilibrary.com/download/yui2/ \
+        http://yui.zenfs.com/releases/yui2/yui_([\d\.]*).zip

-- 
Yahoo! User Interface Toolkit (yui)



More information about the Pkg-javascript-commits mailing list