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

svn commit: r413306 [14/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/widget/Widget.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/Widget.js?rev=413306&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/Widget.js (added)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/Widget.js Sat Jun 10 07:27:44 2006
@@ -0,0 +1,578 @@
+/*
+	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.Widget");
+dojo.provide("dojo.widget.tags");
+
+dojo.require("dojo.lang.func");
+dojo.require("dojo.lang.array");
+dojo.require("dojo.lang.extras");
+dojo.require("dojo.lang.declare");
+dojo.require("dojo.widget.Manager");
+dojo.require("dojo.event.*");
+
+dojo.declare("dojo.widget.Widget", null, {
+	initializer: function() {								 
+		// these properties aren't primitives and need to be created on a per-item
+		// basis.
+		this.children = [];
+		// this.selection = new dojo.widget.Selection();
+		// FIXME: need to replace this with context menu stuff
+		this.extraArgs = {};
+	},
+	// FIXME: need to be able to disambiguate what our rendering context is
+	//        here!
+	//
+	// needs to be a string with the end classname. Every subclass MUST
+	// over-ride.
+	//
+	// base widget properties
+	parent: null,
+	// obviously, top-level and modal widgets should set these appropriately
+	isTopLevel:  false,
+	isModal: false,
+
+	isEnabled: true,
+	isHidden: false,
+	isContainer: false, // can we contain other widgets?
+	widgetId: "",
+	widgetType: "Widget", // used for building generic widgets
+
+	toString: function() {
+		return '[Widget ' + this.widgetType + ', ' + (this.widgetId || 'NO ID') + ']';
+	},
+
+	repr: function(){
+		return this.toString();
+	},
+
+	enable: function(){
+		// should be over-ridden
+		this.isEnabled = true;
+	},
+
+	disable: function(){
+		// should be over-ridden
+		this.isEnabled = false;
+	},
+
+	hide: function(){
+		// should be over-ridden
+		this.isHidden = true;
+	},
+
+	show: function(){
+		// should be over-ridden
+		this.isHidden = false;
+	},
+
+	onResized: function(){
+		// Clients should override this function to do special processing,
+		// then call this.notifyChildrenOfResize() to notify children of resize
+		this.notifyChildrenOfResize();
+	},
+	
+	notifyChildrenOfResize: function(){
+		for(var i=0; i<this.children.length; i++){
+			var child = this.children[i];
+			//dojo.debug(this.widgetId + " resizing child " + child.widgetId);
+			if( child.onResized ){
+				child.onResized();
+			}
+		}
+	},
+
+	create: function(args, fragment, parentComp){
+		// dojo.debug(this.widgetType, "create");
+		this.satisfyPropertySets(args, fragment, parentComp);
+		// dojo.debug(this.widgetType, "-> mixInProperties");
+		this.mixInProperties(args, fragment, parentComp);
+		// dojo.debug(this.widgetType, "-> postMixInProperties");
+		this.postMixInProperties(args, fragment, parentComp);
+		// dojo.debug(this.widgetType, "-> dojo.widget.manager.add");
+		dojo.widget.manager.add(this);
+		// dojo.debug(this.widgetType, "-> buildRendering");
+		this.buildRendering(args, fragment, parentComp);
+		// dojo.debug(this.widgetType, "-> initialize");
+		this.initialize(args, fragment, parentComp);
+		// dojo.debug(this.widgetType, "-> postInitialize");
+		this.postInitialize(args, fragment, parentComp);
+		// dojo.debug(this.widgetType, "-> postCreate");
+		this.postCreate(args, fragment, parentComp);
+		// dojo.debug(this.widgetType, "done!");
+		return this;
+	},
+
+	// Destroy this widget and it's descendants
+	destroy: function(finalize){
+		// FIXME: this is woefully incomplete
+		this.destroyChildren();
+		this.uninitialize();
+		this.destroyRendering(finalize);
+		dojo.widget.manager.removeById(this.widgetId);
+	},
+
+	// Destroy the children of this widget, and their descendents
+	destroyChildren: function(){
+		while(this.children.length > 0){
+			var tc = this.children[0];
+			this.removeChild(tc);
+			tc.destroy();
+		}
+	},
+
+	getChildrenOfType: function(type, recurse){
+		var ret = [];
+		var isFunc = dojo.lang.isFunction(type);
+		if(!isFunc){
+			type = type.toLowerCase();
+		}
+		for(var x=0; x<this.children.length; x++){
+			if(isFunc){
+				if(this.children[x] instanceof type){
+					ret.push(this.children[x]);
+				}
+			}else{
+				if(this.children[x].widgetType.toLowerCase() == type){
+					ret.push(this.children[x]);
+				}
+			}
+			if(recurse){
+				ret = ret.concat(this.children[x].getChildrenOfType(type, recurse));
+			}
+		}
+		return ret;
+	},
+
+	getDescendants: function(){
+		var result = [];
+		var stack = [this];
+		var elem;
+		while (elem = stack.pop()){
+			result.push(elem);
+			dojo.lang.forEach(elem.children, function(elem) { stack.push(elem); });
+		}
+		return result;
+	},
+
+	satisfyPropertySets: function(args){
+		// dojo.profile.start("satisfyPropertySets");
+		// get the default propsets for our component type
+		/*
+		var typePropSets = []; // FIXME: need to pull these from somewhere!
+		var localPropSets = []; // pull out propsets from the parser's return structure
+
+		// for(var x=0; x<args.length; x++){
+		// }
+
+		for(var x=0; x<typePropSets.length; x++){
+		}
+
+		for(var x=0; x<localPropSets.length; x++){
+		}
+		*/
+		// dojo.profile.end("satisfyPropertySets");
+		
+		return args;
+	},
+
+	mixInProperties: function(args, frag){
+		if((args["fastMixIn"])||(frag["fastMixIn"])){
+			// dojo.profile.start("mixInProperties_fastMixIn");
+			// fast mix in assumes case sensitivity, no type casting, etc...
+			// dojo.lang.mixin(this, args);
+			for(var x in args){
+				this[x] = args[x];
+			}
+			// dojo.profile.end("mixInProperties_fastMixIn");
+			return;
+		}
+		// dojo.profile.start("mixInProperties");
+		/*
+		 * the actual mix-in code attempts to do some type-assignment based on
+		 * PRE-EXISTING properties of the "this" object. When a named property
+		 * of a propset is located, it is first tested to make sure that the
+		 * current object already "has one". Properties which are undefined in
+		 * the base widget are NOT settable here. The next step is to try to
+		 * determine type of the pre-existing property. If it's a string, the
+		 * property value is simply assigned. If a function, the property is
+		 * replaced with a "new Function()" declaration. If an Array, the
+		 * system attempts to split the string value on ";" chars, and no
+		 * further processing is attempted (conversion of array elements to a
+		 * integers, for instance). If the property value is an Object
+		 * (testObj.constructor === Object), the property is split first on ";"
+		 * chars, secondly on ":" chars, and the resulting key/value pairs are
+		 * assigned to an object in a map style. The onus is on the property
+		 * user to ensure that all property values are converted to the
+		 * expected type before usage.
+		 */
+
+		var undef;
+
+		// NOTE: we cannot assume that the passed properties are case-correct
+		// (esp due to some browser bugs). Therefore, we attempt to locate
+		// properties for assignment regardless of case. This may cause
+		// problematic assignments and bugs in the future and will need to be
+		// documented with big bright neon lights.
+
+		// FIXME: fails miserably if a mixin property has a default value of null in 
+		// a widget
+
+		// NOTE: caching lower-cased args in the prototype is only 
+		// acceptable if the properties are invariant.
+		// if we have a name-cache, get it
+		var lcArgs = dojo.widget.lcArgsCache[this.widgetType];
+		if ( lcArgs == null ){
+			// build a lower-case property name cache if we don't have one
+			lcArgs = {};
+			for(var y in this){
+				lcArgs[((new String(y)).toLowerCase())] = y;
+			}
+			dojo.widget.lcArgsCache[this.widgetType] = lcArgs;
+		}
+		var visited = {};
+		for(var x in args){
+			if(!this[x]){ // check the cache for properties
+				var y = lcArgs[(new String(x)).toLowerCase()];
+				if(y){
+					args[y] = args[x];
+					x = y; 
+				}
+			}
+			if(visited[x]){ continue; }
+			visited[x] = true;
+			if((typeof this[x]) != (typeof undef)){
+				if(typeof args[x] != "string"){
+					this[x] = args[x];
+				}else{
+					if(dojo.lang.isString(this[x])){
+						this[x] = args[x];
+					}else if(dojo.lang.isNumber(this[x])){
+						this[x] = new Number(args[x]); // FIXME: what if NaN is the result?
+					}else if(dojo.lang.isBoolean(this[x])){
+						this[x] = (args[x].toLowerCase()=="false") ? false : true;
+					}else if(dojo.lang.isFunction(this[x])){
+
+						// FIXME: need to determine if always over-writing instead
+						// of attaching here is appropriate. I suspect that we
+						// might want to only allow attaching w/ action items.
+						
+						// RAR, 1/19/05: I'm going to attach instead of
+						// over-write here. Perhaps function objects could have
+						// some sort of flag set on them? Or mixed-into objects
+						// could have some list of non-mutable properties
+						// (although I'm not sure how that would alleviate this
+						// particular problem)? 
+
+						// this[x] = new Function(args[x]);
+
+						// after an IRC discussion last week, it was decided
+						// that these event handlers should execute in the
+						// context of the widget, so that the "this" pointer
+						// takes correctly.
+						
+						// argument that contains no punctuation other than . is 
+						// considered a function spec, not code
+						if(args[x].search(/[^\w\.]+/i) == -1){
+							this[x] = dojo.evalObjPath(args[x], false);
+						}else{
+							var tn = dojo.lang.nameAnonFunc(new Function(args[x]), this);
+							dojo.event.connect(this, x, this, tn);
+						}
+					}else if(dojo.lang.isArray(this[x])){ // typeof [] == "object"
+						this[x] = args[x].split(";");
+					} else if (this[x] instanceof Date) {
+						this[x] = new Date(Number(args[x])); // assume timestamp
+					}else if(typeof this[x] == "object"){ 
+						// FIXME: should we be allowing extension here to handle
+						// other object types intelligently?
+
+						// if we defined a URI, we probablt want to allow plain strings
+						// to override it
+						if (this[x] instanceof dojo.uri.Uri){
+
+							this[x] = args[x];
+						}else{
+
+							// FIXME: unlike all other types, we do not replace the
+							// object with a new one here. Should we change that?
+							var pairs = args[x].split(";");
+							for(var y=0; y<pairs.length; y++){
+								var si = pairs[y].indexOf(":");
+								if((si != -1)&&(pairs[y].length>si)){
+									this[x][pairs[y].substr(0, si).replace(/^\s+|\s+$/g, "")] = pairs[y].substr(si+1);
+								}
+							}
+						}
+					}else{
+						// the default is straight-up string assignment. When would
+						// we ever hit this?
+						this[x] = args[x];
+					}
+				}
+			}else{
+				// collect any extra 'non mixed in' args
+				this.extraArgs[x.toLowerCase()] = args[x];
+			}
+		}
+		// dojo.profile.end("mixInProperties");
+	},
+	
+	postMixInProperties: function(){
+	},
+
+	initialize: function(args, frag){
+		// dojo.unimplemented("dojo.widget.Widget.initialize");
+		return false;
+	},
+
+	postInitialize: function(args, frag){
+		return false;
+	},
+
+	postCreate: function(args, frag){
+		return false;
+	},
+
+	uninitialize: function(){
+		// dojo.unimplemented("dojo.widget.Widget.uninitialize");
+		return false;
+	},
+
+	buildRendering: function(){
+		// SUBCLASSES MUST IMPLEMENT
+		dojo.unimplemented("dojo.widget.Widget.buildRendering, on "+this.toString()+", ");
+		return false;
+	},
+
+	destroyRendering: function(){
+		// SUBCLASSES MUST IMPLEMENT
+		dojo.unimplemented("dojo.widget.Widget.destroyRendering");
+		return false;
+	},
+
+	cleanUp: function(){
+		// SUBCLASSES MUST IMPLEMENT
+		dojo.unimplemented("dojo.widget.Widget.cleanUp");
+		return false;
+	},
+
+	addedTo: function(parent){
+		// this is just a signal that can be caught
+	},
+
+	addChild: function(child){
+		// SUBCLASSES MUST IMPLEMENT
+		dojo.unimplemented("dojo.widget.Widget.addChild");
+		return false;
+	},
+
+	// Detach the given child widget from me, but don't destroy it
+	removeChild: function(widget){
+		for(var x=0; x<this.children.length; x++){
+			if(this.children[x] === widget){
+				this.children.splice(x, 1);
+				break;
+			}
+		}
+		return widget;
+	},
+
+	resize: function(width, height){
+		// both width and height may be set as percentages. The setWidth and
+		// setHeight  functions attempt to determine if the passed param is
+		// specified in percentage or native units. Integers without a
+		// measurement are assumed to be in the native unit of measure.
+		this.setWidth(width);
+		this.setHeight(height);
+	},
+
+	setWidth: function(width){
+		if((typeof width == "string")&&(width.substr(-1) == "%")){
+			this.setPercentageWidth(width);
+		}else{
+			this.setNativeWidth(width);
+		}
+	},
+
+	setHeight: function(height){
+		if((typeof height == "string")&&(height.substr(-1) == "%")){
+			this.setPercentageHeight(height);
+		}else{
+			this.setNativeHeight(height);
+		}
+	},
+
+	setPercentageHeight: function(height){
+		// SUBCLASSES MUST IMPLEMENT
+		return false;
+	},
+
+	setNativeHeight: function(height){
+		// SUBCLASSES MUST IMPLEMENT
+		return false;
+	},
+
+	setPercentageWidth: function(width){
+		// SUBCLASSES MUST IMPLEMENT
+		return false;
+	},
+
+	setNativeWidth: function(width){
+		// SUBCLASSES MUST IMPLEMENT
+		return false;
+	},
+
+	getPreviousSibling: function() {
+		var idx = this.getParentIndex();
+ 
+		 // first node is idx=0 not found is idx<0
+		if (idx<=0) return null;
+ 
+		return this.getSiblings()[idx-1];
+	},
+ 
+	getSiblings: function() {
+		return this.parent.children;
+	},
+ 
+	getParentIndex: function() {
+		return dojo.lang.indexOf( this.getSiblings(), this, true);
+	},
+ 
+	getNextSibling: function() {
+ 
+		var idx = this.getParentIndex();
+ 
+		if (idx == this.getSiblings().length-1) return null; // last node
+		if (idx < 0) return null; // not found
+ 
+		return this.getSiblings()[idx+1];
+ 
+	}
+});
+
+// Lower case name cache: listing of the lower case elements in each widget.
+// We can't store the lcArgs in the widget itself because if B subclasses A,
+// then B.prototype.lcArgs might return A.prototype.lcArgs, which is not what we
+// want
+dojo.widget.lcArgsCache = {};
+
+// TODO: should have a more general way to add tags or tag libraries?
+// TODO: need a default tags class to inherit from for things like getting propertySets
+// TODO: parse properties/propertySets into component attributes
+// TODO: parse subcomponents
+// TODO: copy/clone raw markup fragments/nodes as appropriate
+dojo.widget.tags = {};
+dojo.widget.tags.addParseTreeHandler = function(type){
+	var ltype = type.toLowerCase();
+	this[ltype] = function(fragment, widgetParser, parentComp, insertionIndex, localProps){ 
+		return dojo.widget.buildWidgetFromParseTree(ltype, fragment, widgetParser, parentComp, insertionIndex, localProps);
+	}
+}
+dojo.widget.tags.addParseTreeHandler("dojo:widget");
+
+dojo.widget.tags["dojo:propertyset"] = function(fragment, widgetParser, parentComp){
+	// FIXME: Is this needed?
+	// FIXME: Not sure that this parses into the structure that I want it to parse into...
+	// FIXME: add support for nested propertySets
+	var properties = widgetParser.parseProperties(fragment["dojo:propertyset"]);
+}
+
+// FIXME: need to add the <dojo:connect />
+dojo.widget.tags["dojo:connect"] = function(fragment, widgetParser, parentComp){
+	var properties = widgetParser.parseProperties(fragment["dojo:connect"]);
+}
+
+// FIXME: if we know the insertion point (to a reasonable location), why then do we:
+//	- create a template node
+//	- clone the template node
+//	- render the clone and set properties
+//	- remove the clone from the render tree
+//	- place the clone
+// this is quite dumb
+dojo.widget.buildWidgetFromParseTree = function(type, frag, 
+												parser, parentComp, 
+												insertionIndex, localProps){
+	var stype = type.split(":");
+	stype = (stype.length == 2) ? stype[1] : type;
+	// FIXME: we don't seem to be doing anything with this!
+	// var propertySets = parser.getPropertySets(frag);
+	var localProperties = localProps || parser.parseProperties(frag["dojo:"+stype]);
+	// var tic = new Date();
+	var twidget = dojo.widget.manager.getImplementation(stype);
+	if(!twidget){
+		throw new Error("cannot find \"" + stype + "\" widget");
+	}else if (!twidget.create){
+		throw new Error("\"" + stype + "\" widget object does not appear to implement *Widget");
+	}
+	localProperties["dojoinsertionindex"] = insertionIndex;
+	// FIXME: we loose no less than 5ms in construction!
+	var ret = twidget.create(localProperties, frag, parentComp);
+	// dojo.debug(new Date() - tic);
+	return ret;
+}
+
+/*
+ * Create a widget constructor function (aka widgetClass)
+ */
+dojo.widget.defineWidget = function(widgetClass /*string*/, renderer /*string*/, superclasses /*function||array*/, init /*function*/, props /*object*/){
+	// This meta-function does parameter juggling for backward compat and overloading
+	// if 4th argument is a string, we are using the old syntax
+	// old sig: widgetClass, superclasses, props (object), renderer (string), init (function)
+	if(dojo.lang.isString(arguments[3])){
+		dojo.widget._defineWidget(arguments[0], arguments[3], arguments[1], arguments[4], arguments[2]);
+	}else{
+		// widgetClass
+		var args = [ arguments[0] ], p = 3;
+		if(dojo.lang.isString(arguments[1])){
+			// renderer, superclass
+			args.push(arguments[1], arguments[2]);
+		}else{
+			// superclass
+			args.push('', arguments[1]);
+			p = 2;
+		}
+		if(dojo.lang.isFunction(arguments[p])){
+			// init (function), props (object) 
+			args.push(arguments[p], arguments[p+1]);
+		}else{
+			// props (object) 
+			args.push(null, arguments[p]);
+		}
+		dojo.widget._defineWidget.apply(this, args);
+	}
+}
+
+dojo.widget.defineWidget.renderers = "html|svg|vml";
+
+dojo.widget._defineWidget = function(widgetClass /*string*/, renderer /*string*/, superclasses /*function||array*/, init /*function*/, props /*object*/){
+	// FIXME: uncomment next line to test parameter juggling ... remove when confidence improves
+	//dojo.debug('(c:)' + widgetClass + '\n\n(r:)' + renderer + '\n\n(i:)' + init + '\n\n(p:)' + props);
+	// widgetClass takes the form foo.bar.baz<.renderer>.WidgetName (e.g. foo.bar.baz.WidgetName or foo.bar.baz.html.WidgetName)
+	var namespace = widgetClass.split(".");
+	var type = namespace.pop(); // type <= WidgetName, namespace <= foo.bar.baz<.renderer>
+	var regx = "\\.(" + (renderer ? renderer + '|' : '') + dojo.widget.defineWidget.renderers + ")\\.";
+	//dojo.debug(regx);
+	var r = widgetClass.search(new RegExp(regx));
+	namespace = (r < 0 ? namespace.join(".") : widgetClass.substr(0, r));
+	//dojo.debug(r + ': ' + widgetClass + ': ' + namespace);
+
+	dojo.widget.manager.registerWidgetPackage(namespace);
+	dojo.widget.tags.addParseTreeHandler("dojo:"+type.toLowerCase());
+
+	props=(props)||{};
+	props.widgetType = type;
+	if((!init)&&(props["classConstructor"])){
+		init = props.classConstructor;
+		delete props.classConstructor;
+	}
+	dojo.declare(widgetClass, superclasses, init, props);
+}
\ No newline at end of file

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

Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/Wizard.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/Wizard.js?rev=413306&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/Wizard.js (added)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/Wizard.js Sat Jun 10 07:27:44 2006
@@ -0,0 +1,210 @@
+/*
+	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.Wizard");
+
+dojo.require("dojo.widget.*");
+dojo.require("dojo.widget.LayoutContainer");
+dojo.require("dojo.widget.ContentPane");
+dojo.require("dojo.event.*");
+dojo.require("dojo.html");
+dojo.require("dojo.style");
+
+//////////////////////////////////////////
+// WizardContainer -- a set of panels
+//////////////////////////////////////////
+dojo.widget.WizardContainer = function() {
+	dojo.widget.html.LayoutContainer.call(this);
+}
+dojo.inherits(dojo.widget.WizardContainer, dojo.widget.html.LayoutContainer);
+
+dojo.lang.extend(dojo.widget.WizardContainer, {
+
+	widgetType: "WizardContainer",
+
+	labelPosition: "top",
+
+	templatePath: dojo.uri.dojoUri("src/widget/templates/Wizard.html"),
+	templateCssPath: dojo.uri.dojoUri("src/widget/templates/Wizard.css"),
+
+	selected: null,		// currently selected panel
+	wizardNode: null, // the outer wizard node
+	wizardPanelContainerNode: null, // the container for the panels
+	wizardControlContainerNode: null, // the container for the wizard controls
+	previousButton: null, // the previous button
+	nextButton: null, // the next button
+	cancelButton: null, // the cancel button
+	doneButton: null, // the done button
+	nextButtonLabel: "next",
+	previousButtonLabel: "previous",
+	cancelButtonLabel: "cancel",
+	doneButtonLabel: "done",
+	cancelFunction : "",
+
+	hideDisabledButtons: false,
+
+	fillInTemplate: function(args, frag){
+		dojo.event.connect(this.nextButton, "onclick", this, "nextPanel");
+		dojo.event.connect(this.previousButton, "onclick", this, "previousPanel");
+		if (this.cancelFunction){
+			dojo.event.connect(this.cancelButton, "onclick", this.cancelFunction);
+		}else{
+			this.cancelButton.style.display = "none";
+		}
+		dojo.event.connect(this.doneButton, "onclick", this, "done");
+		this.nextButton.value = this.nextButtonLabel;
+		this.previousButton.value = this.previousButtonLabel;
+		this.cancelButton.value = this.cancelButtonLabel;
+		this.doneButton.value = this.doneButtonLabel;
+	},
+
+	checkButtons: function(){
+		var lastStep = !this.hasNextPanel();
+		this.nextButton.disabled = lastStep;
+		this.setButtonClass(this.nextButton);
+		if(this.selected.doneFunction){
+			this.doneButton.style.display = "";
+			// hide the next button if this is the last one and we have a done function
+			if(lastStep){
+				this.nextButton.style.display = "none";
+			}
+		}else{
+			this.doneButton.style.display = "none";
+		}
+		this.previousButton.disabled = ((!this.hasPreviousPanel()) || (!this.selected.canGoBack));
+		this.setButtonClass(this.previousButton);
+	},
+
+	setButtonClass: function(button){
+		if(!this.hideDisabledButtons){
+			button.style.display = "";
+			dojo.html.setClass(button, button.disabled ? "WizardButtonDisabled" : "WizardButton");
+		}else{
+			button.style.display = button.disabled ? "none" : "";
+		}
+	},
+
+	registerChild: function(panel, insertionIndex){
+		dojo.widget.WizardContainer.superclass.registerChild.call(this, panel, insertionIndex);
+		this.wizardPanelContainerNode.appendChild(panel.domNode);
+		panel.hide();
+
+		if(!this.selected){
+			this.onSelected(panel);
+		}
+		this.checkButtons();
+	},
+
+	onSelected: function(panel){
+		// Deselect old panel and select new one
+		if(this.selected ){
+			if (this.selected.checkPass()) {
+				this.selected.hide();
+			} else {
+				return;
+			}
+		}
+		panel.show();
+		this.selected = panel;
+	},
+
+	getPanels: function() {
+		return this.getChildrenOfType("WizardPane", false);
+	},
+
+	selectedIndex: function() {
+		if (this.selected) {
+			return dojo.lang.indexOf(this.getPanels(), this.selected);
+		}
+		return -1;
+	},
+
+	nextPanel: function() {
+		var selectedIndex = this.selectedIndex();
+		if ( selectedIndex > -1 ) {
+			var childPanels = this.getPanels();
+			if (childPanels[selectedIndex + 1]) {
+				this.onSelected(childPanels[selectedIndex + 1]);
+			}
+		}
+		this.checkButtons();
+	},
+
+	previousPanel: function() {
+		var selectedIndex = this.selectedIndex();
+		if ( selectedIndex > -1 ) {
+			var childPanels = this.getPanels();
+			if (childPanels[selectedIndex - 1]) {
+				this.onSelected(childPanels[selectedIndex - 1]);
+			}
+		}
+		this.checkButtons();
+	},
+
+	hasNextPanel: function() {
+		var selectedIndex = this.selectedIndex();
+		return (selectedIndex < (this.getPanels().length - 1));
+	},
+
+	hasPreviousPanel: function() {
+		var selectedIndex = this.selectedIndex();
+		return (selectedIndex > 0);
+	},
+
+	done: function() {
+		this.selected.done();
+	}
+});
+dojo.widget.tags.addParseTreeHandler("dojo:WizardContainer");
+
+//////////////////////////////////////////
+// WizardPane -- a panel in a wizard
+//////////////////////////////////////////
+dojo.widget.WizardPane = function() {
+	dojo.widget.html.ContentPane.call(this);
+}
+dojo.inherits(dojo.widget.WizardPane, dojo.widget.html.ContentPane);
+
+dojo.lang.extend(dojo.widget.WizardPane, {
+	widgetType: "WizardPane",
+
+	canGoBack: true,
+
+	passFunction: "",
+	doneFunction: "",
+
+	fillInTemplate: function(args, frag) {
+		if (this.passFunction) {
+			this.passFunction = dj_global[this.passFunction];
+		}
+		if (this.doneFunction) {
+			this.doneFunction = dj_global[this.doneFunction];
+		}
+	},
+
+	checkPass: function() {
+		if (this.passFunction && dojo.lang.isFunction(this.passFunction)) {
+			var failMessage = this.passFunction();
+			if (failMessage) {
+				alert(failMessage);
+				return false;
+			}
+		}
+		return true;
+	},
+
+	done: function() {
+		if (this.doneFunction && dojo.lang.isFunction(this.doneFunction)) {
+			this.doneFunction();
+		}
+	}
+});
+
+dojo.widget.tags.addParseTreeHandler("dojo:WizardPane");

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

Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/YahooMap.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/YahooMap.js?rev=413306&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/YahooMap.js (added)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/YahooMap.js Sat Jun 10 07:27:44 2006
@@ -0,0 +1,27 @@
+/*
+	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.YahooMap");
+dojo.provide("dojo.widget.YahooMap.Controls");
+dojo.require("dojo.widget.*");
+
+dojo.widget.defineWidget(
+	"dojo.widget.YahooMap",
+	dojo.widget.Widget,
+	{ isContainer: false }
+);
+
+dojo.widget.YahooMap.Controls={
+	MapType:"maptype",
+	Pan:"pan",
+	ZoomLong:"zoomlong",
+	ZoomShort:"zoomshort"
+};
+dojo.requireAfterIf("html", "dojo.widget.html.YahooMap");

Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/DemoItem.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/DemoItem.js?rev=413306&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/DemoItem.js (added)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/DemoItem.js Sat Jun 10 07:27:44 2006
@@ -0,0 +1,71 @@
+/*
+	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.demoEngine.DemoItem");
+dojo.require("dojo.widget.*");
+dojo.require("dojo.widget.HtmlWidget");
+
+dojo.widget.defineWidget("my.widget.demoEngine.DemoItem", 
+	dojo.widget.HtmlWidget, 
+	{
+		templatePath: dojo.uri.dojoUri("src/widget/demoEngine/templates/DemoItem.html"),
+		templateCssPath: dojo.uri.dojoUri("src/widget/demoEngine/templates/DemoItem.css"),
+		postCreate: function() {
+			dojo.html.addClass(this.domNode,this.domNodeClass);
+			dojo.html.addClass(this.summaryBoxNode, this.summaryBoxClass);
+			dojo.html.addClass(this.screenshotTdNode, this.screenshotTdClass);
+			dojo.html.addClass(this.summaryContainerNode, this.summaryContainerClass);
+			dojo.html.addClass(this.summaryNode, this.summaryClass);
+			dojo.html.addClass(this.viewDemoLinkNode, this.viewDemoLinkClass);
+
+			this.nameNode.appendChild(document.createTextNode(this.name));
+			this.descriptionNode.appendChild(document.createTextNode(this.description));
+			this.thumbnailImageNode.src = this.thumbnail;
+			this.thumbnailImageNode.name=this.name;
+			this.viewDemoImageNode.src = this.viewDemoImage;
+			this.viewDemoImageNode.name=this.name;
+		},
+		onSelectDemo: function() {
+			//Attach to this to do something when a demo is selected
+		}
+	},
+	"",
+	function() {
+		this.demo = "";
+
+		this.domNodeClass="demoItemWrapper";
+
+		this.summaryBoxNode="";
+		this.summaryBoxClass="demoItemSummaryBox";
+
+		this.nameNode="";
+		this.thumbnailImageNode="";
+		this.viewDemoImageNode="";
+
+		this.screenshotTdNode="";
+		this.screenshotTdClass="demoItemScreenshot";
+
+		this.summaryContainerNode="";
+		this.summaryContainerClass="demoItemSummaryContainer";
+
+		this.summaryNode="";
+		this.summaryClass="demoItemSummary";
+
+		this.viewDemoLinkNode="";
+		this.viewDemoLinkClass="demoItemView";
+
+		this.descriptionNode="";
+
+		this.name="Some Demo";
+		this.description="This is the description of this demo.";
+		this.thumbnail="images/test_thumb.gif";
+		this.viewDemoImage="images/viewDemo.png";
+	}
+);

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

Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/DemoNavigator.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/DemoNavigator.js?rev=413306&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/DemoNavigator.js (added)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/DemoNavigator.js Sat Jun 10 07:27:44 2006
@@ -0,0 +1,188 @@
+/*
+	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.demoEngine.DemoNavigator");
+dojo.require("dojo.widget.*");
+dojo.require("dojo.widget.HtmlWidget");
+dojo.require("dojo.widget.Button");
+dojo.require("dojo.widget.demoEngine.DemoItem");
+dojo.require("dojo.io.*");
+dojo.require("dojo.lfx.*");
+dojo.require("dojo.lang.Common");
+
+dojo.widget.defineWidget("my.widget.demoEngine.DemoNavigator", 
+	dojo.widget.HtmlWidget, 
+	{
+		templatePath: dojo.uri.dojoUri("src/widget/demoEngine/templates/DemoNavigator.html"),
+		templateCssPath: dojo.uri.dojoUri("src/widget/demoEngine/templates/DemoNavigator.css"),
+		postCreate: function() {
+			dojo.html.addClass(this.domNode,this.domNodeClass);
+			dojo.html.addClass(this.demoListWrapperNode,this.demoListWrapperClass);
+			dojo.html.addClass(this.demoListContainerNode,this.demoListContainerClass);
+
+			if (dojo.render.html.ie) {
+				dojo.debug("render ie");
+				dojo.html.hide(this.demoListWrapperNode); 
+			} else {
+				dojo.debug("render non-ie");
+				dojo.lfx.html.fadeHide(this.demoListWrapperNode, 0).play();	
+			}
+
+			this.getRegistry(this.demoRegistryUrl);
+
+			this.demoContainer = dojo.widget.createWidget("DemoContainer",{returnImage: this.returnImage},this.demoNode);
+			dojo.event.connect(this.demoContainer,"returnToDemos", this, "returnToDemos");
+			this.demoContainer.hide();
+		},
+
+		returnToDemos: function() {
+			this.demoContainer.hide();
+			if (dojo.render.html.ie) {
+				dojo.debug("render ie");
+				dojo.html.show(this.navigationContainer) ;
+			} else {	
+				dojo.debug("render non-ie");
+				dojo.lfx.html.fadeShow(this.navigationContainer,250).play();
+			}
+
+			//if (dojo.render.html.ie) {
+			//	dojo.html.setOpacity(this.navigationContainer);
+			//}
+
+			dojo.lang.forEach(this.categoriesChildren, dojo.lang.hitch(this, function(child){
+				child.checkSize();
+			}));
+
+			dojo.lang.forEach(this.demoListChildren, dojo.lang.hitch(this, function(child){
+				child.checkSize();
+			}));
+		},
+
+		show: function() {
+			//dojo.widget.demoEngine.DemoNavigator.superclass.show.call(this);
+			dojo.html.show(this.domNode);
+			dojo.html.setOpacity(this.domNode,1);
+			//dojo.html.setOpacity(this.navigationContainer);	
+			//dojo.html.show(this.navigationContainer);
+			dojo.html.setOpacity(this.navigationContainer,1);
+
+			dojo.lang.forEach(this.categoriesChildren, dojo.lang.hitch(this, function(child){
+				child.checkSize();
+			}));
+
+			dojo.lang.forEach(this.demoListChildren, dojo.lang.hitch(this, function(child){
+				child.checkSize();
+			}));
+		},
+		getRegistry: function(url) {
+			dojo.io.bind({
+				url: url,
+				load: dojo.lang.hitch(this,this.processRegistry),
+				mimetype: "text/json"
+			});
+		},
+
+		processRegistry: function(type,registry,e) {
+			dojo.debug("Processing Registry");
+			this.registry = registry;
+			dojo.lang.forEach(this.registry.navigation, dojo.lang.hitch(this,this.addCategory)); 
+		},
+
+		addCategory: function(category) {
+				var newCat = dojo.widget.createWidget("Button",{caption: category.name});
+
+				if(!dojo.lang.isObject(this.registry.categories)) {
+					this.registry.categories=function(){};
+				}
+
+				this.registry.categories[category.name] = category;
+				this.categoriesChildren.push(newCat);
+				this.categoriesButtonsNode.appendChild(newCat.domNode);	
+				newCat.domNode.categoryName = category.name;
+				dojo.event.connect(newCat,"onClick", this, "onSelectCategory");
+		},
+
+		addDemo: function(demoName) {
+			var demo = this.registry.definitions[demoName];
+
+			if (dojo.render.html.ie) {
+				dojo.html.show(this.demoListWrapperNode) 
+			} else {
+				dojo.lfx.html.fadeShow(this.demoListWrapperNode, 250).play();
+			}
+
+			var newDemo = dojo.widget.createWidget("DemoItem",{viewDemoImage: this.viewDemoImage, name: demoName, description: demo.description, thumbnail: demo.thumbnail});
+			this.demoListChildren.push(newDemo);
+			this.demoListContainerNode.appendChild(newDemo.domNode);	
+			dojo.event.connect(newDemo,"onSelectDemo",this,"onSelectDemo");
+		},
+
+		onSelectCategory: function(e) {
+			catName = e.currentTarget.categoryName;	
+			dojo.debug("Selected Category: " + catName);
+			//Remove current list of demos
+			dojo.lang.forEach(this.demoListChildren, function(child) {
+					child.destroy();
+			});
+			this.demoListChildren=[];
+
+			//add demos from this cat
+			dojo.lang.forEach(this.registry.categories[catName].demos, dojo.lang.hitch(this,function(demoName){
+				this.addDemo(demoName);
+			}));
+		},
+
+		onSelectDemo: function(e) {
+			//Attach to this to do something when a demo is selected
+			dojo.debug("Demo Selected: " + e.target.name);
+
+			if (dojo.render.html.ie) {
+				dojo.debug("render ie");
+				dojo.html.hide(this.navigationContainer) ;
+				this.demoContainer.show();
+				this.demoContainer.showDemo();
+			} else {
+				dojo.debug("render non-ie");
+				dojo.lfx.html.fadeHide(this.navigationContainer,250,null,dojo.lang.hitch(this, function() {
+					this.demoContainer.show();	
+					this.demoContainer.showDemo();
+				})).play();
+			}
+
+			this.demoContainer.loadDemo(this.registry.definitions[e.target.name].url);
+			this.demoContainer.setName(e.target.name);
+			this.demoContainer.setSummary(this.registry.definitions[e.target.name].description);
+		}
+		
+	},
+	"",
+	function() {
+		this.demoRegistryUrl="demoRegistry.json";
+		this.registry=function(){};
+
+		this.categoriesNode="";
+		this.categoriesButtonsNode="";
+		this.navigationContainer="";
+
+		this.domNodeClass="demoNavigator";
+
+		this.demoNode="";
+		this.demoContainer="";
+
+		this.demoListWrapperNode="";
+		this.demoListWrapperClass="demoNavigatorListWrapper";
+		this.demoListContainerClass="demoNavigatorListContainer";
+
+		this.returnImage="images/dojoDemos.gif";
+		this.viewDemoImage="images/viewDemo.png";
+		this.demoListChildren = [];
+		this.categoriesChildren = [];
+	}
+);

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

Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/SourcePane.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/SourcePane.js?rev=413306&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/SourcePane.js (added)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/SourcePane.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.provide("dojo.widget.demoEngine.SourcePane");
+dojo.require("dojo.widget.*");
+dojo.require("dojo.widget.HtmlWidget");
+dojo.require("dojo.io.*");
+
+dojo.widget.defineWidget("my.widget.demoEngine.SourcePane", 
+	dojo.widget.HtmlWidget, 
+	{
+		templatePath: dojo.uri.dojoUri("src/widget/demoEngine/templates/SourcePane.html"),
+		templateCssPath: dojo.uri.dojoUri("src/widget/demoEngine/templates/SourcePane.css"),
+		postCreate: function() {
+			dojo.html.addClass(this.domNode,this.domNodeClass);
+			dojo.debug("PostCreate");
+		},
+	
+		getSource: function() {
+			if (this.href) {
+				dojo.io.bind({
+					url: this.href,
+					load: dojo.lang.hitch(this, "fillInSource"),
+					mimetype: "text/plain"
+				});
+			}
+		},	
+
+		fillInSource: function(type, source, e) {
+			this.sourceNode.value=source;
+		},
+
+		setHref: function(url) {
+			this.href = url;
+			this.getSource();
+		}
+	},
+	"",
+	function() {
+		dojo.debug("SourcePane Init");
+		this.domNodeClass="sourcePane";
+		this.sourceNode = "";
+		this.href = "";
+	}
+);

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

Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/templates/DemoContainer.css
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/templates/DemoContainer.css?rev=413306&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/templates/DemoContainer.css (added)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/templates/DemoContainer.css Sat Jun 10 07:27:44 2006
@@ -0,0 +1,38 @@
+.demoContainer{
+	width: 100%;
+	height: 100%;
+	padding: 0px;
+	margin: 0px;
+}
+
+.demoContainer .return {
+	cursor: pointer;
+}
+
+.demoContainer span {
+	margin-right: 10px;
+	cursor: pointer;
+}
+
+.demoContainer .selected {
+	border-bottom: 5px solid #95bfff;
+}
+
+.demoContainer table {
+	background: #f5f5f5;
+	width: 100%;
+	height: 100%;
+}
+
+.demoContainerTabs {
+	width: 100%;
+	height: 400px;
+}
+
+.demoContainerTabs .dojoTabLabels-top {
+	display: none;
+}
+
+.demoContainerTabs .dojoTabPaneWrapper {
+	border: 0px;
+}

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

Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/templates/DemoContainer.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/templates/DemoContainer.html?rev=413306&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/templates/DemoContainer.html (added)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/templates/DemoContainer.html Sat Jun 10 07:27:44 2006
@@ -0,0 +1,25 @@
+<div dojoAttachPoint="domNode">
+	<table width="100%" cellspacing="0" cellpadding="5">
+		<tbody>
+			<tr dojoAttachPoint="headerNode">
+				<td dojoAttachPoint="returnNode" valign="middle" width="1%">
+					<img dojoAttachPoint="returnImageNode" dojoAttachEvent="onclick: returnToDemos"/>
+				</td>
+				<td>
+					<h1 dojoAttachPoint="demoNameNode"></h1>
+					<p dojoAttachPoint="summaryNode"></p>
+				</td>
+				<td dojoAttachPoint="tabControlNode" valign="middle" align="right" nowrap>
+					<span dojoAttachPoint="sourceButtonNode" dojoAttachEvent="onclick: showSource">source</span>
+					<span dojoAttachPoint="demoButtonNode" dojoAttachEvent="onclick: showDemo">demo</span>
+				</td>
+			</tr>
+			<tr>
+				<td colspan="3">
+					<div dojoAttachPoint="tabNode">
+					</div>
+				</td>
+			</tr>
+		</tbody>
+	</table>
+</div>

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

Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/templates/DemoItem.css
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/templates/DemoItem.css?rev=413306&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/templates/DemoItem.css (added)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/templates/DemoItem.css Sat Jun 10 07:27:44 2006
@@ -0,0 +1,58 @@
+.demoItemSummaryBox {
+	background: #efefef;
+	border:1px solid #dae3ee;
+}
+
+.demoItemScreenshot {
+	padding:0.65em;
+	width:175px;
+	border-right:1px solid #fafafa;
+	text-align:center;
+	cursor: pointer;
+}
+
+.demoItemWrapper{
+	margin-bottom:1em;
+}
+
+.demoItemWrapper a:link, .demoItemWrapper a:visited {
+	color:#a6238f;
+	text-decoration:none;
+}
+
+.demoItemSummaryContainer {
+	border-left:1px solid #ddd;
+}
+
+.demoItemSummaryContainer h1 {
+	background-color:#e8e8e8;
+	border-bottom: 1px solid #e6e6e6;
+	color:#738fb9;
+	margin:1px;
+	padding:0.5em;
+	font-family:"Lucida Grande", "Tahoma", serif;
+	font-size:1.25em;
+	font-weight:normal;
+}
+
+.demoItemSummaryContainer h1 .packageSummary {
+	display:block;
+	color:#000;
+	font-size:10px;
+	margin-top:2px;
+}
+
+.demoItemSummaryContainer .demoItemSummary{
+	padding:1em;
+}
+
+.demoItemSummaryContainer .demoItemSummary p {
+	font-size:0.85em;
+	padding:0;
+	margin:0;
+}
+
+.demoItemView {
+	text-align:right;
+	cursor: pointer;
+}

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

Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/templates/DemoItem.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/templates/DemoItem.html?rev=413306&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/templates/DemoItem.html (added)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/templates/DemoItem.html Sat Jun 10 07:27:44 2006
@@ -0,0 +1,21 @@
+<div dojoAttachPoint="domNode">
+	<div dojoAttachPoint="summaryBoxNode">
+		<table width="100%" cellspacing="0" cellpadding="0">
+			<tbody>
+				<tr>
+					<td dojoAttachPoint="screenshotTdNode" valign="top" width="1%">
+						<img dojoAttachPoint="thumbnailImageNode" dojoAttachEvent="onclick: onSelectDemo" />
+					</td>
+					<td dojoAttachPoint="summaryContainerNode" valign="top">
+						<h1 dojoAttachPoint="nameNode">
+						</h1>
+						<div dojoAttachPoint="summaryNode">
+							<p dojoAttachPoint="descriptionNode"></p>
+							<div dojoAttachPoint="viewDemoLinkNode"><img dojoAttachPoint="viewDemoImageNode"/ dojoAttachEvent="onclick: onSelectDemo"></div>
+						</div>
+					</td>
+				</tr>
+			</tbody>
+		</table>
+	</div>
+</div>

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

Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/templates/DemoNavigator.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/templates/DemoNavigator.html?rev=413306&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/templates/DemoNavigator.html (added)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/templates/DemoNavigator.html Sat Jun 10 07:27:44 2006
@@ -0,0 +1,24 @@
+<div dojoAttachPoint="domNode">
+	<table width="100%" cellspacing="0" cellpadding="5">
+		<tbody>
+			<tr dojoAttachPoint="navigationContainer">
+				<td dojoAttachPoint="categoriesNode" valign="top" width="1%">
+					<h1>Categories</h1>
+					<div dojoAttachPoint="categoriesButtonsNode"></div>
+				</td>
+
+				<td dojoAttachPoint="demoListNode" valign="top">
+					<div dojoAttachPoint="demoListWrapperNode">
+						<div dojoAttachPoint="demoListContainerNode">
+						</div>
+					</div>
+				</td>
+			</tr>
+			<tr>
+				<td colspan="2">
+					<div dojoAttachPoint="demoNode"></div>
+				</td>
+			</tr>
+		</tbody>
+	</table>
+</div>

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

Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/templates/DemoPane.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/templates/DemoPane.html?rev=413306&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/templates/DemoPane.html (added)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/templates/DemoPane.html Sat Jun 10 07:27:44 2006
@@ -0,0 +1,3 @@
+<div dojoAttachPoint="domNode">
+	<iframe dojoAttachPoint="demoNode"></iframe>
+</div>

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

Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/templates/SourcePane.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/templates/SourcePane.html?rev=413306&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/templates/SourcePane.html (added)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/templates/SourcePane.html Sat Jun 10 07:27:44 2006
@@ -0,0 +1,3 @@
+<div dojoAttachPoint="domNode">
+	<textarea dojoAttachPoint="sourceNode" rows="100%"></textarea>
+</div>

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

Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/templates/images/test_thumb.gif
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/templates/images/test_thumb.gif?rev=413306&view=auto
==============================================================================
Binary file - no diff available.

Propchange: tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/templates/images/test_thumb.gif
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/templates/images/viewDemo.png
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/templates/images/viewDemo.png?rev=413306&view=auto
==============================================================================
Binary file - no diff available.

Propchange: tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/demoEngine/templates/images/viewDemo.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/html/AccordionPane.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/html/AccordionPane.js?rev=413306&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/html/AccordionPane.js (added)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/html/AccordionPane.js Sat Jun 10 07:27:44 2006
@@ -0,0 +1,98 @@
+/*
+	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.AccordionPane");
+dojo.require("dojo.widget.TitlePane");
+
+dojo.widget.html.AccordionPane = function(){
+
+	dojo.widget.html.TitlePane.call(this);
+	this.widgetType = "AccordionPane";
+
+	this.open=false;
+	this.allowCollapse=true;
+	this.label="";
+	this.open=false;
+
+	this.labelNodeClass="";
+	this.containerNodeClass="";
+}
+
+dojo.inherits(dojo.widget.html.AccordionPane, dojo.widget.html.TitlePane);
+
+dojo.lang.extend(dojo.widget.html.AccordionPane, {
+        postCreate: function() {
+                dojo.widget.html.AccordionPane.superclass.postCreate.call(this);
+		this.domNode.widgetType=this.widgetType;
+		this.setSizes();
+		dojo.html.addClass(this.labelNode, this.labelNodeClass);
+		dojo.html.disableSelection(this.labelNode);
+		dojo.html.addClass(this.containerNode, this.containerNodeClass);
+        },
+
+	collapse: function() {
+		//dojo.fx.html.wipeOut(this.containerNode,250);
+		//var anim = dojo.fx.html.wipe(this.containerNode, 1000, this.containerNode.offsetHeight, 0, null, true);
+		this.containerNode.style.display="none";
+		this.open=false;
+	},
+
+	expand: function() {
+		//dojo.fx.html.wipeIn(this.containerNode,250);
+		this.containerNode.style.display="block";
+		//var anim = dojo.fx.html.wipe(this.containerNode, 1000, 0, this.containerNode.scrollHeight, null, true);
+		this.open=true;
+	},
+
+	getCollapsedHeight: function() {
+		return dojo.style.getOuterHeight(this.labelNode)+1;
+	},
+
+	setSizes: function() {
+		var siblings = this.domNode.parentNode.childNodes;
+		var height=dojo.style.getInnerHeight(this.domNode.parentNode)-this.getCollapsedHeight();
+
+		this.siblingWidgets = [];
+	
+		for (var x=0; x<siblings.length; x++) {
+			if (siblings[x].widgetType==this.widgetType) {
+				if (this.domNode != siblings[x]) {
+					var ap = dojo.widget.byNode(siblings[x]);
+					this.siblingWidgets.push(ap);
+					height -= ap.getCollapsedHeight();
+				}
+			}
+		}
+	
+		for (var x=0; x<this.siblingWidgets.length; x++) {
+			dojo.style.setOuterHeight(this.siblingWidgets[x].containerNode,height);
+		}
+
+		dojo.style.setOuterHeight(this.containerNode,height);
+	},
+
+	onLabelClick: function() {
+		this.setSizes();
+		if (!this.open) { 
+			for (var x=0; x<this.siblingWidgets.length;x++) {
+				if (this.siblingWidgets[x].open) {
+					this.siblingWidgets[x].collapse();
+				}
+			}
+			this.expand();
+		} else {
+			if (this.allowCollapse) {
+				this.collapse();
+			}
+		}
+	}
+});
+
+dojo.widget.tags.addParseTreeHandler("dojo:AccordionPane");

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

Modified: tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/html/Button2.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/html/Button2.js?rev=413306&r1=413305&r2=413306&view=diff
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/html/Button2.js (original)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/html/Button2.js Sat Jun 10 07:27:44 2006
@@ -8,18 +8,18 @@
 		http://dojotoolkit.org/community/licensing.shtml
 */
 
-// this is a stub that will be removed in 0.4, see ../Button2.html for details
-
-dojo.provide("dojo.widget.html.Button2");
-
-dojo.widget.html.Button2 = function(){}
-dojo.inherits(dojo.widget.html.Button2, dojo.widget.html.Button);
-dojo.lang.extend(dojo.widget.html.Button2, { widgetType: "Button2" });
-
-dojo.widget.html.DropDownButton2 = function(){}
-dojo.inherits(dojo.widget.html.DropDownButton2, dojo.widget.html.DropDownButton);
-dojo.lang.extend(dojo.widget.html.DropDownButton2, { widgetType: "DropDownButton2" });
-
-dojo.widget.html.ComboButton2 = function(){}
-dojo.inherits(dojo.widget.html.ComboButton2, dojo.widget.html.ComboButton);
+// this is a stub that will be removed in 0.4, see ../Button2.html for details
+
+dojo.provide("dojo.widget.html.Button2");
+
+dojo.widget.html.Button2 = function(){}
+dojo.inherits(dojo.widget.html.Button2, dojo.widget.html.Button);
+dojo.lang.extend(dojo.widget.html.Button2, { widgetType: "Button2" });
+
+dojo.widget.html.DropDownButton2 = function(){}
+dojo.inherits(dojo.widget.html.DropDownButton2, dojo.widget.html.DropDownButton);
+dojo.lang.extend(dojo.widget.html.DropDownButton2, { widgetType: "DropDownButton2" });
+
+dojo.widget.html.ComboButton2 = function(){}
+dojo.inherits(dojo.widget.html.ComboButton2, dojo.widget.html.ComboButton);
 dojo.lang.extend(dojo.widget.html.ComboButton2, { widgetType: "ComboButton2" });

Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/html/ComboBox.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/html/ComboBox.js?rev=413306&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/html/ComboBox.js (added)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/html/ComboBox.js Sat Jun 10 07:27:44 2006
@@ -0,0 +1,612 @@
+/*
+	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.ComboBox");
+dojo.require("dojo.widget.ComboBox");
+dojo.require("dojo.widget.*");
+dojo.require("dojo.io.*");
+dojo.require("dojo.lfx.*");
+dojo.require("dojo.dom");
+dojo.require("dojo.html");
+dojo.require("dojo.string");
+dojo.require("dojo.widget.html.stabile");
+
+dojo.widget.defineWidget(
+	"dojo.widget.html.ComboBox",
+	[dojo.widget.HtmlWidget, dojo.widget.ComboBox],
+	{
+		autoComplete: true,
+		formInputName: "",
+		name: "", // clone in the name from the DOM node
+		textInputNode: null,
+		comboBoxValue: null,
+		comboBoxSelectionValue: null,
+		optionsListWrapper: null,
+		optionsListNode: null,
+		downArrowNode: null,
+		cbTableNode: null,
+		searchTimer: null,
+		searchDelay: 100,
+		dataUrl: "",
+		fadeTime: 200,
+		// maxListLength limits list to X visible rows, scroll on rest 
+		maxListLength: 8, 
+		// mode can also be "remote" for JSON-returning live search or "html" for
+		// dumber live search
+		mode: "local", 
+		selectedResult: null,
+		_highlighted_option: null,
+		_prev_key_backspace: false,
+		_prev_key_esc: false,
+		_result_list_open: false,
+		_gotFocus: false,
+		_mouseover_list: false,
+		dataProviderClass: "dojo.widget.ComboBoxDataProvider",
+
+		templatePath: dojo.uri.dojoUri("src/widget/templates/HtmlComboBox.html"),
+		templateCssPath: dojo.uri.dojoUri("src/widget/templates/HtmlComboBox.css"),
+	
+		setValue: function(value) {
+			this.comboBoxValue.value = value;
+			if (this.textInputNode.value != value) { // prevent mucking up of selection
+				this.textInputNode.value = value;
+			}
+			dojo.widget.html.stabile.setState(this.widgetId, this.getState(), true);
+		},
+	
+		getValue: function() {
+			return this.comboBoxValue.value;
+		},
+	
+		getState: function() {
+			return {value: this.getValue()};
+		},
+	
+		setState: function(state) {
+			this.setValue(state.value);
+		},
+	
+		getCaretPos: function(element){
+			// khtml 3.5.2 has selection* methods as does webkit nightlies from 2005-06-22
+			if(dojo.lang.isNumber(element.selectionStart)){
+				// FIXME: this is totally borked on Moz < 1.3. Any recourse?
+				return element.selectionStart;
+			}else if(dojo.render.html.ie){
+				// in the case of a mouse click in a popup being handled,
+				// then the document.selection is not the textarea, but the popup
+				// var r = document.selection.createRange();
+				// hack to get IE 6 to play nice. What a POS browser.
+				var tr = document.selection.createRange().duplicate();
+				var ntr = element.createTextRange();
+				tr.move("character",0);
+				ntr.move("character",0);
+				try {
+					// If control doesnt have focus, you get an exception.
+					// Seems to happen on reverse-tab, but can also happen on tab (seems to be a race condition - only happens sometimes).
+					// There appears to be no workaround for this - googled for quite a while.
+					ntr.setEndPoint("EndToEnd", tr);
+					return String(ntr.text).replace(/\r/g,"").length;
+				} catch (e) {
+					return 0; // If focus has shifted, 0 is fine for caret pos.
+				}
+				
+			}
+		},
+	
+		setCaretPos: function(element, location){
+			location = parseInt(location);
+			this.setSelectedRange(element, location, location);
+		},
+	
+		setSelectedRange: function(element, start, end){
+			if(!end){ end = element.value.length; }  // NOTE: Strange - should be able to put caret at start of text?
+			// Mozilla
+			// parts borrowed from http://www.faqts.com/knowledge_base/view.phtml/aid/13562/fid/130
+			if(element.setSelectionRange){
+				element.focus();
+				element.setSelectionRange(start, end);
+			}else if(element.createTextRange){ // IE
+				var range = element.createTextRange();
+				with(range){
+					collapse(true);
+					moveEnd('character', end);
+					moveStart('character', start);
+					select();
+				}
+			}else{ //otherwise try the event-creation hack (our own invention)
+				// do we need these?
+				element.value = element.value;
+				element.blur();
+				element.focus();
+				// figure out how far back to go
+				var dist = parseInt(element.value.length)-end;
+				var tchar = String.fromCharCode(37);
+				var tcc = tchar.charCodeAt(0);
+				for(var x = 0; x < dist; x++){
+					var te = document.createEvent("KeyEvents");
+					te.initKeyEvent("keypress", true, true, null, false, false, false, false, tcc, tcc);
+					element.dispatchEvent(te);
+				}
+			}
+		},
+	
+		// does the keyboard related stuff
+		_handleKeyEvents: function(evt){
+			if(evt.ctrlKey || evt.altKey){ return; }
+	
+			// reset these
+			this._prev_key_backspace = false;
+			this._prev_key_esc = false;
+	
+			var k = dojo.event.browser.keys;
+			var doSearch = true;
+	
+			// mozilla quirk 
+			// space has no keyCode in mozilla
+			var keyCode = evt.keyCode;
+			if(keyCode==0 && evt.charCode==k.KEY_SPACE){
+				keyCode = k.KEY_SPACE;
+			}
+			switch(keyCode){
+	 			case k.KEY_DOWN_ARROW:
+					if(!this._result_list_open){
+						this.startSearchFromInput();
+					}
+					this.highlightNextOption();
+					dojo.event.browser.stopEvent(evt);
+					return;
+				case k.KEY_UP_ARROW:
+					this.highlightPrevOption();
+					dojo.event.browser.stopEvent(evt);
+					return;
+				case k.KEY_ENTER:
+					// prevent submitting form if we press enter with list open
+					if(this._result_list_open){
+						dojo.event.browser.stopEvent(evt);
+					}
+					// fallthrough
+				case k.KEY_TAB:
+					// using linux alike tab for autocomplete
+					if(!this.autoComplete && this._result_list_open && this._highlighted_option){
+						dojo.event.browser.stopEvent(evt);
+						this.selectOption({ 'target': this._highlighted_option, 'noHide': true });
+	
+						// put caret last
+						this.setSelectedRange(this.textInputNode, this.textInputNode.value.length, null);
+					}else{
+						this.selectOption();
+						return;
+					}
+					break;
+				case k.KEY_SPACE:
+					if(this._result_list_open && this._highlighted_option){
+						dojo.event.browser.stopEvent(evt);
+						this.selectOption();
+						this.hideResultList();
+						return;
+					}
+					break;
+				case k.KEY_ESCAPE:
+					this.hideResultList();
+					this._prev_key_esc = true;
+					return;
+				case k.KEY_BACKSPACE:
+					this._prev_key_backspace = true;
+					if(!this.textInputNode.value.length){
+						this.setAllValues("", "");
+						this.hideResultList();
+						doSearch = false;
+					}
+					break;
+				case k.KEY_RIGHT_ARROW: // fall through
+				case k.KEY_LEFT_ARROW: // fall through
+				case k.KEY_SHIFT:
+					doSearch = false;
+					break;
+				default:// non char keys (F1-F12 etc..)  shouldn't open list
+					if(evt.charCode==0){
+						doSearch = false;
+					}
+			}
+	
+			if(this.searchTimer){
+				clearTimeout(this.searchTimer);
+			}
+			if(doSearch){
+				// if we have gotten this far we dont want to keep our highlight
+				this.blurOptionNode();
+	
+				// need to wait a tad before start search so that the event bubbles through DOM and we have value visible
+				this.searchTimer = setTimeout(dojo.lang.hitch(this, this.startSearchFromInput), this.searchDelay);
+			}
+		},
+	
+		onKeyDown: function(evt){
+			// IE needs to stop keyDown others need to stop keyPress
+			if(!document.createEvent){ // only IE
+				this._handleKeyEvents(evt);
+			}
+			// FIXME: What about ESC ??
+		},
+	
+		onKeyPress: function(evt){
+			if(document.createEvent){ // never IE
+				this._handleKeyEvents(evt);
+			}
+		},
+	
+		onKeyUp: function(evt){
+			this.setValue(this.textInputNode.value);
+		},
+	
+		setSelectedValue: function(value){
+			// FIXME, not sure what to do here!
+			this.comboBoxSelectionValue.value = value;
+		},
+
+		setAllValues: function(value1, value2){
+			this.setValue(value1);
+			this.setSelectedValue(value2);
+		},
+	
+		// opera, khtml, safari doesnt support node.scrollIntoView(), workaround
+		scrollIntoView: function(){
+			var node = this._highlighted_option;
+			var parent = this.optionsListNode;
+			// don't rely on that node.scrollIntoView works just because the function is there
+			// it doesnt work in Konqueror or Opera even though the function is there and probably
+			// not safari either
+			// dont like browser sniffs implementations but sometimes you have to use it
+			if(dojo.render.html.ie || dojo.render.html.mozilla){
+				// IE, mozilla
+				node.scrollIntoView(false);	
+			}else{
+				var parentBottom = parent.scrollTop + dojo.style.getInnerHeight(parent);
+				var nodeBottom = node.offsetTop + dojo.style.getOuterHeight(node);
+				if(parentBottom < nodeBottom){
+					parent.scrollTop += (nodeBottom - parentBottom);
+				}else if(parent.scrollTop > node.offsetTop){
+					parent.scrollTop -= (parent.scrollTop - node.offsetTop);
+				}
+			}
+		},
+	
+		// does the actual highlight
+		focusOptionNode: function(node){
+			if(this._highlighted_option != node){
+				this.blurOptionNode();
+				this._highlighted_option = node;
+				dojo.html.addClass(this._highlighted_option, "dojoComboBoxItemHighlight");
+			}
+		},
+	
+		// removes highlight on highlighted
+		blurOptionNode: function(){
+			if(this._highlighted_option){
+				dojo.html.removeClass(this._highlighted_option, "dojoComboBoxItemHighlight");
+				this._highlighted_option = null;
+			}
+		},
+	
+		highlightNextOption: function(){
+			if((!this._highlighted_option) || !this._highlighted_option.parentNode){
+				this.focusOptionNode(this.optionsListNode.firstChild);
+			}else if(this._highlighted_option.nextSibling){
+				this.focusOptionNode(this._highlighted_option.nextSibling);
+			}
+			this.scrollIntoView();
+		},
+	
+		highlightPrevOption: function(){
+			if(this._highlighted_option && this._highlighted_option.previousSibling){
+				this.focusOptionNode(this._highlighted_option.previousSibling);
+			}else{
+				this._highlighted_option = null;
+				this.hideResultList();
+				return;
+			}
+			this.scrollIntoView();
+		},
+	
+		itemMouseOver: function(evt){
+			this.focusOptionNode(evt.target);
+			dojo.html.addClass(this._highlighted_option, "dojoComboBoxItemHighlight");
+		},
+	
+		itemMouseOut: function(evt){
+			this.blurOptionNode();
+		},
+	
+		fillInTemplate: function(args, frag){
+			// FIXME: need to get/assign DOM node names for form participation here.
+			this.comboBoxValue.name = this.name;
+			this.comboBoxSelectionValue.name = this.name+"_selected";
+	
+			var source = this.getFragNodeRef(frag);
+			dojo.html.copyStyle(this.domNode, source);
+	
+			var dpClass;
+			if(this.mode == "remote"){
+				dpClass = dojo.widget.incrementalComboBoxDataProvider;
+			}else if(typeof this.dataProviderClass == "string"){
+				dpClass = dojo.evalObjPath(this.dataProviderClass)
+			}else{
+				dpClass = this.dataProviderClass;
+			}
+			this.dataProvider = new dpClass();
+			this.dataProvider.init(this, this.getFragNodeRef(frag));
+	
+			// Prevent IE bleed-through problem
+			this.optionsIframe = new dojo.html.BackgroundIframe(this.optionsListWrapper);
+			this.optionsIframe.size([0,0,0,0]);
+		},
+	
+	
+		focus: function(){
+			// summary
+			//	set focus to input node from code
+			this.tryFocus();
+		},
+	
+		openResultList: function(results){
+			this.clearResultList();
+			if(!results.length){
+				this.hideResultList();
+			}
+	
+			if(	(this.autoComplete)&&
+				(results.length)&&
+				(!this._prev_key_backspace)&&
+				(this.textInputNode.value.length > 0)){
+				var cpos = this.getCaretPos(this.textInputNode);
+				// only try to extend if we added the last character at the end of the input
+				if((cpos+1) > this.textInputNode.value.length){
+					// only add to input node as we would overwrite Capitalisation of chars
+					this.textInputNode.value += results[0][0].substr(cpos);
+					// build a new range that has the distance from the earlier
+					// caret position to the end of the first string selected
+					this.setSelectedRange(this.textInputNode, cpos, this.textInputNode.value.length);
+				}
+			}
+	
+			var even = true;
+			while(results.length){
+				var tr = results.shift();
+				if(tr){
+					var td = document.createElement("div");
+					td.appendChild(document.createTextNode(tr[0]));
+					td.setAttribute("resultName", tr[0]);
+					td.setAttribute("resultValue", tr[1]);
+					td.className = "dojoComboBoxItem "+((even) ? "dojoComboBoxItemEven" : "dojoComboBoxItemOdd");
+					even = (!even);
+					this.optionsListNode.appendChild(td);
+					dojo.event.connect(td, "onmouseover", this, "itemMouseOver");
+					dojo.event.connect(td, "onmouseout", this, "itemMouseOut");
+				}
+			}
+	
+			// show our list (only if we have content, else nothing)
+			this.showResultList();
+		},
+	
+		onFocusInput: function(){
+			this._hasFocus = true;
+		},
+	
+		onBlurInput: function(){
+			this._hasFocus = false;
+			this._handleBlurTimer(true, 500);
+		},
+	
+		// collect all blur timers issues here
+		_handleBlurTimer: function(/*Boolean*/clear, /*Number*/ millisec){
+			if(this.blurTimer && (clear || millisec)){
+				clearTimeout(this.blurTimer);
+			}
+			if(millisec){ // we ignore that zero is false and never sets as that never happens in this widget
+				this.blurTimer = dojo.lang.setTimeout(this, "checkBlurred", millisec);
+			}
+		},
+	
+		// these 2 are needed in IE and Safari as inputTextNode loses focus when scrolling optionslist
+		_onMouseOver: function(evt){
+			if(!this._mouseover_list){
+				this._handleBlurTimer(true, 0);
+				this._mouseover_list = true;
+			}
+		},
+	
+		_onMouseOut:function(evt){
+			var relTarget = evt.relatedTarget;
+			if(!relTarget || relTarget.parentNode!=this.optionsListNode){
+				this._mouseover_list = false;
+				this._handleBlurTimer(true, 100);
+				this.tryFocus();
+			}
+		},
+	
+		_isInputEqualToResult: function(result){
+			input = this.textInputNode.value;
+			if(!this.dataProvider.caseSensitive){
+				input = input.toLowerCase();
+				result = result.toLowerCase();
+			}
+			return (input == result);
+		},
+
+		_isValidOption: function(){
+			tgt = dojo.dom.firstElement(this.optionsListNode);
+			isValidOption = false;
+			while(!isValidOption && tgt){
+				if(this._isInputEqualToResult(tgt.getAttribute("resultName"))){
+					isValidOption = true;
+				}else{
+					tgt = dojo.dom.nextElement(tgt);
+				}
+			}
+			return isValidOption;
+		},
+
+		checkBlurred: function(){
+			if(!this._hasFocus && !this._mouseover_list){
+				this.hideResultList();
+				// clear the list if the user empties field and moves away.
+				if(!this.textInputNode.value.length){
+					this.setAllValues("", "");
+					return;
+				}
+				
+				isValidOption = this._isValidOption();
+				// enforce selection from option list
+				if(this.forceValidOption && !isValidOption){
+					this.setAllValues("", "");
+					return;
+				}
+				if(!isValidOption){// clear
+					this.setSelectedValue("");
+				}
+			}
+		},
+	
+		sizeBackgroundIframe: function(){
+			var w = dojo.style.getOuterWidth(this.optionsListNode);
+			var h = dojo.style.getOuterHeight(this.optionsListNode);
+			if( w==0 || h==0 ){
+				// need more time to calculate size
+				dojo.lang.setTimeout(this, "sizeBackgroundIframe", 100);
+				return;
+			}
+			if(this._result_list_open){
+				this.optionsIframe.size([0,0,w,h]);
+			}
+		},
+	
+		selectOption: function(evt){
+			var tgt = null;
+			if(!evt){
+				evt = { target: this._highlighted_option };
+			}
+	
+			if(!dojo.dom.isDescendantOf(evt.target, this.optionsListNode)){
+				// handle autocompletion where the the user has hit ENTER or TAB
+	
+				// if the input is empty do nothing
+				if(!this.textInputNode.value.length){
+					return;
+				}
+				tgt = dojo.dom.firstElement(this.optionsListNode);
+	
+				// user has input value not in option list
+				if(!tgt || !this._isInputEqualToResult(tgt.getAttribute("resultName"))){
+					return;
+				}
+				// otherwise the user has accepted the autocompleted value
+			}else{
+				tgt = evt.target; 
+			}
+	
+			while((tgt.nodeType!=1)||(!tgt.getAttribute("resultName"))){
+				tgt = tgt.parentNode;
+				if(tgt === document.body){
+					return false;
+				}
+			}
+	
+			this.textInputNode.value = tgt.getAttribute("resultName");
+			this.selectedResult = [tgt.getAttribute("resultName"), tgt.getAttribute("resultValue")];
+			this.setAllValues(tgt.getAttribute("resultName"), tgt.getAttribute("resultValue"));
+			if(!evt.noHide){
+				this.hideResultList();
+				this.setSelectedRange(this.textInputNode, 0, null);
+			}
+			this.tryFocus();
+		},
+	
+		clearResultList: function(){
+			var oln = this.optionsListNode;
+			while(oln.firstChild){
+				dojo.event.disconnect(oln.firstChild, "onmouseover", this, "itemMouseOver");
+				dojo.event.disconnect(oln.firstChild, "onmouseout", this, "itemMouseOut");
+				oln.removeChild(oln.firstChild);
+			}
+		},
+	
+		hideResultList: function(){
+			if(this._result_list_open){
+				this._result_list_open = false;
+				this.optionsIframe.size([0,0,0,0]);
+				dojo.lfx.fadeHide(this.optionsListNode, this.fadeTime).play();
+			}
+		},
+	
+		showResultList: function(){
+			// Our dear friend IE doesnt take max-height so we need to calculate that on our own every time
+			var childs = this.optionsListNode.childNodes;
+			if(childs.length){
+				var visibleCount = this.maxListLength;
+				if(childs.length < visibleCount){
+					visibleCount = childs.length;
+				}
+	
+				with(this.optionsListNode.style){
+					display = "";
+					height = ((visibleCount) ? (dojo.style.getOuterHeight(childs[0]) * visibleCount) : 0)+"px";
+					width = dojo.html.getOuterWidth(this.cbTableNode)-2+"px";
+				}
+				// only fadein once (flicker)
+				if(!this._result_list_open){
+					dojo.html.setOpacity(this.optionsListNode, 0);
+					dojo.lfx.fadeIn(this.optionsListNode, this.fadeTime).play();
+				}
+				
+				// prevent IE bleed through
+				this._iframeTimer = dojo.lang.setTimeout(this, "sizeBackgroundIframe", 200);
+				this._result_list_open = true;
+			}else{
+				this.hideResultList();
+			}
+		},
+	
+		handleArrowClick: function(){
+			this._handleBlurTimer(true, 0);
+			this.tryFocus();
+			if(this._result_list_open){
+				this.hideResultList();
+			}else{
+				this.startSearch("");
+				// this.startSearchFromInput();
+			}
+		},
+	
+		tryFocus: function(){
+			try {
+				this.textInputNode.focus();
+			} catch (e) {
+				// element isn't focusable if disabled, or not visible etc - not easy to test for.
+	 		};
+		},
+		
+		startSearchFromInput: function(){
+			this.startSearch(this.textInputNode.value);
+		},
+	
+		postCreate: function(){
+			dojo.event.connect(this, "startSearch", this.dataProvider, "startSearch");
+			dojo.event.connect(this.dataProvider, "provideSearchResults", this, "openResultList");
+			dojo.event.connect(this.textInputNode, "onblur", this, "onBlurInput");
+			dojo.event.connect(this.textInputNode, "onfocus", this, "onFocusInput");
+	
+			var s = dojo.widget.html.stabile.getState(this.widgetId);
+			if (s) {
+				this.setState(s);
+			}
+		}
+	}
+);

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

Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/html/DatePicker.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/html/DatePicker.js?rev=413306&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/html/DatePicker.js (added)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/html/DatePicker.js Sat Jun 10 07:27:44 2006
@@ -0,0 +1,346 @@
+/*
+	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.DatePicker");
+dojo.require("dojo.widget.*");
+dojo.require("dojo.widget.HtmlWidget");
+dojo.require("dojo.widget.DatePicker");
+dojo.require("dojo.event.*");
+dojo.require("dojo.html");
+dojo.require("dojo.date");
+
+/*
+	Some assumptions:
+	- I'm planning on always showing 42 days at a time, and we can scroll by week,
+	not just by month or year
+	- To get a sense of what month to highlight, I basically initialize on the 
+	first Saturday of each month, since that will be either the first of two or 
+	the second of three months being partially displayed, and then I work forwards 
+	and backwards from that point.
+	Currently, I assume that dates are stored in the RFC 3339 format,
+	because I find it to be most human readable and easy to parse
+	http://www.faqs.org/rfcs/rfc3339.html: 		2005-06-30T08:05:00-07:00
+*/
+
+dojo.widget.defineWidget(
+	"dojo.widget.html.DatePicker",
+	dojo.widget.HtmlWidget,
+	{
+		classConstructor: function() {
+			// mixin dojo.widget.DatePicker non-demoninational code
+			dojo.widget.DatePicker.call(this);
+			// today's date, JS Date object
+			this.today = "";
+			// selected date, JS Date object
+			this.date = "";
+			// rfc 3339 date
+			this.storedDate = "";
+			// date currently selected in the UI, stored in year, month, date in the format that will be actually displayed
+			this.currentDate = {};
+			// stored in year, month, date in the format that will be actually displayed
+			this.firstSaturday = {};
+		},
+		classNames: {
+			previous: "previousMonth",
+			current: "currentMonth",
+			next: "nextMonth",
+			currentDate: "currentDate",
+			selectedDate: "selectedItem"
+		},
+		templatePath:  dojo.uri.dojoUri("src/widget/templates/HtmlDatePicker.html"),
+		templateCssPath:  dojo.uri.dojoUri("src/widget/templates/HtmlDatePicker.css"),
+
+		fillInTemplate: function(){
+			dojo.widget.DatePicker.call(this);
+			this.initData();
+			this.initUI();
+		},
+		initData: function() {
+			this.today = new Date();
+			if(this.storedDate && (this.storedDate.split("-").length > 2)) {
+				this.date = dojo.widget.DatePicker.util.fromRfcDate(this.storedDate);
+			} else {
+				this.date = this.today;
+			}
+			// calendar math is simplified if time is set to 0
+			this.today.setHours(0);
+			this.date.setHours(0);
+			var month = this.date.getMonth();
+			var tempSaturday = dojo.widget.DatePicker.util.initFirstSaturday(this.date.getMonth().toString(), this.date.getFullYear());
+			this.firstSaturday.year = tempSaturday.year;
+			this.firstSaturday.month = tempSaturday.month;
+			this.firstSaturday.date = tempSaturday.date;
+		},
+		
+		setDate: function(rfcDate) {
+			this.storedDate = rfcDate;
+		},
+		
+		initUI: function() {
+			this.selectedIsUsed = false;
+			this.currentIsUsed = false;
+			var currentClassName = "";
+			var previousDate = new Date();
+			var calendarNodes = this.calendarDatesContainerNode.getElementsByTagName("td");
+			var currentCalendarNode;
+			// set hours of date such that there is no chance of rounding error due to 
+			// time change in local time zones
+			previousDate.setHours(8);
+			var nextDate = new Date(this.firstSaturday.year, this.firstSaturday.month, this.firstSaturday.date, 8);
+			
+			if(this.firstSaturday.date < 7) {
+				// this means there are days to show from the previous month
+				var dayInWeek = 6;
+				for (var i=this.firstSaturday.date; i>0; i--) {
+					currentCalendarNode = calendarNodes.item(dayInWeek);
+					currentCalendarNode.innerHTML = nextDate.getDate();
+					dojo.html.setClass(currentCalendarNode, this.getDateClassName(nextDate, "current"));
+					dayInWeek--;
+					previousDate = nextDate;
+					nextDate = this.incrementDate(nextDate, false);
+				}
+				for(var i=dayInWeek; i>-1; i--) {
+					currentCalendarNode = calendarNodes.item(i);
+					currentCalendarNode.innerHTML = nextDate.getDate();
+					dojo.html.setClass(currentCalendarNode, this.getDateClassName(nextDate, "previous"));
+					previousDate = nextDate;
+					nextDate = this.incrementDate(nextDate, false);				
+				}
+			} else {
+				nextDate.setDate(this.firstSaturday.date-6);
+				for(var i=0; i<7; i++) {
+					currentCalendarNode = calendarNodes.item(i);
+					currentCalendarNode.innerHTML = nextDate.getDate();
+					dojo.html.setClass(currentCalendarNode, this.getDateClassName(nextDate, "current"));
+					previousDate = nextDate;
+					nextDate = this.incrementDate(nextDate, true);				
+				}
+			}
+			previousDate.setDate(this.firstSaturday.date);
+			previousDate.setMonth(this.firstSaturday.month);
+			previousDate.setFullYear(this.firstSaturday.year);
+			nextDate = this.incrementDate(previousDate, true);
+			var count = 7;
+			currentCalendarNode = calendarNodes.item(count);
+			while((nextDate.getMonth() == previousDate.getMonth()) && (count<42)) {
+				currentCalendarNode.innerHTML = nextDate.getDate();
+				dojo.html.setClass(currentCalendarNode, this.getDateClassName(nextDate, "current"));
+				currentCalendarNode = calendarNodes.item(++count);
+				previousDate = nextDate;
+				nextDate = this.incrementDate(nextDate, true);
+			}
+			
+			while(count < 42) {
+				currentCalendarNode.innerHTML = nextDate.getDate();
+				dojo.html.setClass(currentCalendarNode, this.getDateClassName(nextDate, "next"));
+				currentCalendarNode = calendarNodes.item(++count);
+				previousDate = nextDate;
+				nextDate = this.incrementDate(nextDate, true);
+			}
+			this.setMonthLabel(this.firstSaturday.month);
+			this.setYearLabels(this.firstSaturday.year);
+		},
+		
+		incrementDate: function(date, bool) {
+			// bool: true to increase, false to decrease
+			var time = date.getTime();
+			var increment = 1000 * 60 * 60 * 24;
+			time = (bool) ? (time + increment) : (time - increment);
+			var returnDate = new Date();
+			returnDate.setTime(time);
+			return returnDate;
+		},
+		
+		incrementWeek: function(evt) {
+			var date = this.firstSaturday.date;
+			var month = this.firstSaturday.month;
+			var year = this.firstSaturday.year;
+			switch(evt.target) {
+				case this.increaseWeekNode.getElementsByTagName("img").item(0): 
+				case this.increaseWeekNode:
+					date = date + 7;
+					if (date>this._daysIn(month,year)) {
+						date = date - this._daysIn(month,year);
+						if (month < 11) {
+							month++;	
+						} else {
+							month=0;
+							year++;
+						}
+					}
+					break;
+				case this.decreaseWeekNode.getElementsByTagName("img").item(0):
+				case this.decreaseWeekNode:
+					if (date > 7) {
+						date = date - 7;
+					} else {
+						var diff = 7 - date;
+						if (month > 0) {
+							month--;
+							date = this._daysIn(month,year) - diff;
+						}else {
+							year--;
+							month=11;
+							date = 31 - diff;
+						}
+					}
+					break;
+	
+			}
+	
+			this.firstSaturday.date=date;
+			this.firstSaturday.month=month;
+			this.firstSaturday.year=year;
+			this.initUI();
+		},
+	
+		incrementMonth: function(evt) {
+			var month = this.firstSaturday.month;
+			var year = this.firstSaturday.year;
+			switch(evt.currentTarget) {
+				case this.increaseMonthNode:
+					if(month < 11) {
+						month++;
+					} else {
+						month = 0;
+						year++;
+						
+						this.setYearLabels(year);
+					}
+					break;
+				case this.decreaseMonthNode:
+					if(month > 0) {
+						month--;
+					} else {
+						month = 11;
+						year--;
+						this.setYearLabels(year);
+					}
+					break;
+				case this.increaseMonthNode.getElementsByTagName("img").item(0):
+					if(month < 11) {
+						month++;
+					} else {
+						month = 0;
+						year++;
+						this.setYearLabels(year);
+					}
+					break;
+				case this.decreaseMonthNode.getElementsByTagName("img").item(0):
+					if(month > 0) {
+						month--;
+					} else {
+						month = 11;
+						year--;
+						this.setYearLabels(year);
+					}
+					break;
+			}
+			var tempSaturday = dojo.widget.DatePicker.util.initFirstSaturday(month.toString(), year);
+			this.firstSaturday.year = tempSaturday.year;
+			this.firstSaturday.month = tempSaturday.month;
+			this.firstSaturday.date = tempSaturday.date;
+			this.initUI();
+		},
+	
+		incrementYear: function(evt) {
+			var year = this.firstSaturday.year;
+			switch(evt.target) {
+				case this.nextYearLabelNode:
+					year++;
+					break;
+				case this.previousYearLabelNode:
+					year--;
+					break;
+			}
+			var tempSaturday = dojo.widget.DatePicker.util.initFirstSaturday(this.firstSaturday.month.toString(), year);
+			this.firstSaturday.year = tempSaturday.year;
+			this.firstSaturday.month = tempSaturday.month;
+			this.firstSaturday.date = tempSaturday.date;
+			this.initUI();
+		},
+	
+		_daysIn: function(month,year) {
+			var daysIn = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; 
+			
+			if (month==1) {
+				return (year%400 == 0) ? 29: (year%100 == 0) ? 28: (year%4 == 0) ? 29: 28;
+			} else {
+				return daysIn[month];
+			}
+		},
+	
+		onIncrementDate: function(evt) {
+			dojo.unimplemented('dojo.widget.html.DatePicker.onIncrementDate');
+		},
+	
+		onIncrementWeek: function(evt) {
+			evt.stopPropagation();
+			this.incrementWeek(evt);
+		},
+	
+		onIncrementMonth: function(evt) {
+			evt.stopPropagation();
+			this.incrementMonth(evt);
+		},
+		
+		onIncrementYear: function(evt) {
+			evt.stopPropagation();
+			this.incrementYear(evt);
+		},
+	
+		setMonthLabel: function(monthIndex) {
+			this.monthLabelNode.innerHTML = dojo.date.months[monthIndex];
+		},
+		
+		setYearLabels: function(year) {
+			this.previousYearLabelNode.innerHTML = year - 1;
+			this.currentYearLabelNode.innerHTML = year;
+			this.nextYearLabelNode.innerHTML = year + 1;
+		},
+		
+		getDateClassName: function(date, monthState) {
+			var currentClassName = this.classNames[monthState];
+			if ((!this.selectedIsUsed) && (date.getDate() == this.date.getDate()) && (date.getMonth() == this.date.getMonth()) && (date.getFullYear() == this.date.getFullYear())) {
+				currentClassName = this.classNames.selectedDate + " " + currentClassName;
+				this.selectedIsUsed = 1;
+			}
+			if((!this.currentIsUsed) && (date.getDate() == this.today.getDate()) && (date.getMonth() == this.today.getMonth()) && (date.getFullYear() == this.today.getFullYear())) {
+				currentClassName = currentClassName + " "  + this.classNames.currentDate;
+				this.currentIsUsed = 1;
+			}
+			return currentClassName;
+		},
+	
+		onClick: function(evt) {
+			dojo.event.browser.stopEvent(evt)
+		},
+		
+		onSetDate: function(evt) {
+			dojo.event.browser.stopEvent(evt);
+			this.selectedIsUsed = 0;
+			this.todayIsUsed = 0;
+			var month = this.firstSaturday.month;
+			var year = this.firstSaturday.year;
+			if (dojo.html.hasClass(evt.target, this.classNames["next"])) {
+				month = ++month % 12;
+				// if month is now == 0, add a year
+				year = (month==0) ? ++year : year;
+			} else if (dojo.html.hasClass(evt.target, this.classNames["previous"])) {
+				month = --month % 12;
+				// if month is now == 0, add a year
+				year = (month==11) ? --year : year;
+			}
+			this.date = new Date(year, month, evt.target.innerHTML);
+			this.setDate(dojo.widget.DatePicker.util.toRfcDate(this.date));
+			this.initUI();
+		}
+	}
+);

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

Modified: tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/html/DebugConsole.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/html/DebugConsole.js?rev=413306&r1=413305&r2=413306&view=diff
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/html/DebugConsole.js (original)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/html/DebugConsole.js Sat Jun 10 07:27:44 2006
@@ -8,24 +8,24 @@
 		http://dojotoolkit.org/community/licensing.shtml
 */
 
-dojo.provide("dojo.widget.html.DebugConsole");
-
-dojo.require("dojo.widget.*");
-dojo.require("dojo.widget.FloatingPane");
-
-dojo.widget.html.DebugConsole= function(){
-
-	dojo.widget.html.FloatingPane.call(this);
-	dojo.widget.DebugConsole.call(this);
-}
-
-dojo.inherits(dojo.widget.html.DebugConsole, dojo.widget.html.FloatingPane);
-
-dojo.lang.extend(dojo.widget.html.DebugConsole, {
-	fillInTemplate: function() {
-		dojo.widget.html.DebugConsole.superclass.fillInTemplate.apply(this, arguments);
-		this.containerNode.id = "debugConsoleClientPane";
-		djConfig.isDebug = true;
-		djConfig.debugContainerId = this.containerNode.id;
-	}
-});
+dojo.provide("dojo.widget.html.DebugConsole");
+
+dojo.require("dojo.widget.*");
+dojo.require("dojo.widget.FloatingPane");
+
+dojo.widget.html.DebugConsole= function(){
+
+	dojo.widget.html.FloatingPane.call(this);
+	dojo.widget.DebugConsole.call(this);
+}
+
+dojo.inherits(dojo.widget.html.DebugConsole, dojo.widget.html.FloatingPane);
+
+dojo.lang.extend(dojo.widget.html.DebugConsole, {
+	fillInTemplate: function() {
+		dojo.widget.html.DebugConsole.superclass.fillInTemplate.apply(this, arguments);
+		this.containerNode.id = "debugConsoleClientPane";
+		djConfig.isDebug = true;
+		djConfig.debugContainerId = this.containerNode.id;
+	}
+});