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/09/23 01:22:51 UTC

svn commit: r449122 [35/40] - in /tapestry/tapestry4/trunk/tapestry-framework/src: java/org/apache/tapestry/ java/org/apache/tapestry/dojo/ java/org/apache/tapestry/dojo/form/ java/org/apache/tapestry/dojo/html/ java/org/apache/tapestry/form/ java/org/...

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/html/loader.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/html/loader.js?view=auto&rev=449122
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/html/loader.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/html/loader.js Fri Sep 22 16:22:30 2006
@@ -0,0 +1,842 @@
+/*
+	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.widget.html.loader");
+
+dojo.require("dojo.widget.HtmlWidget");
+dojo.require("dojo.io.*");
+dojo.require("dojo.lang.common");
+dojo.require("dojo.lang.extras");
+
+dojo.require("dojo.experimental");
+
+// as this is a singleton dojo.declare doesnt by us anything here
+dojo.widget.html.loader = new (function(){
+	// summary:
+	// 	loading stuff moved out of contentpane to make it directly accessible by other widgets
+	this.toString = function(){ return "dojo.widget.html.loader"; }
+	var _loader = this;
+
+	// back/forward tracking
+	dojo.addOnLoad(function(){
+		dojo.experimental(_loader.toString());
+		var undo = dojo.evalObjPath("dojo.undo.browser");
+		if(djConfig["preventBackButtonFix"] && undo && !undo.initialState){
+			undo.setInitialState(new trackerObj);
+		}
+	});
+
+	var logger = {};
+	var trackerObj = function(id, data){
+		this.id = id;
+		this.data = data
+	};
+	trackerObj.prototype.handle = function(type){
+		if(typeof dojo == 'undefined'){ return; } // wtf? how can dojo become undef?
+		var wg = dojo.widget.byId(this.id);
+		if(wg){ wg.setContent(this.data, true); }
+	};
+
+	this._log = function(widget, data){
+		// if a loader widget B is a child of loader widget A
+		// we need to destroy all of B's undo if we switch content
+		if(widget.trackHistory){
+			if(!logger[widget.widgetId]){
+				logger[widget.widgetId] = { childrenIds: [], stack:[data] };
+			}var children = logger[widget.widgetId].childrenIds;
+			while(children && children.length){
+				delete logger[children.pop()];
+			}
+			for(var child in widget.children){
+				logger[widget.widgetId].childrenIds = child.widgetId;
+			}
+			dojo.undo.browser.addToHistory(new trackerObj(widget.widgetId, dojo.lang.shallowCopy(data, true)));
+		}
+	}
+
+	// shortCuts
+	var undef = dojo.lang.isUndefined;
+	var isFunc = dojo.lang.isFunction;
+
+
+
+	/************ private needed functions, no need to be part of widget API ***********/
+	// usefull if user wants to prevent default behaviour ie: _setContent("Error...")
+	function handleDefaults(e, handler, useAlert){
+		if(!handler){ handler = "onContentError"; }
+		if(dojo.lang.isString(e)){ e = {_text: e}; }
+		if(!e._text){ e._text = e.toString(); }
+		e.toString = function(){ return this._text; };
+		if(typeof e.returnValue != "boolean"){
+			e.returnValue = true; 
+		}
+		if(typeof e.preventDefault != "function"){
+			e.preventDefault = function(){ this.returnValue = false; };
+		}
+		// call our handler
+		this[handler](e);
+		if(e.returnValue){
+			if(useAlert){
+				alert(e.toString());
+			}else{
+				this.loader.callOnUnLoad.call(this, false);
+				this.onSetContent(e.toString());
+			}
+		}
+	};
+
+	// set up downloader, used by both scripts and content
+	function downloader(bindArgs) {
+		for(var x in this.bindArgs){
+			bindArgs[x] = (undef(bindArgs[x]) ? this.bindArgs[x] : undefined);
+		}
+		var cache = this.cacheContent;
+		if(undef(bindArgs.useCache)){ bindArgs.useCache = cache; }
+		if(undef(bindArgs.preventCache)){ bindArgs.preventCache = !cache; }
+		if(undef(bindArgs.mimetype)){ bindArgs.mimetype = "text/html"; }
+		this.loader.bindObj = dojo.io.bind(bindArgs);
+	};
+
+	// runs addOnLoad/addOnUnLoad functions
+	function stackRunner(st){
+		var err = "", func = null;
+		var scope = this.scriptScope || dojo.global();
+		while(st.length){
+			func = st.shift();
+			try{
+				func.call(scope);
+			}catch(e){
+				err += "\n"+func+" failed: "+e;
+			}
+		}
+		if(err.length){
+			var name = (st== this.loader.addOnLoads) ? "addOnLoad" : "addOnUnLoad";
+			handleDefaults.call(this, name+" failure\n "+err, "onExecError", true);
+		}
+	};
+
+	// push addOnLoad and addOnUnLoad functions onto stack
+	function stackPusher(st, obj, func){
+		if(typeof func == 'undefined') {
+			st.push(obj);
+		}else{
+			st.push(function(){ obj[func](); });
+		}
+	};
+
+	// code saver, collects onLoad, onResized and isLoaded
+	function refreshed(){
+		this.onResized();
+		this.onLoad();
+		this.isLoaded = true;
+	};
+
+	// runs scripts and starts the content parser
+	function asyncParse(data){
+		if(this.executeScripts){
+			this.onExecScript.call(this, data.scripts);
+		}
+		if(this.parseContent){
+			this.onContentParse.call(this);
+		}
+		refreshed.call(this);
+	};
+
+	// run java function
+	function runHandler(){
+		//FIXME: current behaviour is to return false if handler is there, is that intended?
+		if(dojo.lang.isFunction(this.handler)) {
+			this.handler(this, this.containerNode||this.domNode);
+			refreshed.call(this);
+			return false;
+		}
+		return true;
+	};
+
+	// divided up splitAndFixPaths in different parts
+	this.htmlContentBasicFix = function(/*string*/s, /*string||dojo.uri.Uri*/url){
+		// summary:
+		//	strips out <style, <link rel=stylesheet and <title tags
+		//	intended to take out tags that might cause DOM faults
+		var titles = [], styles = [];
+		/************** <title> ***********/
+		// khtml can't attach a <style> or <title> node as child of body
+		var regex = /<title[^>]*>([\s\S]*?)<\/title>/i;
+		while(match = regex.exec(s)){
+			titles.push(match[1]);
+			s = s.substring(0, match.index) + s.substr(match.index + match[0].length);
+		};
+		/****************  cut out all <style> and <link rel="stylesheet" href=".."> **************/
+		regex = /(?:<(style)[^>]*>([\s\S]*?)<\/style>|<link ([^>]*rel=['"]?stylesheet['"]?[^>]*)>)/i;
+		while(match = regex.exec(s)){
+			if(match[1] && match[1].toLowerCase() == "style"){
+				styles.push(dojo.html.fixPathsInCssText(match[2],url));
+			}else if(attr = match[3].match(/href=(['"]?)([^'">]*)\1/i)){
+				styles.push({path: attr[2]});
+			}
+			s = s.substring(0, match.index) + s.substr(match.index + match[0].length);
+		};
+		return {'s': s, 'titles': titles, 'styles': styles};//object
+	};
+
+	this.htmlContentAdjustPaths = function(/*string*/s, /*string||dojo.uri.Uri*/url){
+		// summary:
+		//	adjusts relative paths in content to be relative to current page
+		var tag = "", str = "", tagFix = "", path = "";
+		var attr = [], origPath = "", fix = "";
+
+		// attributepaths one tag can have multiple paths example:
+		// <input src="..." style="url(..)"/> or <a style="url(..)" href="..">
+		// strip out the tag and run fix on that.
+		// this guarantees that we won't run replace on another tag's attribute + it was easier do
+		var regexFindTag = /<[a-z][a-z0-9]*[^>]*\s(?:(?:src|href|style)=[^>])+[^>]*>/i;
+		var regexFindAttr = /\s(src|href|style)=(['"]?)([\w()\[\]\/.,\\'"-:;#=&?\s@]+?)\2/i;
+		// these are the supported protocols, all other is considered relative
+		var regexProtocols = /^(?:[#]|(?:(?:https?|ftps?|file|javascript|mailto|news):))/;
+
+		while(tag = regexFindTag.exec(s)){
+			str += s.substring(0, tag.index);
+			s = s.substring((tag.index + tag[0].length), s.length);
+			tag = tag[0];
+
+			// loop through attributes
+			tagFix = '';
+			while(attr = regexFindAttr.exec(tag)){
+				path = ""; origPath = attr[3];
+				switch(attr[1].toLowerCase()){
+					case "src":// falltrough
+					case "href":
+						if(regexProtocols.exec(origPath)){
+							path = origPath;
+						} else {
+							path = (new dojo.uri.Uri(url, origPath).toString());
+						}
+						break;
+					case "style":// style
+						path = dojo.html.fixPathsInCssText(origPath, url);
+						break;
+					default:
+						path = origPath;
+				}
+
+				fix = " " + attr[1] + "=" + attr[2] + path + attr[2];
+
+				// slices up tag before next attribute check
+				tagFix += tag.substring(0, attr.index) + fix;
+				tag = tag.substring((attr.index + attr[0].length), tag.length);
+			}
+			str += tagFix + tag;
+		}
+		return str+s; // string
+	};
+
+
+	this.htmlContentScripts = function(/*string*/s, /*boolean*/collectScripts){
+		// summary:
+		// 	handles scripts and dojo .require(...) etc calls
+		// NOTE: we need to go through here even if we have executeScripts=false
+		//		 and if we have parseWidgets true 
+		var scripts = [], requires = [], match = [];
+		var attr = "", tmp = null, tag = "", sc = "", str = "";
+		
+		/***************** cut out all <script> tags, push them into scripts array ***************/
+		var regex = /<script([^>]*)>([\s\S]*?)<\/script>/i;
+		var regexSrc = /src=(['"]?)([^"']*)\1/i;
+		var regexDojoJs = /.*(\bdojo\b\.js(?:\.uncompressed\.js)?)$/;
+		var regexInvalid = /(?:var )?\bdjConfig\b(?:[\s]*=[\s]*\{[^}]+\}|\.[\w]*[\s]*=[\s]*[^;\n]*)?;?|dojo\.hostenv\.writeIncludes\(\s*\);?/g;
+		var regexRequires = /dojo\.(?:(?:require(?:After)?(?:If)?)|(?:widget\.(?:manager\.)?registerWidgetPackage)|(?:(?:hostenv\.)?setModulePrefix)|defineNamespace)\((['"]).*?\1\)\s*;?/;
+
+		while(match = regex.exec(s)){
+			if(this.executeScripts && match[1]){
+				if(attr = regexSrc.exec(match[1])){
+					// remove a dojo.js or dojo.js.uncompressed.js from remoteScripts
+					// we declare all files named dojo.js as bad, regardless of path
+					if(regexDojoJs.exec(attr[2])){
+						dojo.debug("Security note! inhibit:"+attr[2]+" from  beeing loaded again.");
+					}else{
+						scripts.push({path: attr[2]});
+					}
+				}
+			}
+			if(match[2]){
+				// remove all invalid variables etc like djConfig and dojo.hostenv.writeIncludes()
+				sc = match[2].replace(regexInvalid, "");
+				if(!sc){ continue; }
+
+				// cut out all dojo .require (...) calls, if we have execute 
+				// scripts false widgets dont get there require calls
+				// takes out possible widgetpackage registration as well
+				while(tmp = regexRequires.exec(sc)){
+					requires.push(tmp[0]);
+					sc = sc.substring(0, tmp.index) + sc.substr(tmp.index + tmp[0].length);
+				}
+				if(collectScripts){
+					scripts.push(sc);
+				}
+			}
+			s = s.substr(0, match.index) + s.substr(match.index + match[0].length);
+		}
+		/******** scan for scriptScope in html eventHandlers 
+					and replace with link to this widget *********/
+		if(collectScripts){
+			var regex = /(<[a-zA-Z][a-zA-Z0-9]*\s[^>]*\S=(['"])[^>]*[^\.\]])scriptScope([^>]*>)/;
+			str = "";
+			while(tag = regex.exec(s)){
+				tmp = ((tag[2]=="'") ? '"': "'");
+				str += s.substring(0, tag.index);
+				s = s.substr(tag.index).replace(regex, "$1dojo.widget.byId("+ tmp + this.widgetId + tmp + ").scriptScope$3");
+			}
+			s = str + s;
+		}
+		return {'s': s, 'requires': requires, 'scripts': scripts}; // object
+	};
+
+		
+	this.splitAndFixPaths = function(/*object*/args){
+		// summary:
+		//	pathfixes, require calls, css stuff and neccesary content clean
+		// args:
+		//	content 		string
+		//	url 			string? or dojo.uri.Uri that that pulled the content in, for path adjust
+		//	adjustPaths		boolean, if true adjust relative paths in content to match this page
+		//	collectScripts	boolean, if true it takes out all <script and <script src=.. tags and collects
+		//					 dojo.require calls in a separate array, usefull for eval
+		//	collectRequires	boolean, if true and collectScripts is false it still collects scripts along with
+		//					 dojo.require calls
+		//	bodyExtract		boolean, if true only return content inside of the body tag
+
+		// return:			{xml: string,
+		//					styles: array, remote style get object {path: /*string*/url}
+		//					requires: array,
+		//					scripts: array, remote scripts get object {path: /*string*/url}
+		//					url: string}
+		if(!args.url) { args.url = "./"; } // point to this page if not set
+		// make sure back/forward buttons dont mess up url.
+		url = new dojo.uri.Uri(location, args.url).toString();
+		var ret = {'xml': 	"",
+				'styles':	[],
+				'titles':	[],
+				'requires':	[],
+				'scripts':	[],
+				'url':		url };
+
+		if(args.content){ // make sure we dont run regexes on empty content
+			var tmp = null, content = args.content;
+			if(args.adjustPaths){
+				content = _loader.htmlContentAdjustPaths.call(this, content, url);
+			}
+
+			tmp = _loader.htmlContentBasicFix.call(this, content, url);
+			content = tmp.s;
+			ret.styles = tmp.styles;
+			ret.titles = tmp.titles;
+
+			if(args.collectRequires || args.collectScripts){
+				tmp = _loader.htmlContentScripts.call(this, content, args.collectScripts);
+				content = tmp.s;
+				ret.requires = tmp.requires;
+				ret.scripts = tmp.scripts;
+			}
+
+			/********* extract content *********/
+			var match = [];
+			if(args.bodyExtract){
+				match = content.match(/<body[^>]*>\s*([\s\S]+)\s*<\/body>/im);
+				if(match) { content = match[1]; }
+			}
+			ret.xml = content;
+		}
+		return ret;// object 
+	};
+
+
+	// the all important startup function
+	this.hookUp = function(/*object*/args){
+		// summary:
+		// 	mixin or extend loader into a widget
+		// args:
+		//	widget: widget reference
+		//	mixin: boolean, default false
+		// 		if mixin true, it will only extend the current widget, not its prototype
+		var widget = args.widget;
+		if(dojo.lang.isString(widget)){
+			if(args.mixin){	
+				dojo.raise(this.toString()+", cant use mixin when widget is a string");
+			 }
+			widget = dojo.evalObjPath(widget);
+		}
+		if(!widget || !(widget instanceof dojo.widget.HtmlWidget)){
+			dojo.raise(this.toString()+" Widget is'nt defined or isnt a HtmlWidget instance"); 
+		}
+		// make sure we dont mixin more than once
+		if(widget.loader && widget.setUrl){ return; }
+
+		// extend widget prototype or mixin this widget instance
+		var widgetProto = (args.mixin) ? widget : widget.constructor.prototype;
+	
+		/********************************************
+		** per widgetImpl variables, mixin into widget 
+		********************************************/
+		// stuff it into a loader obj
+		widget.loader = {
+			isLoaded: false,
+			styleNodes:  [],
+			addOnLoads: [],
+			addOnUnLoads: [],
+			callOnUnLoad:(function(canCall){
+							return function(after){ this.abort();
+								if(canCall){ this.onUnLoad(); }
+								canCall = after;
+							};
+						})(false),
+			bindObj: null,
+			// to disconnect widget
+			unHook: (function(w, wg){
+				var oldProps = {
+					isContainer: w.isContainer,
+					adjustPats: w.adjustPaths,
+					href: w.href,
+					extractContent: w.extractContent,
+					parseContent: w.parseContent,
+					cacheContent: w.cacheContent,
+					bindArgs: w.bindArgs,
+					preload: w.preload,
+					refreshOnShow: w.refreshOnShow,
+					handler: w.handler,
+					trackHistory: w.trackHistory,
+					executeScripts: w.executeScripts,
+					scriptScope: w.scriptScope,
+					// functions
+					postCreate: w.postCreate,
+					show: w.show,
+					refresh: w.refresh,
+					loadContents: w.loadContents,
+					abort: w.abort,
+					destroy: w.destroy,
+					onLoad: w.onLoad,
+					onUnLoad: w.onUnLoad,
+					addOnLoad: w.addOnLoad,
+					addOnUnLoad: w.addOnUnLoad,
+					onDownloadStart: w.onDownloadStart,
+					onDownloadEnd: w.onDownloadEnd,
+					onDownloadError: w.onDownloadError,
+					onContentError: w.onContentError,
+					onExecError: w.onExecError,
+					onSetContent: w.onSetContent,
+					setUrl: w.setUrl,
+					setContent: w.setContent,
+					onContentParse: w.onContentParse,
+					onExecScript: w.onExecScript,
+					setHandler: w.setHandler
+				};
+				return function(){
+					if(wg.abort){ wg.abort(); }
+					// make sure we dont unhook prototype if there is more widgets of this type left
+					if((w != wg) && (dojo.widget.byType(wg.widgetType).length>1)){ return; }
+					for(var x in oldProps){
+						if(oldProps[x]===undefined){
+							delete w[x]; continue;
+						}
+						w[x] = oldProps[x];
+					}
+					delete wg._loader_defined;
+					delete wg.loader;
+				};
+			})(widgetProto, widget)
+		};
+
+		// make sure we dont do this more than once per widget/widgetprototype
+		if(widgetProto._loader_defined || widget._loader_defined){ return; }		
+
+		/**************** private variables *********************/
+
+		// loading options, prototype parts of widgets mixin to prototype
+		dojo.mixin(widgetProto, {
+			// always set to a containerwidget
+			isContainer: true,
+			// fix relative paths in content to fit into this page
+			adjustPaths: 	undef(widgetProto.adjustPaths) ? true : widgetProto.adjustPaths,
+			// only usable on construction, use setUrl or setContent after that
+			href: 			undef(widgetProto.href) ? "" : widgetProto.href,
+			// extract visible content from inside of <body> .... </body>
+			extractContent: undef(widgetProto.extractContent) ? true : widgetProto.extractContent,
+			// construct all widgets that is in content
+			// FIXME: rename to parseWidgets?
+			parseContent: 	undef(widgetProto.parseContent) ? true : widgetProto.parseContent,
+			// use io binds javascript cache, or if false, prevent browsercache
+			cacheContent: 	undef(widgetProto.cacheContent) ? true : widgetProto.cacheContent,
+			// specify  specific  io.bind arguments such as transport and useCache
+			bindArgs:		undef(widgetProto.bindArgs) ? {} : widgetProto.bindArgs,
+			// force load even if widget isnt shown (lazyload setting)
+			preload: 		undef(widgetProto.preload) ? false : widgetProto.preload,
+			// reload content automatically onShow, use with cacheContent = flase
+			refreshOnShow:	undef(widgetProto.refreshOnShow) ? false : widgetProto.refreshOnShow,
+			// name of java function which should generate content
+			handler: 		undef(widgetProto.handler) ? "" : widgetProto.handler,
+			// if true scripts in content will be evaled after content is innerHTML'ed
+			executeScripts: undef(widgetProto.executeScripts) ? false : widgetProto.executeScripts,
+			// log contents (back/forward support)
+			trackHistory:	undef(widgetProto.tracHistory) ? false : widgetProto.trackHistory,
+			scriptScope: null // always overwrite
+		});
+
+		/****************************************************
+		******* public functions, becomes part of widgets API
+		*****************************************************/
+
+		/*********** Public functions that wigets cant overide **********/
+		// set up postCreate, call originalcode before our own
+		widgetProto.postCreate = (function(postCreate){
+			return function(){
+				if(widgetProto.constructor.superclass.postCreate != postCreate){
+					postCreate.apply(this, arguments);
+				}else{
+					widgetProto.constructor.superclass.postCreate.apply(this, arguments);
+				}
+				if(this.handler!==""){ this.setHandler(this.handler); }
+				if(this.isShowing() || this.preload){ 
+					this.loadContents();
+					if(!this.href){ // back/forward save initial state
+						_loader._log(this,(this.domNode||this.containerNode).innerHTML);
+					}
+				}
+			}
+		})(widgetProto.postCreate);
+
+		// set up onShow listener, call original code after this block
+		widgetProto.show = (function(show){
+			return function(){
+				// if refreshOnShow is true, reload the contents every time; otherwise, load only the first time
+				if(this.refreshOnShow){
+					this.refresh();
+				}else{ 
+					this.loadContents();
+				}
+				if((widgetProto.constructor.superclass.show == show) || !isFunc(show)){
+					widgetProto.constructor.superclass.show.apply(this, arguments);
+				}else{
+					show.apply(this, arguments);
+				}
+			};
+		})(widgetProto.show);
+
+		// destroy cleanups, original code in the middle
+		widgetProto.destroy = (function(destroy){
+			return function(destroy){
+				this.onUnLoad();
+				this.abort();
+				this.loader.unHook();
+				if((widgetProto.constructor.superclass.destroy != destroy) && isFunc(destroy)){
+					destroy.apply(this, arguments);
+				}else{
+					widgetProto.constructor.superclass.destroy.apply(this, arguments);
+				}
+			}
+		})(widgetProto.destroy);
+
+
+		/******* Public functions that widgets can overide *****/
+		// set up a refresh function
+		if(!widgetProto.refresh){
+			widgetProto.refresh = function(){
+				this.loader.isLoaded = false;
+				this.loadContents();
+			};
+		}
+
+		// set up html loading contents
+		if(!widgetProto.loadContents){
+			widgetProto.loadContents = function(){
+				if(this.loader.isLoaded){ return; }
+				// javafunction
+				if(isFunc(this.handler)){
+					runHandler.call(this);
+				}else if(this.href !== ""){
+					handleDefaults.call(this, "Loading...", "onDownloadStart");
+					var self = this, url = this.href;
+					downloader.call(this, {
+						url: url,
+						load: function(type, data, xhr){
+							self.onDownloadEnd.call(self, url, data);
+						},
+						error: function(type, err, xhr){
+							// XHR insnt a normal JS object, copy esentials
+							var e = {
+								responseText: xhr.responseText,
+								status: xhr.status,
+								statusText: xhr.statusText,
+								responseHeaders: (xhr.getAllResponseHeaders) ? xhr.getAllResponseHeaders():[],
+								_text: "Error loading '" + url + "' (" + xhr.status + " "+  xhr.statusText + ")"
+							};
+							handleDefaults.call(self, e, "onDownloadError");
+							self.onLoad();
+						}
+					});
+				}
+			};
+		}
+
+		// set up abort
+		if(!widgetProto.abort){
+			widgetProto.abort = function(){
+				if(!this.loader || !this.loader.bindObj || !this.loader.bindObj.abort){ return; }
+				this.loader.bindObj.abort();
+				this.loader.bindObj = null;
+			};
+		}
+
+		// onLoad
+		if(!widgetProto.onLoad){
+			widgetProto.onLoad = function(){
+				stackRunner.call(this, this.loader.addOnLoads);
+				this.loader.isLoaded = true;
+			};
+		}
+
+		// onUnLoad, original code in the middle
+		if(!widgetProto.onUnLoad){
+			widgetProto.onUnLoad = function(){
+				stackRunner.call(this, this.loader.addOnUnLoads);
+				delete this.scriptScope;
+			}
+		}
+
+		// add to onLoad queue
+		if(!widgetProto.addOnLoad){
+			widgetProto.addOnLoad = function(obj, func){
+				stackPusher.call(this, this.loader.addOnLoads, obj, func);
+			};
+		}
+
+		// add to onUnLoad queue 
+		if(!widgetProto.addOnUnLoad){
+			widgetProto.addOnUnLoad = function(obj, func){
+				stackPusher.call(this, this.loader.addOnUnLoads, obj, func);
+			}
+		}
+
+		// script or java errors, preventDefault-able
+		if(!widgetProto.onExecError){
+			widgetProto.onExecError = function(){/*stub*/};
+		}
+	
+		// called on DOM faults, require fault etc in content, preventDefault-able
+		if(!widgetProto.onContentError){
+			widgetProto.onContentError = function(){/*stub*/};
+		}
+	
+		// called when download error occurs, preventDefault-able
+		if(!widgetProto.onDownloadError){
+			widgetProto.onDownloadError = function(){/*stub*/};
+		}
+	
+		// called before download starts, preventDefault-able
+		if(!widgetProto.onDownloadStart){
+			widgetProto.onDownloadStart = function(onDownloadStart){/*stub*/};
+		}
+	
+		// called when download is finished successfully
+		if(!widgetProto.onDownloadEnd){
+			widgetProto.onDownloadEnd = function(url, data){
+				var args =  {content: data,
+							url: url,
+							adjustPaths: this.adjustPaths,
+							collectScripts: this.executeScripts,
+							collectRequires: this.parseContent,
+							bodyExtract: this.extractContent };
+				data = _loader.splitAndFixPaths.call(this, args);
+				this.setContent(data);
+			}
+		}
+
+		// previously called _setContent, widget defined onSetContent can modify content or cancel
+		if(!widgetProto.onSetContent){
+			widgetProto.onSetContent = function(cont){
+				this.destroyChildren();
+		
+				// remove old stylenodes from HEAD
+				var styleNodes = this.loader.styleNodes;
+				while(styleNodes.length){
+					var st = styleNodes.pop();
+					if(st && st.parentNode){
+						st.parentNode.removeChild(st);
+					}
+				}
+		
+				var node = this.containerNode || this.domNode;
+				while(node.firstChild){
+					try{
+						dojo.event.browser.clean(node.firstChild);
+					}catch(e){}
+					node.removeChild(node.firstChild);
+				}
+				try{
+					if(typeof cont != "string"){
+						node.appendChild(cont);
+					}else{
+						try{// hack to deal with domfaults, ie. appending div to tablenodes
+							node.innerHTML = cont;
+						}catch(e){var tmp;
+							(tmp = dojo.doc().createElement("div")).innerHTML = cont;
+							while(tmp.firstChild){
+								node.appendChild(tmp.removeChild(tmp.firstChild));
+							}
+						}
+					}
+				}catch(e){
+					e._text = "Could'nt load content: "+e;
+					var useAlert = (this.loader._onSetContent_err == e._text); // make sure we dont loop
+					this.loader._onSetContent_err = e._text;
+					handleDefaults.call(this, e, "onContentError", useAlert);
+				}
+			};
+		}
+
+		if(!widgetProto.setUrl){
+			widgetProto.setUrl = function(url){
+				this.href = url;
+				this.loader.isLoaded = false;
+				if ( this.preload || this.isShowing() ){
+					this.loadContents();
+				}
+			}
+		}
+
+		if(!widgetProto.setContent){
+			widgetProto.setContent = function(data, dontLog){
+				this.loader.callOnUnLoad.call(this, true);
+		
+				if(!data||dojo.html.isNode(data)){
+					this.onSetContent(data);
+					refreshed.call(this);
+				}else{
+					// need to run splitAndFixPaths? ie. manually setting content
+					// adjustPaths is taken care of inside splitAndFixPaths
+					if(typeof data.xml != 'string'){
+						this.href = ""; // so we can refresh safely
+						var args =  {content: data,
+							url: this.href,
+							adjustPaths: this.adjustPaths,
+							collectScripts: this.executeScripts,
+							collectRequires: this.parseContent,
+							bodyExtract: this.extractContent };
+						data = _loader.splitAndFixPaths.call(this, args); 
+					}else if(data.url!="./"){
+						 this.url = data.url;// backbutton thing
+					}
+					this.onSetContent(data.xml);
+	
+					// insert styles from content (in same order they came in)
+					for(var i = 0, styles = data.styles; i < styles.length; i++){
+						if(styles[i].path){
+							this.loader.styleNodes.push(dojo.html.insertCssFile(styles[i].path));
+						}else{
+							this.loader.styleNodes.push(dojo.html.insertCssText(styles[i]));
+						}
+					}
+		
+					if(this.parseContent){
+						for(var i = 0, requires = data.requires; i < requires.length; i++){
+							try{
+								eval(requires[i]);
+							} catch(e){
+								e._text = "dojo.widget.html.loader.hookUp: error in package loading calls, "+(e.description||e);
+								handleDefaults.call(this, e, "onContentError", true);
+							}
+						}
+					}
+					// need to allow async load, Xdomain uses it
+					// NOTE: on Xdomain loads this can break the sync thread of setContent
+					// 		if you you do any dojo. require(...) etc
+					if(dojo.hostenv.isXDomain && data.requires.length){
+						dojo.addOnLoad(function(){ 
+							asyncParse.call(this, data);
+							if(!dontLog){
+								_loader._log(this, data);
+							}
+						});// this opens a thread need abort undo
+						dontLog = true;
+					}else{
+						asyncParse.call(this, data);
+					}
+				}if(!dontLog){
+// 					_loader._log(this, data);
+				}
+			};
+		}
+
+		if(!widgetProto.onContentParse){
+			widgetProto.onContentParse = function(){
+				var node = this.containerNode || this.domNode;
+				var parser = new dojo.xml.Parse();
+				var frag = parser.parseElement(node, null, true);
+				dojo.widget.getParser().createSubComponents(frag, this);
+			};
+		}
+
+		// previously called _executeScripts
+		if(!widgetProto.onExecScript){
+			widgetProto.onExecScript = function(scripts){
+				// loop through the scripts in the order they came in
+				var self = this, tmp = "", code = "";
+				for(var i = 0; i < scripts.length; i++){ // remotescript
+					if(scripts[i].path){
+						var url = scripts[i].path;
+						downloader.call(this,{
+							'url': 		url,
+							'load': function(type, scriptStr){
+								(function(){tmp = scriptStr; scripts[i] = scriptStr;}).call(self);
+							},
+							'error': function(type, error){
+								error._text = type + " downloading remote script";
+								handleDefaults.call(self, error, "onExecError", true);
+							},
+							'mimetype': "text/plain",
+							'sync':     true
+						});
+						code += tmp;
+					}else{
+						code += scripts[i];
+					}
+				}
+
+				try{
+					// initialize a new anonymous container for our script, dont make it part of this widgets scope chain
+					// instead send in a variable that points to this widget, usefull to connect events to onLoad, onUnLoad etc..
+					delete this.scriptScope;
+					this.scriptScope = new (new Function('_container_', code+'; return this;'))(self);
+				}catch(e){
+					e._text = "Error running scripts from content:\n"+(e.description||e.toString());
+					handleDefaults.call(this, e, "onExecError", true);
+				}
+			};
+		}
+
+		// Generate content from given java function
+		if(!widgetProto.setHandler){
+			widgetProto.setHandler = function(handler) {
+				var fcn = dojo.lang.isFunction(handler) ? handler : window[handler];
+				if(!isFunc(fcn)) {
+					// FIXME: needs testing! somebody with java knowledge needs to try this
+					handleDefaults.call(this, "Unable to set handler, '" + handler + "' not a function.", "onExecError", true);
+					return;
+				}
+				this.handler = function() {
+					return fcn.apply(this, arguments);
+				};
+			};
+		}
+
+		// make sure we extend this widget only once
+		widgetProto._loader_defined = true;
+	};
+
+
+})();

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

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/html/stabile.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/html/stabile.js?view=auto&rev=449122
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/html/stabile.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/html/stabile.js Fri Sep 22 16:22:30 2006
@@ -0,0 +1,213 @@
+/*
+	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
+*/
+
+// Maintain state of widgets when user hits back/forward button
+
+dojo.provide("dojo.widget.html.stabile");
+
+dojo.widget.html.stabile = {
+	// Characters to quote in single-quoted regexprs
+	_sqQuotables: new RegExp("([\\\\'])", "g"),
+
+	// Current depth.
+	_depth: 0,
+
+	// Set to true when calling v.toString, to sniff for infinite
+	// recursion.
+	_recur: false,
+
+	// Levels of nesting of Array and object displays.
+	// If when >= depth, no display or array or object internals.
+	depthLimit: 2
+};
+
+
+
+
+
+//// PUBLIC METHODS
+
+// Get the state stored for the widget with the given ID, or undefined
+// if none.
+// 
+dojo.widget.html.stabile.getState = function(id){
+	dojo.widget.html.stabile.setup();
+	return dojo.widget.html.stabile.widgetState[id];
+}
+
+
+// Set the state stored for the widget with the given ID.  If isCommit
+// is true, commits all widget state to more stable storage.
+// 
+dojo.widget.html.stabile.setState = function(id, state, isCommit){
+	dojo.widget.html.stabile.setup();
+	dojo.widget.html.stabile.widgetState[id] = state;
+	if(isCommit){
+		dojo.widget.html.stabile.commit(dojo.widget.html.stabile.widgetState);
+	}
+}
+
+
+// Sets up widgetState: a hash keyed by widgetId, maps to an object
+// or array writable with "describe".  If there is data in the widget
+// storage area, use it, otherwise initialize an empty object.
+// 
+dojo.widget.html.stabile.setup = function(){
+	if(!dojo.widget.html.stabile.widgetState){
+		var text = dojo.widget.html.stabile.getStorage().value;
+		dojo.widget.html.stabile.widgetState = text ? dj_eval("("+text+")") : {};
+	}
+}
+
+
+// Commits all widget state to more stable storage, so if the user
+// navigates away and returns, it can be restored.
+// 
+dojo.widget.html.stabile.commit = function(state){
+	dojo.widget.html.stabile.getStorage().value = dojo.widget.html.stabile.description(state);
+}
+
+// Return a JSON "description string" for the given value.
+// Supports only core JavaScript types with literals, plus Date,
+// and cyclic structures are unsupported.
+// showAll defaults to false -- if true, this becomes a simple symbolic
+// object dumper, but you cannot "eval" the output.
+//
+dojo.widget.html.stabile.description = function(v, showAll){
+	// Save and later restore dojo.widget.html.stabile._depth;
+	var depth = dojo.widget.html.stabile._depth;
+
+	var describeThis = function() {
+		 return this.description(this, true);
+	} 
+	
+	try {
+
+		if(v===void(0)){
+			return "undefined";
+		}
+		if(v===null){
+			return "null";
+		}
+		if(typeof(v)=="boolean" || typeof(v)=="number"
+		    || v instanceof Boolean || v instanceof Number){
+			return v.toString();
+		}
+
+		if(typeof(v)=="string" || v instanceof String){
+			// Quote strings and their contents as required.
+			// Replacing by $& fails in IE 5.0
+			var v1 = v.replace(dojo.widget.html.stabile._sqQuotables, "\\$1"); 
+			v1 = v1.replace(/\n/g, "\\n");
+			v1 = v1.replace(/\r/g, "\\r");
+			// Any other important special cases?
+			return "'"+v1+"'";
+		}
+
+		if(v instanceof Date){
+			// Create a data constructor.
+			return "new Date("+d.getFullYear+","+d.getMonth()+","+d.getDate()+")";
+		}
+
+		var d;
+		if(v instanceof Array || v.push){
+			// "push" test needed for KHTML/Safari, don't know why -cp
+
+			if(depth>=dojo.widget.html.stabile.depthLimit)
+			  return "[ ... ]";
+
+			d = "[";
+			var first = true;
+			dojo.widget.html.stabile._depth++;
+			for(var i=0; i<v.length; i++){
+				// Skip functions and undefined values
+				// if(v[i]==undef || typeof(v[i])=="function")
+				//   continue;
+				if(first){
+					first = false;
+				}else{
+					d += ",";
+				}
+				d+=arguments.callee(v[i], showAll);
+			}
+			return d+"]";
+		}
+
+		if(v.constructor==Object
+		    || v.toString==describeThis){
+			if(depth>=dojo.widget.html.stabile.depthLimit)
+			  return "{ ... }";
+
+			// Instanceof Hash is good, or if we just use Objects,
+			// we can say v.constructor==Object.
+			// IE (5?) lacks hasOwnProperty, but perhaps objects do not always
+			// have prototypes??
+			if(typeof(v.hasOwnProperty)!="function" && v.prototype){
+				throw new Error("description: "+v+" not supported by script engine");
+			}
+			var first = true;
+			d = "{";
+			dojo.widget.html.stabile._depth++;
+			for(var key in v){
+				// Skip values that are functions or undefined.
+				if(v[key]==void(0) || typeof(v[key])=="function")
+					continue;
+				if(first){
+					first = false;
+				}else{
+					d += ", ";
+				}
+				var kd = key;
+				// If the key is not a legal identifier, use its description.
+				// For strings this will quote the stirng.
+				if(!kd.match(/^[a-zA-Z_][a-zA-Z0-9_]*$/)){
+					kd = arguments.callee(key, showAll);
+				}
+				d += kd+": "+arguments.callee(v[key], showAll);
+			}
+			return d+"}";
+		}
+
+		if(showAll){
+			if(dojo.widget.html.stabile._recur){
+				// Save the original definitions of toString;
+				var objectToString = Object.prototype.toString;
+				return objectToString.apply(v, []);
+			}else{
+				dojo.widget.html.stabile._recur = true;
+				return v.toString();
+			}
+		}else{
+			// log("Description? "+v.toString()+", "+typeof(v));
+			throw new Error("Unknown type: "+v);
+			return "'unknown'";
+		}
+
+	} finally {
+		// Always restore the global current depth.
+		dojo.widget.html.stabile._depth = depth;
+	}
+
+}
+
+
+
+//// PRIVATE TO MODULE
+
+// Gets an object (form field) with a read/write "value" property.
+// 
+dojo.widget.html.stabile.getStorage = function(){
+	if (dojo.widget.html.stabile.dataField) {
+		return dojo.widget.html.stabile.dataField;
+	}
+	var form = document.forms._dojo_form;
+	return dojo.widget.html.stabile.dataField = form ? form.stabile : {value: ""};
+}
+

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

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/nls/DropdownDatePicker.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/nls/DropdownDatePicker.js?view=auto&rev=449122
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/nls/DropdownDatePicker.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/nls/DropdownDatePicker.js Fri Sep 22 16:22:30 2006
@@ -0,0 +1,13 @@
+/*
+	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
+*/
+
+({
+		selectDate: "Select a date"
+})

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

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/nls/DropdownTimePicker.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/nls/DropdownTimePicker.js?view=auto&rev=449122
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/nls/DropdownTimePicker.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/nls/DropdownTimePicker.js Fri Sep 22 16:22:30 2006
@@ -0,0 +1,13 @@
+/*
+	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
+*/
+
+({
+		selectTime: "Select time"
+})

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

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/nls/TimePicker.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/nls/TimePicker.js?view=auto&rev=449122
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/nls/TimePicker.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/nls/TimePicker.js Fri Sep 22 16:22:30 2006
@@ -0,0 +1,13 @@
+/*
+	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
+*/
+
+({
+		any: "any"
+})

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

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/nls/fr/validate.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/nls/fr/validate.js?view=auto&rev=449122
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/nls/fr/validate.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/nls/fr/validate.js Fri Sep 22 16:22:30 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
+*/
+
+({
+		invalidMessage: "* La valeur saisie est incorrecte.",
+		missingMessage: "* Cette valeur est obligatoire.",
+		rangeMessage: "* Cette valeur est hors limites."
+})

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

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/nls/ja/validate.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/nls/ja/validate.js?view=auto&rev=449122
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/nls/ja/validate.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/nls/ja/validate.js Fri Sep 22 16:22:30 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
+*/
+
+/*<?xml version="1.0" encoding="UTF-8" ?>*/
+({
+		invalidMessage: "* 入力したデータに該当するものがありません。",
+		missingMessage: "* 入力が必須です。",
+		rangeMessage: "* 入力した数値は選択範囲外です。"
+})

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

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/nls/validate.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/nls/validate.js?view=auto&rev=449122
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/nls/validate.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/nls/validate.js Fri Sep 22 16:22:30 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
+*/
+
+({
+		invalidMessage: "* The value entered is not valid.",
+		missingMessage: "* This value is required.",
+		rangeMessage: "* This value is out of range."
+})

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

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/nls/zh-cn/validate.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/nls/zh-cn/validate.js?view=auto&rev=449122
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/nls/zh-cn/validate.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/nls/zh-cn/validate.js Fri Sep 22 16:22:30 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
+*/
+
+({
+		invalidMessage: "* 非法的输入值。",
+		missingMessage: "* 此值是必须的。",
+		rangeMessage: "* 输入数据超出值域。"
+})

Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/nls/zh-cn/validate.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/svg/Chart.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/svg/Chart.js?view=auto&rev=449122
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/svg/Chart.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/svg/Chart.js Fri Sep 22 16:22:30 2006
@@ -0,0 +1,552 @@
+/*
+	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.widget.svg.Chart");
+
+dojo.require("dojo.widget.HtmlWidget");
+dojo.require("dojo.widget.Chart");
+dojo.require("dojo.html.layout");
+dojo.require("dojo.math");
+dojo.require("dojo.svg");
+dojo.require("dojo.gfx.color");
+
+dojo.require("dojo.json");
+
+dojo.widget.defineWidget(
+	"dojo.widget.svg.Chart",
+	[dojo.widget.HtmlWidget, dojo.widget.Chart],
+	function(){
+		this.templatePath=null;
+		this.templateCssPath=null;
+		this._isInitialize=false;
+		this.hasData=false;
+		this.vectorNode=null;
+		this.plotArea=null;
+		this.dataGroup=null;
+		this.axisGroup=null;
+		this.properties={
+			height:0,	//	defaults, will resize to the domNode.
+			width:0,
+			defaultWidth:600,
+			defaultHeight:400,
+			plotType:null,
+			padding:{
+				top:10,
+				bottom:2,
+				left:60,
+				right:30
+			},
+			axes:{
+				x:{
+					plotAt:0,
+					label:"",
+					unitLabel:"",
+					unitType:Number,
+					nUnitsToShow:10,
+					range:{
+						min:0,
+						max:200
+					}
+				},
+				y:{
+					plotAt:0,
+					label:"",
+					unitLabel:"",
+					unitType:Number,
+					nUnitsToShow:10,
+					range:{
+						min:0,
+						max:200
+					}
+				}
+			}
+		};
+	},
+	{
+		parseProperties:function(/* HTMLElement */node){
+			//	summary
+			//	Parse the properties off the main tag
+			var bRangeX=false;
+			var bRangeY=false;
+			if (node.getAttribute("width")){ 
+				this.properties.width=node.getAttribute("width");
+			}
+			if (node.getAttribute("height")){
+				this.properties.height=node.getAttribute("height");
+			}
+			if (node.getAttribute("plotType")){
+				this.properties.plotType=node.getAttribute("plotType");
+			}
+			if (node.getAttribute("padding")){
+				if (node.getAttribute("padding").indexOf(",") > -1)
+					var p=node.getAttribute("padding").split(","); 
+				else var p=node.getAttribute("padding").split(" ");
+				if (p.length==1){
+					var pad=parseFloat(p[0]);
+					this.properties.padding.top=pad;
+					this.properties.padding.right=pad;
+					this.properties.padding.bottom=pad;
+					this.properties.padding.left=pad;
+				} else if(p.length==2){
+					var padV=parseFloat(p[0]);
+					var padH=parseFloat(p[1]);
+					this.properties.padding.top=padV;
+					this.properties.padding.right=padH;
+					this.properties.padding.bottom=padV;
+					this.properties.padding.left=padH;
+				} else if(p.length==4){
+					this.properties.padding.top=parseFloat(p[0]);
+					this.properties.padding.right=parseFloat(p[1]);
+					this.properties.padding.bottom=parseFloat(p[2]);
+					this.properties.padding.left=parseFloat(p[3]);
+				}
+			}
+			if (node.getAttribute("rangeX")){
+				var p=node.getAttribute("rangeX");
+				if (p.indexOf(",")>-1) p=p.split(",");
+				else p=p.split(" ");
+				this.properties.axes.x.range.min=parseFloat(p[0]);
+				this.properties.axes.x.range.max=parseFloat(p[1]);
+				bRangeX=true;
+			}
+			if (node.getAttribute("rangeY")){
+				var p=node.getAttribute("rangeY");
+				if (p.indexOf(",")>-1) p=p.split(",");
+				else p=p.split(" ");
+				this.properties.axes.y.range.min=parseFloat(p[0]);
+				this.properties.axes.y.range.max=parseFloat(p[1]);
+				bRangeY=true;
+			}
+			return { rangeX:bRangeX, rangeY:bRangeY };
+		},
+		setAxesPlot:function(/* HTMLElement */table){
+			//	where to plot the axes
+			if (table.getAttribute("axisAt")){
+				var p=table.getAttribute("axisAt");
+				if (p.indexOf(",")>-1) p=p.split(",");
+				else p=p.split(" ");
+				
+				//	x axis
+				if (!isNaN(parseFloat(p[0]))){
+					this.properties.axes.x.plotAt=parseFloat(p[0]);
+				} else if (p[0].toLowerCase()=="ymin"){
+					this.properties.axes.x.plotAt=this.properties.axes.y.range.min;
+				} else if (p[0].toLowerCase()=="ymax"){
+					this.properties.axes.x.plotAt=this.properties.axes.y.range.max;
+				}
+
+				// y axis
+				if (!isNaN(parseFloat(p[1]))){
+					this.properties.axes.y.plotAt=parseFloat(p[1]);
+				} else if (p[1].toLowerCase()=="xmin"){
+					this.properties.axes.y.plotAt=this.properties.axes.x.range.min;
+				} else if (p[1].toLowerCase()=="xmax"){
+					this.properties.axes.y.plotAt=this.properties.axes.x.range.max;
+				}
+			} else {
+				this.properties.axes.x.plotAt=this.properties.axes.y.range.min;
+				this.properties.axes.y.plotAt=this.properties.axes.x.range.min;
+			}
+		},
+		drawVectorNode:function(){
+			// ok, lets create the chart itself.
+			dojo.svg.g.suspend();		
+			if(this.vectorNode) this.destroy();
+			this.vectorNode=document.createElementNS(dojo.svg.xmlns.svg, "svg");
+			this.vectorNode.setAttribute("width", this.properties.width);
+			this.vectorNode.setAttribute("height", this.properties.height);
+			dojo.svg.g.resume();
+		},
+		drawPlotArea:function(){
+			//	set up the clip path for the plot area.
+			dojo.svg.g.suspend();		
+			if(this.plotArea){
+				this.plotArea.parentNode.removeChild(this.plotArea);
+				this.plotArea=null;
+			}
+			var defs = document.createElementNS(dojo.svg.xmlns.svg, "defs");
+			var clip = document.createElementNS(dojo.svg.xmlns.svg, "clipPath");
+			clip.setAttribute("id","plotClip"+this.widgetId);
+			var rect = document.createElementNS(dojo.svg.xmlns.svg, "rect");		
+			rect.setAttribute("x", this.properties.padding.left);
+			rect.setAttribute("y", this.properties.padding.top);
+			rect.setAttribute("width", this.properties.width-this.properties.padding.left-this.properties.padding.right);
+			rect.setAttribute("height", this.properties.height-this.properties.padding.top-this.properties.padding.bottom);
+			clip.appendChild(rect);
+			defs.appendChild(clip);
+			this.vectorNode.appendChild(defs);
+
+			//	the plot background.
+			this.plotArea = document.createElementNS(dojo.svg.xmlns.svg, "g");
+			this.vectorNode.appendChild(this.plotArea);
+			var rect = document.createElementNS(dojo.svg.xmlns.svg, "rect");		
+			rect.setAttribute("x", this.properties.padding.left);
+			rect.setAttribute("y", this.properties.padding.top);
+			rect.setAttribute("width", this.properties.width-this.properties.padding.left-this.properties.padding.right);
+			rect.setAttribute("height", this.properties.height-this.properties.padding.top-this.properties.padding.bottom);
+			rect.setAttribute("fill", "#fff");
+			this.plotArea.appendChild(rect);
+			dojo.svg.g.resume();
+		},
+		drawDataGroup:function(){
+			//	data group
+			dojo.svg.g.suspend();		
+			if(this.dataGroup){
+				this.dataGroup.parentNode.removeChild(this.dataGroup);
+				this.dataGroup=null;
+			}
+			this.dataGroup = document.createElementNS(dojo.svg.xmlns.svg, "g");
+			this.dataGroup.setAttribute("style","clip-path:url(#plotClip"+this.widgetId+");");
+			this.plotArea.appendChild(this.dataGroup);
+			dojo.svg.g.resume();
+		},
+		drawAxes:function(){
+			dojo.svg.g.suspend();		
+			if(this.axisGroup){
+				this.axisGroup.parentNode.removeChild(this.axisGroup);
+				this.axisGroup=null;
+			}
+			//	axis group
+			this.axisGroup = document.createElementNS(dojo.svg.xmlns.svg, "g");
+			this.plotArea.appendChild(this.axisGroup);
+
+			//	x axis
+			var stroke=1;
+			var line = document.createElementNS(dojo.svg.xmlns.svg, "line");
+			var y=dojo.widget.svg.Chart.Plotter.getY(this.properties.axes.x.plotAt, this);
+			line.setAttribute("y1", y);
+			line.setAttribute("y2", y);
+			line.setAttribute("x1",this.properties.padding.left-stroke);
+			line.setAttribute("x2",this.properties.width-this.properties.padding.right);
+			line.setAttribute("style","stroke:#000;stroke-width:"+stroke+";");
+			this.axisGroup.appendChild(line);
+			
+			//	x axis units.
+			//	(min and max)
+			var textSize=10;
+			var text = document.createElementNS(dojo.svg.xmlns.svg, "text");
+			text.setAttribute("x", this.properties.padding.left);
+			text.setAttribute("y", this.properties.height-this.properties.padding.bottom+textSize+2);
+			text.setAttribute("style", "text-anchor:middle;font-size:"+textSize+"px;fill:#000;");
+			text.appendChild(document.createTextNode(dojo.math.round(parseFloat(this.properties.axes.x.range.min),2)));
+			this.axisGroup.appendChild(text);
+			
+			var text = document.createElementNS(dojo.svg.xmlns.svg, "text");
+			text.setAttribute("x", this.properties.width-this.properties.padding.right-(textSize/2));
+			text.setAttribute("y", this.properties.height-this.properties.padding.bottom+textSize+2);
+			text.setAttribute("style", "text-anchor:middle;font-size:"+textSize+"px;fill:#000;");
+			text.appendChild(document.createTextNode(dojo.math.round(parseFloat(this.properties.axes.x.range.max),2)));
+			this.axisGroup.appendChild(text);	
+			
+			//	y axis
+			var line=document.createElementNS(dojo.svg.xmlns.svg, "line");
+			var x=dojo.widget.svg.Chart.Plotter.getX(this.properties.axes.y.plotAt, this);
+			line.setAttribute("x1", x);
+			line.setAttribute("x2", x);
+			line.setAttribute("y1", this.properties.padding.top);
+			line.setAttribute("y2", this.properties.height-this.properties.padding.bottom);
+			line.setAttribute("style", "stroke:#000;stroke-width:"+stroke+";");
+			this.axisGroup.appendChild(line);
+
+			//	y axis units
+			var text = document.createElementNS(dojo.svg.xmlns.svg, "text");
+			text.setAttribute("x", this.properties.padding.left-4);
+			text.setAttribute("y", this.properties.height-this.properties.padding.bottom);
+			text.setAttribute("style", "text-anchor:end;font-size:"+textSize+"px;fill:#000;");
+			text.appendChild(document.createTextNode(dojo.math.round(parseFloat(this.properties.axes.y.range.min),2)));
+			this.axisGroup.appendChild(text);
+			
+			var text = document.createElementNS(dojo.svg.xmlns.svg, "text");
+			text.setAttribute("x", this.properties.padding.left-4);
+			text.setAttribute("y", this.properties.padding.top+(textSize/2));
+			text.setAttribute("style", "text-anchor:end;font-size:"+textSize+"px;fill:#000;");
+			text.appendChild(document.createTextNode(dojo.math.round(parseFloat(this.properties.axes.y.range.max),2)));
+			this.axisGroup.appendChild(text);	
+			dojo.svg.g.resume();
+		},
+
+		init:function(){
+			//	get the width and the height.
+			if(!this.properties.width || !this.properties.height){
+				var box=dojo.html.getContentBox(this.domNode);
+				if(!this.properties.width){
+					this.properties.width=(box.width<32)?this.properties.defaultWidth:box.width;
+				}
+				if(!this.properties.height){
+					this.properties.height=(box.height<32)?this.properties.defaultHeight:box.height;
+				}
+			}
+
+			//	set up the chart; each is a method so that it can be selectively overridden.
+			this.drawVectorNode();
+			this.drawPlotArea();
+			this.drawDataGroup();
+			this.drawAxes();
+
+			//	this is last.
+			this.domNode.appendChild(this.vectorNode);
+			this.assignColors();
+			this._isInitialized=true;
+		},
+		destroy:function(){
+			while(this.domNode.childNodes.length>0){
+				this.domNode.removeChild(this.domNode.childNodes.item(0));
+			}
+			this.vectorNode=this.plotArea=this.dataGroup=this.axisGroup=null;
+		},
+		render:function(){
+			dojo.svg.g.suspend();
+			
+			if (this.dataGroup){
+				while(this.dataGroup.childNodes.length>0){
+					this.dataGroup.removeChild(this.dataGroup.childNodes.item(0));
+				}
+			} else {
+				this.init();
+			}
+
+			//	plot it.
+			for(var i=0; i<this.series.length; i++){
+				dojo.widget.svg.Chart.Plotter.plot(this.series[i], this);
+			}
+			dojo.svg.g.resume();
+		},
+		postCreate:function(){
+			//	begin by grabbing the table, and reading it in.
+			var table=this.domNode.getElementsByTagName("table")[0];
+			if (table){
+				var ranges=this.parseProperties(table);
+				var bRangeX=false;
+				var bRangeY=false;
+			
+				//	fix the axes
+				var axisValues = this.parseData(table);
+				if(!bRangeX){
+					this.properties.axes.x.range={min:axisValues.x.min, max:axisValues.x.max};
+				}
+				if(!bRangeY){
+					this.properties.axes.y.range={min:axisValues.y.min, max:axisValues.y.max};
+				}
+				this.setAxesPlot(table);
+
+				//	table values should be populated, now pop it off.
+				this.domNode.removeChild(table);
+			}
+			if(this.series.length>0){
+				this.render();
+			}
+		}
+	}
+);
+
+dojo.widget.svg.Chart.Plotter=new function(){
+	var self=this;
+	var plotters = {};
+	var types=dojo.widget.Chart.PlotTypes;
+	
+	this.getX=function(value, chart){
+		var v=parseFloat(value);
+		var min=chart.properties.axes.x.range.min;
+		var max=chart.properties.axes.x.range.max;
+		var ofst=0-min;
+		min+=ofst; max+=ofst; v+=ofst;
+
+		var xmin=chart.properties.padding.left;
+		var xmax=chart.properties.width-chart.properties.padding.right;
+		var x=(v*((xmax-xmin)/max))+xmin;
+		return x;
+	};
+	this.getY=function(value, chart){
+		var v=parseFloat(value);
+		var max=chart.properties.axes.y.range.max;
+		var min=chart.properties.axes.y.range.min;
+		var ofst=0;
+		if(min<0)ofst+=Math.abs(min);
+		min+=ofst; max+=ofst; v+=ofst;
+		
+		var ymin=chart.properties.height-chart.properties.padding.bottom;
+		var ymax=chart.properties.padding.top;
+		var y=(((ymin-ymax)/(max-min))*(max-v))+ymax;
+		return y;
+	};
+
+	this.addPlotter=function(name, func){
+		plotters[name]=func;
+	};
+	this.plot=function(series, chart){
+		if (series.values.length==0) return;
+		if (series.plotType && plotters[series.plotType]){
+			return plotters[series.plotType](series, chart);
+		}
+		else if (chart.plotType && plotters[chart.plotType]){
+			return plotters[chart.plotType](series, chart);
+		}
+	};
+
+	//	plotting
+	plotters["bar"]=function(series, chart){
+		var space=1;
+		var lastW = 0;
+		for (var i=0; i<series.values.length; i++){
+			var x=self.getX(series.values[i].x, chart);
+			var w;
+			if (i==series.values.length-1){
+				w=lastW;
+			} else{
+				w=self.getX(series.values[i+1].x, chart)-x-space;
+				lastW=w;
+			}
+			x-=(w/2);
+
+			var yA=self.getY(chart.properties.axes.x.plotAt, chart);
+			var y=self.getY(series.values[i].value, chart);
+			var h=Math.abs(yA-y);
+			if (parseFloat(series.values[i].value)<chart.properties.axes.x.plotAt){
+				var oy=yA;
+				yA=y;
+				y=oy;
+			}
+
+			var bar=document.createElementNS(dojo.svg.xmlns.svg, "rect");
+			bar.setAttribute("fill", series.color);
+			bar.setAttribute("title", series.label + ": " + series.values[i].value);
+			bar.setAttribute("stroke-width", "0");
+			bar.setAttribute("x", x);
+			bar.setAttribute("y", y);
+			bar.setAttribute("width", w);
+			bar.setAttribute("height", h);
+			bar.setAttribute("fill-opacity", "0.9");
+			chart.dataGroup.appendChild(bar);
+		}
+	};
+	plotters["line"]=function(series, chart){
+		var tension=1.5;
+		var line = document.createElementNS(dojo.svg.xmlns.svg, "path");
+		line.setAttribute("fill", "none");
+		line.setAttribute("stroke", series.color);
+		line.setAttribute("stroke-width", "2");
+		line.setAttribute("stroke-opacity", "0.85");
+		line.setAttribute("title", series.label);
+		chart.dataGroup.appendChild(line);
+
+		var path = [];
+		for (var i=0; i<series.values.length; i++){
+			var x = self.getX(series.values[i].x, chart)
+			var y = self.getY(series.values[i].value, chart);
+
+			var dx = chart.properties.padding.left+1;
+			var dy = chart.properties.height-chart.properties.padding.bottom;
+			if (i>0){
+				dx=x-self.getX(series.values[i-1].x, chart);
+				dy=self.getY(series.values[i-1].value, chart);
+			}
+			
+			if (i==0) path.push("M");
+			else {
+				path.push("C");
+				var cx=x-(tension-1)*(dx/tension);
+				path.push(cx+","+dy);
+				cx=x-(dx/tension);
+				path.push(cx+","+y);
+			}
+			path.push(x+","+y);
+		}
+		line.setAttribute("d", path.join(" "));
+	};
+	plotters["area"]=function(series, chart){
+		var tension=1.5;
+		var line = document.createElementNS(dojo.svg.xmlns.svg, "path");
+		line.setAttribute("fill", series.color);
+		line.setAttribute("fill-opacity", "0.4");
+		line.setAttribute("stroke", series.color);
+		line.setAttribute("stroke-width", "1");
+		line.setAttribute("stroke-opacity", "0.8");
+		line.setAttribute("title", series.label);
+		chart.dataGroup.appendChild(line);
+
+		var path = [];
+		for (var i=0; i<series.values.length; i++){
+			var x = self.getX(series.values[i].x, chart)
+			var y = self.getY(series.values[i].value, chart);
+
+			var dx = chart.properties.padding.left+1;
+			var dy = chart.properties.height-chart.properties.padding.bottom;
+			if (i>0){
+				dx=x-self.getX(series.values[i-1].x, chart);
+				dy=self.getY(series.values[i-1].value, chart);
+			}
+			
+			if (i==0) path.push("M");
+			else {
+				path.push("C");
+				var cx=x-(tension-1)*(dx/tension);
+				path.push(cx+","+dy);
+				cx=x-(dx/tension);
+				path.push(cx+","+y);
+			}
+			path.push(x+","+y);
+		}
+		//	finish it off
+		path.push("L");
+		path.push(x + "," + self.getY(0, chart));
+		path.push("L");
+		path.push(self.getX(0, chart) + "," + self.getY(0, chart));
+		path.push("Z");
+		line.setAttribute("d", path.join(" "));
+	},
+	plotters["scatter"]=function(series, chart){
+		var r=7;
+		for (var i=0; i<series.values.length; i++){
+			var x=self.getX(series.values[i].x, chart);
+			var y=self.getY(series.values[i].value, chart);
+			var point = document.createElementNS(dojo.svg.xmlns.svg, "path");
+			point.setAttribute("fill", series.color);
+			point.setAttribute("stroke-width", "0");
+			point.setAttribute("title", series.label + ": " + series.values[i].value);
+			point.setAttribute("d",
+				"M " + x + "," + (y-r) + " " +
+				"Q " + x + "," + y + " " + (x+r) + "," + y + " " +
+				"Q " + x + "," + y + " " + x + "," + (y+r) + " " +
+				"Q " + x + "," + y + " " + (x-r) + "," + y + " " +
+				"Q " + x + "," + y + " " + x + "," + (y-r) + " " +
+				"Z"
+			);
+			chart.dataGroup.appendChild(point);
+		}
+	};
+	plotters["bubble"]=function(series, chart){
+		//	added param for series[n].value: size
+		var minR=1;
+		
+		//	do this off the x axis?
+		var min=chart.properties.axes.x.range.min;
+		var max=chart.properties.axes.x.range.max;
+		var ofst=0-min;
+		min+=ofst; max+=ofst;
+
+		var xmin=chart.properties.padding.left;
+		var xmax=chart.properties.width-chart.properties.padding.right;
+		var factor=(max-min)/(xmax-xmin)*25;
+		
+		for (var i=0; i<series.values.length; i++){
+			var size = series.values[i].size;
+			if (isNaN(parseFloat(size))) size=minR;
+			var point=document.createElementNS(dojo.svg.xmlns.svg, "circle");
+			point.setAttribute("stroke-width", 0);
+			point.setAttribute("fill", series.color);
+			point.setAttribute("fill-opacity", "0.8");
+			point.setAttribute("r", (parseFloat(size)*factor)/2);
+			point.setAttribute("cx", self.getX(series.values[i].x, chart));
+			point.setAttribute("cy", self.getY(series.values[i].value, chart));
+			point.setAttribute("title", series.label + ": " + series.values[i].value + " (" + size + ")");
+			chart.dataGroup.appendChild(point);
+		}
+	};
+}();

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

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/ButtonTemplate.css
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/ButtonTemplate.css?view=auto&rev=449122
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/ButtonTemplate.css (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/ButtonTemplate.css Fri Sep 22 16:22:30 2006
@@ -0,0 +1,59 @@
+/* ---- button --- */
+.dojoButton {
+	padding: 0 0 0 0;
+	font-size: 8pt;
+	white-space: nowrap;
+	cursor: pointer;
+	font-family: Myriad, Tahoma, Verdana, sans-serif;
+}
+
+.dojoButton .dojoButtonContents {
+	padding: 2px 2px 2px 2px;
+	text-align: center;		/* if icon and label are split across two lines, center icon */
+	color: white;
+}
+
+.dojoButtonLeftPart .dojoButtonContents {
+	padding-right: 8px;
+}
+
+.dojoButtonDisabled {
+	cursor: url("images/no.gif"), default;
+}
+
+
+.dojoButtonContents img {
+	vertical-align: middle;	/* if icon and label are on same line, center them */
+}
+
+/* -------- colors ------------ */
+
+.dojoButtonHover .dojoButtonContents {
+}
+
+.dojoButtonDepressed .dojoButtonContents {
+	color: #293a4b;
+}
+
+.dojoButtonDisabled .dojoButtonContents {
+	color: #eeeeee;
+}
+
+
+/* ---------- drop down button specific ---------- */
+
+/* border between label and arrow (for drop down buttons */
+.dojoButton .border {
+	width: 1px;
+	background: gray;
+}
+
+/* button arrow */
+.dojoButton .downArrow {
+	padding-left: 10px;
+	text-align: center;
+}
+
+.dojoButton.disabled .downArrow {
+	cursor : default;
+}
\ No newline at end of file

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

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/ButtonTemplate.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/ButtonTemplate.html?view=auto&rev=449122
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/ButtonTemplate.html (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/ButtonTemplate.html Fri Sep 22 16:22:30 2006
@@ -0,0 +1,6 @@
+<div dojoAttachPoint="buttonNode" class="dojoButton" style="position:relative;" dojoAttachEvent="onMouseOver; onMouseOut; onMouseDown; onMouseUp; onClick:buttonClick; onKey:onKey; onFocus;">
+  <div class="dojoButtonContents" align=center dojoAttachPoint="containerNode" style="position:absolute;z-index:2;"></div>
+  <img dojoAttachPoint="leftImage" style="position:absolute;left:0px;">
+  <img dojoAttachPoint="centerImage" style="position:absolute;z-index:1;">
+  <img dojoAttachPoint="rightImage" style="position:absolute;top:0px;right:0px;">
+</div>

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

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/Checkbox.css
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/Checkbox.css?view=auto&rev=449122
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/Checkbox.css (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/Checkbox.css Fri Sep 22 16:22:30 2006
@@ -0,0 +1,27 @@
+.dojoHtmlCheckbox {
+	border: 0px;
+	width: 20px;
+	height: 20px;
+	display: -moz-inline-box;
+	display: inline-block;
+	margin-right: 5px;
+}
+
+.dojoHtmlCheckboxOn {
+	background: url(check.gif) 0px 0px;
+}
+.dojoHtmlCheckboxOff {
+	background: url(check.gif) -20px 0px;
+}
+.dojoHtmlCheckboxDisabledOn {
+	background: url(check.gif) -40px 0px;
+}
+.dojoHtmlCheckboxDisabledOff {
+	background: url(check.gif) -60px 0px;
+}
+.dojoHtmlCheckboxOnHover {
+	background: url(check.gif) -80px 0px;
+}
+.dojoHtmlCheckboxOffHover {
+	background: url(check.gif) -100px 0px;
+}
\ No newline at end of file

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

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/Checkbox.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/Checkbox.html?view=auto&rev=449122
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/Checkbox.html (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/Checkbox.html Fri Sep 22 16:22:30 2006
@@ -0,0 +1,5 @@
+<span class='dojoHtmlCheckbox' tabIndex="${this.tabIndex}"  dojoAttachEvent="mouseOver; mouseOut; onKey; onClick: _onClick;" waiRole="checkbox" id="${this.id}">
+	<input type="checkbox" name="${this.name}" style="display: none" ${this.checkedStr} value="${this.value}"
+		dojoAttachPoint="inputNode">
+	&nbsp;
+</span>

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

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/CheckboxA11y.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/CheckboxA11y.html?view=auto&rev=449122
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/CheckboxA11y.html (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/CheckboxA11y.html Fri Sep 22 16:22:30 2006
@@ -0,0 +1,4 @@
+<span class='dojoHtmlCheckbox'>
+	<input type="checkbox" name="${this.name}" tabIndex="${this.tabIndex}" ${this.disabledStr} id="${this.id}" ${this.checkedStr} value="${this.value}"
+		 dojoAttachEvent="onClick: _onClick;" dojoAttachPoint="inputNode"> 
+</span>

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

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/CiviCrmDatePicker.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/CiviCrmDatePicker.html?view=auto&rev=449122
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/CiviCrmDatePicker.html (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/CiviCrmDatePicker.html Fri Sep 22 16:22:30 2006
@@ -0,0 +1,12 @@
+<table cellpadding="0" cellspacing="0" border="0" width="400">
+	<tr>
+		<td id="dateHolderTd" width="200">
+		</td>
+		<td id="timeHolderTd" width="200">
+		</td>
+	</tr>
+	<tr style="display: none;" id="formItemsTr">
+		<td id="formItemsTd">&nbsp;</td>
+		<td>&nbsp;</td>
+	</tr>
+</table>

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

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/ComboBox.css
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/ComboBox.css?view=auto&rev=449122
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/ComboBox.css (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/ComboBox.css Fri Sep 22 16:22:30 2006
@@ -0,0 +1,54 @@
+/* the table holding the input and the button */
+.dojoComboBox {
+	border: 1px solid #afafaf;
+	padding: 0px;
+	line-height: 0px;
+	display: inline;	/* for IE and safari */
+}
+
+.dj_gecko .dojoComboBox {
+	display: -moz-inline-box;
+}
+
+.dj_opera .dojoComboBox {
+	display: inline-table;
+}
+
+/* the input box */
+input.dojoComboBoxInput {
+	/* font-size: 0.8em; */
+	border: 0px;
+	margin: 0px;
+	padding: 0px;
+}
+
+/* the drop down */
+.dojoComboBoxOptions {
+	font-family: Verdana, Helvetica, Garamond, sans-serif;
+	/* font-size: 0.7em; */
+	background-color: white;
+	border: 1px solid #afafaf;
+	position: absolute;
+	z-index: 1000; 
+	overflow: auto;
+	cursor: default;
+}
+
+.dojoComboBoxItem {
+	padding-left: 2px;
+	padding-top: 2px;
+	margin: 0px;
+}
+
+.dojoComboBoxItemEven {
+	background-color: #f4f4f4;
+}
+
+.dojoComboBoxItemOdd {
+	background-color: white;
+}
+
+.dojoComboBoxItemHighlight {
+	background-color: #63709A;
+	color: white;
+}

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

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/ComboBox.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/ComboBox.html?view=auto&rev=449122
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/ComboBox.html (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/ComboBox.html Fri Sep 22 16:22:30 2006
@@ -0,0 +1,25 @@
+<span>
+	<input style="display:none"  tabindex="-1" name="" value="" 
+		dojoAttachPoint="comboBoxValue">
+	<input style="display:none"  tabindex="-1" name="" value="" 
+		dojoAttachPoint="comboBoxSelectionValue">
+	<table class="dojoComboBox"
+		cellpadding="0"
+		cellspacing="0"
+		border="0"
+		dojoAttachPoint="cbTableNode">
+		<tr>
+			<td><input type="text" autocomplete="off" class="dojoComboBoxInput"
+					dojoAttachEvent="key:_handleKeyEvents; keyUp: onKeyUp; compositionEnd; onResize"
+					dojoAttachPoint="textInputNode"></td>
+			<td><img border="0" 
+					hspace="0"
+					vspace="0"
+					class="dojoComboArrow"
+					dojoAttachPoint="downArrowNode"
+					dojoAttachEvent="onMouseUp: handleArrowClick;"
+					src="${this.buttonSrc}"
+					style="width: ${this.initialButtonSize}; height: ${this.initialButtonSize};"></td>
+		</tr>
+	</table>
+</span>

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

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/ComboButtonTemplate.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/ComboButtonTemplate.html?view=auto&rev=449122
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/ComboButtonTemplate.html (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/ComboButtonTemplate.html Fri Sep 22 16:22:30 2006
@@ -0,0 +1,18 @@
+<div class="dojoButton" style="position:relative;top:0px;left:0px; text-align:none;" dojoAttachEvent="onKey;onFocus">
+
+	<div dojoAttachPoint="buttonNode" class="dojoButtonLeftPart" style="position:absolute;left:0px;top:0px;"
+		dojoAttachEvent="onMouseOver; onMouseOut; onMouseDown; onMouseUp; onClick:buttonClick;">
+		<div class="dojoButtonContents" dojoAttachPoint="containerNode" style="position:absolute;top:0px;right:0px;z-index:2;"></div>
+		<img dojoAttachPoint="leftImage" style="position:absolute;left:0px;top:0px;">
+		<img dojoAttachPoint="centerImage" style="position:absolute;right:0px;top:0px;z-index:1;">
+	</div>
+
+	<div dojoAttachPoint="rightPart" class="dojoButtonRightPart" style="position:absolute;top:0px;right:0px;"
+		dojoAttachEvent="onMouseOver:rightOver; onMouseOut:rightOut; onMouseDown:rightDown; onMouseUp:rightUp; onClick:rightClick;">
+		<img dojoAttachPoint="arrowBackgroundImage" style="position:absolute;top:0px;left:0px;z-index:1;">
+		<img src="${dojoRoot}src/widget/templates/images/whiteDownArrow.gif"
+		  		style="z-index:2;position:absolute;left:3px;top:50%;">
+		<img dojoAttachPoint="rightImage" style="position:absolute;top:0px;right:0px;">
+	</div>
+
+</div>

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

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/DatePicker.css
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/DatePicker.css?view=auto&rev=449122
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/DatePicker.css (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/DatePicker.css Fri Sep 22 16:22:30 2006
@@ -0,0 +1,159 @@
+.datePickerContainer {
+	width:160px; /* needed for proper user styling */
+}
+
+.calendarContainer {
+/*	border:1px solid #566f8f;*/
+}
+
+.calendarBodyContainer {
+	width:160px; /* needed for the explode effect */
+	background: #7591bc url("images/dpBg.gif") top left repeat-x;
+}
+
+.calendarBodyContainer thead tr td {
+	color:#293a4b;
+	font:bold 0.75em Helvetica, Arial, Verdana, sans-serif;
+	text-align:center;
+	padding:0.25em;
+	background: url("images/dpHorizLine.gif") bottom left repeat-x;
+}
+
+.calendarBodyContainer tbody tr td {
+	color:#fff;
+	font:bold 0.7em Helvetica, Arial, Verdana, sans-serif;
+	text-align:center;
+	padding:0.4em;
+	background: url("images/dpVertLine.gif") top right repeat-y;
+	cursor:pointer;
+	cursor:hand;
+}
+
+
+.monthWrapper {
+	padding-bottom:2px;
+	background: url("images/dpHorizLine.gif") bottom left repeat-x;
+}
+
+.monthContainer {
+	width:100%;
+}
+
+.monthLabelContainer {
+	text-align:center;
+	font:bold 0.75em Helvetica, Arial, Verdana, sans-serif;
+	background: url("images/dpMonthBg.png") repeat-x top left !important;
+	color:#293a4b;
+	padding:0.25em;
+}
+
+.monthCurve {
+	width:12px;
+}
+
+.monthCurveTL {
+	background: url("images/dpCurveTL.png") no-repeat top left !important;
+}
+
+.monthCurveTR {
+		background: url("images/dpCurveTR.png") no-repeat top right !important;
+}
+
+
+.yearWrapper {
+	background: url("images/dpHorizLineFoot.gif") top left repeat-x;
+	padding-top:2px;
+}
+
+.yearContainer {
+	width:100%;
+}
+
+.yearContainer td {
+	background:url("images/dpYearBg.png") top left repeat-x;
+}
+
+.yearContainer .yearLabel {
+	margin:0;
+	padding:0.45em 0 0.45em 0;
+	color:#fff;
+	font:bold 0.75em Helvetica, Arial, Verdana, sans-serif;
+	text-align:center;
+}
+
+.curveBL {
+	background: url("images/dpCurveBL.png") bottom left no-repeat !important;
+	width:9px !important;
+	padding:0;
+	margin:0;
+}
+
+.curveBR {
+	background: url("images/dpCurveBR.png") bottom right no-repeat !important;
+	width:9px !important;
+	padding:0;
+	margin:0;
+}
+
+
+.previousMonth {
+	background-color:#6782a8 !important;
+}
+
+.previousMonthDisabled {
+	background-color:#a4a5a6 !important;
+	cursor:default !important
+}
+.currentMonth {
+}
+
+.currentMonthDisabled {
+	background-color:#bbbbbc !important;
+	cursor:default !important
+}
+.nextMonth {
+	background-color:#6782a8 !important;
+}
+.nextMonthDisabled {
+	background-color:#a4a5a6 !important;
+	cursor:default !important;
+}
+
+.currentDate {
+	text-decoration:underline;
+	font-style:italic;
+}
+
+.selectedItem {
+	background-color:#fff !important;
+	color:#6782a8 !important;
+}
+
+.yearLabel .selectedYear {
+	padding:0.2em;
+	background-color:#9ec3fb !important;
+}
+
+.nextYear, .previousYear {
+	cursor:pointer;cursor:hand;
+	margin:0 0.55em;
+}
+
+.incrementControl {
+	cursor:pointer;cursor:hand;
+	width:1em;
+}
+
+.increase {
+	float:right;
+}
+
+.decrease {
+	float:left;
+}
+
+.lastColumn {
+	background-image:none !important;
+}
+
+

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

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/DatePicker.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/DatePicker.html?view=auto&rev=449122
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/DatePicker.html (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/DatePicker.html Fri Sep 22 16:22:30 2006
@@ -0,0 +1,96 @@
+<div class="datePickerContainer" dojoAttachPoint="datePickerContainerNode">
+	<table cellspacing="0" cellpadding="0" class="calendarContainer">
+		<thead>
+			<tr>
+				<td class="monthWrapper" valign="top">
+					<table class="monthContainer" cellspacing="0" cellpadding="0" border="0">
+						<tr>
+							<td class="monthCurve monthCurveTL" valign="top"></td>
+							<td class="monthLabelContainer" valign="top">
+								<span dojoAttachPoint="increaseWeekNode" 
+									dojoAttachEvent="onClick: onIncrementWeek;" 
+									class="incrementControl increase">
+									<img src="${dojoRoot}src/widget/templates/images/incrementMonth.png" 
+									alt="&darr;" style="width:7px;height:5px;" />
+								</span>
+								<span 
+									dojoAttachPoint="increaseMonthNode" 
+									dojoAttachEvent="onClick: onIncrementMonth;" class="incrementControl increase">
+									<img src="${dojoRoot}src/widget/templates/images/incrementMonth.png" 
+										alt="&darr;"  dojoAttachPoint="incrementMonthImageNode">
+								</span>
+								<span 
+									dojoAttachPoint="decreaseWeekNode" 
+									dojoAttachEvent="onClick: onIncrementWeek;" 
+									class="incrementControl decrease">
+									<img src="${dojoRoot}src/widget/templates/images/decrementMonth.png" alt="&uarr;" style="width:7px;height:5px;" />
+								</span>
+								<span 
+									dojoAttachPoint="decreaseMonthNode" 
+									dojoAttachEvent="onClick: onIncrementMonth;" class="incrementControl decrease">
+									<img src="${dojoRoot}src/widget/templates/images/decrementMonth.png" 
+										alt="&uarr;" dojoAttachPoint="decrementMonthImageNode">
+								</span>
+								<span dojoAttachPoint="monthLabelNode" class="month">July</span>
+							</td>
+							<td class="monthCurve monthCurveTR" valign="top"></td>
+						</tr>
+					</table>
+				</td>
+			</tr>
+		</thead>
+		<tbody>
+			<tr>
+				<td colspan="3">
+					<table class="calendarBodyContainer" cellspacing="0" cellpadding="0" border="0">
+						<thead>
+							<tr dojoAttachPoint="dayLabelsRow">
+								<td></td>
+								<td></td>
+								<td></td>
+								<td></td>
+								<td></td>
+								<td></td>
+								<td></td>
+							</tr>
+						</thead>
+						<tbody dojoAttachPoint="calendarDatesContainerNode" 
+							dojoAttachEvent="onClick: _handleUiClick;">
+							<tr dojoAttachPoint="calendarWeekTemplate">
+								<td></td>
+								<td></td>
+								<td></td>
+								<td></td>
+								<td></td>
+								<td></td>
+								<td></td>
+							</tr>
+						</tbody>
+					</table>
+				</td>
+			</tr>
+		</tbody>
+		<tfoot>
+			<tr>
+				<td colspan="3" class="yearWrapper">
+					<table cellspacing="0" cellpadding="0" border="0" class="yearContainer">
+						<tr>
+							<td class="curveBL" valign="top"></td>
+							<td valign="top">
+								<h3 class="yearLabel">
+									<span dojoAttachPoint="previousYearLabelNode"
+										dojoAttachEvent="onClick: onIncrementYear;" class="previousYear"></span>
+									<span class="selectedYear" dojoAttachPoint="currentYearLabelNode"></span>
+									<span dojoAttachPoint="nextYearLabelNode" 
+										dojoAttachEvent="onClick: onIncrementYear;" class="nextYear"></span>
+								</h3>
+							</td>
+							<td class="curveBR" valign="top"></td>
+						</tr>
+					</table>
+				</td>
+			</tr>
+		</tfoot>
+	</table>
+	
+</div>

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

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/DemoEngine.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/DemoEngine.html?view=auto&rev=449122
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/DemoEngine.html (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/DemoEngine.html Fri Sep 22 16:22:30 2006
@@ -0,0 +1,24 @@
+<div dojoAttachPoint="domNode">
+	<div dojoAttachPoint="navigationNode">
+		<table border="0" cellspacing="0" cellpadding="0">
+			<tr>
+				<td width="1%" valign="top" class="navigationCell"><h1>Categories</h1><div dojoAttachPoint="menuNavigationNode"></div></td>
+				<td width="99%" valign="top">
+					<div dojoAttachPoint="demoNavigationNode">
+					</div>
+				</td>
+			</tr>
+		</table>
+	</div>
+
+	<div dojoAttachPoint="demoContainerNode">
+
+		<div dojoAttachPoint="demoPaneNode">
+		</div>
+
+		<div dojoAttachPoint="demoHeaderNode">
+			<span dojoAttachPoint="collapsedMenuNode" dojoAttachEvent="onclick: expandDemoNavigation"></span>
+			<div dojoAttachPoint="aboutNode">About this Demo</div>
+		</div>
+	</div>
+</div>

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

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/Dialog.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/Dialog.html?view=auto&rev=449122
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/Dialog.html (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/templates/Dialog.html Fri Sep 22 16:22:30 2006
@@ -0,0 +1,7 @@
+<div id="${this.widgetId}" class="dojoDialog" dojoattachpoint="wrapper">
+	<span dojoattachpoint="tabStartOuter" dojoonfocus="trapTabs" dojoonblur="clearTrap"	tabindex="0"></span>
+	<span dojoattachpoint="tabStart" dojoonfocus="trapTabs" dojoonblur="clearTrap" tabindex="0"></span>
+	<div dojoattachpoint="containerNode" style="position: relative; z-index: 2;"></div>
+	<span dojoattachpoint="tabEnd" dojoonfocus="trapTabs" dojoonblur="clearTrap" tabindex="0"></span>
+	<span dojoattachpoint="tabEndOuter" dojoonfocus="trapTabs" dojoonblur="clearTrap" tabindex="0"></span>
+</div>

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