You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by jk...@apache.org on 2006/06/10 16:27:54 UTC

svn commit: r413306 [10/17] - in /tapestry/tapestry4/trunk: examples/TimeTracker/src/java/org/apache/tapestry/timetracker/page/ framework/src/java/org/apache/tapestry/ framework/src/java/org/apache/tapestry/dojo/form/ framework/src/java/org/apache/tape...

Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/rpc/yahoo.smd
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/rpc/yahoo.smd?rev=413306&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/rpc/yahoo.smd (added)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/rpc/yahoo.smd Sat Jun 10 07:27:44 2006
@@ -0,0 +1,263 @@
+{
+	"SMDVersion":".1",
+	"objectName":"yahoo",
+	"serviceType":"JSON-P",
+	"methods":[
+		//
+		// MAPS 
+		//
+		{
+			// http://developer.yahoo.com/maps/rest/V1/mapImage.html
+			"name":"mapImage",
+			"serviceURL": "http://api.local.yahoo.com/MapsService/V1/mapImage",
+			"parameters":[
+				{ "name":"street", "type":"STRING" },
+				{ "name":"city", "type":"STRING" },
+				{ "name":"zip", "type":"INTEGER" },
+				{ "name":"location", "type":"STRING" },
+				{ "name":"longitude", "type":"FLOAT" },
+				{ "name":"latitude", "type":"FLOAT" },
+				{ "name":"image_type", "type":"STRING" },
+				{ "name":"image_width", "type":"INTEGER" },
+				{ "name":"image_height", "type":"INTEGER" },
+				{ "name":"zoom", "type":"INTEGER" },
+				{ "name":"radius", "type":"INTEGER" }
+			]
+		},
+		{
+			// http://developer.yahoo.com/traffic/rest/V1/index.html
+			"name":"trafficData",
+			"serviceURL": "http://api.local.yahoo.com/MapsService/V1/trafficData",
+			"parameters":[
+				{ "name":"street", "type":"STRING" },
+				{ "name":"city", "type":"STRING" },
+				{ "name":"zip", "type":"INTEGER" },
+				{ "name":"location", "type":"STRING" },
+				{ "name":"longitude", "type":"FLOAT" },
+				{ "name":"latitude", "type":"FLOAT" },
+				{ "name":"severity", "type":"INTEGER" },
+				{ "name":"include_map", "type":"INTEGER" },
+				{ "name":"image_type", "type":"STRING" },
+				{ "name":"image_width", "type":"INTEGER" },
+				{ "name":"image_height", "type":"INTEGER" },
+				{ "name":"zoom", "type":"INTEGER" },
+				{ "name":"radius", "type":"INTEGER" }
+			]
+		},
+		/*
+			// Yahoo's geocoding service is f'd for JSON and Y! advises that it
+			// may not be returning
+		{
+			// http://developer.yahoo.com/maps/rest/V1/geocode.html
+			"name":"geocode",
+			"serviceURL": "http://api.local.yahoo.com/MapsService/V1/geocode",
+			"parameters":[
+				{ "name":"street", "type":"STRING" },
+				{ "name":"city", "type":"STRING" },
+				{ "name":"zip", "type":"INTEGER" },
+				{ "name":"location", "type":"STRING" }
+			]
+		},
+		*/
+		//
+		// LOCAL SEARCH
+		//
+		{
+			// http://developer.yahoo.com/search/local/V3/localSearch.html
+			"name":"localSearch",
+			"serviceURL": "http://api.local.yahoo.com/LocalSearchService/V3/localSearch",
+			"parameters":[
+				{ "name":"street", "type":"STRING" },
+				{ "name":"city", "type":"STRING" },
+				{ "name":"zip", "type":"INTEGER" },
+				{ "name":"location", "type":"STRING" },
+				{ "name":"listing_id", "type":"STRING" },
+				{ "name":"sort", "type":"STRING" }, // "relevence", "title", "distance", or "rating"
+				{ "name":"start", "type":"INTEGER" },
+				{ "name":"radius", "type":"FLOAT" },
+				{ "name":"results", "type":"INTEGER" }, // 1-50, defaults to 10
+				{ "name":"longitude", "type":"FLOAT" },
+				{ "name":"latitude", "type":"FLOAT" },
+				{ "name":"category", "type":"INTEGER" },
+				{ "name":"omit_category", "type":"INTEGER" },
+				{ "name":"minimum_rating", "type":"INTEGER" }
+			]
+		},
+		//
+		// WEB SEARCH
+		//
+
+		// NOTE: contextual search and term extraction are not stubbed out
+		// becaues I'm not sure if we can POST via script src inclusion method
+		{
+			// http://developer.yahoo.com/search/web/V1/webSearch.html 
+			"name":"webSearch",
+			"serviceURL": "http://api.search.yahoo.com/WebSearchService/V1/webSearch",
+			"parameters":[
+				{ "name":"query", "type":"STRING" },
+				{ "name":"type", "type":"STRING" }, // defaults to "all"
+				{ "name":"region", "type":"STRING" }, // defaults to "us"
+				{ "name":"results", "type":"INTEGER" }, // defaults to 10
+				{ "name":"start", "type":"INTEGER" }, // defaults to 1
+				{ "name":"format", "type":"STRING" }, // defaults to "any", can be "html", "msword", "pdf", "ppt", "rst", "txt", or "xls"
+				{ "name":"adult_ok", "type":"INTEGER" }, // defaults to null
+				{ "name":"similar_ok", "type":"INTEGER" }, // defaults to null
+				{ "name":"language", "type":"STRING" }, // defaults to null
+				{ "name":"country", "type":"STRING" }, // defaults to null
+				{ "name":"site", "type":"STRING" }, // defaults to null
+				{ "name":"subscription", "type":"STRING" }, // defaults to null
+				{ "name":"license", "type":"STRING" } // defaults to "any"
+			]
+		},
+		{
+			// http://developer.yahoo.com/search/web/V1/spellingSuggestion.html
+			"name":"spellingSuggestion",
+			"serviceURL": "http://api.search.yahoo.com/WebSearchService/V1/spellingSuggestion",
+			"parameters":[ { "name":"query", "type":"STRING" } ]
+		},
+		{
+			// http://developer.yahoo.com/search/web/V1/relatedSuggestion.html
+			"name":"spellingSuggestion",
+			"serviceURL": "http://api.search.yahoo.com/WebSearchService/V1/relatedSuggestion",
+			"parameters":[
+				{ "name":"query", "type":"STRING" },
+				{ "name":"results", "type":"INTEGER" } // 1-50, defaults to 10
+			]
+		},
+		//
+		// IMAGE SEARCH
+		//
+		{
+			// http://developer.yahoo.com/search/image/V1/imageSearch.html
+			"name":"imageSearch",
+			"serviceURL": "http://api.search.yahoo.com/ImageSearchService/V1/imageSearch",
+			"parameters":[
+				{ "name":"query", "type":"STRING" },
+				{ "name":"type", "type":"STRING" }, // defaults to "all", can by "any" or "phrase"
+				{ "name":"results", "type":"INTEGER" }, // defaults to 10
+				{ "name":"start", "type":"INTEGER" }, // defaults to 1
+				{ "name":"format", "type":"STRING" }, // defaults to "any", can be "bmp", "gif", "jpeg", or "png"
+				{ "name":"adult_ok", "type":"INTEGER" }, // defaults to null
+				{ "name":"coloration", "type":"STRING" }, // "any", "color", or "bw"
+				{ "name":"site", "type":"STRING" } // defaults to null
+			]
+		},
+		//
+		// SITE EXPLORER
+		//
+		{
+			// http://developer.yahoo.com/search/siteexplorer/V1/inlinkData.html 
+			"name":"inlinkData",
+			"serviceURL": "http://api.search.yahoo.com/SiteExplorerService/V1/inlinkData",
+			"parameters":[
+				{ "name":"query", "type":"STRING" },
+				{ "name":"type", "type":"STRING" }, // defaults to "all", can by "any" or "phrase"
+				{ "name":"entire_site", "type":"INTEGER" }, // defaults to null
+				{ "name":"omit_inlinks", "type":"STRING" }, // "domain" or "subdomain", defaults to null
+				{ "name":"results", "type":"INTEGER" }, // defaults to 50
+				{ "name":"start", "type":"INTEGER" }, // defaults to 1
+				{ "name":"site", "type":"STRING" } // defaults to null
+			]
+		},
+		{
+			// http://developer.yahoo.com/search/siteexplorer/V1/pageData.html
+			"name":"pageData",
+			"serviceURL": "http://api.search.yahoo.com/SiteExplorerService/V1/pageData",
+			"parameters":[
+				{ "name":"query", "type":"STRING" },
+				{ "name":"type", "type":"STRING" }, // defaults to "all", can by "any" or "phrase"
+				{ "name":"domain_only", "type":"INTEGER" }, // defaults to null
+				{ "name":"results", "type":"INTEGER" }, // defaults to 50
+				{ "name":"start", "type":"INTEGER" }, // defaults to 1
+				{ "name":"site", "type":"STRING" } // defaults to null
+			]
+		},
+		//
+		// MUSIC SEARCH
+		//
+		{
+			// http://developer.yahoo.com/search/audio/V1/artistSearch.html
+			"name":"artistSearch",
+			"serviceURL": "http://api.search.yahoo.com/AudioSearchService/V1/artistSearch",
+			"parameters":[
+				{ "name":"artist", "type":"STRING" },
+				{ "name":"artistid", "type":"STRING" },
+				{ "name":"type", "type":"STRING" }, // "all", "any", or "phrase"
+				{ "name":"results", "type":"INTEGER" }, // 1-50, defaults to 10
+				{ "name":"start", "type":"INTEGER" } // defaults to 1
+			]
+		},
+		{
+			// http://developer.yahoo.com/search/audio/V1/albumSearch.html
+			"name":"albumSearch",
+			"serviceURL": "http://api.search.yahoo.com/AudioSearchService/V1/albumSearch",
+			"parameters":[
+				{ "name":"artist", "type":"STRING" },
+				{ "name":"artistid", "type":"STRING" },
+				{ "name":"album", "type":"STRING" },
+				{ "name":"type", "type":"STRING" }, // "all", "any", or "phrase"
+				{ "name":"results", "type":"INTEGER" }, // 1-50, defaults to 10
+				{ "name":"start", "type":"INTEGER" } // defaults to 1
+			]
+		},
+		{
+			// http://developer.yahoo.com/search/audio/V1/songSearch.html
+			"name":"songSearch",
+			"serviceURL": "http://api.search.yahoo.com/AudioSearchService/V1/songSearch",
+			"parameters":[
+				{ "name":"artist", "type":"STRING" },
+				{ "name":"artistid", "type":"STRING" },
+				{ "name":"album", "type":"STRING" },
+				{ "name":"albumid", "type":"STRING" },
+				{ "name":"song", "type":"STRING" },
+				{ "name":"songid", "type":"STRING" },
+				{ "name":"type", "type":"STRING" }, // "all", "any", or "phrase"
+				{ "name":"results", "type":"INTEGER" }, // 1-50, defaults to 10
+				{ "name":"start", "type":"INTEGER" } // defaults to 1
+			]
+		},
+		{
+			// http://developer.yahoo.com/search/audio/V1/songDownloadLocation.html
+			"name":"songDownloadLocation",
+			"serviceURL": "http://api.search.yahoo.com/AudioSearchService/V1/songDownloadLocation",
+			"parameters":[
+				{ "name":"songid", "type":"STRING" },
+				// "source" can contain:
+				//	audiolunchbox artistdirect buymusic dmusic
+				//	emusic epitonic garageband itunes yahoo
+				//	livedownloads mp34u msn musicmatch mapster passalong
+				//	rhapsody soundclick theweb
+				{ "name":"source", "type":"STRING" },
+				{ "name":"results", "type":"INTEGER" }, // 1-50, defaults to 10
+				{ "name":"start", "type":"INTEGER" } // defaults to 1
+			]
+		},
+		//
+		// NEWS SEARCH
+		//
+		{
+			// http://developer.yahoo.com/search/news/V1/newsSearch.html
+			"name":"newsSearch",
+			"serviceURL": "http://api.search.yahoo.com/NewsSearchService/V1/newsSearch",
+			"parameters":[
+				{ "name":"query", "type":"STRING" },
+				{ "name":"type", "type":"STRING" }, // defaults to "all"
+				{ "name":"results", "type":"INTEGER" }, // defaults to 10
+				{ "name":"start", "type":"INTEGER" }, // defaults to 1
+				{ "name":"sort", "type":"STRING" }, // "rank" or "date"
+				{ "name":"language", "type":"STRING" }, // defaults to null
+				{ "name":"site", "type":"STRING" } // defaults to null
+			]
+		}
+		/*
+		{
+			// 
+			"name":"",
+			"serviceURL": "",
+			"parameters":[
+				{ "name":"street", "type":"STRING" },
+			]
+		}
+		*/
+	]
+}

Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/storage.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/storage.js?rev=413306&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/storage.js (added)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/storage.js Sat Jun 10 07:27:44 2006
@@ -0,0 +1,418 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+/** 
+		FIXME: Write better docs.
+
+		@author Alex Russel, alex@dojotoolkit.org
+		@author Brad Neuberg, bkn3@columbia.edu 
+*/
+dojo.provide("dojo.storage");
+dojo.provide("dojo.storage.StorageProvider");
+
+dojo.require("dojo.lang.*");
+dojo.require("dojo.event.*");
+
+
+/** The base class for all storage providers. */
+
+/** 
+	 The constructor for a storage provider. You should avoid initialization
+	 in the constructor; instead, define initialization in your initialize()
+	 method. 
+*/
+dojo.storage = function(){
+}
+
+dojo.lang.extend(dojo.storage, {
+	/** A put() call to a storage provider was succesful. */
+	SUCCESS: "success",
+	
+	/** A put() call to a storage provider failed. */
+	FAILED: "failed",
+	
+	/** A put() call to a storage provider is pending user approval. */
+	PENDING: "pending",
+	
+	/** 
+	  Returned by getMaximumSize() if this storage provider can not determine
+	  the maximum amount of data it can support. 
+	*/
+	SIZE_NOT_AVAILABLE: "Size not available",
+	
+	/**
+	  Returned by getMaximumSize() if this storage provider has no theoretical
+	  limit on the amount of data it can store. 
+	*/
+	SIZE_NO_LIMIT: "No size limit",
+	
+	/** 
+	  The namespace for all storage operations. This is useful if
+	  several applications want access to the storage system from the same
+	  domain but want different storage silos. 
+	*/
+	namespace: "dojoStorage",
+	
+	/**  
+	  If a function is assigned to this property, then 
+	  when the settings provider's UI is closed this
+	  function is called. Useful, for example, if the
+	  user has just cleared out all storage for this
+	  provider using the settings UI, and you want to 
+	  update your UI.
+	*/
+	onHideSettingsUI: null,
+
+	/** 
+	  Allows this storage provider to initialize itself. This is called
+	  after the page has finished loading, so you can not do document.writes(). 
+	*/
+	initialize: function(){
+	 dojo.unimplemented("dojo.storage.initialize");
+	},
+	
+	/** 
+	  Returns whether this storage provider is 
+	  available on this platform. 
+	
+	  @returns True or false if this storage 
+	  provider is supported.
+	*/
+	isAvailable: function(){
+		dojo.unimplemented("dojo.storage.isAvailable");
+	},
+	
+	/**
+	  Puts a key and value into this storage system.
+
+	  @param key A string key to use when retrieving 
+	         this value in the future.
+	  @param value A value to store; this can be 
+	         any JavaScript type.
+	  @param resultsHandler A callback function 
+	         that will receive three arguments.
+	         The first argument is one of three 
+	         values: dojo.storage.SUCCESS,
+	         dojo.storage.FAILED, or 
+	         dojo.storage.PENDING; these values 
+	         determine how the put request went. 
+	         In some storage systems users can deny
+	         a storage request, resulting in a 
+	         dojo.storage.FAILED, while in 
+	         other storage systems a storage 
+	         request must wait for user approval,
+	         resulting in a dojo.storage.PENDING 
+	         status until the request
+	         is either approved or denied, 
+	         resulting in another call back
+	         with dojo.storage.SUCCESS. 
+  
+	  The second argument in the call back is the key name
+	  that was being stored.
+	  
+	  The third argument in the call back is an 
+	  optional message that details possible error 
+	  messages that might have occurred during
+	  the storage process.
+
+	  Example:
+	    var resultsHandler = function(status, key, message){
+	      alert("status="+status+", key="+key+", message="+message);
+	    };
+	    dojo.storage.put("test", "hello world", 
+	                     resultsHandler);	
+	*/
+	put: function(key, value, resultsHandler){ 
+    dojo.unimplemented("dojo.storage.put");
+  },
+
+	/**
+	  Gets the value with the given key. Returns null
+	  if this key is not in the storage system.
+	
+	  @param key A string key to get the value of.
+	  @returns Returns any JavaScript object type; 
+	  null if the key is not
+	  present. 
+	*/
+	get: function(key){
+    dojo.unimplemented("dojo.storage.get");
+  },
+
+	/**
+	  Determines whether the storage has the given 
+	  key. 
+	
+	    @returns Whether this key is 
+	             present or not. 
+	*/
+	hasKey: function(key){
+		if (this.get(key) != null)
+			return true;
+		else
+			return false;
+	},
+
+	/**
+	  Enumerates all of the available keys in 
+	  this storage system.
+	
+	  @returns Array of string keys in this 
+	           storage system.
+	*/
+	getKeys: function(){
+    dojo.unimplemented("dojo.storage.getKeys");
+  },
+
+	/**
+	  Completely clears this storage system of all 
+	  of it's values and keys. 
+	*/
+	clear: function(){
+    dojo.unimplemented("dojo.storage.clear");
+  },
+  
+  /** Removes the given key from the storage system. */
+  remove: function(key){
+  	dojo.unimplemented("dojo.storage.remove");
+  },
+
+	/**
+	  Returns whether this storage provider's 
+	  values are persisted when this platform 
+	  is shutdown. 
+	
+	  @returns True or false whether this 
+	  storage is permanent. 
+	*/
+	isPermanent: function(){
+		dojo.unimplemented("dojo.storage.isPermanent");
+	},
+
+	/**
+	  The maximum storage allowed by this provider.
+	
+	  @returns Returns the maximum storage size 
+	           supported by this provider, in 
+	           thousands of bytes (i.e., if it 
+	           returns 60 then this means that 60K 
+	           of storage is supported).
+	    
+	           If this provider can not determine 
+	           it's maximum size, then 
+	           dojo.storage.SIZE_NOT_AVAILABLE is 
+	           returned; if there is no theoretical
+	           limit on the amount of storage 
+	           this provider can return, then
+	           dojo.storage.SIZE_NO_LIMIT is 
+	           returned
+	*/
+	getMaximumSize: function(){
+    dojo.unimplemented("dojo.storage.getMaximumSize");
+  },
+
+	/**
+	  Determines whether this provider has a 
+	  settings UI.
+	
+	  @returns True or false if this provider has 
+	           the ability to show a
+	           a settings UI to change it's 
+	           values, change the amount of storage
+	           available, etc. 
+	*/
+	hasSettingsUI: function(){
+		return false;
+	},
+
+	/**
+	  If this provider has a settings UI, it is 
+	  shown. 
+	*/
+	showSettingsUI: function(){
+	 dojo.unimplemented("dojo.storage.showSettingsUI");
+	},
+
+	/**
+	  If this provider has a settings UI, hides
+	  it.
+	*/
+	hideSettingsUI: function(){
+	 dojo.unimplemented("dojo.storage.hideSettingsUI");
+	},
+	
+	/** 
+	  The provider name as a string, such as 
+	  "dojo.storage.FlashStorageProvider". 
+	*/
+	getType: function(){
+		dojo.unimplemented("dojo.storage.getType");
+	},
+	
+	/**
+	  Subclasses can call this to ensure that the key given is valid in a
+	  consistent way across different storage providers. We use the lowest
+	  common denominator for key values allowed: only letters, numbers, and
+	  underscores are allowed. No spaces. 
+	*/
+	isValidKey: function(keyName){
+		if (keyName == null || typeof keyName == "undefined")
+			return false;
+			
+		return /^[0-9A-Za-z_]*$/.test(keyName);
+  }
+});
+
+
+
+
+/**
+	Initializes the storage systems and figures out the best available 
+	storage options on this platform.
+*/
+dojo.storage.manager = new function(){
+	this.currentProvider = null;
+	this.available = false;
+	this.initialized = false;
+	this.providers = new Array();
+	
+	// TODO: Provide a way for applications to override the default namespace
+	this.namespace = "dojo.storage";
+	
+	/** Initializes the storage system. */
+	this.initialize = function(){
+		// autodetect the best storage provider we can provide on this platform
+		this.autodetect();
+	}
+	
+	/**
+	  Registers the existence of a new storage provider; used by subclasses
+	  to inform the manager of their existence. 
+	
+	  @param name The full class name of this provider, such as 
+	  "dojo.storage.browser.Flash6StorageProvider".
+	  @param instance An instance of this provider, which we will use to
+	  call isAvailable() on. 
+	*/
+	this.register = function(name, instance) {
+		this.providers[this.providers.length] = instance;
+		this.providers[name] = instance;
+	}
+	
+	/**
+	  Instructs the storageManager to use 
+	  the given storage class for all storage requests.
+	    
+	  Example:
+	    
+	  dojo.storage.setProvider(
+	         dojo.storage.browser.IEStorageProvider)
+	*/
+	this.setProvider = function(storageClass){
+	
+	}
+	
+	/** 
+	  Autodetects the best possible persistent
+	  storage provider available on this platform. 
+	*/
+	this.autodetect = function(){
+		if(this.initialized == true) // already finished
+			return;
+			
+		// go through each provider, seeing if it can be used
+		var providerToUse = null;
+		for(var i = 0; i < this.providers.length; i++) {
+			providerToUse = this.providers[i];
+			if(providerToUse.isAvailable()){
+				break;
+			}
+		}	
+		
+		if(providerToUse == null){ // no provider available
+			this.initialized = true;
+			this.available = false;
+			this.currentProvider = null;
+			dojo.raise("No storage provider found for this platform");
+		}
+			
+		// create this provider and copy over it's properties
+		this.currentProvider = providerToUse;
+	  	for(var i in providerToUse){
+	  		dojo.storage[i] = providerToUse[i];
+		}
+		dojo.storage.manager = this;
+		
+		// have the provider initialize itself
+		dojo.storage.initialize();
+		
+		this.initialized = true;
+		this.available = true;
+	}
+	
+	/** Returns whether any storage options are available. */
+	this.isAvailable = function(){
+		return this.available;
+	}
+	
+	/** 
+	 	Returns whether the storage system is initialized and
+	 	ready to be used. 
+	*/
+	this.isInitialized = function(){
+		// FIXME: This should _really_ not be in here, but it fixes a bug
+		if(dojo.flash.ready == false){
+			return false;
+		}else{
+			return this.initialized;
+		}
+	}
+
+	/**
+	  Determines if this platform supports
+	  the given storage provider.
+	
+	  Example:
+			
+	  dojo.storage.manager.supportsProvider(
+	    "dojo.storage.browser.InternetExplorerStorageProvider");
+	*/
+	this.supportsProvider = function(storageClass){
+		// construct this class dynamically
+		try{
+			// dynamically call the given providers class level isAvailable()
+			// method
+			var provider = eval("new " + storageClass + "()");
+			var results = provider.isAvailable();
+			if(results == null || typeof results == "undefined")
+				return false;
+			return results;
+		}catch (exception){
+			dojo.debug("exception="+exception);
+			return false;
+		}
+	}
+
+	/** Gets the current provider. */
+	this.getProvider = function(){
+		return this.currentProvider;
+	}
+	
+	/** 
+	  The storage provider should call this method when it is loaded and
+	  ready to be used. Clients who will use the provider will connect
+	  to this method to know when they can use the storage system:
+	
+	  dojo.connect(dojo.storage.manager, "loaded", someInstance, 
+	               someInstance.someMethod);
+	*/
+	this.loaded = function(){
+	}
+}

Propchange: tapestry/tapestry4/trunk/framework/src/js/dojo/src/storage.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/storage/Storage.as
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/storage/Storage.as?rev=413306&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/storage/Storage.as (added)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/storage/Storage.as Sat Jun 10 07:27:44 2006
@@ -0,0 +1,145 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+import DojoExternalInterface;
+
+class Storage {
+	public static var SUCCESS = "success";
+	public static var FAILED = "failed";
+	public static var PENDING = "pending";
+	
+	public var so;
+	
+	public function Storage(){
+		//getURL("javascript:dojo.debug('FLASH:Storage constructor')");
+		DojoExternalInterface.initialize();
+		DojoExternalInterface.addCallback("put", this, put);
+		DojoExternalInterface.addCallback("get", this, get);
+		DojoExternalInterface.addCallback("showSettings", this, showSettings);
+		DojoExternalInterface.addCallback("clear", this, clear);
+		DojoExternalInterface.addCallback("getKeys", this, getKeys);
+		DojoExternalInterface.addCallback("remove", this, remove);
+		DojoExternalInterface.loaded();
+		
+		// preload the System Settings finished button movie for offline
+		// access so it is in the cache
+		_root.createEmptyMovieClip("_settingsBackground", 1);
+		_root._settingsBackground.loadMovie(DojoExternalInterface.dojoPath + "storage_dialog.swf");
+	}
+
+	public function put(keyName, keyValue, namespace){
+		// Get the SharedObject for these values and save it
+		so = SharedObject.getLocal(namespace);
+		
+		// prepare a storage status handler
+		var self = this;
+		so.onStatus = function(infoObject:Object){
+			//getURL("javascript:dojo.debug('FLASH: onStatus, infoObject="+infoObject.code+"')");
+			
+			// delete the data value if the request was denied
+			if (infoObject.code == "SharedObject.Flush.Failed"){
+				delete self.so.data[keyName];
+			}
+			
+			var statusResults;
+			if(infoObject.code == "SharedObject.Flush.Failed"){
+				statusResults = Storage.FAILED;
+			}else if(infoObject.code == "SharedObject.Flush.Pending"){
+				statusResults = Storage.PENDING;
+			}else if(infoObject.code == "SharedObject.Flush.Success"){
+				statusResults = Storage.SUCCESS;
+			}
+			//getURL("javascript:dojo.debug('FLASH: onStatus, statusResults="+statusResults+"')");
+			
+			// give the status results to JavaScript
+			DojoExternalInterface.call("dojo.storage._onStatus", null, statusResults, 
+																 keyName);
+		}
+		
+		// save the key and value
+		so.data[keyName] = keyValue;
+		var flushResults = so.flush();
+		
+		// return results of this command to JavaScript
+		var statusResults;
+		if(flushResults == true){
+			statusResults = Storage.SUCCESS;
+		}else if(flushResults == "pending"){
+			statusResults = Storage.PENDING;
+		}else{
+			statusResults = Storage.FAILED;
+		}
+		
+		DojoExternalInterface.call("dojo.storage._onStatus", null, statusResults, 
+															 keyName);
+	}
+
+	public function get(keyName, namespace){
+		// Get the SharedObject for these values and save it
+		so = SharedObject.getLocal(namespace);
+		var results = so.data[keyName];
+		
+		return results;
+	}
+	
+	public function showSettings(){
+		// Show the configuration options for the Flash player, opened to the
+		// section for local storage controls (pane 1)
+		System.showSettings(1);
+		
+		// there is no way we can intercept when the Close button is pressed, allowing us
+		// to hide the Flash dialog. Instead, we need to load a movie in the
+		// background that we can show a close button on.
+		_root.createEmptyMovieClip("_settingsBackground", 1);
+		_root._settingsBackground.loadMovie(DojoExternalInterface.dojoPath + "storage_dialog.swf");
+	}
+	
+	public function clear(namespace){
+		so = SharedObject.getLocal(namespace);
+		so.clear();
+		so.flush();
+	}
+	
+	public function getKeys(namespace){
+		// Returns a list of the available keys in this namespace
+		
+		// get the storage object
+		so = SharedObject.getLocal(namespace);
+		
+		// get all of the keys
+		var results = new Array();
+		for(var i in so.data)
+			results.push(i);	
+		
+		// join the keys together in a comma seperated string
+		results = results.join(",");
+		
+		return results;
+	}
+	
+	public function remove(keyName, namespace){
+		// Removes a key
+
+		// get the storage object
+		so = SharedObject.getLocal(namespace);
+		
+		// delete this value
+		delete so.data[keyName];
+		
+		// save the changes
+		so.flush();
+	}
+
+	static function main(mc){
+		//getURL("javascript:dojo.debug('FLASH: storage loaded')");
+		_root.app = new Storage(); 
+	}
+}
+

Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/storage/__package__.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/storage/__package__.js?rev=413306&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/storage/__package__.js (added)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/storage/__package__.js Sat Jun 10 07:27:44 2006
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.kwCompoundRequire({
+	common: ["dojo.storage"],
+	browser: ["dojo.storage.browser"],
+	dashboard: ["dojo.storage.dashboard"]
+});
+dojo.provide("dojo.storage.*");

Propchange: tapestry/tapestry4/trunk/framework/src/js/dojo/src/storage/__package__.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/storage/browser.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/storage/browser.js?rev=413306&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/storage/browser.js (added)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/storage/browser.js Sat Jun 10 07:27:44 2006
@@ -0,0 +1,198 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.storage.browser");
+dojo.provide("dojo.storage.browser.FlashStorageProvider");
+
+dojo.require("dojo.storage");
+dojo.require("dojo.flash");
+dojo.require("dojo.json");
+dojo.require("dojo.uri.*");
+
+/** 
+		Storage provider that uses features in Flash to achieve permanent storage.
+		
+		@author Alex Russel, alex@dojotoolkit.org
+		@author Brad Neuberg, bkn3@columbia.edu 
+*/
+dojo.storage.browser.FlashStorageProvider = function(){
+}
+
+dojo.inherits(dojo.storage.browser.FlashStorageProvider, dojo.storage);
+
+// instance methods and properties
+dojo.lang.extend(dojo.storage.browser.FlashStorageProvider, {
+	namespace: "default",
+	initialized: false,
+	_available: null,
+	_statusHandler: null,
+	
+	initialize: function(){
+		if(djConfig["disableFlashStorage"] == true){
+			return;
+		}
+		
+		// initialize our Flash
+		var loadedListener = function(){
+			dojo.storage._flashLoaded();
+		}
+		dojo.flash.addLoadedListener(loadedListener);
+		var swfloc6 = dojo.uri.dojoUri("Storage_version6.swf").toString();
+		var swfloc8 = dojo.uri.dojoUri("Storage_version8.swf").toString();
+		dojo.flash.setSwf({flash6: swfloc6, flash8: swfloc8, visible: false});
+	},
+	
+	isAvailable: function(){
+		if(djConfig["disableFlashStorage"] == true){
+			this._available = false;
+		}
+		
+		return this._available;
+	},
+	
+	setNamespace: function(namespace){
+		this.namespace = namespace;
+	},
+
+	put: function(key, value, resultsHandler){
+		if(this.isValidKey(key) == false){
+			dojo.raise("Invalid key given: " + key);
+		}
+			
+		this._statusHandler = resultsHandler;
+		
+		// serialize the value
+		// Handle strings differently so they have better performance
+		if(dojo.lang.isString(value)){
+			value = "string:" + value;
+		}else{
+			value = dojo.json.serialize(value);
+		}
+		
+		dojo.flash.comm.put(key, value, this.namespace);
+	},
+
+	get: function(key){
+		if(this.isValidKey(key) == false){
+			dojo.raise("Invalid key given: " + key);
+		}
+		
+		var results = dojo.flash.comm.get(key, this.namespace);
+
+		if(results == ""){
+			return null;
+		}
+    
+		// destringify the content back into a 
+		// real JavaScript object
+		// Handle strings differently so they have better performance
+		if(!dojo.lang.isUndefined(results) && results != null 
+			 && /^string:/.test(results)){
+			results = results.substring("string:".length);
+		}else{
+			results = dojo.json.evalJson(results);
+		}
+    
+		return results;
+	},
+
+	getKeys: function(){
+		var results = dojo.flash.comm.getKeys(this.namespace);
+		
+		if(results == ""){
+			return new Array();
+		}
+
+		// the results are returned comma seperated; split them
+		results = results.split(",");
+		
+		return results;
+	},
+
+	clear: function(){
+		dojo.flash.comm.clear(this.namespace);
+	},
+	
+	remove: function(key){
+	},
+	
+	isPermanent: function(){
+		return true;
+	},
+
+	getMaximumSize: function(){
+		return dojo.storage.SIZE_NO_LIMIT;
+	},
+
+	hasSettingsUI: function(){
+		return true;
+	},
+
+	showSettingsUI: function(){
+		dojo.flash.comm.showSettings();
+		dojo.flash.obj.setVisible(true);
+		dojo.flash.obj.center();
+	},
+
+	hideSettingsUI: function(){
+		// hide the dialog
+		dojo.flash.obj.setVisible(false);
+		
+		// call anyone who wants to know the dialog is
+		// now hidden
+		if(dojo.storage.onHideSettingsUI != null &&
+			!dojo.lang.isUndefined(dojo.storage.onHideSettingsUI)){
+			dojo.storage.onHideSettingsUI.call(null);	
+		}
+	},
+	
+	/** 
+			The provider name as a string, such as 
+			"dojo.storage.FlashStorageProvider". 
+	*/
+	getType: function(){
+		return "dojo.storage.FlashStorageProvider";
+	},
+	
+	/** Called when the Flash is finished loading. */
+	_flashLoaded: function(){
+		this.initialized = true;
+
+		// indicate that this storage provider is now loaded
+		dojo.storage.manager.loaded();
+	},
+	
+	/** 
+			Called if the storage system needs to tell us about the status
+			of a put() request. 
+	*/
+	_onStatus: function(statusResult, key){
+		//dojo.debug("_onStatus, statusResult="+statusResult+", key="+key);
+		if(statusResult == dojo.storage.PENDING){
+			dojo.flash.obj.center();
+			dojo.flash.obj.setVisible(true);
+		}else{
+			dojo.flash.obj.setVisible(false);
+		}
+		
+		if(!dojo.lang.isUndefined(dojo.storage._statusHandler) 
+				&& dojo.storage._statusHandler != null){
+			dojo.storage._statusHandler.call(null, statusResult, key);		
+		}
+	}
+});
+
+// register the existence of our storage providers
+dojo.storage.manager.register("dojo.storage.browser.FlashStorageProvider",
+                              new dojo.storage.browser.FlashStorageProvider());
+
+// now that we are loaded and registered tell the storage manager to initialize
+// itself
+dojo.storage.manager.initialize();

Propchange: tapestry/tapestry4/trunk/framework/src/js/dojo/src/storage/browser.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/storage/dashboard.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/storage/dashboard.js?rev=413306&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/storage/dashboard.js (added)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/storage/dashboard.js Sat Jun 10 07:27:44 2006
@@ -0,0 +1,52 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.require("dojo.storage");
+dojo.require("dojo.json");
+dojo.provide("dojo.storage.dashboard");
+
+dojo.storage.dashboard.StorageProvider = function(){
+	this.initialized = false;
+}
+
+dojo.inherits(dojo.storage.dashboard.StorageProvider, dojo.storage.StorageProvider);
+
+dojo.lang.extend(dojo.storage.dashboard.StorageProvider, {
+	storageOnLoad: function(){
+		this.initialized = true;
+	},
+
+	set: function(key, value, ns){
+		if (ns && widget.system){
+			widget.system("/bin/mkdir " + ns);
+			var system = widget.system("/bin/echo " + value + " >" + ns + "/" + key);
+			if(system.errorString){
+				return false;
+			}
+			return true;
+		}
+
+		return widget.setPreferenceForKey(dojo.json.serialize(value), key);
+	},
+
+	get: function(key, ns){
+		if (ns && widget.system) {
+			var system = widget.system("/bin/cat " + ns + "/" + key);
+			if(system.errorString){
+				return "";
+			}
+			return system.outputString;
+		}
+
+		return dojo.json.evalJson(widget.preferenceForKey(key));
+	}
+});
+
+dojo.storage.setProvider(new dojo.storage.dashboard.StorageProvider());

Propchange: tapestry/tapestry4/trunk/framework/src/js/dojo/src/storage/dashboard.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/storage/storage_dialog.fla
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/storage/storage_dialog.fla?rev=413306&view=auto
==============================================================================
Binary file - no diff available.

Propchange: tapestry/tapestry4/trunk/framework/src/js/dojo/src/storage/storage_dialog.fla
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/string/extras.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/string/extras.js?rev=413306&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/string/extras.js (added)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/string/extras.js Sat Jun 10 07:27:44 2006
@@ -0,0 +1,237 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.string.extras");
+
+dojo.require("dojo.string.common");
+dojo.require("dojo.lang");
+
+/**
+ * Performs parameterized substitutions on a string.  For example,
+ *   dojo.string.substituteParams("File '%{0}' is not found in directory '%{1}'.","foo.html","/temp");
+ * returns
+ *   "File 'foo.html' is not found in directory '/temp'."
+ * 
+ * @param template the original string template with %{values} to be replaced
+ * @param hash name/value pairs (type object) to provide substitutions.  Alternatively, substitutions may be
+ *  included as arguments 1..n to this function, corresponding to template parameters 0..n-1
+ * @return the completed string. Throws an exception if any parameter is unmatched
+ */
+//TODO: use ${} substitution syntax instead, like widgets do?
+dojo.string.substituteParams = function(template /*string */, hash /* object - optional or ... */) {
+	var map = (typeof hash == 'object') ? hash : dojo.lang.toArray(arguments, 1);
+
+	return template.replace(/\%\{(\w+)\}/g, function(match, key){
+		return map[key] || dojo.raise("Substitution not found: " + key);
+	});
+};
+
+/**
+ * Parameterized string function
+ * str - formatted string with %{values} to be replaces
+ * pairs - object of name: "value" value pairs
+ * killExtra - remove all remaining %{values} after pairs are inserted
+ */
+dojo.string.paramString = function(str, pairs, killExtra) {
+	dojo.deprecated("dojo.string.paramString",
+		"use dojo.string.substituteParams instead", "0.4");
+
+	for(var name in pairs) {
+		var re = new RegExp("\\%\\{" + name + "\\}", "g");
+		str = str.replace(re, pairs[name]);
+	}
+
+	if(killExtra) { str = str.replace(/%\{([^\}\s]+)\}/g, ""); }
+	return str;
+}
+
+/** Uppercases the first letter of each word */
+dojo.string.capitalize = function (str) {
+	if (!dojo.lang.isString(str)) { return ""; }
+	if (arguments.length == 0) { str = this; }
+
+	var words = str.split(' ');
+	for(var i=0; i<words.length; i++){
+		words[i] = words[i].charAt(0).toUpperCase() + words[i].substring(1);
+	}
+	return words.join(" ");
+}
+
+/**
+ * Return true if the entire string is whitespace characters
+ */
+dojo.string.isBlank = function (str) {
+	if(!dojo.lang.isString(str)) { return true; }
+	return (dojo.string.trim(str).length == 0);
+}
+
+dojo.string.encodeAscii = function(str) {
+	if(!dojo.lang.isString(str)) { return str; }
+	var ret = "";
+	var value = escape(str);
+	var match, re = /%u([0-9A-F]{4})/i;
+	while((match = value.match(re))) {
+		var num = Number("0x"+match[1]);
+		var newVal = escape("&#" + num + ";");
+		ret += value.substring(0, match.index) + newVal;
+		value = value.substring(match.index+match[0].length);
+	}
+	ret += value.replace(/\+/g, "%2B");
+	return ret;
+}
+
+dojo.string.escape = function(type, str) {
+	var args = dojo.lang.toArray(arguments, 1);
+	switch(type.toLowerCase()) {
+		case "xml":
+		case "html":
+		case "xhtml":
+			return dojo.string.escapeXml.apply(this, args);
+		case "sql":
+			return dojo.string.escapeSql.apply(this, args);
+		case "regexp":
+		case "regex":
+			return dojo.string.escapeRegExp.apply(this, args);
+		case "javascript":
+		case "jscript":
+		case "js":
+			return dojo.string.escapeJavaScript.apply(this, args);
+		case "ascii":
+			// so it's encode, but it seems useful
+			return dojo.string.encodeAscii.apply(this, args);
+		default:
+			return str;
+	}
+}
+
+dojo.string.escapeXml = function(str, noSingleQuotes) {
+	str = str.replace(/&/gm, "&amp;").replace(/</gm, "&lt;")
+		.replace(/>/gm, "&gt;").replace(/"/gm, "&quot;");
+	if(!noSingleQuotes) { str = str.replace(/'/gm, "&#39;"); }
+	return str;
+}
+
+dojo.string.escapeSql = function(str) {
+	return str.replace(/'/gm, "''");
+}
+
+dojo.string.escapeRegExp = function(str) {
+	return str.replace(/\\/gm, "\\\\").replace(/([\f\b\n\t\r[\^$|?*+(){}])/gm, "\\$1");
+}
+
+dojo.string.escapeJavaScript = function(str) {
+	return str.replace(/(["'\f\b\n\t\r])/gm, "\\$1");
+}
+
+dojo.string.escapeString = function(str){ 
+	return ('"' + str.replace(/(["\\])/g, '\\$1') + '"'
+		).replace(/[\f]/g, "\\f"
+		).replace(/[\b]/g, "\\b"
+		).replace(/[\n]/g, "\\n"
+		).replace(/[\t]/g, "\\t"
+		).replace(/[\r]/g, "\\r");
+}
+
+// TODO: make an HTML version
+dojo.string.summary = function(str, len) {
+	if(!len || str.length <= len) {
+		return str;
+	} else {
+		return str.substring(0, len).replace(/\.+$/, "") + "...";
+	}
+}
+
+/**
+ * Returns true if 'str' ends with 'end'
+ */
+dojo.string.endsWith = function(str, end, ignoreCase) {
+	if(ignoreCase) {
+		str = str.toLowerCase();
+		end = end.toLowerCase();
+	}
+	if((str.length - end.length) < 0){
+		return false;
+	}
+	return str.lastIndexOf(end) == str.length - end.length;
+}
+
+/**
+ * Returns true if 'str' ends with any of the arguments[2 -> n]
+ */
+dojo.string.endsWithAny = function(str /* , ... */) {
+	for(var i = 1; i < arguments.length; i++) {
+		if(dojo.string.endsWith(str, arguments[i])) {
+			return true;
+		}
+	}
+	return false;
+}
+
+/**
+ * Returns true if 'str' starts with 'start'
+ */
+dojo.string.startsWith = function(str, start, ignoreCase) {
+	if(ignoreCase) {
+		str = str.toLowerCase();
+		start = start.toLowerCase();
+	}
+	return str.indexOf(start) == 0;
+}
+
+/**
+ * Returns true if 'str' starts with any of the arguments[2 -> n]
+ */
+dojo.string.startsWithAny = function(str /* , ... */) {
+	for(var i = 1; i < arguments.length; i++) {
+		if(dojo.string.startsWith(str, arguments[i])) {
+			return true;
+		}
+	}
+	return false;
+}
+
+/**
+ * Returns true if 'str' contains any of the arguments 2 -> n
+ */
+dojo.string.has = function(str /* , ... */) {
+	for(var i = 1; i < arguments.length; i++) {
+		if(str.indexOf(arguments[i]) > -1){
+			return true;
+		}
+	}
+	return false;
+}
+
+dojo.string.normalizeNewlines = function (text,newlineChar) {
+	if (newlineChar == "\n") {
+		text = text.replace(/\r\n/g, "\n");
+		text = text.replace(/\r/g, "\n");
+	} else if (newlineChar == "\r") {
+		text = text.replace(/\r\n/g, "\r");
+		text = text.replace(/\n/g, "\r");
+	} else {
+		text = text.replace(/([^\r])\n/g, "$1\r\n");
+		text = text.replace(/\r([^\n])/g, "\r\n$1");
+	}
+	return text;
+}
+
+dojo.string.splitEscaped = function (str,charac) {
+	var components = [];
+	for (var i = 0, prevcomma = 0; i < str.length; i++) {
+		if (str.charAt(i) == '\\') { i++; continue; }
+		if (str.charAt(i) == charac) {
+			components.push(str.substring(prevcomma, i));
+			prevcomma = i + 1;
+		}
+	}
+	components.push(str.substr(prevcomma));
+	return components;
+}

Propchange: tapestry/tapestry4/trunk/framework/src/js/dojo/src/string/extras.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/style.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/style.js?rev=413306&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/style.js (added)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/style.js Sat Jun 10 07:27:44 2006
@@ -0,0 +1,826 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.style");
+dojo.require("dojo.graphics.color");
+dojo.require("dojo.uri.Uri");
+dojo.require("dojo.lang.common");
+
+(function(){
+	var h = dojo.render.html;
+	var ds = dojo.style;
+	var db = document["body"]||document["documentElement"];
+
+	ds.boxSizing = {
+		MARGIN_BOX: "margin-box",
+		BORDER_BOX: "border-box",
+		PADDING_BOX: "padding-box",
+		CONTENT_BOX: "content-box"
+	};
+	var bs = ds.boxSizing;
+	
+	ds.getBoxSizing = function(node){
+		if((h.ie)||(h.opera)){ 
+			var cm = document["compatMode"];
+			if((cm == "BackCompat")||(cm == "QuirksMode")){ 
+				return bs.BORDER_BOX; 
+			}else{
+				return bs.CONTENT_BOX; 
+			}
+		}else{
+			if(arguments.length == 0){ node = document.documentElement; }
+			var sizing = ds.getStyle(node, "-moz-box-sizing");
+			if(!sizing){ sizing = ds.getStyle(node, "box-sizing"); }
+			return (sizing ? sizing : bs.CONTENT_BOX);
+		}
+	}
+
+	/*
+
+	The following several function use the dimensions shown below
+
+		+-------------------------+
+		|  margin                 |
+		| +---------------------+ |
+		| |  border             | |
+		| | +-----------------+ | |
+		| | |  padding        | | |
+		| | | +-------------+ | | |
+		| | | |   content   | | | |
+		| | | +-------------+ | | |
+		| | +-|-------------|-+ | |
+		| +-|-|-------------|-|-+ |
+		+-|-|-|-------------|-|-|-+
+		| | | |             | | | |
+		| | | |<- content ->| | | |
+		| |<------ inner ------>| |
+		|<-------- outer -------->|
+		+-------------------------+
+
+		* content-box
+
+		|m|b|p|             |p|b|m|
+		| |<------ offset ----->| |
+		| | |<---- client --->| | |
+		| | | |<-- width -->| | | |
+
+		* border-box
+
+		|m|b|p|             |p|b|m|
+		| |<------ offset ----->| |
+		| | |<---- client --->| | |
+		| |<------ width ------>| |
+	*/
+
+	/*
+		Notes:
+
+		General:
+			- Uncomputable values are returned as NaN.
+			- setOuterWidth/Height return *false* if the outer size could not
+			  be computed, otherwise *true*.
+			- (sjmiles) knows no way to find the calculated values for auto-margins. 
+			- All returned values are floating point in 'px' units. If a
+			  non-zero computed style value is not specified in 'px', NaN is
+			  returned.
+
+		FF:
+			- styles specified as '0' (unitless 0) show computed as '0pt'.
+
+		IE:
+			- clientWidth/Height are unreliable (0 unless the object has 'layout').
+			- margins must be specified in px, or 0 (in any unit) for any
+			  sizing function to work. Otherwise margins detect as 'auto'.
+			- padding can be empty or, if specified, must be in px, or 0 (in
+			  any unit) for any sizing function to work.
+
+		Safari:
+			- Safari defaults padding values to 'auto'.
+
+		See the unit tests for examples of (un)computable values in a given browser.
+
+	*/
+
+	// FIXME: these work for some elements (e.g. DIV) but not others (e.g. TABLE, TEXTAREA)
+
+	ds.isBorderBox = function(node){
+		return (ds.getBoxSizing(node) == bs.BORDER_BOX);
+	}
+
+	ds.getUnitValue = function(node, cssSelector, autoIsZero){
+		var s = ds.getComputedStyle(node, cssSelector);
+		if((!s)||((s == 'auto')&&(autoIsZero))){ return { value: 0, units: 'px' }; }
+		if(dojo.lang.isUndefined(s)){return ds.getUnitValue.bad;}
+		// FIXME: is regex inefficient vs. parseInt or some manual test? 
+		var match = s.match(/(\-?[\d.]+)([a-z%]*)/i);
+		if (!match){return ds.getUnitValue.bad;}
+		return { value: Number(match[1]), units: match[2].toLowerCase() };
+	}
+	// FIXME: 'bad' value should be 0?
+	ds.getUnitValue.bad = { value: NaN, units: '' };
+	
+	ds.getPixelValue = function(node, cssSelector, autoIsZero){
+		var result = ds.getUnitValue(node, cssSelector, autoIsZero);
+		// FIXME: there is serious debate as to whether or not this is the right solution
+		if(isNaN(result.value)){ return 0; }
+		// FIXME: code exists for converting other units to px (see Dean Edward's IE7) 
+		// but there are cross-browser complexities
+		if((result.value)&&(result.units != 'px')){ return NaN; }
+		return result.value;
+	}
+	
+	// FIXME: deprecated
+	ds.getNumericStyle = function() {
+		dojo.deprecated('dojo.(style|html).getNumericStyle', 'in favor of dojo.(style|html).getPixelValue', '0.4');
+		return ds.getPixelValue.apply(this, arguments); 
+	}
+
+	ds.setPositivePixelValue = function(node, selector, value){
+		if(isNaN(value)){return false;}
+		node.style[selector] = Math.max(0, value) + 'px'; 
+		return true;
+	}
+	
+	ds._sumPixelValues = function(node, selectors, autoIsZero){
+		var total = 0;
+		for(var x=0; x<selectors.length; x++){
+			total += ds.getPixelValue(node, selectors[x], autoIsZero);
+		}
+		return total;
+	}
+
+	ds.isPositionAbsolute = function(node){
+		return (ds.getComputedStyle(node, 'position') == 'absolute');
+	}
+
+	ds.getBorderExtent = function(node, side){
+		return (ds.getStyle(node, 'border-' + side + '-style') == 'none' ? 0 : ds.getPixelValue(node, 'border-' + side + '-width'));
+	}
+
+	ds.getMarginWidth = function(node){
+		return ds._sumPixelValues(node, ["margin-left", "margin-right"], ds.isPositionAbsolute(node));
+	}
+
+	ds.getBorderWidth = function(node){
+		return ds.getBorderExtent(node, 'left') + ds.getBorderExtent(node, 'right');
+	}
+
+	ds.getPaddingWidth = function(node){
+		return ds._sumPixelValues(node, ["padding-left", "padding-right"], true);
+	}
+
+	ds.getPadBorderWidth = function(node) {
+		return ds.getPaddingWidth(node) + ds.getBorderWidth(node);
+	}
+	
+	ds.getContentBoxWidth = function(node){
+		node = dojo.byId(node);
+		return node.offsetWidth - ds.getPadBorderWidth(node);
+	}
+
+	ds.getBorderBoxWidth = function(node){
+		node = dojo.byId(node);
+		return node.offsetWidth;
+	}
+
+	ds.getMarginBoxWidth = function(node){
+		return ds.getInnerWidth(node) + ds.getMarginWidth(node);
+	}
+
+	ds.setContentBoxWidth = function(node, pxWidth){
+		node = dojo.byId(node);
+		if (ds.isBorderBox(node)){
+			pxWidth += ds.getPadBorderWidth(node);
+		}
+		return ds.setPositivePixelValue(node, "width", pxWidth);
+	}
+
+	ds.setMarginBoxWidth = function(node, pxWidth){
+		node = dojo.byId(node);
+		if (!ds.isBorderBox(node)){
+			pxWidth -= ds.getPadBorderWidth(node);
+		}
+		pxWidth -= ds.getMarginWidth(node);
+		return ds.setPositivePixelValue(node, "width", pxWidth);
+	}
+
+	// FIXME: deprecate and remove
+	ds.getContentWidth = ds.getContentBoxWidth;
+	ds.getInnerWidth = ds.getBorderBoxWidth;
+	ds.getOuterWidth = ds.getMarginBoxWidth;
+	ds.setContentWidth = ds.setContentBoxWidth;
+	ds.setOuterWidth = ds.setMarginBoxWidth;
+
+	ds.getMarginHeight = function(node){
+		return ds._sumPixelValues(node, ["margin-top", "margin-bottom"], ds.isPositionAbsolute(node));
+	}
+
+	ds.getBorderHeight = function(node){
+		return ds.getBorderExtent(node, 'top') + ds.getBorderExtent(node, 'bottom');
+	}
+
+	ds.getPaddingHeight = function(node){
+		return ds._sumPixelValues(node, ["padding-top", "padding-bottom"], true);
+	}
+
+	ds.getPadBorderHeight = function(node) {
+		return ds.getPaddingHeight(node) + ds.getBorderHeight(node);
+	}
+	
+	ds.getContentBoxHeight = function(node){
+		node = dojo.byId(node);
+		return node.offsetHeight - ds.getPadBorderHeight(node);
+	}
+
+	ds.getBorderBoxHeight = function(node){
+		node = dojo.byId(node);
+		return node.offsetHeight; // FIXME: does this work?
+	}
+
+	ds.getMarginBoxHeight = function(node){
+		return ds.getInnerHeight(node) + ds.getMarginHeight(node);
+	}
+
+	ds.setContentBoxHeight = function(node, pxHeight){
+		node = dojo.byId(node);
+		if (ds.isBorderBox(node)){
+			pxHeight += ds.getPadBorderHeight(node);
+		}
+		return ds.setPositivePixelValue(node, "height", pxHeight);
+	}
+
+	ds.setMarginBoxHeight = function(node, pxHeight){
+		node = dojo.byId(node);
+		if (!ds.isBorderBox(node)){
+			pxHeight -= ds.getPadBorderHeight(node);
+		}
+		pxHeight -= ds.getMarginHeight(node);
+		return ds.setPositivePixelValue(node, "height", pxHeight);
+	}
+
+	// FIXME: deprecate and remove
+	ds.getContentHeight = ds.getContentBoxHeight;
+	ds.getInnerHeight = ds.getBorderBoxHeight;
+	ds.getOuterHeight = ds.getMarginBoxHeight;
+	ds.setContentHeight = ds.setContentBoxHeight;
+	ds.setOuterHeight = ds.setMarginBoxHeight;
+
+	/**
+	 * dojo.style.getAbsolutePosition(xyz, true) returns xyz's position relative to the document.
+	 * Itells you where you would position a node
+	 * inside document.body such that it was on top of xyz.  Most people set the flag to true when calling
+	 * getAbsolutePosition().
+	 *
+	 * dojo.style.getAbsolutePosition(xyz, false) returns xyz's position relative to the viewport.
+	 * It returns the position that would be returned
+	 * by event.clientX/Y if the mouse were directly over the top/left of this node.
+	 */
+	ds.getAbsolutePosition = ds.abs = function(node, includeScroll){
+		node = dojo.byId(node);
+		var ret = [];
+		ret.x = ret.y = 0;
+		var st = dojo.html.getScrollTop();
+		var sl = dojo.html.getScrollLeft();
+
+		if(h.ie){
+			with(node.getBoundingClientRect()){
+				ret.x = left-2;
+				ret.y = top-2;
+			}
+		}else if(document.getBoxObjectFor){
+			// mozilla
+			var bo = document.getBoxObjectFor(node);
+			ret.x = bo.x - ds.sumAncestorProperties(node, "scrollLeft");
+			ret.y = bo.y - ds.sumAncestorProperties(node, "scrollTop");
+		}else{
+			if(node["offsetParent"]){
+				var endNode;		
+				// in Safari, if the node is an absolutely positioned child of
+				// the body and the body has a margin the offset of the child
+				// and the body contain the body's margins, so we need to end
+				// at the body
+				if(	(h.safari)&&
+					(node.style.getPropertyValue("position") == "absolute")&&
+					(node.parentNode == db)){
+					endNode = db;
+				}else{
+					endNode = db.parentNode;
+				}
+
+				if(node.parentNode != db){
+					var nd = node;
+					if(window.opera){ nd = db; }
+					ret.x -= ds.sumAncestorProperties(nd, "scrollLeft");
+					ret.y -= ds.sumAncestorProperties(nd, "scrollTop");
+				}
+				do{
+					var n = node["offsetLeft"];
+					ret.x += isNaN(n) ? 0 : n;
+					var m = node["offsetTop"];
+					ret.y += isNaN(m) ? 0 : m;
+					node = node.offsetParent;
+				}while((node != endNode)&&(node != null));
+			}else if(node["x"]&&node["y"]){
+				ret.x += isNaN(node.x) ? 0 : node.x;
+				ret.y += isNaN(node.y) ? 0 : node.y;
+			}
+		}
+
+		// account for document scrolling!
+		if(includeScroll){
+			ret.y += st;
+			ret.x += sl;
+		}
+
+		ret[0] = ret.x;
+		ret[1] = ret.y;
+		return ret;
+	}
+
+	ds.sumAncestorProperties = function(node, prop){
+		node = dojo.byId(node);
+		if(!node){ return 0; } // FIXME: throw an error?
+		
+		var retVal = 0;
+		while(node){
+			var val = node[prop];
+			if(val){
+				retVal += val - 0;
+				if(node==document.body){ break; }// opera and khtml #body & #html has the same values, we only need one value
+			}
+			node = node.parentNode;
+		}
+		return retVal;
+	}
+
+	ds.getTotalOffset = function(node, type, includeScroll){
+		return ds.abs(node, includeScroll)[(type == "top") ? "y" : "x"];
+	}
+
+	ds.getAbsoluteX = ds.totalOffsetLeft = function(node, includeScroll){
+		return ds.getTotalOffset(node, "left", includeScroll);
+	}
+
+	ds.getAbsoluteY = ds.totalOffsetTop = function(node, includeScroll){
+		return ds.getTotalOffset(node, "top", includeScroll);
+	}
+
+	ds.styleSheet = null;
+
+	// FIXME: this is a really basic stub for adding and removing cssRules, but
+	// it assumes that you know the index of the cssRule that you want to add 
+	// or remove, making it less than useful.  So we need something that can 
+	// search for the selector that you you want to remove.
+	ds.insertCssRule = function(selector, declaration, index) {
+		if (!ds.styleSheet) {
+			if (document.createStyleSheet) { // IE
+				ds.styleSheet = document.createStyleSheet();
+			} else if (document.styleSheets[0]) { // rest
+				// FIXME: should create a new style sheet here
+				// fall back on an exsiting style sheet
+				ds.styleSheet = document.styleSheets[0];
+			} else { return null; } // fail
+		}
+
+		if (arguments.length < 3) { // index may == 0
+			if (ds.styleSheet.cssRules) { // W3
+				index = ds.styleSheet.cssRules.length;
+			} else if (ds.styleSheet.rules) { // IE
+				index = ds.styleSheet.rules.length;
+			} else { return null; } // fail
+		}
+
+		if (ds.styleSheet.insertRule) { // W3
+			var rule = selector + " { " + declaration + " }";
+			return ds.styleSheet.insertRule(rule, index);
+		} else if (ds.styleSheet.addRule) { // IE
+			return ds.styleSheet.addRule(selector, declaration, index);
+		} else { return null; } // fail
+	}
+
+	ds.removeCssRule = function(index){
+		if(!ds.styleSheet){
+			dojo.debug("no stylesheet defined for removing rules");
+			return false;
+		}
+		if(h.ie){
+			if(!index){
+				index = ds.styleSheet.rules.length;
+				ds.styleSheet.removeRule(index);
+			}
+		}else if(document.styleSheets[0]){
+			if(!index){
+				index = ds.styleSheet.cssRules.length;
+			}
+			ds.styleSheet.deleteRule(index);
+		}
+		return true;
+	}
+
+	// calls css by XmlHTTP and inserts it into DOM as <style [widgetType="widgetType"]> *downloaded cssText*</style>
+	ds.insertCssFile = function(URI, doc, checkDuplicates){
+		if(!URI){ return; }
+		if(!doc){ doc = document; }
+		var cssStr = dojo.hostenv.getText(URI);
+		cssStr = ds.fixPathsInCssText(cssStr, URI);
+
+		if(checkDuplicates){
+			var styles = doc.getElementsByTagName("style");
+			var cssText = "";
+			for(var i = 0; i<styles.length; i++){
+				cssText = (styles[i].styleSheet && styles[i].styleSheet.cssText) ? styles[i].styleSheet.cssText : styles[i].innerHTML;
+				if(cssStr == cssText){ return; }
+			}
+		}
+
+		var style = ds.insertCssText(cssStr);
+		// insert custom attribute ex dbgHref="../foo.css" usefull when debugging in DOM inspectors, no?
+		if(style && djConfig.isDebug){
+			style.setAttribute("dbgHref", URI);
+		}
+		return style
+	}
+
+	// DomNode Style  = insertCssText(String ".dojoMenu {color: green;}"[, DomDoc document, dojo.uri.Uri Url ])
+	ds.insertCssText = function(cssStr, doc, URI){
+		if(!cssStr){ return; }
+		if(!doc){ doc = document; }
+		if(URI){// fix paths in cssStr
+			cssStr = ds.fixPathsInCssText(cssStr, URI);
+		}
+		var style = doc.createElement("style");
+		style.setAttribute("type", "text/css");
+		// IE is b0rken enough to require that we add the element to the doc
+		// before changing it's properties
+		var head = doc.getElementsByTagName("head")[0];
+		if(!head){ // must have a head tag 
+			dojo.debug("No head tag in document, aborting styles");
+			return;
+		}else{
+			head.appendChild(style);
+		}
+		if(style.styleSheet){// IE
+			style.styleSheet.cssText = cssStr;
+		}else{ // w3c
+			var cssText = doc.createTextNode(cssStr);
+			style.appendChild(cssText);
+		}
+		return style;
+	}
+
+	// String cssText = fixPathsInCssText(String cssStr, dojo.uri.Uri URI)
+	// usage: cssText comes from dojoroot/src/widget/templates/HtmlFoobar.css
+	// 	it has .dojoFoo { background-image: url(images/bar.png);} 
+	//	then uri should point to dojoroot/src/widget/templates/
+	ds.fixPathsInCssText = function(cssStr, URI){
+		if(!cssStr || !URI){ return; }
+		var pos = 0; var str = ""; var url = "";
+		while(pos!=-1){
+			pos = 0;url = "";
+			pos = cssStr.indexOf("url(", pos);
+			if(pos<0){ break; }
+			str += cssStr.slice(0,pos+4);
+			cssStr = cssStr.substring(pos+4, cssStr.length);
+			url += cssStr.match(/^[\t\s\w()\/.\\'"-:#=&?]*\)/)[0]; // url string
+			cssStr = cssStr.substring(url.length-1, cssStr.length); // remove url from css string til next loop
+			url = url.replace(/^[\s\t]*(['"]?)([\w()\/.\\'"-:#=&?]*)\1[\s\t]*?\)/,"$2"); // clean string
+			if(url.search(/(file|https?|ftps?):\/\//)==-1){
+				url = (new dojo.uri.Uri(URI,url).toString());
+			}
+			str += url;
+		};
+		return str+cssStr;
+	}
+
+	ds.getBackgroundColor = function(node) {
+		node = dojo.byId(node);
+		var color;
+		do{
+			color = ds.getStyle(node, "background-color");
+			// Safari doesn't say "transparent"
+			if(color.toLowerCase() == "rgba(0, 0, 0, 0)") { color = "transparent"; }
+			if(node == document.getElementsByTagName("body")[0]) { node = null; break; }
+			node = node.parentNode;
+		}while(node && dojo.lang.inArray(color, ["transparent", ""]));
+		if(color == "transparent"){
+			color = [255, 255, 255, 0];
+		}else{
+			color = dojo.graphics.color.extractRGB(color);
+		}
+		return color;
+	}
+
+	ds.getComputedStyle = function(node, cssSelector, inValue){
+		node = dojo.byId(node);
+		// cssSelector may actually be in camel case, so force selector version
+		var cssSelector = ds.toSelectorCase(cssSelector);
+		var property = ds.toCamelCase(cssSelector);
+		if(!node || !node.style){
+			return inValue;
+		}else if(document.defaultView){ // W3, gecko, KHTML
+			try{			
+				var cs = document.defaultView.getComputedStyle(node, "");
+				if (cs){ 
+					return cs.getPropertyValue(cssSelector);
+				} 
+			}catch(e){ // reports are that Safari can throw an exception above
+				if (node.style.getPropertyValue){ // W3
+					return node.style.getPropertyValue(cssSelector);
+				}else return inValue;
+			}
+		}else if(node.currentStyle){ // IE
+			return node.currentStyle[property];
+		}if(node.style.getPropertyValue){ // W3
+			return node.style.getPropertyValue(cssSelector);
+		}else{
+			return inValue;
+		}
+	}
+
+	/** 
+	 * Retrieve a property value from a node's style object.
+	 */
+	ds.getStyleProperty = function(node, cssSelector){
+		node = dojo.byId(node);
+		// FIXME: should we use node.style.getPropertyValue over style[property]?
+		// style[property] works in all (modern) browsers, getPropertyValue is W3 but not supported in IE
+		// FIXME: what about runtimeStyle?
+		return (node && node.style ? node.style[ds.toCamelCase(cssSelector)] : undefined);
+	}
+
+	/** 
+	 * Retrieve a property value from a node's style object.
+	 */
+	ds.getStyle = function(node, cssSelector){
+		var value = ds.getStyleProperty(node, cssSelector);
+		return (value ? value : ds.getComputedStyle(node, cssSelector));
+	}
+
+	ds.setStyle = function(node, cssSelector, value){
+		node = dojo.byId(node);
+		if(node && node.style){
+			var camelCased = ds.toCamelCase(cssSelector);
+			node.style[camelCased] = value;
+		}
+	}
+
+	ds.toCamelCase = function(selector) {
+		var arr = selector.split('-'), cc = arr[0];
+		for(var i = 1; i < arr.length; i++) {
+			cc += arr[i].charAt(0).toUpperCase() + arr[i].substring(1);
+		}
+		return cc;		
+	}
+
+	ds.toSelectorCase = function(selector) {
+		return selector.replace(/([A-Z])/g, "-$1" ).toLowerCase() ;
+	}
+
+	/* float between 0.0 (transparent) and 1.0 (opaque) */
+	ds.setOpacity = function setOpacity(node, opacity, dontFixOpacity) {
+		node = dojo.byId(node);
+		if(!dontFixOpacity){
+			if( opacity >= 1.0){
+				if(h.ie){
+					ds.clearOpacity(node);
+					return;
+				}else{
+					opacity = 0.999999;
+				}
+			}else if( opacity < 0.0){ opacity = 0; }
+		}
+		if(h.ie){
+			if(node.nodeName.toLowerCase() == "tr"){
+				// FIXME: is this too naive? will we get more than we want?
+				var tds = node.getElementsByTagName("td");
+				for(var x=0; x<tds.length; x++){
+					tds[x].style.filter = "Alpha(Opacity="+opacity*100+")";
+				}
+			}
+			node.style.filter = "Alpha(Opacity="+opacity*100+")";
+		}else if(h.moz){
+			node.style.opacity = opacity; // ffox 1.0 directly supports "opacity"
+			node.style.MozOpacity = opacity;
+		}else if(h.safari){
+			node.style.opacity = opacity; // 1.3 directly supports "opacity"
+			node.style.KhtmlOpacity = opacity;
+		}else{
+			node.style.opacity = opacity;
+		}
+	}
+		
+	ds.getOpacity = function getOpacity (node){
+		node = dojo.byId(node);
+		if(h.ie){
+			var opac = (node.filters && node.filters.alpha &&
+				typeof node.filters.alpha.opacity == "number"
+				? node.filters.alpha.opacity : 100) / 100;
+		}else{
+			var opac = node.style.opacity || node.style.MozOpacity ||
+				node.style.KhtmlOpacity || 1;
+		}
+		return opac >= 0.999999 ? 1.0 : Number(opac);
+	}
+
+	ds.clearOpacity = function clearOpacity(node){
+		node = dojo.byId(node);
+		var ns = node.style;
+		if(h.ie){
+			try {
+				if( node.filters && node.filters.alpha ){
+					ns.filter = ""; // FIXME: may get rid of other filter effects
+				}
+			} catch(e) {
+				/*
+				 * IE7 gives error if node.filters not set;
+				 * don't know why or how to workaround (other than this)
+				 */
+			}
+		}else if(h.moz){
+			ns.opacity = 1;
+			ns.MozOpacity = 1;
+		}else if(h.safari){
+			ns.opacity = 1;
+			ns.KhtmlOpacity = 1;
+		}else{
+			ns.opacity = 1;
+		}
+	}
+
+	/** 
+	* Set the given style attributes for the node. 
+	* Patch submitted by Wolfram Kriesing, 22/03/2006.
+	*
+	* Ie. dojo.style.setStyleAttributes(myNode, "position:absolute; left:10px; top:10px;") 
+	* This just makes it easier to set a style directly without the need to  
+	* override it completely (as node.setAttribute() would). 
+	* If there is a dojo-method for an attribute, like for "opacity" there 
+	* is setOpacity, the dojo method is called instead. 
+	* For example: dojo.style.setStyleAttributes(myNode, "opacity: .4"); 
+	*  
+	* Additionally all the dojo.style.set* methods can also be used. 
+	* Ie. when attributes contains "outer-height: 10;" it will call dojo.style.setOuterHeight("10"); 
+	* 
+	* @param object The node to set the style attributes for. 
+	* @param string Ie. "position:absolute; left:10px; top:10px;" 
+	*/ 
+	ds.setStyleAttributes = function(node, attributes) { 
+		var methodMap={ 
+			"opacity":dojo.style.setOpacity,
+			"content-height":dojo.style.setContentHeight,
+			"content-width":dojo.style.setContentWidth,
+			"outer-height":dojo.style.setOuterHeight,
+			"outer-width":dojo.style.setOuterWidth 
+		} 
+
+		var splittedAttribs=attributes.replace(/(;)?\s*$/, "").split(";"); 
+		for(var i=0; i<splittedAttribs.length; i++){ 
+			var nameValue=splittedAttribs[i].split(":"); 
+			var name=nameValue[0].replace(/\s*$/, "").replace(/^\s*/, "").toLowerCase();
+			var value=nameValue[1].replace(/\s*$/, "").replace(/^\s*/, "");
+			if(dojo.lang.has(methodMap,name)) { 
+				methodMap[name](node,value); 
+			} else { 
+				node.style[dojo.style.toCamelCase(name)]=value; 
+			} 
+		} 
+	} 
+
+	ds._toggle = function(node, tester, setter){
+		node = dojo.byId(node);
+		setter(node, !tester(node));
+		return tester(node);
+	}
+
+	// show/hide are library constructs
+
+	// show() 
+	// if the node.style.display == 'none' then 
+	// set style.display to '' or the value cached by hide()
+	ds.show = function(node){
+		node = dojo.byId(node);
+		if(ds.getStyleProperty(node, 'display')=='none'){
+			ds.setStyle(node, 'display', (node.dojoDisplayCache||''));
+			node.dojoDisplayCache = undefined;	// cannot use delete on a node in IE6
+		}
+	}
+
+	// if the node.style.display == 'none' then 
+	// set style.display to '' or the value cached by hide()
+	ds.hide = function(node){
+		node = dojo.byId(node);
+		if(typeof node["dojoDisplayCache"] == "undefined"){ // it could == '', so we cannot say !node.dojoDisplayCount
+			var d = ds.getStyleProperty(node, 'display')
+			if(d!='none'){
+				node.dojoDisplayCache = d;
+			}
+		}
+		ds.setStyle(node, 'display', 'none');
+	}
+
+	// setShowing() calls show() if showing is true, hide() otherwise
+	ds.setShowing = function(node, showing){
+		ds[(showing ? 'show' : 'hide')](node);
+	}
+
+	// isShowing() is true if the node.style.display is not 'none'
+	// FIXME: returns true if node is bad, isHidden would be easier to make correct
+	ds.isShowing = function(node){
+		return (ds.getStyleProperty(node, 'display') != 'none');
+	}
+
+	// Call setShowing() on node with the complement of isShowing(), then return the new value of isShowing()
+	ds.toggleShowing = function(node){
+		return ds._toggle(node, ds.isShowing, ds.setShowing);
+	}
+
+	// display is a CSS concept
+
+	// Simple mapping of tag names to display values
+	// FIXME: simplistic 
+	ds.displayMap = { tr: '', td: '', th: '', img: 'inline', span: 'inline', input: 'inline', button: 'inline' };
+
+	// Suggest a value for the display property that will show 'node' based on it's tag
+	ds.suggestDisplayByTagName = function(node)
+	{
+		node = dojo.byId(node);
+		if(node && node.tagName){
+			var tag = node.tagName.toLowerCase();
+			return (tag in ds.displayMap ? ds.displayMap[tag] : 'block');
+		}
+	}
+
+	// setDisplay() sets the value of style.display to value of 'display' parameter if it is a string.
+	// Otherwise, if 'display' is false, set style.display to 'none'.
+	// Finally, set 'display' to a suggested display value based on the node's tag
+	ds.setDisplay = function(node, display){
+		ds.setStyle(node, 'display', (dojo.lang.isString(display) ? display : (display ? ds.suggestDisplayByTagName(node) : 'none')));
+	}
+
+	// isDisplayed() is true if the the computed display style for node is not 'none'
+	// FIXME: returns true if node is bad, isNotDisplayed would be easier to make correct
+	ds.isDisplayed = function(node){
+		return (ds.getComputedStyle(node, 'display') != 'none');
+	}
+
+	// Call setDisplay() on node with the complement of isDisplayed(), then
+	// return the new value of isDisplayed()
+	ds.toggleDisplay = function(node){
+		return ds._toggle(node, ds.isDisplayed, ds.setDisplay);
+	}
+
+	// visibility is a CSS concept
+
+	// setVisibility() sets the value of style.visibility to value of
+	// 'visibility' parameter if it is a string.
+	// Otherwise, if 'visibility' is false, set style.visibility to 'hidden'.
+	// Finally, set style.visibility to 'visible'.
+	ds.setVisibility = function(node, visibility){
+		ds.setStyle(node, 'visibility', (dojo.lang.isString(visibility) ? visibility : (visibility ? 'visible' : 'hidden')));
+	}
+
+	// isVisible() is true if the the computed visibility style for node is not 'hidden'
+	// FIXME: returns true if node is bad, isInvisible would be easier to make correct
+	ds.isVisible = function(node){
+		return (ds.getComputedStyle(node, 'visibility') != 'hidden');
+	}
+
+	// Call setVisibility() on node with the complement of isVisible(), then
+	// return the new value of isVisible()
+	ds.toggleVisibility = function(node){
+		return ds._toggle(node, ds.isVisible, ds.setVisibility);
+	}
+
+	// in: coordinate array [x,y,w,h] or dom node
+	// return: coordinate array
+	ds.toCoordinateArray = function(coords, includeScroll) {
+		if(dojo.lang.isArray(coords)){
+			// coords is already an array (of format [x,y,w,h]), just return it
+			while ( coords.length < 4 ) { coords.push(0); }
+			while ( coords.length > 4 ) { coords.pop(); }
+			var ret = coords;
+		} else {
+			// coords is an dom object (or dom object id); return it's coordinates
+			var node = dojo.byId(coords);
+			var pos = ds.getAbsolutePosition(node, includeScroll);
+			var ret = [
+				pos.x,
+				pos.y,
+				ds.getBorderBoxWidth(node),
+				ds.getBorderBoxHeight(node)
+			];
+		}
+		ret.x = ret[0];
+		ret.y = ret[1];
+		ret.w = ret[2];
+		ret.h = ret[3];
+		return ret;
+	};
+})();

Propchange: tapestry/tapestry4/trunk/framework/src/js/dojo/src/style.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/svg.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/svg.js?rev=413306&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/svg.js (added)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/svg.js Sat Jun 10 07:27:44 2006
@@ -0,0 +1,279 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.svg");
+dojo.require("dojo.lang");
+dojo.require("dojo.dom");
+
+dojo.lang.mixin(dojo.svg, dojo.dom);
+
+dojo.svg.graphics=dojo.svg.g=new function(/* DomDocument */ d){
+	//	summary
+	//	Singleton to encapsulate SVG rendering functions.
+	this.suspend=function(){
+		//	summary
+		//	Suspend the rendering engine
+		try { d.documentElement.suspendRedraw(0); } catch(e){ }
+	};
+	this.resume=function(){
+		//	summary
+		//	Resume the rendering engine
+		try { d.documentElement.unsuspendRedraw(0); } catch(e){ }
+	};
+	this.force=function(){
+		//	summary
+		//	Force the render engine to redraw
+		try { d.documentElement.forceRedraw(); } catch(e){ }
+	};
+}(document);
+
+dojo.svg.animations=dojo.svg.anim=new function(/* DOMDocument */ d){
+	//	summary
+	//	Singleton to encapsulate SVG animation functionality.
+	this.arePaused=function(){
+		//	summary
+		//	check to see if all animations are paused
+		try {
+			return d.documentElement.animationsPaused();	//	bool
+		} catch(e){
+			return false;	//	bool
+		}
+	} ;
+	this.pause=function(){
+		//	summary
+		//	pause all animations
+		try { d.documentElement.pauseAnimations(); } catch(e){ }
+	};
+	this.resume=function(){
+		//	summary
+		//	resume all animations
+		try { d.documentElement.unpauseAnimations(); } catch(e){ }
+	};
+}(document);
+
+//	fixme: these functions should be mixed in from dojo.style, but dojo.style is HTML-centric and needs to change.
+dojo.svg.toCamelCase=function(/* string */ selector){
+	//	summary
+	//	converts a CSS-style selector to a camelCased one
+	var arr=selector.split('-'), cc=arr[0];
+	for(var i=1; i < arr.length; i++) {
+		cc += arr[i].charAt(0).toUpperCase() + arr[i].substring(1);
+	}
+	return cc;	// string
+};
+dojo.svg.toSelectorCase=function(/* string */ selector) {
+	//	summary
+	//	converts a camelCased selector to a CSS style one
+	return selector.replace(/([A-Z])/g, "-$1" ).toLowerCase();	//	string
+};
+dojo.svg.getStyle=function(/* SVGElement */ node, /* string */ cssSelector){
+	//	summary
+	//	get the computed style of selector for node.
+	return document.defaultView.getComputedStyle(node, cssSelector);	//	object
+};
+dojo.svg.getNumericStyle=function(/* SVGElement */ node, /* string */ cssSelector){
+	//	summary
+	//	return the numeric version of the computed style of selector on node.
+	return parseFloat(dojo.svg.getStyle(node, cssSelector));
+};
+
+//	fixme: there are different ways of doing the following, need to take into account
+dojo.svg.getOpacity=function(/* SVGElement */node){
+	//	summary
+	//	Return the opacity of the passed element
+	return Math.min(1.0, dojo.svg.getNumericStyle(node, "fill-opacity"));	//	float
+};
+dojo.svg.setOpacity=function(/* SVGElement */ node, /* float */ opacity){
+	//	summary
+	//	set the opacity of node using attributes.
+	node.setAttributeNS(this.xmlns.svg, "fill-opacity", opacity);
+	node.setAttributeNS(this.xmlns.svg, "stroke-opacity", opacity);
+};
+dojo.svg.clearOpacity=function(/* SVGElement */ node){
+	//	summary
+	//	Set any attributes setting opacity to opaque (1.0)
+	node.setAttributeNS(this.xmlns.svg, "fill-opacity", "1.0");
+	node.setAttributeNS(this.xmlns.svg, "stroke-opacity", "1.0");
+};
+
+/**
+ *	Coordinates and dimensions.
+ */
+
+// TODO ////////////////////////////////////////////////////////// TODO
+dojo.svg.getCoords=function(/* SVGElement */ node){
+	if (node.getBBox) {
+		var box=node.getBBox();
+		return { x: box.x, y: box.y };
+	}
+	return null;
+};
+dojo.svg.setCoords=function(node, coords){
+	var p=dojo.svg.getCoords();
+	if (!p) return;
+	var dx=p.x - coords.x;
+	var dy=p.y - coords.y;
+	dojo.svg.translate(node, dx, dy);
+};
+dojo.svg.getDimensions=function(node){
+	if (node.getBBox){
+		var box=node.getBBox();
+		return { width: box.width, height : box.height };
+	}
+	return null;
+};
+dojo.svg.setDimensions=function(node, dim){
+	//	will only support shape-based and container elements; path-based elements are ignored.
+	if (node.width){
+		node.width.baseVal.value=dim.width;
+		node.height.baseVal.value=dim.height;
+	}
+	else if (node.r){
+		node.r.baseVal.value=Math.min(dim.width, dim.height)/2;
+	}
+	else if (node.rx){
+		node.rx.baseVal.value=dim.width/2;
+		node.ry.baseVal.value=dim.height/2;
+	}
+};
+
+/**
+ *	Transformations.
+ */
+dojo.svg.translate=function(node, dx, dy){
+	if (node.transform && node.ownerSVGElement && node.ownerSVGElement.createSVGTransform){
+		var t=node.ownerSVGElement.createSVGTransform();
+		t.setTranslate(dx, dy);
+		node.transform.baseVal.appendItem(t);
+	}
+};
+dojo.svg.scale=function(node, scaleX, scaleY){
+	if (!scaleY) var scaleY=scaleX;
+	if (node.transform && node.ownerSVGElement && node.ownerSVGElement.createSVGTransform){
+		var t=node.ownerSVGElement.createSVGTransform();
+		t.setScale(scaleX, scaleY);
+		node.transform.baseVal.appendItem(t);
+	}
+};
+dojo.svg.rotate=function(node, ang, cx, cy){
+	if (node.transform && node.ownerSVGElement && node.ownerSVGElement.createSVGTransform){
+		var t=node.ownerSVGElement.createSVGTransform();
+		if (!cx) t.setMatrix(t.matrix.rotate(ang));
+		else t.setRotate(ang, cx, cy);
+		node.transform.baseVal.appendItem(t);
+	}
+};
+dojo.svg.skew=function(node, ang, axis){
+	var dir=axis || "x";
+	if (node.transform && node.ownerSVGElement && node.ownerSVGElement.createSVGTransform){
+		var t=node.ownerSVGElement.createSVGTransform();
+		if (dir != "x") t.setSkewY(ang);
+		else t.setSkewX(ang);
+		node.transform.baseVal.appendItem(t);
+	}
+};
+dojo.svg.flip=function(node, axis){
+	var dir=axis || "x";
+	if (node.transform && node.ownerSVGElement && node.ownerSVGElement.createSVGTransform){
+		var t=node.ownerSVGElement.createSVGTransform();
+		t.setMatrix((dir != "x") ? t.matrix.flipY() : t.matrix.flipX());
+		node.transform.baseVal.appendItem(t);
+	}
+};
+dojo.svg.invert=function(node){
+	if (node.transform && node.ownerSVGElement && node.ownerSVGElement.createSVGTransform){
+		var t=node.ownerSVGElement.createSVGTransform();
+		t.setMatrix(t.matrix.inverse());
+		node.transform.baseVal.appendItem(t);
+	}
+};
+dojo.svg.applyMatrix=function(node, a, b, c, d, e, f){
+	if (node.transform && node.ownerSVGElement && node.ownerSVGElement.createSVGTransform){
+		var m;
+		if (b){
+			var m=node.ownerSVGElement.createSVGMatrix();
+			m.a=a;
+			m.b=b;
+			m.c=c;
+			m.d=d;
+			m.e=e;
+			m.f=f;
+		} else m=a;
+		var t=node.ownerSVGElement.createSVGTransform();
+		t.setMatrix(m);
+		node.transform.baseVal.appendItem(t);
+	}
+};
+
+/**
+ *	Grouping and z-index operations.
+ */
+dojo.svg.group=function(nodes){
+	//	expect an array of nodes, attaches the group to the parent of the first node.
+	var p=nodes.item(0).parentNode;
+	var g=document.createElementNS(this.xmlns.svg, "g");
+	for (var i=0; i < nodes.length; i++) g.appendChild(nodes.item(i));
+	p.appendChild(g);
+	return g;
+};
+dojo.svg.ungroup=function(g){
+	//	puts the children of the group on the same level as group was.
+	var p=g.parentNode;
+	while (g.childNodes.length > 0) p.appendChild(g.childNodes.item(0));
+	p.removeChild(g);
+};
+//	if the node is part of a group, return the group, else return null.
+dojo.svg.getGroup=function(node){
+	//	if the node is part of a group, return the group, else return null.
+	var a=this.getAncestors(node);
+	for (var i=0; i < a.length; i++){
+		if (a[i].nodeType == this.ELEMENT_NODE && a[i].nodeName.toLowerCase() == "g")
+			return a[i];
+	}
+	return null;
+};
+dojo.svg.bringToFront=function(node){
+	var n=this.getGroup(node) || node;
+	n.ownerSVGElement.appendChild(n);
+};
+dojo.svg.sendToBack=function(node){
+	var n=this.getGroup(node) || node;
+	n.ownerSVGElement.insertBefore(n, n.ownerSVGElement.firstChild);
+};
+
+//	TODO: possibly push node up a level in the DOM if it's at the beginning or end of the childNodes list.
+dojo.svg.bringForward=function(node){
+	var n=this.getGroup(node) || node;
+	if (this.getLastChildElement(n.parentNode) != n){
+		this.insertAfter(n, this.getNextSiblingElement(n), true);
+	}
+};
+dojo.svg.sendBackward=function(node){
+	var n=this.getGroup(node) || node;
+	if (this.getFirstChildElement(n.parentNode) != n){
+		this.insertBefore(n, this.getPreviousSiblingElement(n), true);
+	}
+};
+// END TODO ////////////////////////////////////////////////////// TODO
+
+dojo.svg.createNodesFromText=function(/* string */ txt, /* bool? */ wrap){
+	//	summary
+	//	Create a list of nodes from text
+	var docFrag=(new DOMParser()).parseFromString(txt, "text/xml").normalize();
+	if(wrap){ 
+		return [docFrag.firstChild.cloneNode(true)];	//	array
+	}
+	var nodes=[];
+	for(var x=0; x<docFrag.childNodes.length; x++){
+		nodes.push(docFrag.childNodes.item(x).cloneNode(true));
+	}
+	return nodes;	// array
+}
+// vim:ts=4:noet:tw=0:

Propchange: tapestry/tapestry4/trunk/framework/src/js/dojo/src/svg.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/text/Builder.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/text/Builder.js?rev=413306&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/text/Builder.js (added)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/text/Builder.js Sat Jun 10 07:27:44 2006
@@ -0,0 +1,16 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.text.Builder");
+dojo.require("dojo.string.Builder");
+
+dojo.deprecated("dojo.text.Builder", "use dojo.string.Builder instead", "0.4");
+
+dojo.text.Builder = dojo.string.Builder;

Propchange: tapestry/tapestry4/trunk/framework/src/js/dojo/src/text/Builder.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/text/String.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/text/String.js?rev=413306&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/text/String.js (added)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/text/String.js Sat Jun 10 07:27:44 2006
@@ -0,0 +1,15 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.deprecated("dojo.text.String", "replaced by dojo.string", "0.4");
+dojo.require("dojo.string");
+
+dojo.text = dojo.string;
+dojo.provide("dojo.text.String");

Propchange: tapestry/tapestry4/trunk/framework/src/js/dojo/src/text/String.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/text/Text.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/text/Text.js?rev=413306&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/text/Text.js (added)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/text/Text.js Sat Jun 10 07:27:44 2006
@@ -0,0 +1,15 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.deprecated("dojo.text.Text", "replaced by dojo.string", "0.4");
+dojo.require("dojo.string");
+
+dojo.text = dojo.string;
+dojo.provide("dojo.text.Text");

Propchange: tapestry/tapestry4/trunk/framework/src/js/dojo/src/text/Text.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/text/textDirectory.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/text/textDirectory.js?rev=413306&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/text/textDirectory.js (added)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/text/textDirectory.js Sat Jun 10 07:27:44 2006
@@ -0,0 +1,81 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.text.textDirectory");
+dojo.provide("dojo.text.textDirectory.Property");
+dojo.provide("dojo.text.textDirectory.tokenise");
+dojo.require("dojo.string");
+
+/* adapted from Paul Sowden's iCalendar work */
+
+dojo.textDirectoryTokeniser = function () {}
+
+/*
+ * This class parses a single line from a text/directory file
+ * and returns an object with four named values; name, group, params
+ * and value. name, group and value are strings containing the original
+ * tokens unaltered and values is an array containing name/value pairs
+ * or a single name token packed into arrays.
+ */
+dojo.textDirectoryTokeniser.Property = function (line) {
+	// split into name/value pair
+	var left = dojo.string.trim(line.substring(0, line.indexOf(':')));
+	var right = dojo.string.trim(line.substr(line.indexOf(':') + 1));
+
+	// seperate name and paramters	
+	var parameters = dojo.string.splitEscaped(left,';');
+	this.name = parameters[0]
+	parameters.splice(0, 1);
+
+	// parse paramters
+	this.params = [];
+	for (var i = 0; i < parameters.length; i++) {
+		var arr = parameters[i].split("=");
+		var key = dojo.string.trim(arr[0].toUpperCase());
+		
+		if (arr.length == 1) { this.params.push([key]); continue; }
+		
+		var values = dojo.string.splitEscaped(arr[1],',');
+		for (var j = 0; j < values.length; j++) {
+			if (dojo.string.trim(values[j]) != '') {
+				this.params.push([key, dojo.string.trim(values[j])]);
+			}
+		}
+	}
+
+	// seperate group
+	if (this.name.indexOf('.') > 0) {
+		var arr = this.name.split('.');
+		this.group = arr[0];
+		this.name = arr[1];
+	}
+	
+	// don't do any parsing, leave to implementation
+	this.value = right;
+}
+
+
+// tokeniser, parses into an array of properties.
+dojo.textDirectoryTokeniser.tokenise = function (text) {
+	// normlize to one propterty per line and parse
+	var nText = dojo.string.normalizeNewlines(text,"\n");
+	nText = nText.replace(/\n[ \t]/g, '');
+	nText = nText.replace(/\x00/g, '');
+		
+	var lines = nText.split("\n");
+	var properties = []
+
+	for (var i = 0; i < lines.length; i++) {
+		if (dojo.string.trim(lines[i]) == '') { continue; }
+		var prop = new dojo.textDirectoryTokeniser.Property(lines[i]);
+		properties.push(prop);
+	}
+	return properties;
+}

Propchange: tapestry/tapestry4/trunk/framework/src/js/dojo/src/text/textDirectory.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/undo/__package__.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/undo/__package__.js?rev=413306&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/undo/__package__.js (added)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/undo/__package__.js Sat Jun 10 07:27:44 2006
@@ -0,0 +1,12 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.require("dojo.undo.Manager");
+dojo.provide("dojo.undo.*");

Propchange: tapestry/tapestry4/trunk/framework/src/js/dojo/src/undo/__package__.js
------------------------------------------------------------------------------
    svn:eol-style = native