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/10/07 20:22:39 UTC

svn commit: r453979 [4/8] - in /tapestry/tapestry4/trunk/tapestry-framework/src/js: dojo/ dojo/src/ dojo/src/collections/ dojo/src/data/ dojo/src/data/csv/ dojo/src/date/ dojo/src/debug/ dojo/src/event/ dojo/src/gfx/ dojo/src/html/ dojo/src/i18n/ dojo/...

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Button.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Button.js?view=diff&rev=453979&r1=453978&r2=453979
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Button.js (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Button.js Sat Oct  7 11:22:33 2006
@@ -15,45 +15,66 @@
 dojo.require("dojo.html.selection");
 dojo.require("dojo.widget.*");
 
+/*
+ * summary
+ *	Basically the same thing as a normal HTML button, but with special styling.
+ * usage
+ *	<button dojoType="button" onClick="...">Hello world</button>
+ *
+ *  var button1 = dojo.widget.createWidget("Button", {caption: "hello world", onClick: foo});
+ *	document.body.appendChild(button1.domNode);
+ */
 dojo.widget.defineWidget(
 	"dojo.widget.Button",
 	dojo.widget.HtmlWidget,
 	{
 		isContainer: true,
 
-		// Constructor arguments
+		// String
+		//	text to display in button
 		caption: "",
+		
+		// Boolean
+		//	if true, cannot click button
 		disabled: false,
-	
+
 		templatePath: dojo.uri.dojoUri("src/widget/templates/ButtonTemplate.html"),
 		templateCssPath: dojo.uri.dojoUri("src/widget/templates/ButtonTemplate.css"),
 		
-		// button images
+		// Url
+		//	prefix of filename holding images (left, center, right) for button in normal state
 		inactiveImg: "src/widget/templates/images/soriaButton-",
+		
+		// Url
+		//	prefix of filename holding images (left, center, right) for button when it's being hovered over
 		activeImg: "src/widget/templates/images/soriaActive-",
+
+		// Url
+		//	prefix of filename holding images (left, center, right) for button between mouse-down and mouse-up
 		pressedImg: "src/widget/templates/images/soriaPressed-",
+
+		// Url
+		//	prefix of filename holding images (left, center, right) for button when it's disabled (aka, grayed-out)
 		disabledImg: "src/widget/templates/images/soriaDisabled-",
+		
+		// Number
+		//	shape of the button's end pieces;
+		//	the height of the end pieces is a function of the button's height (which in turn is a function of the button's content),
+		//	and then the width of the end pieces is relative to their height.
 		width2height: 1.0/3.0,
-	
-		// attach points
-		buttonNode: null,
-		containerNode: null,
-		leftImage: null,
-		centerImage: null,
-		rightImage: null,
-	
-		fillInTemplate: function(args, frag){
-			if(this.caption != ""){
+
+		fillInTemplate: function(){
+			if(this.caption){
 				this.containerNode.appendChild(document.createTextNode(this.caption));
 			}
 			dojo.html.disableSelection(this.containerNode);
 		},
 
-		postCreate: function(args, frag){
-			this.sizeMyself();
+		postCreate: function(){
+			this._sizeMyself();
 		},
 	
-		sizeMyself: function(){
+		_sizeMyself: function(){
 			// we cannot size correctly if any of our ancestors are hidden (display:none),
 			// so temporarily attach to document.body
 			if(this.domNode.parentNode){
@@ -62,7 +83,7 @@
 			}
 			dojo.body().appendChild(this.domNode);
 			
-			this.sizeMyselfHelper();
+			this._sizeMyselfHelper();
 			
 			// Put this.domNode back where it was originally
 			if(placeHolder){
@@ -71,7 +92,7 @@
 			}
 		},
 
-		sizeMyselfHelper: function(){
+		_sizeMyselfHelper: function(){
 			var mb = dojo.html.getMarginBox(this.containerNode);
 			this.height = mb.height;
 			this.containerWidth = mb.width;
@@ -99,26 +120,31 @@
 			this.domNode.style.width= (this.containerWidth+2*endWidth) + "px";
 		},
 	
-		onMouseOver: function(e){
+		onMouseOver: function(/*Event*/ e){
+			// summary: callback when user mouses-over the button
 			if( this.disabled ){ return; }
 			dojo.html.prependClass(this.buttonNode, "dojoButtonHover");
 			this._setImage(this.activeImg);
 		},
 	
-		onMouseDown: function(e){
+		onMouseDown: function(/*Event*/ e){
+			// summary: callback when user starts to click the button
 			if( this.disabled ){ return; }
 			dojo.html.prependClass(this.buttonNode, "dojoButtonDepressed");
 			dojo.html.removeClass(this.buttonNode, "dojoButtonHover");
 			this._setImage(this.pressedImg);
 		},
-		onMouseUp: function(e){
+
+		onMouseUp: function(/*Event*/ e){
+			// summary: callback when the user finishes clicking
 			if( this.disabled ){ return; }
 			dojo.html.prependClass(this.buttonNode, "dojoButtonHover");
 			dojo.html.removeClass(this.buttonNode, "dojoButtonDepressed");
 			this._setImage(this.activeImg);
 		},
 	
-		onMouseOut: function(e){
+		onMouseOut: function(/*Event*/ e){
+			// summary: callback when the user moves the mouse off the button
 			if( this.disabled ){ return; }
 			if( e.toElement && dojo.html.isDescendantOf(e.toElement, this.buttonNode) ){
 				return; // Ignore IE mouseOut events that dont actually leave button - Prevents hover image flicker in IE
@@ -127,15 +153,15 @@
 			this._setImage(this.inactiveImg);
 		},
 
-		onKey: function(e){
+		onKey: function(/*Event*/ e){
+			// summary: callback when the user presses a key (on key-down)
 			if (!e.key) { return; }
 			var menu = dojo.widget.getWidgetById(this.menuId);
 			if (e.key == e.KEY_ENTER || e.key == " "){
 				this.onMouseDown(e);
 				this.buttonClick(e);
 				dojo.lang.setTimeout(this, "onMouseUp", 75, e);
-				e.preventDefault();
-				e.stopPropagation();
+				dojo.event.browser.stopEvent(e);
 			}
 			if(menu && menu.isShowingNow && e.key == e.KEY_DOWN_ARROW){
 				// disconnect onBlur when focus moves into menu
@@ -144,14 +170,16 @@
 			}
 		},
 
-		onFocus: function(e){
+		onFocus: function(/*Event*/ e){
+			// summary: callback on focus to the button
 			var menu = dojo.widget.getWidgetById(this.menuId);
-			if (menu ){
+			if (menu){
 				dojo.event.connectOnce(this.domNode, "onblur", this, "onBlur");
 			}
 		},
 
-		onBlur: function(e){
+		onBlur: function(/*Event*/ e){
+			// summary: callback when button loses focus
 			var menu = dojo.widget.getWidgetById(this.menuId);
 			if ( !menu ) { return; }
 	
@@ -160,19 +188,27 @@
 			}
 		},
 
-		buttonClick: function(e){
-			if( !this.disabled ) { this.onClick(e); }
+		buttonClick: function(/*Event*/ e){
+			// summary: internal function for handling button clicks
+			if(!this.disabled){ 
+				// focus may fail when tabIndex is not supported on div's
+				// by the browser, or when the node is disabled
+				try { this.domNode.focus(); } catch(e2) {};
+				this.onClick(e); 
+			}
 		},
 
-		onClick: function(e) { },
+		onClick: function(/*Event*/ e) {
+			// summary: callback for when button is clicked; user can override this function
+		},
 
-		_setImage: function(prefix){
+		_setImage: function(/*String*/ prefix){
 			this.leftImage.src=dojo.uri.dojoUri(prefix + "l.gif");
 			this.centerImage.src=dojo.uri.dojoUri(prefix + "c.gif");
 			this.rightImage.src=dojo.uri.dojoUri(prefix + "r.gif");
 		},
 		
-		_toggleMenu: function(menuId){
+		_toggleMenu: function(/*String*/ menuId){
 			var menu = dojo.widget.getWidgetById(menuId); 
 			if ( !menu ) { return; }
 			if ( menu.open && !menu.isShowingNow) {
@@ -185,32 +221,47 @@
 			}
 		},
 		
-		setCaption: function(content){
+		setCaption: function(/*String*/ content){
+			// summary: reset the caption (text) of the button; takes an HTML string
 			this.caption=content;
 			this.containerNode.innerHTML=content;
-			this.sizeMyself();
+			this._sizeMyself();
 		},
 		
-		setDisabled: function(disabled){
+		setDisabled: function(/*Boolean*/ disabled){
+			// summary: set disabled state of button
 			this.disabled=disabled;
-			this.sizeMyself();
+			this._sizeMyself();
 		}
 	});
 
-/**** DropDownButton - push the button and a menu shows up *****/
+/*
+ * summary
+ *	push the button and a menu shows up
+ * usage
+ *	<button dojoType="DropDownButton" menuId="mymenu">Hello world</button>
+ *
+ *  var button1 = dojo.widget.createWidget("DropDownButton", {caption: "hello world", menuId: foo});
+ *	document.body.appendChild(button1.domNode);
+ */
 dojo.widget.defineWidget(
 	"dojo.widget.DropDownButton",
 	dojo.widget.Button,
 	{
+		// String
+		//	widget id of the menu that this button should activate
 		menuId: "",
 
-		arrow: null,
-	
+		// Url
+		//	path of arrow image to display to the right of the button text
 		downArrow: "src/widget/templates/images/whiteDownArrow.gif",
+
+		// Url
+		//	path of arrow image to display to the right of the button text, when the button is disabled
 		disabledDownArrow: "src/widget/templates/images/whiteDownArrow.gif",
 	
-		fillInTemplate: function(args, frag){
-			dojo.widget.DropDownButton.superclass.fillInTemplate.call(this, args, frag);
+		fillInTemplate: function(){
+			dojo.widget.DropDownButton.superclass.fillInTemplate.apply(this, arguments);
 	
 			this.arrow = document.createElement("img");
 			dojo.html.setClass(this.arrow, "downArrow");
@@ -218,37 +269,48 @@
 			dojo.widget.wai.setAttr(this.domNode, "waiState", "haspopup", this.menuId);
 		},
 
-		sizeMyselfHelper: function(){
+		_sizeMyselfHelper: function(){
 			// draw the arrow (todo: why is the arror in containerNode rather than outside it?)
 			this.arrow.src = dojo.uri.dojoUri(this.disabled ? this.disabledDownArrow : this.downArrow);
 			this.containerNode.appendChild(this.arrow);
 
-			dojo.widget.DropDownButton.superclass.sizeMyselfHelper.call(this);
+			dojo.widget.DropDownButton.superclass._sizeMyselfHelper.call(this);
 		},
 
-		onClick: function (e){
+		onClick: function(/*Event*/ e){
+			// summary: callback when button is clicked; user shouldn't override this function or else the menu won't toggle
 			this._toggleMenu(this.menuId);
 		}
 	});
 
-/**** ComboButton - left side is normal button, right side shows menu *****/
+/*
+ * summary
+ *	left side is normal button, right side displays menu
+ * usage
+ *	<button dojoType="ComboButton" onClick="..." menuId="mymenu">Hello world</button>
+ *
+ *  var button1 = dojo.widget.createWidget("DropDownButton", {caption: "hello world", onClick: foo, menuId: "myMenu"});
+ *	document.body.appendChild(button1.domNode);
+ */
 dojo.widget.defineWidget(
 	"dojo.widget.ComboButton",
 	dojo.widget.Button,
 	{
+		// String
+		//	widget id of the menu that this button should activate
 		menuId: "",
 	
 		templatePath: dojo.uri.dojoUri("src/widget/templates/ComboButtonTemplate.html"),
 	
-		// attach points
-		rightPart: null,
-		arrowBackgroundImage: null,
-	
-		// constants
-		splitWidth: 2,		// pixels between left&right part of button
-		arrowWidth: 5,		// width of segment holding down arrow
+		// Integer
+		//	# of pixels between left & right part of button
+		splitWidth: 2,
+		
+		// Integer
+		//	width of segment holding down arrow
+		arrowWidth: 5,
 	
-		sizeMyselfHelper: function(e){
+		_sizeMyselfHelper: function(/*Event*/ e){
 			var mb = dojo.html.getMarginBox(this.containerNode);
 			this.height = mb.height;
 			this.containerWidth = mb.width;
@@ -292,33 +354,52 @@
 		},
 	
 		/*** functions on right part of button ***/
-		rightOver: function(e){
+		rightOver: function(/*Event*/ e){
+			// summary:
+			//	callback when mouse-over right part of button;
+			//	onMouseOver() is the callback for the left side of the button.
 			if( this.disabled ){ return; }
 			dojo.html.prependClass(this.rightPart, "dojoButtonHover");
 			this._setImageR(this.activeImg);
 		},
 	
-		rightDown: function(e){
+		rightDown: function(/*Event*/ e){
+			// summary:
+			//	callback when mouse-down right part of button;
+			//	onMouseDown() is the callback for the left side of the button.
 			if( this.disabled ){ return; }
 			dojo.html.prependClass(this.rightPart, "dojoButtonDepressed");
 			dojo.html.removeClass(this.rightPart, "dojoButtonHover");
 			this._setImageR(this.pressedImg);
 		},
-		rightUp: function(e){
+
+		rightUp: function(/*Event*/ e){
+			// summary:
+			//	callback when mouse-up right part of button;
+			//	onMouseUp() is the callback for the left side of the button.
 			if( this.disabled ){ return; }
 			dojo.html.prependClass(this.rightPart, "dojoButtonHover");
 			dojo.html.removeClass(this.rightPart, "dojoButtonDepressed");
 			this._setImageR(this.activeImg);
 		},
 	
-		rightOut: function(e){
+		rightOut: function(/*Event*/ e){
+			// summary:
+			//	callback when moving the mouse off of the right part of button;
+			//	onMouseOut() is the callback for the left side of the button.
 			if( this.disabled ){ return; }
 			dojo.html.removeClass(this.rightPart, "dojoButtonHover");
 			this._setImageR(this.inactiveImg);
 		},
 
-		rightClick: function(e){
+		rightClick: function(/*Event*/ e){
+			// summary:
+			//	callback when clicking the right part of button;
+			//	onClick() is the callback for the left side of the button.
 			if( this.disabled ){ return; }
+			// focus may fail when tabIndex is not supported on div's
+			// by the browser, or when the node is disabled
+			try { this.domNode.focus(); } catch(e2) {};
 			this._toggleMenu(this.menuId);
 		},
 	
@@ -329,21 +410,19 @@
 
 		/*** keyboard functions ***/
 		
-		onKey: function(e){
+		onKey: function(/*Event*/ e){
 			if (!e.key) { return; }
 			var menu = dojo.widget.getWidgetById(this.menuId);
 			if(e.key== e.KEY_ENTER || e.key == " "){
 				this.onMouseDown(e);
 				this.buttonClick(e);
 				dojo.lang.setTimeout(this, "onMouseUp", 75, e);
-				e.preventDefault();
-				e.stopPropagation();
+				dojo.event.browser.stopEvent(e);
 			} else if (e.key == e.KEY_DOWN_ARROW && e.altKey){
 				this.rightDown(e);
 				this.rightClick(e);
 				dojo.lang.setTimeout(this, "rightUp", 75, e);
-				e.preventDefault();
-				e.stopPropagation();
+				dojo.event.browser.stopEvent(e);
 			} else if(menu && menu.isShowingNow && e.key == e.KEY_DOWN_ARROW){
 				// disconnect onBlur when focus moves into menu
 				dojo.event.disconnect(this.domNode, "onblur", this, "onBlur");

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Checkbox.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Checkbox.js?view=diff&rev=453979&r1=453978&r2=453979
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Checkbox.js (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Checkbox.js Sat Oct  7 11:22:33 2006
@@ -14,7 +14,10 @@
 dojo.require("dojo.widget.HtmlWidget");
 dojo.require("dojo.event.*");
 dojo.require("dojo.html.style");
+dojo.require("dojo.html.selection");
 
+// summary
+//	Same as an HTML checkbox, but with fancy styling
 dojo.widget.defineWidget(
 	"dojo.widget.Checkbox",
 	dojo.widget.HtmlWidget,
@@ -22,119 +25,149 @@
 		templatePath: dojo.uri.dojoUri('src/widget/templates/Checkbox.html'),
 		templateCssPath: dojo.uri.dojoUri('src/widget/templates/Checkbox.css'),
 
-		// attributes
-		disabled: "enabled",
+		// Boolean
+		//	if true, clicking will not change the state of the checkbox.
+		//	in markup, this is specified as "disabled='disabled'", or just "disabled", 
+		disabled: false,
+		
+		// String
+		//	name used when submitting form; same as "name" attribute or plain HTML elements
 		name: "",
-		checked: "",
-		tabIndex: "",
+
+		// String
+		//	id attached to the checkbox, used when submitting form
 		id: "",
-		value: "on",
+
+		// Boolean
+		//	if true, checkbox is initially marked turned on;
+		//	in markup, specified as "checked='checked'" or just "checked"
+		checked: false,
+		
+		// Integer
+		//	order fields are traversed when user hits the tab key
+		tabIndex: "",
 
 		postMixInProperties: function(){
 			dojo.widget.Checkbox.superclass.postMixInProperties.apply(this, arguments);
-			// set the variables referenced by the template
-			// valid HTML 4.01 and XHTML use disabled="disabled" - convert to boolean 
-			//NOTE: this doesn't catch disabled with no value if FF
-			this.disabled = (this.disabled == "disabled" || this.disabled == true);
-			// valid HTML 4.01 and XHTML require checked="checked"
-			// convert to boolean NOTE: this doesn't catch checked with no value in FF
-			this.checked = (this.checked == "checked" || this.checked == true);
-
-			// output valid checked and disabled attributes
-			this.disabledStr = this.disabled ? "disabled=\"disabled\"" : "";
-			this.checkedStr = this.checked ? "checked=\"checked\"" : "";
-
+			
 			// set tabIndex="0" because if tabIndex=="" user won't be able to tab to the field
-
-
 			if(!this.disabled && this.tabIndex==""){ this.tabIndex="0"; }
 		},
 
-		postCreate: function(args, frag){
+		postCreate: function(){
 			// find any associated label and create a labelled-by relationship
 			// assumes <label for="inputId">label text </label> rather than
-			// <label><input type="xyzzy">label text</label> 
+			// <label><input type="xyzzy">label text</label>
+			var notcon = true;
+			this.id = this.id !="" ? this.id : this.widgetId;
 			if(this.id != ""){
 				var labels = document.getElementsByTagName("label");
 				if (labels != null && labels.length > 0){
 					for(var i=0; i<labels.length; i++){
 						if (labels[i].htmlFor == this.id){
-							labels[i].id = (labels[i].htmlFor + "label"); 
+							labels[i].id = (labels[i].htmlFor + "label");
+							this._connectEvents(labels[i]);
 							dojo.widget.wai.setAttr(this.domNode, "waiState", "labelledby", labels[i].id);
 							break;
 						}
 					}
 				}
 			}
+			this._connectEvents(this.domNode);
+			// this is needed here for IE
+			this.inputNode.checked=this.checked;
+		},
+
+		_connectEvents: function(/*DomNode*/ node){
+			dojo.event.connect(node, "onmouseover", this, "mouseOver");
+			dojo.event.connect(node, "onmouseout", this, "mouseOut");
+			dojo.event.connect(node, "onkey", this, "onKey");
+			dojo.event.connect(node, "onclick", this, "_onClick");
+			dojo.html.disableSelection(node);
 		},
 
 		fillInTemplate: function(){
 			this._setInfo();
 		},
 
-		_onClick: function(e){
+		_onClick: function(/*Event*/ e){
 			if(this.disabled == false){
 				this.checked = !this.checked;
 				this._setInfo();
 			}
 			e.preventDefault();
+			e.stopPropagation();
 			this.onClick();
 		},
 
-		// user overridable function
-		onClick: function(){ },
+		onClick: function(){
+			// summary: user overridable callback function for checkbox being clicked
+		},
 
-		onKey: function(e){
+		onKey: function(/*Event*/ e){
+			// summary: callback when user hits a key
 			var k = dojo.event.browser.keys;
 			if(e.key == " "){
 	 			this._onClick(e);
 	 		}
 		},
-		
-		mouseOver: function(e){
-			this.hover(e, true);
+
+		mouseOver: function(/*Event*/ e){
+			// summary: callback when user moves mouse over checkbox
+			this._hover(e, true);
 		},
-		
-		mouseOut: function(e){
-			this.hover(e, false);
+
+		mouseOut: function(/*Event*/ e){
+			// summary: callback when user moves mouse off of checkbox
+			this._hover(e, false);
 		},
-		
-		hover: function(e, isOver){
+
+		_hover: function(/*Event*/ e, /*Boolean*/ isOver){
 			if (this.disabled == false){
 				var state = this.checked ? "On" : "Off";
 				var style = "dojoHtmlCheckbox" + state + "Hover";
 				if (isOver){
-					dojo.html.addClass(this.domNode, style);
+					dojo.html.addClass(this.imageNode, style);
 				}else{
-					dojo.html.removeClass(this.domNode,style);
+					dojo.html.removeClass(this.imageNode,style);
 				}
 			}
 		},
 
-		// set CSS class string according to checked/unchecked and disabled/enabled state
 		_setInfo: function(){
+			// summary: set CSS class string according to checked/unchecked and disabled/enabled state
 			var state = "dojoHtmlCheckbox" + (this.disabled ? "Disabled" : "") + (this.checked ? "On" : "Off");
-			dojo.html.setClass(this.domNode, "dojoHtmlCheckbox " + state);
+			dojo.html.setClass(this.imageNode, "dojoHtmlCheckbox " + state);
 			this.inputNode.checked = this.checked;
+			if (this.disabled){
+				this.inputNode.disabled = true;
+			}
 			dojo.widget.wai.setAttr(this.domNode, "waiState", "checked", this.checked);
 		}
 	}
 );
+
+// summary
+//	variation on Checkbox widget to be display on monitors in high-contrast mode (that don't display CSS background images)
 dojo.widget.defineWidget(
 	"dojo.widget.a11y.Checkbox",
 	dojo.widget.Checkbox,
-	{	
+	{
 		templatePath: dojo.uri.dojoUri('src/widget/templates/CheckboxA11y.html'),
-		
+
 		postCreate: function(args, frag){
-			// nothing to do but don't want Checkbox version to run
+			this.inputNode.checked=this.checked;
+			//only set disabled if true since FF interprets any value for disabled as true
+			if (this.disabled){
+				this.inputNode.setAttribute("disabled",true);
+			} 
 		},
-		
+
 		fillInTemplate: function(){
 		},
+
 		_onClick: function(){
 			this.onClick();
 		}
 	}
-);
-
+);
\ No newline at end of file

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Clock.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Clock.js?view=diff&rev=453979&r1=453978&r2=453979
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Clock.js (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Clock.js Sat Oct  7 11:22:33 2006
@@ -208,4 +208,4 @@
 			this.start();
 		}
 	}
-);
+);

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/ColorPalette.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/ColorPalette.js?view=diff&rev=453979&r1=453978&r2=453979
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/ColorPalette.js (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/ColorPalette.js Sat Oct  7 11:22:33 2006
@@ -10,51 +10,18 @@
 
 dojo.provide("dojo.widget.ColorPalette");
 dojo.require("dojo.widget.*");
-dojo.require("dojo.widget.Toolbar");
 dojo.require("dojo.html.layout");
 dojo.require("dojo.html.display");
 dojo.require("dojo.html.selection");
 
 dojo.widget.defineWidget(
-	"dojo.widget.ToolbarColorDialog",
-	dojo.widget.ToolbarDialog,
-{
- 	palette: "7x10",
-
-	fillInTemplate: function (args, frag) {
-		dojo.widget.ToolbarColorDialog.superclass.fillInTemplate.call(this, args, frag);
-		this.dialog = dojo.widget.createWidget("ColorPalette", {palette: this.palette});
-		this.dialog.domNode.style.position = "absolute";
-
-		dojo.event.connect(this.dialog, "onColorSelect", this, "_setValue");
-	},
-
-	_setValue: function(color) {
-		this._value = color;
-		this._fireEvent("onSetValue", color);
-	},
-	
-	showDialog: function (e) {
-		dojo.widget.ToolbarColorDialog.superclass.showDialog.call(this, e);
-		var abs = dojo.html.getAbsolutePosition(this.domNode, true);
-		var y = abs.y + dojo.html.getBorderBox(this.domNode).height;
-		this.dialog.showAt(abs.x, y);
-	},
-	
-	hideDialog: function (e) {
-		dojo.widget.ToolbarColorDialog.superclass.hideDialog.call(this, e);
-		this.dialog.hide();
-	}
-});
-
-dojo.widget.defineWidget(
 	"dojo.widget.ColorPalette",
 	dojo.widget.HtmlWidget,
-{	
+{
 	palette: "7x10",
 
 	bgIframe: null,
-	
+
 	palettes: {
 		"7x10": [["fff", "fcc", "fc9", "ff9", "ffc", "9f9", "9ff", "cff", "ccf", "fcf"],
 			["ccc", "f66", "f96", "ff6", "ff3", "6f9", "3ff", "6ff", "99f", "f9f"],
@@ -63,7 +30,7 @@
 			["666", "900", "c60", "c93", "990", "090", "399", "33f", "60c", "939"],
 			["333", "600", "930", "963", "660", "060", "366", "009", "339", "636"],
 			["000", "300", "630", "633", "330", "030", "033", "006", "309", "303"]],
-	
+
 		"3x4": [["ffffff"/*white*/, "00ff00"/*lime*/, "008000"/*green*/, "0000ff"/*blue*/],
 			["c0c0c0"/*silver*/, "ffff00"/*yellow*/, "ff00ff"/*fuchsia*/, "000080"/*navy*/],
 			["808080"/*gray*/, "ff0000"/*red*/, "800080"/*purple*/, "000000"/*black*/]]
@@ -88,7 +55,7 @@
 				if (colors[i][j].length == 3) {
 					colors[i][j] = colors[i][j].replace(/(.)(.)(.)/, "$1$1$2$2$3$3");
 				}
-	
+
 				var td = tr.insertCell(-1);
 				with (td.style) {
 					backgroundColor = "#" + colors[i][j];
@@ -96,13 +63,13 @@
 					width = height = "15px";
 					fontSize = "1px";
 				}
-	
+
 				td.color = "#" + colors[i][j];
-	
+
 				td.onmouseover = function (e) { this.style.borderColor = "white"; }
 				td.onmouseout = function (e) { this.style.borderColor = "gray"; }
 				dojo.event.connect(td, "onmousedown", this, "click");
-	
+
 				td.innerHTML = "&nbsp;";
 			}
 		}
@@ -132,7 +99,7 @@
 			this.bgIframe.style.display = "none";
 		}
 	},
-	
+
 	showAt: function (x, y) {
 		with(this.domNode.style){
 			top = y + "px";

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/ComboBox.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/ComboBox.js?view=diff&rev=453979&r1=453978&r2=453979
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/ComboBox.js (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/ComboBox.js Sat Oct  7 11:22:33 2006
@@ -76,8 +76,8 @@
 	// structure for storage of items.
 
 	this.data = [];
-	this.searchTimeout = timeout | 500;
-	this.searchLimit = limit | 30;
+	this.searchTimeout = timeout || 500;
+	this.searchLimit = limit || 30;
 	this.searchType = "STARTSTRING"; // may also be "STARTWORD" or "SUBSTRING"
 	this.caseSensitive = false;
 	// for caching optimizations
@@ -95,7 +95,8 @@
 				var ol = opts.length;
 				var data = [];
 				for(var x=0; x<ol; x++){
-					var keyValArr = [String(opts[x].innerHTML), String(opts[x].value)];
+					var text = opts[x].textContent || opts[x].innerText || opts[x].innerHTML;
+					var keyValArr = [String(text), String(opts[x].value)];
 					data.push(keyValArr);
 					if(opts[x].selected){ 
 						cbox.setAllValues(keyValArr[0], keyValArr[1]);
@@ -242,7 +243,6 @@
 		optionsListWrapper: null,
 		optionsListNode: null,
 		downArrowNode: null,
-		cbTableNode: null,
 		searchTimer: null,
 		searchDelay: 100,
 		dataUrl: "",
@@ -458,8 +458,8 @@
 		},
 
 		setAllValues: function(value1, value2){
-			this.setValue(value1);
 			this.setSelectedValue(value2);
+			this.setValue(value1);
 		},
 
 		// does the actual highlight
@@ -512,19 +512,14 @@
 
 		// reset button size; this function is called when the input area has changed size
 		onResize: function(){
-			var inputSize = dojo.html.getBorderBox(this.textInputNode);
+			var inputSize = dojo.html.getContentBox(this.textInputNode);
+			if( inputSize.height == 0 ){
+				// need more time to calculate size
+				dojo.lang.setTimeout(this, "onResize", 50);
+				return;
+			}
 			var buttonSize = { width: inputSize.height, height: inputSize.height};
-			dojo.html.setMarginBox(this.downArrowNode, buttonSize);
-		},
-
-		postMixInProperties: function(args, frag){
-			this.inherited("postMixInProperties", [args, frag]); 
-
-			// set image size before instantiating template;
-			// changing it afterwards doesn't work on FF
-			var inputNode = this.getFragNodeRef(frag);
-			var inputSize = dojo.html.getBorderBox(inputNode);
-			this.initialButtonSize = inputSize.height + "px";
+			dojo.html.setContentBox(this.downArrowNode, buttonSize);
 		},
 
 		fillInTemplate: function(args, frag){
@@ -536,7 +531,14 @@
 			this.comboBoxValue.name = this.name; 
 			this.comboBoxSelectionValue.name = this.name+"_selected";
 
+			/* different nodes get different parts of the style */
+			dojo.html.copyStyle(this.domNode, source);
 			dojo.html.copyStyle(this.textInputNode, source);
+			dojo.html.copyStyle(this.downArrowNode, source);
+			with (this.downArrowNode.style) { // calculate these later
+				width = "0px";
+				height = "0px";
+			}
 
 			var dpClass;
 			if(this.mode == "remote"){
@@ -729,7 +731,6 @@
 				}
 			}
 
-			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){
@@ -773,7 +774,7 @@
 					width = (dojo.html.getMarginBox(this.domNode).width-2)+"px";
 					
 				}
-				this.popupWidget.open(this.cbTableNode, this, this.downArrowNode);
+				this.popupWidget.open(this.domNode, this, this.downArrowNode);
 			}else{
 				this.hideResultList();
 			}
@@ -804,6 +805,7 @@
 		},
 
 		postCreate: function(){
+			this.onResize();
 			dojo.event.connect(this, "startSearch", this.dataProvider, "startSearch");
 			dojo.event.connect(this.dataProvider, "provideSearchResults", this, "openResultList");
 			dojo.event.connect(this.textInputNode, "onblur", this, "onBlurInput");
@@ -816,5 +818,3 @@
 		}
 	}
 );
-
-

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/ContentPane.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/ContentPane.js?view=diff&rev=453979&r1=453978&r2=453979
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/ContentPane.js (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/ContentPane.js Sat Oct  7 11:22:33 2006
@@ -8,10 +8,6 @@
 		http://dojotoolkit.org/community/licensing.shtml
 */
 
-// This widget doesn't do anything; is basically the same as <div>.
-// It's useful as a child of LayoutContainer, SplitContainer, or TabContainer.
-// But note that those classes can contain any widget as a child.
-
 dojo.provide("dojo.widget.ContentPane");
 
 dojo.require("dojo.widget.*");
@@ -21,6 +17,15 @@
 dojo.require("dojo.string.extras");
 dojo.require("dojo.html.style");
 
+
+// summary:
+//		dojo.widget.ContentPane, a widget that can be used as a standalone widget 
+//		or as a baseclass for other widgets
+//		Handles replacement of document fragment using either external uri or javascript/java 
+//		generated markup or DomNode content, instanciating widgets within content and runs scripts.
+//		Dont confuse it with an iframe, it only needs document fragments.
+//		It's useful as a child of LayoutContainer, SplitContainer, or TabContainer.
+//		But note that those classes can contain any widget as a child.
 dojo.widget.defineWidget(
 	"dojo.widget.ContentPane",
 	dojo.widget.HtmlWidget,
@@ -29,28 +34,76 @@
 		this._styleNodes =  [];
 		this._onLoadStack = [];
 		this._onUnloadStack = [];
-		this._callOnUnLoad = false;
-		this.scriptScope; // undefined for now
+		this._callOnUnload = false;
 		this._ioBindObj;
+		// Function:
+		//		reference holder to the inline scripts container, if scriptSeparation is true
+		//	Note:
+		//		dont change this value externally
+		this.scriptScope; // undefined for now
 
 		// loading option
-		this.bindArgs = {}; // example bindArgs="preventCache:false;" overrides cacheContent
+		// Object:
+		//		Send in extra args to the dojo.io.bind call
+		//	example:
+		//		bindArgs="preventCache:false;" overrides cacheContent
+		this.bindArgs = {};
+
+	
 	}, {
 		isContainer: true,
 
 		// loading options
-		adjustPaths: true, // fix relative paths in content to fit in this page
-		href: "", // only usable on construction, use setUrl or setContent after that
-		extractContent: true,	// extract visible content from inside of <body> .... </body>
-		parseContent:	true,	// construct all widgets that is in content
+		// Boolean:
+		//		adjust relative paths in markup to fit this page
+		adjustPaths: true,
+
+		// String:
+		//		The href of the content that displays now
+		//		Set this at construction if you want to load externally,
+		//		changing href after creation doesnt have any effect, see setUrl
+		href: "",
+
+		// Boolean: Extract visible content from inside of <body> .... </body>
+		extractContent: true,
+
+		// Boolean: Construct all widgets that is in content
+		parseContent:	true,
+
+		// Boolean: Cache content retreived externally
 		cacheContent:	true,
-		preload: false,	// force load of data even if pane is hidden
-		refreshOnShow: false,	// use with cacheContent: false
-		handler: "", // generate pane content from a java function
-		executeScripts: false,	// if true scripts in content will be evaled after content is innerHTML'ed
-		scriptSeparation: true,	// if false script eval in global scope
+
+		// Boolean:
+		//		Force load of data even if pane is hidden
+		//	Note:
+		//		In order to delay download you need to initially hide the node it constructs from
+		preload: false,
+
+		// Boolean:
+		//		Refresh (re-download) content when pane goes from hidden to shown
+		refreshOnShow: false,
+
+		// String||Function:
+		//		Generate pane content from a java function
+		//		The name of the java proxy function
+		handler: "",
+
+		// Boolean:
+		//		Run scripts within content, extractContent has NO effect on this
+		//	Note:
+		//		if true scripts in content will be evaled after content is innerHTML'ed
+		executeScripts: false,
+
+		// Boolean:
+		//		Run scripts in a separate scope, unique for each ContentPane
+		scriptSeparation: true,
+
+		// String: Message that shows while downloading
 		loadingMessage: "Loading...",
 
+		// Boolean: Tells loading status
+		isLoaded: false,
+
 		postCreate: function(args, frag, parentComp){
 			if (this.handler!==""){
 				this.setHandler(this.handler);
@@ -71,11 +124,15 @@
 		},
 	
 		refresh: function(){
+			// summary:
+			//		Force a refresh (re-download) of content, be sure to turn of cache
 			this.isLoaded=false;
 			this.loadContents();
 		},
 	
 		loadContents: function() {
+			// summary:
+			//		Download if isLoaded is false, else ignore
 			if ( this.isLoaded ){
 				return;
 			}
@@ -86,9 +143,11 @@
 			}
 		},
 		
-		setUrl: function(/*String or dojo.uri.Uri*/ url) {
+		setUrl: function(/*String||dojo.uri.Uri*/ url) {
 			// summary:
-			// 	Reset the (external defined) content of this pane and replace with new url
+			//		Reset the (external defined) content of this pane and replace with new url
+			//	Note:
+			//		It delays the download until widget is shown if preload is false
 			this.href = url;
 			this.isLoaded = false;
 			if ( this.preload || this.isShowing() ){
@@ -98,7 +157,7 @@
 
 		abort: function(){
 			// summary
-			//	abort download of content
+			//		Aborts a inflight download of content
 			var bind = this._ioBindObj;
 			if(!bind || !bind.abort){ return; }
 			bind.abort();
@@ -147,16 +206,28 @@
 			return bindObj;
 		},
 
-		// called when setContent is finished
 		onLoad: function(e){
+			// summary:
+			//		Event hook, is called after everything is loaded and widgetified 
 			this._runStack("_onLoadStack");
 			this.isLoaded=true;
 		},
 	
-		// called before old content is cleared
 		onUnLoad: function(e){
+			// summary:
+			//		Deprecated, use onUnload (lowercased load)
+			dojo.deprecated(this.widgetType+".onUnLoad, use .onUnload (lowercased load)", 0.5);
+		},
+
+		onUnload: function(e){
+			// summary:
+			//		Event hook, is called before old content is cleared
 			this._runStack("_onUnloadStack");
 			delete this.scriptScope;
+			// FIXME: remove for 0.5 along with onUnLoad
+			if(this.onUnLoad !== dojo.widget.ContentPane.prototype.onUnLoad){
+				this.onUnLoad.apply(this, arguments);
+			}
 		},
 	
 		_runStack: function(stName){
@@ -177,19 +248,31 @@
 			}
 		},
 	
-		addOnLoad: function(/*Function or Object ?*/ obj, /*Function*/ func){
+		addOnLoad: function(/*Function||Object, optional*/ obj, /*Function*/ func){
 			// summary
-			// 	same as to dojo.addOnLoad but does not take "function_name" as a string
+			//		Stores function refs and calls them one by one in the order they came in
+			//		when load event occurs.
+			//	obj:
+			//		holder object
+			//	func:
+			//		function that will be called 
 			this._pushOnStack(this._onLoadStack, obj, func);
 		},
 	
-		addOnUnload: function(/*Function or Object ?*/ obj, /*Function*/ func){
+		addOnUnload: function(/*Function||Object, optional*/ obj, /*Function*/ func){
 			// summary
-			// 	same as to dojo.addUnOnUnload but does not take "function_name" as a string
+			//		Stores function refs and calls them one by one in the order they came in
+			//		when unload event occurs.
+			//	obj:
+			//		holder object
+			//	func:
+			//		function that will be called 
 			this._pushOnStack(this._onUnloadStack, obj, func);
 		},
 
 		addOnUnLoad: function(){
+			// summary:
+			//		Deprecated use addOnUnload (lower cased load)
 			dojo.deprecated(this.widgetType + ".addOnUnLoad, use addOnUnload instead. (lowercased Load)", 0.5);
 			this.addOnUnload.apply(this, arguments);
 		},
@@ -203,25 +286,43 @@
 		},
 	
 		destroy: function(){
-			// make sure we call onUnLoad
-			this.onUnLoad();
+			// make sure we call onUnload
+			this.onUnload();
 			dojo.widget.ContentPane.superclass.destroy.call(this);
 		},
+ 
+		onExecError: function(/*Object*/e){
+			// summary:
+			//		called when content script eval error or Java error occurs, preventDefault-able
+			//		default is to debug not alert as in 0.3.1
+		},
 	
-		// called when content script eval error or Java error occurs, preventDefault-able
-		onExecError: function(e){ /*stub*/ },
-	
-		// called on DOM faults, require fault etc in content, preventDefault-able
-		onContentError: function(e){ /*stub*/ },
+		onContentError: function(/*Object*/e){
+			// summary: 
+			//		called on DOM faults, require fault etc in content, preventDefault-able
+			//		default is to display errormessage inside pane
+		},
 	
-		// called when download error occurs, preventDefault-able
-		onDownloadError: function(e){ /*stub*/ },
+		onDownloadError: function(/*Object*/e){
+			// summary: 
+			//		called when download error occurs, preventDefault-able
+			//		default is to display errormessage inside pane
+		},
 	
-		// called before download starts, preventDefault-able
-		onDownloadStart: function(e){ /*stub*/ },
+		onDownloadStart: function(/*Object*/e){
+			// summary:
+			//		called before download starts, preventDefault-able
+			//		default is to display loadingMessage inside pane
+			//		by changing e.text in your event handler you can change loading message
+		},
 	
-		// called when download is finished
-		onDownloadEnd: function(/*String*/ url, /*content*/ data){
+		// 
+		onDownloadEnd: function(/*String*/ url, /*String*/ data){
+			// summary:
+			//		called when download is finished
+			//
+			//	url: url that downloaded data
+			//	data: the markup that was downloaded
 			data = this.splitAndFixPaths(data, url);
 			this.setContent(data);
 		},
@@ -253,10 +354,10 @@
 						dojo.debug(e.toString()); break;
 					default:
 					// makes sure scripts can clean up after themselves, before we setContent
-					if(this._callOnUnLoad){ this.onUnLoad(); } 
+					if(this._callOnUnload){ this.onUnload(); } 
 					// makes sure we dont try to call onUnLoad again on this event,
 					// ie onUnLoad before 'Loading...' but not before clearing 'Loading...'
-					this._callOnUnLoad = false;
+					this._callOnUnload = false;
 
 					// we might end up in a endless recursion here if domNode cant append content
 					if(arguments.callee._loopStop){
@@ -271,13 +372,15 @@
 		},
 	
 		// pathfixes, require calls, css stuff and neccesary content clean
-		splitAndFixPaths: function(/*String*/s, /*dojo.uri.Uri?*/url){
+		splitAndFixPaths: function(/*String*/s, /*String||dojo.uri.Uri, optional*/url){
 			// summary:
-			// 	fixes all relative paths in (hopefully) all cases for example images, remote scripts, links etc.
-			// 	splits up content in different pieces, scripts, title, style, link and whats left becomes .xml
+			// 		adjusts all relative paths in (hopefully) all cases, images, remote scripts, links etc.
+			// 		splits up content in different pieces, scripts, title, style, link and whats left becomes .xml
 
-			// init vars
-			var titles = [], scripts = [],tmp = [];
+			//	s:	The markup in string
+			//	url: url that pulled in markup
+
+			var titles = [], scripts = [],tmp = [];// init vars
 			var match = [], requires = [], attr = [], styles = [];
 			var str = '', path = '', fix = '', tagFix = '', tag = '', origPath = '';
 	
@@ -456,12 +559,14 @@
 			}
 		},
 	
-		setContent: function(/*String or DOMNode*/ data){
+		setContent: function(/*String||DomNode*/ data){
 			// summary:
-			// 	Destroys old content and sets new content, and possibly initialize any widgets within 'data'
+			//		Replaces old content with data content, include style classes from old content
+			//	data:	new content, be it Document fragment or a DomNode chain
+			//			If data contains style tags, link rel=stylesheet it inserts those styles into DOM
 			this.abort();
-			if(this._callOnUnLoad){ this.onUnLoad(); }// this tells a remote script clean up after itself
-			this._callOnUnLoad = true;
+			if(this._callOnUnload){ this.onUnload(); }// this tells a remote script clean up after itself
+			this._callOnUnload = true;
 	
 			if(!data || dojo.html.isNode(data)){
 				// if we do a clean using setContent(""); or setContent(#node) bypass all parsing, extractContent etc
@@ -490,7 +595,7 @@
 				if(this.parseContent){
 					for(var i = 0; i < data.requires.length; i++){
 						try{
-							eval(data.requires[i]);dojo.debug(data.requires[i]);
+							eval(data.requires[i]);
 						} catch(e){
 							e.text = "ContentPane: error in package loading calls, " + (e.description||e);
 							this._handleDefaults(e, "onContentError", "debug");
@@ -524,9 +629,10 @@
 				}
 			}
 		},
-	
-		// Generate pane content from given java function
-		setHandler: function(handler) {
+
+		setHandler: function(/*Function*/ handler) {
+			// summary:
+			//		Generate pane content from given java function
 			var fcn = dojo.lang.isFunction(handler) ? handler : window[handler];
 			if(!dojo.lang.isFunction(fcn)) {
 				// FIXME: needs testing! somebody with java knowledge needs to try this
@@ -576,7 +682,7 @@
 			try{
 				if(this.scriptSeparation){
 					// 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, useful to connect events to onLoad, onUnLoad etc..
+					// instead send in a variable that points to this widget, useful to connect events to onLoad, onUnload etc..
 					delete this.scriptScope;
 					this.scriptScope = new (new Function('_container_', code+'; return this;'))(self);
 				}else{

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/DatePicker.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/DatePicker.js?view=diff&rev=453979&r1=453978&r2=453979
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/DatePicker.js (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/DatePicker.js Sat Oct  7 11:22:33 2006
@@ -18,10 +18,6 @@
 dojo.require("dojo.dom");
 dojo.require("dojo.html.style");
 
-dojo.widget.defineWidget(
-	"dojo.widget.DatePicker",
-	dojo.widget.HtmlWidget,
-	{
 		/*
 		summary: 
 	 	              Base class for a stand-alone DatePicker widget 
@@ -45,25 +41,41 @@
 	 	 
 	 	              <div dojoType="DatePicker"></div> 
 		*/
-	
+
+dojo.widget.defineWidget(
+	"dojo.widget.DatePicker",
+	dojo.widget.HtmlWidget,
+	{	
 		//start attributes
 		
-		//total weeks to display default 
+		//String|Date
+		//	form value property if =='today' will default to todays date
+		value: "", 
+		//String
+		// 	name of the form element
+		name: "",
+		//Integer
+		//	total weeks to display default 
 		displayWeeks: 6, 
-		//if true, weekly size of calendar changes to acomodate the month if false, 42 day format is used
+		//Boolean
+		//	if true, weekly size of calendar changes to acomodate the month if false, 42 day format is used
 		adjustWeeks: false,
-		//first available date in the calendar set
+		//String|Date
+		//	first available date in the calendar set
 		startDate: "1492-10-12",
-		//last available date in the calendar set
+		//String|Date
+		//	last available date in the calendar set
 		endDate: "2941-10-12",
-		//adjusts the first day of the week 0==Sunday..6==Saturday
+		//Integer
+		//	adjusts the first day of the week 0==Sunday..6==Saturday
 		weekStartsOn: "",
-		//current date selected by DatePicker in rfc 3339 date format "yyyy-MM-dd" -- once initialized, this.date will be a date Object
-		date: "",
-		storedDate: "", //deprecated use date instead
-		//disable all incremental controls, must pick a date in the current display
+		//String
+		//	deprecated use value instead
+		storedDate: "",
+		//Boolean
+		//d	isable all incremental controls, must pick a date in the current display
 		staticDisplay: false,
-
+		
 		//how to render the names of the days in the header.  see dojo.date.getDayNames
 		dayWidth: 'narrow',
 		classNames: {
@@ -87,7 +99,7 @@
 			dojo.widget.DatePicker.superclass.postMixInProperties.apply(this, arguments);
 			if(this.storedDate){
 				dojo.deprecated("dojo.widget.DatePicker", "use 'date' instead of 'storedDate'", "0.5");
-				this.date=this.storedDate;
+				this.value=this.storedDate;
 			}
 			this.startDate = dojo.date.fromRfc3339(this.startDate);
 			this.endDate = dojo.date.fromRfc3339(this.endDate);
@@ -98,9 +110,9 @@
 			}
 			this.today = new Date();
 			this.today.setHours(0,0,0,0);
-			if(this.date && (typeof this.date=="string") && (this.date.split("-").length > 2)) {
-				this.date = dojo.date.fromRfc3339(this.date);
-				this.date.setHours(0,0,0,0);
+			if(this.value && (typeof this.value=="string") && (this.value.split("-").length > 2)) {
+				this.value = dojo.date.fromRfc3339(this.value);
+				this.value.setHours(0,0,0,0);
 			}
 		},
 
@@ -114,7 +126,7 @@
 			dojo.html.copyStyle(this.domNode, source);
 
 			this.weekTemplate = dojo.dom.removeNode(this.calendarWeekTemplate);
-			this._preInitUI((this.date)?this.date:this.today,false,true); //init UI with date selected ONLY if user supplies one
+			this._preInitUI((this.value)?this.value:this.today,false,true); //init UI with date selected ONLY if user supplies one
 
 			// Insert localized day names in the template
 			var dayLabels = dojo.lang.unnest(dojo.date.getNames('days', this.dayWidth, 'standAlone', this.lang)); //if we dont use unnest, we risk modifying the dayLabels array inside of dojo.date and screwing up other calendars on the page
@@ -132,12 +144,12 @@
 		
 		getValue: function() {
 			// summary: return current date in RFC 3339 format
-			return dojo.date.toRfc3339(new Date(this.date),'dateOnly'); /*String*/
+			return dojo.date.toRfc3339(new Date(this.value),'dateOnly'); /*String*/
 		},
 
 		getDate: function() {
 			// summary: return current date as a Date object
-			return this.date; /*Date*/
+			return this.value; /*Date*/
 		},
 
 		setValue: function(/*Date|String*/rfcDate) {
@@ -148,11 +160,11 @@
 		setDate: function(/*Date|String*/dateObj) {
 			//summary: set the current date and update the UI
 			if(typeof dateObj=="string"){
-				this.date = dojo.date.fromRfc3339(dateObj);
+				this.value = dojo.date.fromRfc3339(dateObj);
 			}else{
-				this.date = new Date(dateObj);
+				this.value = new Date(dateObj);
 			}
-			this.date.setHours(0,0,0,0);
+			this.value.setHours(0,0,0,0);
 			if(this.selectedNode!=null){
 				dojo.html.removeClass(this.selectedNode,this.classNames.selectedDate);
 			}
@@ -161,16 +173,16 @@
 				this.selectedNode = this.clickedNode;
 			}else{
 				//only call this if setDate was called by means other than clicking a date
-				this._preInitUI(this.date,false,true);
+				this._preInitUI(this.value,false,true);
 			}
 			this.clickedNode=null;
-			this.onSetDate();
+			this.onValueChanged(this.value);
 		},
 
 		_preInitUI: function(dateObj,initFirst,initUI) {
 			//initFirst is to tell _initFirstDay if you want first day of the displayed calendar, or first day of the week for dateObj
 			//initUI tells preInitUI to go ahead and run initUI if set to true
-			this.firstDay = this._initFirstDay(dateObj,initFirst,false);
+			this.firstDay = this._initFirstDay(dateObj,initFirst);
 			this.selectedIsUsed = false;
 			this.currentIsUsed = false;
 			var nextDate = new Date(this.firstDay);
@@ -214,7 +226,7 @@
 				//this is our new UI loop... one loop to rule them all, and in the datepicker bind them
 				currentCalendarNode = calendarNodes.item(i);
 				currentCalendarNode.innerHTML = nextDate.getDate();
-				var curClass = (nextDate.getMonth() == this.curMonth.getMonth())? 'current':'previous';
+				var curClass = (nextDate.getMonth()<this.curMonth.getMonth())?'previous':(nextDate.getMonth()==this.curMonth.getMonth())?'current':'next';
 				var mappedClass = curClass;
 				if(this._isDisabledDate(nextDate)){
 					var classMap={previous:"disabledPrevious",current:"disabledCurrent",next:"disabledNext"};
@@ -392,7 +404,7 @@
 		_getDateClassName: function(date, monthState) {
 			var currentClassName = this.classNames[monthState];
 			//we use Number comparisons because 2 dateObjects never seem to equal each other otherwise
-			if ((!this.selectedIsUsed && this.date) && (Number(date) == Number(this.date))) {
+			if ((!this.selectedIsUsed && this.value) && (Number(date) == Number(this.value))) {
 				currentClassName = this.classNames.selectedDate + " " + currentClassName;
 				this.selectedIsUsed = true;
 			}
@@ -428,7 +440,7 @@
 			this.setDate(new Date(year, month, eventTarget.innerHTML));
 		},
 		
-		onSetDate: function() {
+		onValueChanged: function(/*Date*/date) {
 			//summary: the set date event handler
 		},
 		

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Dialog.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Dialog.js?view=diff&rev=453979&r1=453978&r2=453979
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Dialog.js (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Dialog.js Sat Oct  7 11:22:33 2006
@@ -18,24 +18,37 @@
 dojo.require("dojo.html.display");
 dojo.require("dojo.html.iframe");
 
+// summary
+//	Mixin for widgets implementing a modal dialog
 dojo.declare(
 	"dojo.widget.ModalDialogBase", 
 	null,
 	{
 		isContainer: true,
-		_scrollConnected: false,
 
-		// provide a focusable element or element id if you need to
-		// work around FF's tendency to send focus into outer space on hide
+		// static variables
+		shared: {bg: null, bgIframe: null},
+
+		// String
+		//	provide a focusable element or element id if you need to
+		//	work around FF's tendency to send focus into outer space on hide
 		focusElement: "",
 
-		shared: {bg: null, bgIframe: null},
+		// String
+		//	color of viewport when displaying a dialog
 		bgColor: "black",
+		
+		// Number
+		//	opacity (0~1) of viewport color (see bgColor attribute)
 		bgOpacity: 0.4,
+
+		// Boolean
+		//	if true, readjusts the dialog (and dialog background) when the user moves the scrollbar
 		followScroll: true,
-		_fromTrap: false,
 
-		trapTabs: function(e){
+		trapTabs: function(/*Event*/ e){
+			// summary
+			//	callback on focus
 			if(e.target == this.tabStartOuter) {
 				if(this._fromTrap) {
 					this.tabStart.focus();
@@ -69,18 +82,21 @@
 			}
 		},
 
-		clearTrap: function(e) {
+		clearTrap: function(/*Event*/ e) {
+			// summary
+			//	callback on blur
 			var _this = this;
 			setTimeout(function() {
 				_this._fromTrap = false;
 			}, 100);
 		},
 
-		//if the target mixin class already defined postCreate,
-		//dojo.widget.ModalDialogBase.prototype.postCreate.call(this)
-		//should be called in its postCreate()
 		postCreate: function() {
-			with(this.domNode.style) {
+			// summary
+			//	if the target mixin class already defined postCreate,
+			//	dojo.widget.ModalDialogBase.prototype.postCreate.call(this)
+			//	should be called in its postCreate()
+			with(this.domNode.style){
 				position = "absolute";
 				zIndex = 999;
 				display = "none";
@@ -92,7 +108,7 @@
 			if(!this.shared.bg){
 				this.shared.bg = document.createElement("div");
 				this.shared.bg.className = "dialogUnderlay";
-				with(this.shared.bg.style) {
+				with(this.shared.bg.style){
 					position = "absolute";
 					left = top = "0px";
 					zIndex = 998;
@@ -100,12 +116,16 @@
 				}
 				this.setBackgroundColor(this.bgColor);
 				b.appendChild(this.shared.bg);
-	
 				this.shared.bgIframe = new dojo.html.BackgroundIframe(this.shared.bg);
 			}
 		},
 
-		setBackgroundColor: function(color) {
+		setBackgroundColor: function(/*String*/ color) {
+			// summary
+			//	changes background color specified by "bgColor" parameter
+			//	usage:
+			//		setBackgrounColor("black");
+			//		setBackgroundColor(0xff, 0xff, 0xff);
 			if(arguments.length >= 3) {
 				color = new dojo.gfx.color.Color(arguments[0], arguments[1], arguments[2]);
 			} else {
@@ -115,7 +135,9 @@
 			return this.bgColor = color;
 		},
 
-		setBackgroundOpacity: function(op) {
+		setBackgroundOpacity: function(/*Number*/ op) {
+			// summary
+			//	changes background opacity set by "bgOpacity" parameter
 			if(arguments.length == 0) { op = this.bgOpacity; }
 			dojo.html.setOpacity(this.shared.bg, op);
 			try {
@@ -126,13 +148,19 @@
 			return this.bgOpacity;
 		},
 
-		sizeBackground: function() {
+		_sizeBackground: function() {
 			if(this.bgOpacity > 0) {
+				
 				var viewport = dojo.html.getViewport();
 				var h = viewport.height;
 				var w = viewport.width;
-				this.shared.bg.style.width = w + "px";
-				this.shared.bg.style.height = h + "px";
+				with(this.shared.bg.style){
+					width = w + "px";
+					height = h + "px";
+				}
+				var scroll_offset = dojo.html.getScroll().offset;
+				this.shared.bg.style.top = scroll_offset.y + "px";
+				this.shared.bg.style.left = scroll_offset.x + "px";
 				// process twice since the scroll bar may have been removed
 				// by the previous resizing
 				var viewport = dojo.html.getViewport();
@@ -141,7 +169,7 @@
 			}
 		},
 
-		showBackground: function() {
+		_showBackground: function() {
 			if(this.bgOpacity > 0) {
 				this.shared.bg.style.display = "block";
 			}
@@ -150,32 +178,36 @@
 		placeModalDialog: function() {
 			var scroll_offset = dojo.html.getScroll().offset;
 			var viewport_size = dojo.html.getViewport();
-
+			
 			// find the size of the dialog
 			var mb = dojo.html.getMarginBox(this.containerNode);
-
+			
 			var x = scroll_offset.x + (viewport_size.width - mb.width)/2;
 			var y = scroll_offset.y + (viewport_size.height - mb.height)/2;
 
-			with(this.domNode.style) {
+			with(this.domNode.style){
 				left = x + "px";
 				top = y + "px";
 			}
 		},
 
-		//call this function in show() of subclass
 		showModalDialog: function() {
+			// summary
+			//	call this function in show() of subclass
 			if (this.followScroll && !this._scrollConnected){
 				this._scrollConnected = true;
-				dojo.event.connect(window, "onscroll", this, "onScroll");
+				dojo.event.connect(window, "onscroll", this, "_onScroll");
 			}
+			
 			this.setBackgroundOpacity();
-			this.sizeBackground();
-			this.showBackground();
+			this._sizeBackground();
+			this._showBackground();
 		},
 
-		//call this function in hide() of subclass
 		hideModalDialog: function(){
+			// summary
+			//	call this function in hide() of subclass
+
 			// workaround for FF focus going into outer space
 			if (this.focusElement) { 
 				dojo.byId(this.focusElement).focus(); 
@@ -187,35 +219,41 @@
 
 			if (this._scrollConnected){
 				this._scrollConnected = false;
-				dojo.event.disconnect(window, "onscroll", this, "onScroll");
+				dojo.event.disconnect(window, "onscroll", this, "_onScroll");
 			}
 		},
 
-		onScroll: function(){
+		_onScroll: function(){
 			var scroll_offset = dojo.html.getScroll().offset;
 			this.shared.bg.style.top = scroll_offset.y + "px";
 			this.shared.bg.style.left = scroll_offset.x + "px";
 			this.placeModalDialog();
 		},
 
-		// Called when the browser window's size is changed
 		checkSize: function() {
 			if(this.isShowing()){
-				this.sizeBackground();
+				this._sizeBackground();
 				this.placeModalDialog();
 				this.onResized();
 			}
 		}
 	});
 
+// summary
+//	Pops up a modal dialog window, blocking access to the screen and also graying out the screen
+//	Dialog is extended from ContentPane so it supports all the same parameters (href, etc.)
 dojo.widget.defineWidget(
 	"dojo.widget.Dialog",
 	[dojo.widget.ContentPane, dojo.widget.ModalDialogBase],
 	{
 		templatePath: dojo.uri.dojoUri("src/widget/templates/Dialog.html"),
 
-		anim: null,
+		// Integer
+		//	number of seconds for which the user cannot dismiss the dialog
 		blockDuration: 0,
+		
+		// Integer
+		//	if set, this controls the number of seconds the dialog will be displayed before automatically disappearing
 		lifetime: 0,
 
 		show: function() {
@@ -236,12 +274,11 @@
 						this.closeNode.style.display = "none";
 					}
 				}
-				this.timer = setInterval(dojo.lang.hitch(this, "onTick"), 100);
+				this.timer = setInterval(dojo.lang.hitch(this, "_onTick"), 100);
 			}
 
 			this.showModalDialog();
 			dojo.widget.Dialog.superclass.show.call(this);
-			this.checkSize();
 		},
 
 		onLoad: function(){
@@ -265,19 +302,30 @@
 		},
 		
 		setTimerNode: function(node){
+			// summary
+			//	specify into which node to write the remaining # of seconds
+			// TODO: make this a parameter too
 			this.timerNode = node;
 		},
 
 		setCloseControl: function(node) {
+			// summary
+			//	specify which node is the close button for this dialog
+			// TODO: make this a parameter too
 			this.closeNode = node;
 			dojo.event.connect(node, "onclick", this, "hide");
 		},
 
 		setShowControl: function(node) {
+			// summary
+			//	when specified node is clicked, show this dialog
+			// TODO: make this a parameter too
 			dojo.event.connect(node, "onclick", this, "show");
 		},
 		
-		onTick: function(){
+		_onTick: function(){
+			// summary
+			//	callback every second that the timer clicks
 			if(this.timer){
 				this.timeRemaining -= 100;
 				if(this.lifetime - this.timeRemaining >= this.blockDuration){

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/DomWidget.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/DomWidget.js?view=diff&rev=453979&r1=453978&r2=453979
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/DomWidget.js (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/DomWidget.js Sat Oct  7 11:22:33 2006
@@ -11,6 +11,7 @@
 dojo.provide("dojo.widget.DomWidget");
 
 dojo.require("dojo.event.*");
+dojo.require("dojo.io.*");
 dojo.require("dojo.widget.Widget");
 dojo.require("dojo.dom");
 dojo.require("dojo.html.style");
@@ -543,9 +544,103 @@
 				dojo.widget.manager.topWidgets[this.widgetId]=this;
 			}
 
+			if(this.widgetsInTemplate){
+				var parser = new dojo.xml.Parse();
+
+				var subContainerNode;
+				//TODO: use xpath here?
+				var subnodes = this.domNode.getElementsByTagName("*");
+				for(var i=0;i<subnodes.length;i++){
+					if(subnodes[i].getAttribute('dojoAttachPoint') == 'subContainerWidget'){
+						subContainerNode = subnodes[i];
+//						break;
+					}
+					if(subnodes[i].getAttribute('dojoType')){
+						subnodes[i].setAttribute('_isSubWidget', true);
+					}
+				}
+				if (this.isContainer && !this.containerNode){
+					//no containerNode is available, which means a widget is used as a container. find it here and move
+					//all dom nodes defined in the main html page as children of this.domNode into the actual container
+					//widget's node (at this point, the subwidgets defined in the template file is not parsed yet)
+					if(subContainerNode){
+						var src = this.getFragNodeRef(frag);
+						if (src){
+							dojo.dom.moveChildren(src, subContainerNode);
+							//do not need to follow children nodes in the main html page, as they
+							//will be dealt with in the subContainerWidget
+							frag['dojoDontFollow'] = true;
+						}
+					}else{
+						dojo.debug("No subContainerWidget node can be found in template file for widget "+this);
+					}
+				}
+
+				var templatefrag = parser.parseElement(this.domNode, null, true);
+				// createSubComponents not createComponents because frag has already been created
+				dojo.widget.getParser().createSubComponents(templatefrag, this);
+	
+				//find all the sub widgets defined in the template file of this widget
+				var subwidgets = [];
+				var stack = [this];
+				var w;
+				while((w = stack.pop())){
+					for(var i = 0; i < w.children.length; i++){
+						var cwidget = w.children[i];
+						if(cwidget._processedSubWidgets || !cwidget.extraArgs['_issubwidget']){ continue; }
+						subwidgets.push(cwidget);
+						if(cwidget.isContainer){
+							stack.push(cwidget);
+						}
+					}
+				}
+	
+				//connect event to this widget/attach dom node
+				for(var i = 0; i < subwidgets.length; i++){
+					var widget = subwidgets[i];
+					if(widget._processedSubWidgets){
+						dojo.debug("This should not happen: widget._processedSubWidgets is already true!");
+						return;
+					}
+					widget._processedSubWidgets = true;
+					if(widget.extraArgs['dojoattachevent']){
+						var evts = widget.extraArgs['dojoattachevent'].split(";");
+						for(var j=0; j<evts.length; j++){
+							var thisFunc = null;
+							var tevt = dojo.string.trim(evts[j]);
+							if(tevt.indexOf(":") >= 0){
+								// oh, if only JS had tuple assignment
+								var funcNameArr = tevt.split(":");
+								tevt = dojo.string.trim(funcNameArr[0]);
+								thisFunc = dojo.string.trim(funcNameArr[1]);
+							}
+							if(!thisFunc){
+								thisFunc = tevt;
+							}
+							if(dojo.lang.isFunction(widget[tevt])){
+								dojo.event.kwConnect({
+									srcObj: widget, 
+									srcFunc: tevt, 
+									targetObj: this, 
+									targetFunc: thisFunc
+								});
+							}else{
+								alert(tevt+" is not a function in widget "+widget);
+							}
+						}
+					}
+	
+					if(widget.extraArgs['dojoattachpoint']){
+						//don't attach widget.domNode here, as we do not know which
+						//dom node we should connect to (in checkbox widget case, 
+						//it is inputNode). So we make the widget itself available
+						this[widget.extraArgs['dojoattachpoint']] = widget;
+					}
+				}
+			}
 
 			//dojo.profile.end(this.widgetType + " postInitialize");
-			
+
 			// Expand my children widgets
 			/* dojoDontFollow is important for a very special case
 			 * basically if you have a widget that you instantiate from script
@@ -711,107 +806,6 @@
 			// dojo.profile.start("attachTemplateNodes");
 			this.attachTemplateNodes();
 			// dojo.profile.end("attachTemplateNodes");
-	
-			if(this.widgetsInTemplate){
-				var parser = new dojo.xml.Parse();
-
-				var subContainerNode;
-				//TODO: use xpath here?
-				var subnodes = this.domNode.getElementsByTagName("*");
-				for(var i=0;i<subnodes.length;i++){
-					if(subnodes[i].getAttribute('dojoAttachPoint') == 'subContainerWidget'){
-						subContainerNode = subnodes[i];
-//						break;
-					}
-					if(subnodes[i].getAttribute('dojoType')){
-						subnodes[i].setAttribute('_isSubWidget', true);
-					}
-				}
-				if (this.isContainer && !this.containerNode){
-					//no containerNode is available, which means a widget is used as a container. find it here and move
-					//all dom nodes defined in the main html page as children of this.domNode into the actual container
-					//widget's node (at this point, the subwidgets defined in the template file is not parsed yet)
-					if(subContainerNode){
-						var src = this.getFragNodeRef(frag);
-						if (src){
-							dojo.dom.moveChildren(src, subContainerNode);
-							//do not need to follow children nodes in the main html page, as they
-							//will be dealt with in the subContainerWidget
-							frag['dojoDontFollow'] = true;
-						}
-					}else{
-						dojo.debug("No subContainerWidget node can be found in template file for widget "+this);
-					}
-				}
-
-				var templatefrag = parser.parseElement(this.domNode, null, true);
-				// createSubComponents not createComponents because frag has already been created
-				dojo.widget.getParser().createSubComponents(templatefrag, this);
-	
-				//find all the sub widgets defined in the template file of this widget
-				var subwidgets = [];
-				var stack = [this];
-				var w;
-				while((w = stack.pop())){
-					for(var i = 0; i < w.children.length; i++){
-						var cwidget = w.children[i];
-						if(cwidget._processedSubWidgets || !cwidget.extraArgs['_issubwidget']){ continue; }
-						subwidgets.push(cwidget);
-						if(cwidget.isContainer){
-							stack.push(cwidget);
-						}
-					}
-				}
-	
-				//connect event to this widget/attach dom node
-				for(var i = 0; i < subwidgets.length; i++){
-					var widget = subwidgets[i];
-					if(widget._processedSubWidgets){
-						dojo.debug("This should not happen: widget._processedSubWidgets is already true!");
-						return;
-					}
-					widget._processedSubWidgets = true;
-					if(widget.extraArgs['dojoattachevent']){
-						var evts = widget.extraArgs['dojoattachevent'].split(";");
-						for(var j=0; j<evts.length; j++){
-							var thisFunc = null;
-							var tevt = dojo.string.trim(evts[j]);
-							if(tevt.indexOf(":") >= 0){
-								// oh, if only JS had tuple assignment
-								var funcNameArr = tevt.split(":");
-								tevt = dojo.string.trim(funcNameArr[0]);
-								thisFunc = dojo.string.trim(funcNameArr[1]);
-							}
-							if(!thisFunc){
-								thisFunc = tevt;
-							}
-							if(dojo.lang.isFunction(widget[tevt])){
-								dojo.event.connect(widget, tevt, this, thisFunc);
-							}else{
-								alert(tevt+" is not a function in widget "+widget);
-							}
-						}
-					}
-	
-					//if an isContainer widget has isSubContainer = 'true', set
-					//it as this.subContainerWidget
-//					if(widget.isContainer && widget.extraArgs['issubcontainer']){
-//						if(this.containerNode){
-//							dojo.debug("this.containerNode is already set for widget "+this+" ("+this.containerNode+", "+this.containerNode_Widget+")");
-//							return;
-//						}
-//	
-//						this.subContainerWidget = widget;
-//					}
-//	dojo.debug(widget);
-					if(widget.extraArgs['dojoattachpoint']){
-						//don't attach widget.domNode here, as we do not know which
-						//dom node we should connect to (in checkbox widget case, 
-						//it is inputNode). So we make the widget itself available
-						this[widget.extraArgs['dojoattachpoint']] = widget;
-					}
-				}
-			}
 		
 			// relocate source contents to templated container node
 			// this.containerNode must be able to receive children, or exceptions will be thrown

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/DropdownContainer.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/DropdownContainer.js?view=diff&rev=453979&r1=453978&r2=453979
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/DropdownContainer.js (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/DropdownContainer.js Sat Oct  7 11:22:33 2006
@@ -18,22 +18,33 @@
 dojo.require("dojo.html.iframe");
 dojo.require("dojo.html.util");
 
+// summary:
+//		dojo.widget.DropdownContainer provides an input box and a button for a dropdown.
+//		In subclass, the dropdown can be specified.
 dojo.widget.defineWidget(
 	"dojo.widget.DropdownContainer",
 	dojo.widget.HtmlWidget,
 	{
+		// String: width of the input box
 		inputWidth: "7em",
+		// String: id of this widget
 		id: "",
+		// String: id of the input box
 		inputId: "",
+		// String: name of the input box
 		inputName: "",
+		// dojo.uri.Uri: icon for the dropdown button
 		iconURL: dojo.uri.dojoUri("src/widget/templates/images/combo_box_arrow.png"),
+		// dojo.uri.Uri: alt text for the dropdown button icon
 		iconAlt: "",
 
 		inputNode: null,
 		buttonNode: null,
 		containerNode: null,
 
+		// String: toggle property of the dropdown
 		containerToggle: "plain",
+		// Int: toggle duration property of the dropdown
 		containerToggleDuration: 150,
 		containerAnimInProgress: false,
 
@@ -66,11 +77,14 @@
 		},
 
 		hideContainer: function(){
+			// summary: hide the dropdown
 			if(this.popup.isShowingNow){
 				this.popup.close();
 			}
 		},
 
-		onInputChange: function(){}
+		onInputChange: function(){
+			// summary: signal for changes in the input box
+		}
 	}
 );

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/DropdownDatePicker.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/DropdownDatePicker.js?view=diff&rev=453979&r1=453978&r2=453979
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/DropdownDatePicker.js (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/DropdownDatePicker.js Sat Oct  7 11:22:33 2006
@@ -21,25 +21,65 @@
 dojo.require("dojo.i18n.common");
 dojo.requireLocalization("dojo.widget", "DropdownDatePicker");
 
+		/*
+		summary: 
+			DatePicker form input that allows for selecting a Date from the UI or typing of date in an inputbox
+	 	description: 
+			Basically this is DatePicker in a DropdownContainer, it supports all features of DatePicker as well
+			as wrapping its value inside of a form element to be submitted.
+	 	 usage: 
+	 	              var ddp = dojo.widget.createWidget("DropdownDatePicker", {},   
+	 	              dojo.byId("DropdownDatePickerNode")); 
+	 	 
+	 	              <input dojoType="DropdownDatePicker">
+		*/
+
 dojo.widget.defineWidget(
 	"dojo.widget.DropdownDatePicker",
 	dojo.widget.DropdownContainer,
 	{
 		iconURL: dojo.uri.dojoUri("src/widget/templates/images/dateIcon.gif"),
 		zIndex: "10",
-
-		// pattern used in display of formatted date.  See dojo.date.format.
+		
+		//String
+		// 	pattern used in display of formatted date.  See dojo.date.format.
 		displayFormat: "",
 		dateFormat: "", // deprecated in 0.5
-		// formatting used when submitting form.  A pattern string like display format or one of the following:
-		// rfc|iso|posix|unix  By default, uses rfc3339 style date formatting.
+		//String
+		// 	formatting used when submitting form.  A pattern string like display format or one of the following:
+		// 	rfc|iso|posix|unix  By default, uses rfc3339 style date formatting.
 		saveFormat: "",
-		// type of format appropriate to locale.  see dojo.date.format
+		//String
+		// 	type of format appropriate to locale.  see dojo.date.format
 		formatLength: "short", // only parsing of short is supported at this time
-		date: "", //if =='today' will default to todays date
-		// name of the form element
+		//String|Date
+		//	form value property if =='today' will default to todays date
+		value: "", 
+		//String
+		// 	name of the form element
 		name: "",
-
+		//Integer
+		//	total weeks to display default 
+		displayWeeks: 6, 
+		//Boolean
+		//	if true, weekly size of calendar changes to acomodate the month if false, 42 day format is used
+		adjustWeeks: false,
+		//String|Date
+		//	first available date in the calendar set
+		startDate: "1492-10-12",
+		//String|Date
+		//	last available date in the calendar set
+		endDate: "2941-10-12",
+		//Integer
+		//	adjusts the first day of the week 0==Sunday..6==Saturday
+		weekStartsOn: "",
+		//String
+		//	deprecated use value instead
+		storedDate: "",
+		//Boolean
+		//d	isable all incremental controls, must pick a date in the current display
+		staticDisplay: false,
+		
 		postMixInProperties: function(localProperties, frag){
 			// summary: see dojo.widget.DomWidget
 
@@ -47,29 +87,38 @@
 			var messages = dojo.i18n.getLocalization("dojo.widget", "DropdownDatePicker", this.lang);
 			this.iconAlt = messages.selectDate;
 			
-			if(typeof(this.date)=='string'&&this.date.toLowerCase()=='today'){
-				this.date = new Date();
+			if(typeof(this.value)=='string'&&this.value.toLowerCase()=='today'){
+				this.value = new Date();
 			}
-			if(this.date && isNaN(this.date)){
-				var orig = this.date;
-				this.date = dojo.date.fromRfc3339(this.date);
-				if(!this.date){this.date = new Date(orig); dojo.deprecated("dojo.widget.DropdownDatePicker", "date attributes must be passed in Rfc3339 format", "0.5");}
+			if(this.value && isNaN(this.value)){
+				var orig = this.value;
+				this.value = dojo.date.fromRfc3339(this.value);
+				if(!this.value){this.value = new Date(orig); dojo.deprecated("dojo.widget.DropdownDatePicker", "date attributes must be passed in Rfc3339 format", "0.5");}
 			}
-			if(this.date && !isNaN(this.date)){
-				this.date = new Date(this.date);
+			if(this.value && !isNaN(this.value)){
+				this.value = new Date(this.value);
 			}
 		},
 
 		fillInTemplate: function(args, frag){
 			// summary: see dojo.widget.DomWidget
-
 			dojo.widget.DropdownDatePicker.superclass.fillInTemplate.call(this, args, frag);
-
-			this.datePicker = dojo.widget.createWidget("DatePicker",
-				{ widgetContainerId: this.widgetId, lang: this.lang, date: this.date }, this.containerNode, "child");
-			dojo.event.connect(this.datePicker, "onSetDate", this, "onSetDate");
+			//attributes to be passed on to DatePicker
+			var dpArgs = {widgetContainerId: this.widgetId};
+			if(this.value){ dpArgs.value = this.value; }
+			if(this.startDate){ dpArgs.startDate = this.startDate; }
+			if(this.endDate){ dpArgs.endDate = this.endDate; }
+			if(this.displayWeeks){ dpArgs.displayWeeks = this.displayWeeks; }
+			if(this.weekStartsOn){ dpArgs.weekStartsOn = this.weekStartsOn; }
+			if(this.adjustWeeks){ dpArgs.adjustWeeks = this.adjustWeeks; }
+			if(this.staticDisplay){ dpArgs.staticDisplay = this.staticDisplay; }
+			if(this.value){ dpArgs.date = this.value; }
+			if(this.storedDate){ dpArgs.storedDate = this.storedDate; } //deprecated in 0.5
+			//build the args for DatePicker based on the public attributes of DropdownDatePicker
+			this.datePicker = dojo.widget.createWidget("DatePicker", dpArgs, this.containerNode, "child");
+			dojo.event.connect(this.datePicker, "onValueChanged", this, "onSetDate");
 			
-			if(this.date){
+			if(this.value){
 				this.onSetDate();
 			}
 			this.containerNode.style.zIndex = this.zIndex;
@@ -77,36 +126,43 @@
 			this.valueNode.name=this.name;
 		},
 
-		onSetDate: function(){
-			if(this.dateFormat){
-				dojo.deprecated("dojo.widget.DropdownDatePicker",
-				"Must use displayFormat attribute instead of dateFormat.  See dojo.date.format for specification.", "0.5");
-				this.inputNode.value = dojo.date.strftime(this.datePicker.date, this.dateFormat, this.lang);
-			}else{
-				this.inputNode.value = dojo.date.format(this.datePicker.date,
-					{formatLength:this.formatLength, datePattern:this.displayFormat, selector:'dateOnly', locale:this.lang});
-			}
-			this._synchValueNode();
-			this.hideContainer();
-		},
 		getValue: function(/*Boolean*/displayFormat){
 			// summary: return current date in RFC 3339 format if displayFormat is false otherwise, uses displayFormat that inputNode uses
-			return (displayFormat)?dojo.date.format(this.datePicker.date,{formatLength:this.formatLength, datePattern:this.displayFormat, selector:'dateOnly', locale:this.lang}):dojo.date.toRfc3339(new Date(this.datePicker.date),'dateOnly'); /*String*/
+			return (displayFormat)?dojo.date.format(this.datePicker.value,{formatLength:this.formatLength, datePattern:this.displayFormat, selector:'dateOnly', locale:this.lang}):dojo.date.toRfc3339(new Date(this.datePicker.value),'dateOnly'); /*String*/
 		},
 
 		getDate: function(){
 			// summary: return current date as a Date object
-			return this.datePicker.date; /*Date*/
+			return this.datePicker.value; /*Date*/
 		},
 
 		setValue: function(/*Date|String*/rfcDate){
 			//summary: set the current date from RFC 3339 formatted string or a date object, synonymous with setDate
-			this.datePicker.setDate(rfcDate);
+			this.setDate(rfcDate);
 		},			
 			
 		setDate: function(/*Date|String*/rfcDate){
 		//summary: set the current date and update the UI
 			this.datePicker.setDate(rfcDate);
+			this._synchValueNode();
+		},
+		
+		onSetDate: function(){
+			if(this.dateFormat){
+				dojo.deprecated("dojo.widget.DropdownDatePicker",
+				"Must use displayFormat attribute instead of dateFormat.  See dojo.date.format for specification.", "0.5");
+				this.inputNode.value = dojo.date.strftime(this.datePicker.value, this.dateFormat, this.lang);
+			}else{
+				this.inputNode.value = dojo.date.format(this.datePicker.value,
+					{formatLength:this.formatLength, datePattern:this.displayFormat, selector:'dateOnly', locale:this.lang});
+			}
+			this._synchValueNode();
+			this.onValueChanged(this.getDate());
+			this.hideContainer();
+		},
+
+		onValueChanged: function(/*Date*/date){
+		//summary: triggered when this.value is changed
 		},
 		
 		onInputChange: function(){
@@ -119,8 +175,7 @@
 					var inputDate = dojo.date.parse(input,
 							{formatLength:this.formatLength, datePattern:this.displayFormat, selector:'dateOnly', locale:this.lang});			
 					if(inputDate){
-						this.datePicker.setDate(inputDate);
-						this._synchValueNode();
+						this.setDate(inputDate);
 					}
 				} else {
 					this.valueNode.value = input;
@@ -134,7 +189,7 @@
 		},
 
 		_synchValueNode: function(){
-			var date = this.datePicker.date;
+			var date = this.datePicker.value;
 			var value;
 			switch(this.saveFormat.toLowerCase()){
 				case "rfc": case "iso": case "":

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/DropdownTimePicker.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/DropdownTimePicker.js?view=diff&rev=453979&r1=453978&r2=453979
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/DropdownTimePicker.js (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/DropdownTimePicker.js Sat Oct  7 11:22:33 2006
@@ -15,39 +15,60 @@
 dojo.require("dojo.widget.TimePicker");
 dojo.require("dojo.event.*");
 dojo.require("dojo.html.*");
-
+dojo.require("dojo.date.format");
+dojo.require("dojo.date.serialize");
 dojo.require("dojo.i18n.common");
 dojo.requireLocalization("dojo.widget", "DropdownTimePicker");
 
+// summary
+//	input box with a drop-down gui control, for setting the time (hours, minutes, seconds, am/pm) of an event
 dojo.widget.defineWidget(
 	"dojo.widget.DropdownTimePicker",
 	dojo.widget.DropdownContainer,
 	{
+		// URL
+		//	path of icon for button to display time picker widget
 		iconURL: dojo.uri.dojoUri("src/widget/templates/images/timeIcon.gif"),
-		zIndex: "10",
-		timePicker: null,
 		
-		timeFormat: "%R",
-		time: null,
+		// Number
+		//	z-index of time picker widget
+		zIndex: "10",
+
+		// pattern used in display of formatted time.  See dojo.date.format.
+		displayFormat: "",
+
+		// String
+		//	Deprecated. format string for how time is displayed in the input box using strftime, see dojo.date.strftime	
+		timeFormat: "",
 
-		postMixInProperties: function(localProperties, frag) {
+//FIXME: need saveFormat attribute support
+
+		// type of format appropriate to locale.  see dojo.date.format
+		formatLength: "short",
+
+		// String
+		//	time value in RFC3339 format (http://www.ietf.org/rfc/rfc3339.txt)
+		//	ex: 12:00
+		value: "",
+
+		postMixInProperties: function() {
 			dojo.widget.DropdownTimePicker.superclass.postMixInProperties.apply(this, arguments);
 			var messages = dojo.i18n.getLocalization("dojo.widget", "DropdownTimePicker", this.lang);
 			this.iconAlt = messages.selectTime;
 		},
 
-		fillInTemplate: function(args, frag){
-			dojo.widget.DropdownTimePicker.superclass.fillInTemplate.call(this, args, frag);
+		fillInTemplate: function(){
+			dojo.widget.DropdownTimePicker.superclass.fillInTemplate.apply(this, arguments);
 
-			var timeProps = { widgetContainerId: this.widgetId };
+			var timeProps = { widgetContainerId: this.widgetId, lang: this.lang };
 			this.timePicker = dojo.widget.createWidget("TimePicker", timeProps, this.containerNode, "child");
 			dojo.event.connect(this.timePicker, "onSetTime", this, "onSetTime");
 			dojo.event.connect(this.inputNode,  "onchange",  this, "onInputChange");
 			this.containerNode.style.zIndex = this.zIndex;
 			this.containerNode.explodeClassName = "timeBorder";
-			if(args.storedtime){
+			if(this.value){
 				this.timePicker.selectedTime.anyTime = false;
-				this.timePicker.setDateTime("2005-01-01T" + args.storedtime);
+				this.timePicker.setDateTime("2005-01-01T" + this.value);
 				this.timePicker.initData();
 				this.timePicker.initUI();
 				this.onSetTime();
@@ -55,24 +76,38 @@
 		},
 		
 		onSetTime: function(){
-			this.inputNode.value = this.timePicker.selectedTime.anyTime ? "" : dojo.date.strftime(this.timePicker.time, this.timeFormat);
+			// summary: callback when user sets the time via the TimePicker widget
+			if(this.timePicker.selectedTime.anyTime){
+				this.inputNode.value = "";
+			}else if(this.timeFormat){
+				dojo.deprecated("dojo.widget.DropdownTimePicker",
+				"Must use displayFormat attribute instead of timeFormat.  See dojo.date.format for specification.", "0.5");
+				this.inputNode.value = dojo.date.strftime(this.timePicker.time, this.timeFormat, this.lang);
+			}else{
+				this.inputNode.value = dojo.date.format(this.timePicker.time,
+					{formatLength:this.formatLength, datePattern:this.displayFormat, selector:'timeOnly', locale:this.lang});
+			}
+
 			this.hideContainer();
 		},
 		
 		onInputChange: function(){
-			this.timePicker.time = "2005-01-01T" + this.inputNode.value;
+			// summary: callback when the user has typed in a time value manually
+			this.timePicker.time = "2005-01-01T" + this.inputNode.value; //FIXME: i18n
 			this.timePicker.setDateTime(this.timePicker.time);
 			this.timePicker.initData();
 			this.timePicker.initUI();
 		},
 		
 		enable: function() {
+			// summary: enable this widget to accept user input
 			this.inputNode.disabled = false;
 			this.timePicker.enable();
 			this.inherited("enable", []);
 		},
 		
 		disable: function() {
+			// summary: lock this widget so that the user can't change the value
 			this.inputNode.disabled = true;
 			this.timePicker.disable();
 			this.inherited("disable", []);