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 [6/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/PopupContainer.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/PopupContainer.js?view=diff&rev=453979&r1=453978&r2=453979
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/PopupContainer.js (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/PopupContainer.js Sat Oct  7 11:22:33 2006
@@ -23,7 +23,7 @@
 //it can open in a given position x,y or around a given node.
 //In addition, it handles animation and IE bleed through workaround.
 //This class can not be used standalone: it should be mixed-in to a
-//dojo.widget.HtmlWidget. Use PopupContainer instead if you want a 
+//dojo.widget.HtmlWidget. Use PopupContainer instead if you want a
 //a standalone popup widget
 dojo.declare(
 	"dojo.widget.PopupContainerBase",
@@ -118,7 +118,7 @@
 		this.popupIndex = parentPopup ? parentPopup.popupIndex + 1 : 1;
 
 		if(this.isTopLevel){
-			var button = explodeSrc instanceof Array ? null : explodeSrc;
+			var button = dojo.html.isNode(explodeSrc) ? explodeSrc : null;
 			dojo.widget.PopupManager.opened(this, button);
 		}
 
@@ -130,7 +130,7 @@
 			this._bookmark = null;
 		}
 
-		//convert explodeSrc from format [x, y] to 
+		//convert explodeSrc from format [x, y] to
 		//{left: x, top: y, width: 0, height: 0} which is the new
 		//format required by dojo.html.toCoordinateObject
 		if(explodeSrc instanceof Array){
@@ -228,7 +228,7 @@
 
 	closeSubpopup: function(force) {
 		if(this.currentSubpopup == null){ return; }
-		
+
 		this.currentSubpopup.close(force);
 		this.currentSubpopup = null;
 	},
@@ -237,7 +237,7 @@
 		this.inherited('onShow');
 		// With some animation (wipe), after close, the size of the domnode is 0
 		// and next time when shown, the open() function can not determine
-		// the correct place to popup, so we store the opened size here and 
+		// the correct place to popup, so we store the opened size here and
 		// set it after close (in function onHide())
 		this.openedSize={w: this.domNode.style.width, h: this.domNode.style.height};
 		// prevent IE bleed through
@@ -265,7 +265,7 @@
 
 	onHide: function() {
 		dojo.widget.HtmlWidget.prototype.onHide.call(this);
-		
+
 		//restore size of the domnode, see comment in
 		//function onShow()
 		if(this.openedSize){
@@ -274,7 +274,7 @@
 				height=this.openedSize.h;
 			}
 		}
-		
+
 		this.processQueue();
 	}
 });
@@ -312,16 +312,16 @@
 
 	/*
 		This function register all the iframes and the top window,
-		so that whereever the user clicks in the page, the popup 
+		so that whereever the user clicks in the page, the popup
 		menu will be closed
 		In case you add an iframe after onload event, please call
 		dojo.widget.PopupManager.registerWin manually
 	*/
 	this.registerAllWindows = function(targetWindow){
-		//starting from window.top, clicking everywhere in this page 
+		//starting from window.top, clicking everywhere in this page
 		//should close popup menus
 		if(!targetWindow) { //see comment below
-			targetWindow = dojo.html.getDocumentWindow(window.top.document);
+			targetWindow = dojo.html.getDocumentWindow(window.top && window.top.document || window.document);
 		}
 
 		this.registerWin(targetWindow);

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/ProgressBar.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/ProgressBar.js?view=diff&rev=453979&r1=453978&r2=453979
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/ProgressBar.js (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/ProgressBar.js Sat Oct  7 11:22:33 2006
@@ -202,6 +202,7 @@
 				this._animationStopped = false;
 				this._setupAnimation();
 				this.showText(false);
+				this.internalProgress.style.height="105%";
 				this._animation.play();
 			}
 		},
@@ -209,6 +210,7 @@
 			if (this._animation) {
 				this._animationStopped = true;
 				this._animation.stop();
+				this.internalProgress.style.height="100%";
 				this.internalProgress.style.left = "0px";
 				this._restoreValues();
 				this._setLabelPosition();

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/RichText.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/RichText.js?view=diff&rev=453979&r1=453978&r2=453979
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/RichText.js (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/RichText.js Sat Oct  7 11:22:33 2006
@@ -48,7 +48,7 @@
 		// Boolean:
 		//		whether focusing into this instance of richtext when page onload
 		focusOnLoad: true,
-		
+
 		// String:
 		//		If a save name is specified the content is saved and restored if the
 		//		editor is not properly closed after editing has started.
@@ -57,7 +57,7 @@
 		// String:
 		//		temporary content storage
 		_content: "",
-		
+
 		// String:
 		//		set height to fix the editor at a specific height, with scrolling
 		height: "",
@@ -89,30 +89,23 @@
 	 *******/
 
 		fillInTemplate: function(){
-			// summary: see dojo.widget.DomWidget 
+			// summary: see dojo.widget.DomWidget
 			dojo.event.topic.publish("dojo.widget.RichText::init", this);
 			this.open();
 
-			// add the formatting functions
-			var funcs = ["queryCommandEnabled", "queryCommandState",
-				"queryCommandValue", "execCommand"];
-			for(var i = 0; i < funcs.length; i++){
-				dojo.event.connect("around", this, funcs[i], this, "_normalizeCommand");
-			}
-			
 			// backwards compatibility, needs to be removed
 			dojo.event.connect(this, "onKeyPressed", this, "afterKeyPress");
 			dojo.event.connect(this, "onKeyPress", this, "keyPress");
 			dojo.event.connect(this, "onKeyDown", this, "keyDown");
 			dojo.event.connect(this, "onKeyUp", this, "keyUp");
 
-			// add default some key handlers		
+			// add default some key handlers
 			var ctrl = this.KEY_CTRL;
 			var exec = function (cmd, arg) {
 				return arguments.length == 1 ? function () { this.execCommand(cmd); } :
 					function () { this.execCommand(cmd, arg); }
 			}
-				
+
 			this.addKeyHandler("b", ctrl, exec("bold"));
 			this.addKeyHandler("i", ctrl, exec("italic"));
 			this.addKeyHandler("u", ctrl, exec("underline"));
@@ -120,12 +113,12 @@
 			//this.addKeyHandler("k", ctrl, exec("createlink", ""));
 			//this.addKeyHandler("K", ctrl, exec("unlink"));
 			this.addKeyHandler("s", ctrl, function () { this.save(true); });
-			
+
 			this.addKeyHandler("1", ctrl, exec("formatblock", "h1"));
 			this.addKeyHandler("2", ctrl, exec("formatblock", "h2"));
 			this.addKeyHandler("3", ctrl, exec("formatblock", "h3"));
 			this.addKeyHandler("4", ctrl, exec("formatblock", "h4"));
-					
+
 			this.addKeyHandler("\\", ctrl, exec("insertunorderedlist"));
 			if(!dojo.render.html.ie){
 				this.addKeyHandler("Z", ctrl, exec("redo"));
@@ -163,7 +156,7 @@
 				this.domNode = dojo.doc().createElement("div");
 				dojo.html.copyStyle(this.domNode, this.textarea);
 				var tmpFunc = dojo.lang.hitch(this, function(){
-					//some browsers refuse to submit display=none textarea, so 
+					//some browsers refuse to submit display=none textarea, so
 					//move the textarea out of screen instead
 					with(this.textarea.style){
 						display = "block";
@@ -176,8 +169,8 @@
 						}
 					}
 				});
-				if(h.ie){ 
-					setTimeout(tmpFunc, 10); 
+				if(h.ie){
+					setTimeout(tmpFunc, 10);
 				}else{
 					tmpFunc();
 				}
@@ -188,16 +181,16 @@
 					dojo.html.insertBefore(this.domNode, this.textarea);
 				}
 				// this.domNode.innerHTML = html;
-				
+
 				if(this.textarea.form){
-					dojo.event.connect(this.textarea.form, "onsubmit", 
+					dojo.event.connect(this.textarea.form, "onsubmit",
 						// FIXME: should we be calling close() here instead?
 						dojo.lang.hitch(this, function(){
 							this.textarea.value = this.getEditorContent();
 						})
 					);
 				}
-				
+
 				// dojo plucks our original domNode from the document so we need
 				// to go back and put ourselves back in
 				var editor = this;
@@ -230,7 +223,7 @@
 				(this.domNode.nodeName == "LI")){
 				this.domNode.innerHTML = " <br>";
 			}
-					
+
 			if(this.saveName != ""){
 				var saveTextarea = dojo.doc().getElementById("dojo.widget.RichText.savedContent");
 				if (saveTextarea.value != "") {
@@ -242,7 +235,7 @@
 							datas.splice(i, 1);
 							break;
 						}
-					}				
+					}
 				}
 				dojo.event.connect("before", window, "onunload", this, "_saveContent");
 				// dojo.event.connect(window, "onunload", this, "_saveContent");
@@ -296,7 +289,7 @@
 				// behavior. It's particularly bad if the element you're editing
 				// contains childnodes that don't have margin: defined in local
 				// css rules. It would be nice if it was possible to hack around
-				// this. Sadly _firstChildContributingMargin and 
+				// this. Sadly _firstChildContributingMargin and
 				// _lastChildContributingMargin don't work on IE unless all
 				// elements have margins set in CSS :-(
 
@@ -336,12 +329,12 @@
 				}
 
 				this.editNode.innerHTML = html;
-				if(this.height){ this.editNode.style.overflowY="scroll"; }
+				if(this.height){ this.document.body.style.overflowY="scroll"; }
 
 				dojo.lang.forEach(this.events, function(e){
 					dojo.event.connect(this.editNode, e.toLowerCase(), this, e);
 				}, this);
-				
+
 				this.onLoad();
 			} else { // designMode in iframe
 				this._drawIframe(html);
@@ -351,7 +344,7 @@
 			// TODO: this is a guess at the default line-height, kinda works
 			if (this.domNode.nodeName == "LI") { this.domNode.lastChild.style.marginTop = "-1.2em"; }
 			dojo.html.addClass(this.domNode, "RichTextEditable");
-			
+
 			this.isClosed = false;
 		},
 
@@ -359,11 +352,11 @@
 			// summary:
 			//		check if an element has padding or borders on the given side
 			//		which would prevent it from collapsing margins
-			if (dojo.html.getPixelValue(element, 
-										 'border-'+side+'-width', 
+			if (dojo.html.getPixelValue(element,
+										 'border-'+side+'-width',
 										 false)) {
 				return false;
-			} else if (dojo.html.getPixelValue(element, 
+			} else if (dojo.html.getPixelValue(element,
 												'padding-'+side,
 												false)) {
 				return false;
@@ -398,8 +391,8 @@
 			function isSignificantNode(element) {
 				// see if an node is significant in the current context
 				// for calulating margins
-				return !(element.nodeType==3 && dojo.string.isBlank(element.data)) 
-					&& dojo.html.getStyle(element, "display") != "none" 
+				return !(element.nodeType==3 && dojo.string.isBlank(element.data))
+					&& dojo.html.getStyle(element, "display") != "none"
 					&& !dojo.html.isPositionAbsolute(element);
 			}
 
@@ -411,11 +404,11 @@
 				while ((!isSignificantNode(child)) && child[childSiblingAttr]) {
 					child = child[childSiblingAttr];
 				}
-						  
+
 				childMargin = Math.max(childMargin, dojo.html.getPixelValue(child, marginProp, false));
 				// stop if we hit a bordered/padded element
 				if (!this._hasCollapseableMargin(child, topOrBottom)) break;
-				child = child[childAttr];								   
+				child = child[childAttr];
 			}
 
 			// if this element has a border, return full child margin immediately
@@ -427,15 +420,15 @@
 			var sibling = element[siblingAttr];
 			while (sibling) {
 				if (isSignificantNode(sibling)) {
-					contextMargin = dojo.html.getPixelValue(sibling, 
-															 siblingMarginProp, 
+					contextMargin = dojo.html.getPixelValue(sibling,
+															 siblingMarginProp,
 															 false);
 					break;
 				}
 				sibling = sibling[siblingAttr];
 			}
 			if (!sibling) { // no sibling, look at parent's margin instead
-				contextMargin = dojo.html.getPixelValue(element.parentNode, 
+				contextMargin = dojo.html.getPixelValue(element.parentNode,
 												marginProp, false);
 			}
 
@@ -444,12 +437,12 @@
 			} else {
 				return 0;
 			}
-			
+
 		},
 
 		_drawIframe: function (/*String*/html) {
 			// summary:
-			//		Draws an iFrame using the existing one if one exists. 
+			//		Draws an iFrame using the existing one if one exists.
 			//		Used by Mozilla, Safari, and Opera
 
 			// detect firefox < 1.5, which has some iframe loading issues
@@ -538,7 +531,7 @@
 						getStyle('font-weight') + " " +
 						getStyle('font-size') + " " +
 						getStyle('font-family');
-					
+
 					// line height is tricky - applying a units value will mess things up.
 					// if we can't get a non-units value, bail out.
 					var lineHeight = "1.0";
@@ -552,8 +545,8 @@
 						// TODO: left positioning will case contents to disappear out of view
 						//       if it gets too wide for the visible area
 						'    body { top: 0; left: 0; right: 0;' +
-						(((this.height)||(dojo.render.html.opera)) ? '' : ' position: fixed; ') + 
-						'        font: ' + font + ';\n' + 
+						(((this.height)||(dojo.render.html.opera)) ? '' : ' position: fixed; ') +
+						'        font: ' + font + ';\n' +
 						'        min-height: ' + this.minHeight + '; \n' +
 						'        line-height: ' + lineHeight + '} \n' +
 						'    p { margin: 1em 0 !important; }\n' +
@@ -561,7 +554,7 @@
 						'    body > *:last-child { padding-bottom: 0 !important; margin-bottom: ' + this._lastChildContributingMargin + 'px !important; }\n' +
 						'    li > ul:-moz-first-node, li > ol:-moz-first-node { padding-top: 1.2em; }\n' +
 						'    li { min-height: 1.2em; }\n' +
-						//'    p,ul,li { padding-top: 0; padding-bottom: 0; margin-top:0; margin-bottom: 0; }\n' + 
+						//'    p,ul,li { padding-top: 0; padding-bottom: 0; margin-top:0; margin-bottom: 0; }\n' +
 						'', this.document);
 
 					tmpContent.parentNode.removeChild(tmpContent);
@@ -605,7 +598,7 @@
 			if(files.length>0){
 				for(var i=0;i<files.length;i++){
 					var url = files[i];
-					if(url){ 
+					if(url){
 						this.addStyleSheet(new dojo.uri.Uri(dojo.global().location, url));
 	 				}
 	 			}
@@ -635,7 +628,7 @@
 				head.appendChild(stylesheet);
 			}
 		},
-		
+
 		removeStyleSheet: function (/*dojo.uri.Uri*/uri) {
 			// summary:
 			//		remove an external stylesheet for the editing area
@@ -699,7 +692,7 @@
 		_local2NativeFormatNames: {},
 		_native2LocalFormatNames: {},
 		//in IE, names for blockformat is locale dependent, so we cache the values here
-		//we use activeX to obtain the list, if success or the names are already cached, 
+		//we use activeX to obtain the list, if success or the names are already cached,
 		//return true
 		_cacheLocalBlockFormatNames: function(){
 			if(!this._native2LocalFormatNames['p']){
@@ -715,8 +708,8 @@
 						return false;
 					}
 				}
-				var oNamesParm = new ActiveXObject("DEGetBlockFmtNamesParam.DEGetBlockFmtNamesParam"); 
-				obj.ExecCommand(this._activeX.command['getblockformatnames'], 0, oNamesParm); 
+				var oNamesParm = new ActiveXObject("DEGetBlockFmtNamesParam.DEGetBlockFmtNamesParam");
+				obj.ExecCommand(this._activeX.command['getblockformatnames'], 0, oNamesParm);
 				var vbNamesArray = new VBArray(oNamesParm.Names);
 				var localFormats = vbNamesArray.toArray();
 				var nativeFormats = ['p', 'pre', 'address', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ol', 'ul', '', '', '','','div'];
@@ -752,13 +745,13 @@
 			}else if (this.iframe && !dojo.render.html.ie){
 				this.editNode = this.document.body;
 				this.connect(this, "onDisplayChanged", "_updateHeight");
-		
+
 				try { // sanity check for Mozilla
 					this.document.execCommand("useCSS", false, true); // old moz call
 					this.document.execCommand("styleWithCSS", false, false); // new moz call
 					//this.document.execCommand("insertBrOnReturn", false, false); // new moz call
 				}catch(e2){ }
-				
+
 				if (dojo.render.html.safari) {
 					/*
 					this.iframe.style.visiblity = "visible";
@@ -770,7 +763,7 @@
 					this.connect(this.editNode, "onblur", "onBlur");
 					this.connect(this.editNode, "onfocus", "onFocus");
 					this.connect(this.editNode, "onclick", "onFocus");
-				
+
 					this.interval = setInterval(dojo.lang.hitch(this, "onDisplayChanged"), 750);
 					// dojo.raise("onload");
 					// dojo.debug(this.editNode.parentNode.parentNode.parentNode.nodeName);
@@ -793,7 +786,7 @@
 					addListener(this.document, "keyup", dojo.lang.hitch(this, "onKeyUp"));
 					addListener(this.document, "click", dojo.lang.hitch(this, "onClick"));
 				}
-				// FIXME: when scrollbars appear/disappear this needs to be fired						
+				// FIXME: when scrollbars appear/disappear this needs to be fired
 			}else if(dojo.render.html.ie){
 				// IE contentEditable
 				this.connect(this, "onDisplayChanged", "_updateHeight");
@@ -822,7 +815,7 @@
 				e.stopPropagation();
 				// FIXME: this is a poor-man's indent/outdent. It would be
 				// better if it added 4 "&nbsp;" chars in an undoable way.
-				// Unfortuantly pasteHTML does not prove to be undoable 
+				// Unfortuantly pasteHTML does not prove to be undoable
 				this.execCommand((e.shiftKey ? "outdent" : "indent"));
 			}else if(dojo.render.html.ie){
 				if((65 <= e.keyCode)&&(e.keyCode <= 90)){
@@ -835,14 +828,14 @@
 				// this.onKeyPress(e);
 			}
 		},
-		
+
 		/** Fired on keyup */
 		onKeyUp: function(e){
 			return;
 		},
-		
+
 		KEY_CTRL: 1,
-		
+
 		/** Fired on keypress. */
 		onKeyPress: function(e){
 			if((!e)&&(this.object)){
@@ -866,7 +859,7 @@
 					}
 				}
 			}
-			
+
 			/*
 			// define some key combos
 			if (e.ctrlKey || e.metaKey) { // modifier pressed
@@ -879,14 +872,14 @@
 					//case "K": this.execCommand("unlink"); break;
 					case "Z": this.execCommand("redo"); break;
 					case "s": this.close(true); break; // saves
-					
+
 					case "1": this.execCommand("formatblock", "h1"); break;
 					case "2": this.execCommand("formatblock", "h2"); break;
 					case "3": this.execCommand("formatblock", "h3"); break;
 					case "4": this.execCommand("formatblock", "h4"); break;
-					
+
 					case "\\": this.execCommand("insertunorderedlist"); break;
-					
+
 					default: switch (code) {
 						case e.KEY_LEFT_ARROW:
 						case e.KEY_RIGHT_ARROW:
@@ -906,14 +899,14 @@
 						preventDefault = false; break; // didn't handle here
 				}
 			}
-			
+
 			if (preventDefault) { e.preventDefault(); }
 			*/
 
 			// function call after the character has been inserted
 			dojo.lang.setTimeout(this, this.onKeyPressed, 1, e);
 		},
-		
+
 		addKeyHandler: function (key, modifiers, handler) {
 			if (!(this._keyHandlers[key] instanceof Array)) { this._keyHandlers[key] = []; }
 			this._keyHandlers[key].push({
@@ -921,9 +914,9 @@
 				handler: handler
 			});
 		},
-		
-		
-		
+
+
+
 		/**
 		 * Fired after a keypress event has occured and it's action taken. This
 		 * is useful if action needs to be taken after text operations have
@@ -940,7 +933,7 @@
 			// and so we need to remove the <p>s to ensure the position of the cursor
 			// changes from the users perspective when they hit enter, as the second two
 			// html snippets render the same when margins are set to 0.
-			
+
 			// TODO: doesn't really work; is this really needed?
 			//if (dojo.render.html.moz) {
 			//	for (var i = 0; i < this.document.getElementsByTagName("p").length; i++) {
@@ -953,11 +946,11 @@
 			//}
 			this.onDisplayChanged(/*e*/); // can't pass in e
 		},
-		
+
 		onClick: function(e){ this.onDisplayChanged(e); },
 		onBlur: function(e){ },
 		_initialFocus: true,
-		onFocus: function(e){ 
+		onFocus: function(e){
 			if( (dojo.render.html.mozilla)&&(this._initialFocus) ){
 				this._initialFocus = false;
 				if(dojo.string.trim(this.editNode.innerHTML) == "&nbsp;"){
@@ -972,22 +965,25 @@
 			else if(this.object) { this.document.body.blur(); }
 			else if(this.editNode) { this.editNode.blur(); }
 		},
-		
+
 		focus: function () {
 			if(this.iframe && !dojo.render.html.ie) { this.window.focus(); }
 			else if(this.object) { this.document.focus(); }
 			// editNode may be hidden in display:none div, lets just punt in this case
-			else if(this.editNode && dojo.lang.isFunction(this.editNode.focus)) { this.editNode.focus(); }
+			else if(this.editNode && this.editNode.focus) { this.editNode.focus(); }
+			else{
+				dojo.debug("Have no idea how to focus into the editor!");
+			}
 		},
-		
+
 		/** this event will be fired everytime the display context changes and the
 		 result needs to be reflected in the UI */
 		onDisplayChanged: function (e){ },
-		
+
 
 	/* Formatting commands
 	 **********************/
-		
+
 		/** IE's Active X codes: see http://www.computerbytesman.com/js/activex/dhtmledit.htm */
 		_activeX: {
 			command: {
@@ -1027,7 +1023,7 @@
 				deleterows: 5007,
 				mergecells: 5029,
 				splitcell: 5047,
-				
+
 				// the command need mapping, they don't translate directly
 				// to the contentEditable commands
 				setblockformat: 5043,
@@ -1041,12 +1037,12 @@
 				getbackcolor: 5010,
 				setforecolor: 5046,
 				getforecolor: 5015,
-				
+
 				findtext: 5008,
 				font: 5009,
 				hyperlink: 5016,
 				image: 5017,
-				
+
 				lockelement: 5027,
 				makeabsolute: 5028,
 				sendbackward: 5036,
@@ -1055,16 +1051,16 @@
 				bringabovetext: 5039,
 				sendtoback: 5040,
 				bringtofront: 5041,
-				
+
 				properties: 5052
 			},
-			
+
 			ui: {
 				"default": 0,
 				prompt: 1,
 				noprompt: 2
 			},
-			
+
 			status: {
 				notsupported: 0,
 				disabled: 1,
@@ -1072,19 +1068,19 @@
 				latched: 7,
 				ninched: 11
 			},
-			
+
 			appearance: {
 				flat: 0,
 				inset: 1
 			},
-			
+
 			state: {
 				unchecked: 0,
 				checked: 1,
 				gray: 2
 			}
 		},
-		
+
 		/**
 		 * Used as the advice function by dojo.event.connect to map our
 		 * normalized set of commands to those supported by the target
@@ -1094,16 +1090,12 @@
 		 *                  item, the command and an optional second item,
 		 *                  an argument.
 		 */
-		_normalizeCommand: function (joinObject){
+		_normalizeCommand: function (cmd){
 			var drh = dojo.render.html;
-			
-			var command = joinObject.args[0].toLowerCase();
+
+			var command = cmd.toLowerCase();
 			if(command == "formatblock"){
 				if(drh.safari){ command = "heading"; }
-				if(this.object && joinObject.args[1]){ //IE activeX mode
-					joinObject.args[1] = this._native2LocalFormatNames[joinObject.args[1]];
-				}
-				else if(drh.ie){ joinObject.args[1] = "<"+joinObject.args[1]+">"; }
 			}else if(this.object){
 				switch(command){
 					case "createlink":
@@ -1117,17 +1109,9 @@
 				command = "backcolor";
 			}
 
-			joinObject.args[0] = command;
-			
-			if (joinObject.args.length > 1) { // a command was specified
-				var argument = joinObject.args[1];
-				if (command == "heading") { throw new Error("unimplemented"); }
-				joinObject.args[1] = argument;
-			}
-			
-			return joinObject.proceed();
+			return command;
 		},
-		
+
 		/**
 		 * Tests whether a command is supported by the host. Clients SHOULD check
 		 * whether a command is supported before attempting to use it, behaviour
@@ -1142,7 +1126,7 @@
 			var safari = 1 << 2;
 			var opera = 1 << 3;
 			var safari420 = 1 << 4;
-		
+
 			var gt420 = false;
 			if(dojo.render.html.safari){
 				var tmp = dojo.render.html.UA.split("AppleWebKit/")[1];
@@ -1161,21 +1145,21 @@
 			}
 
 			var supportedBy = null;
-			
+
 			switch (command.toLowerCase()) {
 				case "bold": case "italic": case "underline":
 				case "subscript": case "superscript":
 				case "fontname": case "fontsize":
 				case "forecolor": case "hilitecolor":
-				case "justifycenter": case "justifyfull": case "justifyleft": 
+				case "justifycenter": case "justifyfull": case "justifyleft":
 				case "justifyright": case "delete": case "selectall":
 					supportedBy = isSupportedBy(mozilla | ie | safari | opera);
 					break;
-					
+
 				case "createlink": case "unlink": case "removeformat":
 				case "inserthorizontalrule": case "insertimage":
 				case "insertorderedlist": case "insertunorderedlist":
-				case "indent": case "outdent": case "formatblock": 
+				case "indent": case "outdent": case "formatblock":
 				case "inserthtml": case "undo": case "redo": case "strikethrough":
 					supportedBy = isSupportedBy(mozilla | ie | opera | safari420);
 					break;
@@ -1185,23 +1169,23 @@
 				case "inlinedirltr": case "inlinedirrtl":
 					supportedBy = isSupportedBy(ie);
 					break;
-				case "cut": case "copy": case "paste": 
+				case "cut": case "copy": case "paste":
 					supportedBy = isSupportedBy( ie | mozilla | safari420);
 					break;
-				
+
 				case "inserttable":
 					supportedBy = isSupportedBy(mozilla | (this.object ? ie : 0));
 					break;
-				
+
 				case "insertcell": case "insertcol": case "insertrow":
 				case "deletecells": case "deletecols": case "deleterows":
 				case "mergecells": case "splitcell":
 					supportedBy = isSupportedBy(this.object ? ie : 0);
 					break;
-				
+
 				default: return false;
 			}
-			
+
 			return (dojo.render.html.ie && supportedBy.ie) ||
 				(dojo.render.html.mozilla && supportedBy.mozilla) ||
 				(dojo.render.html.safari && supportedBy.safari) ||
@@ -1223,6 +1207,16 @@
 			//the command, the editor receives the focus as expected
 			this.focus();
 
+			command = this._normalizeCommand(command);
+			if (argument != undefined) {
+				if(command == "heading") { throw new Error("unimplemented"); }
+				else if(command == "formatblock"){
+					if(this.object){ //IE activeX mode
+						argument = this._native2LocalFormatNames[argument];
+					}
+					else if(drh.ie){ argument = '<'+argument+'>'; }
+				}
+			}
 			if(this.object){
 				switch (command) {
 					case "hilitecolor":
@@ -1249,7 +1243,7 @@
 					command = "inserthtml";
 					argument="<hr>";
 				}
-			
+
 				if(command == "inserthtml"){
 					var range = this.document.selection.createRange();
 					if(this.document.selection.type.toUpperCase() == "CONTROL"){
@@ -1285,7 +1279,7 @@
 					insertRange.collapse(true);
 					return true;
 				}else{
-					return this.document.execCommand(command, false, argument);			
+					return this.document.execCommand(command, false, argument);
 				}
 			/* */
 			// fix up unlink in Mozilla to unlink the link and not just the selection
@@ -1301,32 +1295,32 @@
 				var selectionStartOffset = selectionRange.startOffset;
 				var selectionEndContainer = selectionRange.endContainer;
 				var selectionEndOffset = selectionRange.endOffset;
-				
+
 				// select our link and unlink
 				var a = dojo.withGlobal(this.window, "getAncestorElement", dojo.html.selection, ['a']);
 				dojo.withGlobal(this.window, "selectElement", dojo.html.selection, [a]);
-				
+
 				returnValue = this.document.execCommand("unlink", false, null);
-				
+
 				// restore original selection
 				var selectionRange = this.document.createRange();
 				selectionRange.setStart(selectionStartContainer, selectionStartOffset);
 				selectionRange.setEnd(selectionEndContainer, selectionEndOffset);
 				selection.removeAllRanges();
 				selection.addRange(selectionRange);
-				
+
 				return returnValue;
 			}else if((command == "hilitecolor")&&(dojo.render.html.mozilla)){
 				// mozilla doesn't support hilitecolor properly when useCSS is
 				// set to false (bugzilla #279330)
-				
+
 				this.document.execCommand("useCSS", false, false);
-				returnValue = this.document.execCommand(command, false, argument);			
+				returnValue = this.document.execCommand(command, false, argument);
 				this.document.execCommand("useCSS", false, true);
-			
+
 			}else if((dojo.render.html.ie)&&( (command == "backcolor")||(command == "forecolor") )){
 				// Tested under IE 6 XP2, no problem here, comment out
-				// IE weirdly collapses ranges when we exec these commands, so prevent it	
+				// IE weirdly collapses ranges when we exec these commands, so prevent it
 //				var tr = this.document.selection.createRange();
 				argument = arguments.length > 1 ? argument : null;
 				returnValue = this.document.execCommand(command, false, argument);
@@ -1347,12 +1341,13 @@
 					returnValue = this.document.execCommand(command, false, argument);
 				}
 			}
-			
+
 			this.onDisplayChanged();
 			return returnValue;
 		},
 
-		queryCommandEnabled: function(command, argument){
+		queryCommandEnabled: function(command){
+			command = this._normalizeCommand(command);
 			if(this.object){
 				switch (command) {
 					case "hilitecolor":
@@ -1377,14 +1372,15 @@
 
 				if(typeof this._activeX.command[command] == "undefined"){ return false; }
 				var status = this.object.QueryStatus(this._activeX.command[command]);
-				return ((status != this._activeX.status.notsupported)&& 
+				return ((status != this._activeX.status.notsupported)&&
 					(status != this._activeX.status.disabled));
 			}else{
-				// mozilla returns true always
-				if(command == "unlink" && dojo.render.html.mozilla){
-					return dojo.withGlobal(this.window, "hasAncestorElement", dojo.html.selection, ['a']);
-				} else if (command == "inserttable" && dojo.render.html.mozilla) {
-					return true;
+				if(dojo.render.html.mozilla){
+					if(command == "unlink"){ // mozilla returns true always
+						return dojo.withGlobal(this.window, "hasAncestorElement", dojo.html.selection, ['a']);
+					} else if (command == "inserttable") {
+						return true;
+					}
 				}
 
 				// return this.document.queryCommandEnabled(command);
@@ -1393,7 +1389,8 @@
 			}
 		},
 
-		queryCommandState: function(command, argument){
+		queryCommandState: function(command){
+			command = this._normalizeCommand(command);
 			if(this.object){
 				if(command == "forecolor"){
 					command = "setforecolor";
@@ -1415,7 +1412,8 @@
 			}
 		},
 
-		queryCommandValue: function (command, argument) {
+		queryCommandValue: function (command) {
+			command = this._normalizeCommand(command);
 			if (this.object) {
 				switch (command) {
 					case "forecolor":
@@ -1441,17 +1439,17 @@
 				return this.document.queryCommandValue(command);
 			}
 		},
-		
-		
+
+
 	/* Misc.
 	 ********/
-		
+
 		placeCursorAtStart: function(){
 			// summary:
 			//		place the cursor at the start of the editing area
 			this.focus();
 			//see comments in placeCursorAtEnd
-			if(dojo.render.html.moz && this.editNode.firstChild && 
+			if(dojo.render.html.moz && this.editNode.firstChild &&
 				this.editNode.firstChild.nodeType != dojo.dom.TEXT_NODE){
 				dojo.withGlobal(this.window, "selectElementChildren", dojo.html.selection, [this.editNode.firstChild]);
 			}else{
@@ -1466,7 +1464,7 @@
 			this.focus();
 			//In mozilla, if last child is not a text node, we have to use selectElementChildren on this.editNode.lastChild
 			//otherwise the cursor would be placed at the end of the closing tag of this.editNode.lastChild
-			if(dojo.render.html.moz && this.editNode.lastChild && 
+			if(dojo.render.html.moz && this.editNode.lastChild &&
 				this.editNode.lastChild.nodeType != dojo.dom.TEXT_NODE){
 				dojo.withGlobal(this.window, "selectElementChildren", dojo.html.selection, [this.editNode.lastChild]);
 			}else{
@@ -1573,11 +1571,11 @@
 				var re = new RegExp("(?:<p>&nbsp;</p>[\n\r]*)+$", "i");
 				ec = ec.replace(re,"");
 			}
-	
+
 			ec = this._postFilterContent(ec);
 
 			if (this.relativeImageUrls) {
-				// why use a regexp instead of dom? because IE is stupid 
+				// why use a regexp instead of dom? because IE is stupid
 				// and won't let us set img.src to a relative URL
 				// this comes after contentPostFilters because once content
 				// gets innerHTML'd img urls will be fully qualified
@@ -1594,7 +1592,7 @@
 					pathBase = pathParts.join("/") + "/";
 
 				}
-				
+
 				var sameSite = new RegExp("(<img[^>]*\ src=[\"'])("+siteBase+"("+pathBase+")?)", "ig");
 				ec = ec.replace(sameSite, "$1");
 			}
@@ -1603,26 +1601,26 @@
 
 		close: function(/*Boolean*/save, /*Boolean*/force){
 			// summery:
-			//		Kills the editor and optionally writes back the modified contents to the 
+			//		Kills the editor and optionally writes back the modified contents to the
 			//		element from which it originated.
-			// save: 
+			// save:
 			//		Whether or not to save the changes. If false, the changes are discarded.
-			// force: 
+			// force:
 			if(this.isClosed){return false; }
 
 			if (arguments.length == 0) { save = true; }
 			this._content = this._postFilterContent(this.editNode.innerHTML);
 			var changed = (this.savedContent.innerHTML != this._content);
-			
+
 			// line height is squashed for iframes
 			// FIXME: why was this here? if (this.iframe){ this.domNode.style.lineHeight = null; }
 
 			if(this.interval){ clearInterval(this.interval); }
-			
+
 			if(dojo.render.html.ie && !this.object){
 				dojo.event.browser.clean(this.editNode);
 			}
-			
+
 			if (this.iframe) {
 				// FIXME: should keep iframe around for later re-use
 				delete this.iframe;
@@ -1660,7 +1658,7 @@
 				}
 			}
 			delete this.savedContent;
-			
+
 			dojo.html.removeClass(this.domNode, "RichTextEditable");
 			this.isClosed = true;
 			this.isLoaded = false;
@@ -1681,7 +1679,7 @@
 		},
 
 		destroyRendering: function(){}, // stub!
-		
+
 		destroy: function (){
 			this.destroyRendering();
 			if(!this.isClosed){ this.close(false); }
@@ -1693,7 +1691,7 @@
 			// summary: convenient method for dojo.event.connect
 			dojo.event.connect(targetObj, targetFunc, this, thisFunc);
 		},
-		
+
 		disconnect: function (targetObj, targetFunc, thisFunc) {
 			// summary: convenient method for dojo.event.disconnect
 			dojo.event.disconnect(targetObj, targetFunc, this, thisFunc);
@@ -1733,7 +1731,7 @@
 		if(dojo.render.html.moz){
 			this.contentPreFilters.push(this._fixContentForMoz);
 		}
-		
+
 		this._keyHandlers = {};
 	}
 );

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Select.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Select.js?view=diff&rev=453979&r1=453978&r2=453979
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Select.js (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Select.js Sat Oct  7 11:22:33 2006
@@ -69,8 +69,8 @@
 		},
 
 		setAllValues: function(value1, value2){
-			this.setValue(value2);
 			this.setLabel(value1);
+			this.setValue(value2);
 		}
 	}
 );

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/ShowSlide.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/ShowSlide.js?view=diff&rev=453979&r1=453978&r2=453979
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/ShowSlide.js (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/ShowSlide.js Sat Oct  7 11:22:33 2006
@@ -199,7 +199,12 @@
 				}else if(tmpAction == "remove"){
 					component.style.display = "none";
 				}
-				component.style.visibility = "visible";
+
+				if(tmpAction == "hide"){
+					component.style.visibility = "hidden";
+				}else{
+					component.style.visibility = "visible";
+				}
 			}
 		}
 		

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Slider.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Slider.js?view=diff&rev=453979&r1=453978&r2=453979
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Slider.js (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Slider.js Sat Oct  7 11:22:33 2006
@@ -479,7 +479,7 @@
 		_calc_valueSizeX: function () {
 			var constrainingCtrBox = dojo.html.getContentBox(this.constrainingContainerNode);
 			var sliderHandleBox = dojo.html.getContentBox(this.sliderHandleNode);
-			if (constrainingCtrBox.width <= 0 || sliderHandleBox.width <= 0) { 
+			if (isNaN(constrainingCtrBox.width) || isNaN(sliderHandleBox.width) || constrainingCtrBox.width <= 0 || sliderHandleBox.width <= 0) { 
 				return false; 
 			}
 
@@ -562,7 +562,7 @@
 		_calc_valueSizeY: function () {
 			var constrainingCtrBox = dojo.html.getContentBox(this.constrainingContainerNode);
 			var sliderHandleBox = dojo.html.getContentBox(this.sliderHandleNode);
-			if (constrainingCtrBox.height <= 0 || sliderHandleBox.height <= 0) { 
+			if (isNaN(constrainingCtrBox.height) || isNaN(sliderHandleBox.height) || constrainingCtrBox.height <= 0 || sliderHandleBox.height <= 0) { 
 				return false; 
 			}
 
@@ -630,15 +630,14 @@
 				return;
 			}
 
-			var offset = dojo.html.getScroll().offset;
-			var parent = dojo.html.getAbsolutePosition(this.constrainingContainerNode, true);
+			var parent = dojo.html.getAbsolutePosition(this.constrainingContainerNode, true, dojo.html.boxSizing.MARGIN_BOX);
 			var content = dojo.html.getContentBox(this._handleMove.domNode);			
 			if (this.isEnableX) {
-				var x = offset.x + evt.clientX - parent.x - (content.width >> 1);
+				var x = evt.pageX - parent.x - (content.width >> 1);
 				this._snapX(x, this._handleMove);
 			}
 			if (this.isEnableY) {
-				var y = offset.y + evt.clientY - parent.y - (content.height >> 1);
+				var y = evt.pageY - parent.y - (content.height >> 1);
 				this._snapY(y, this._handleMove);
 			}
 			this.notifyListeners();
@@ -801,11 +800,12 @@
 	 *  Extends dojo.dnd.HtmlDragMoveSource by creating a SliderDragMoveSource */
 	onDragStart: function (evt) {
 		this.slider.isDragInProgress = true;
+		var pos = dojo.html.getAbsolutePosition(this.slider.constrainingContainerNode, true, dojo.html.boxSizing.MARGIN_BOX);
 		if (this.slider.isEnableX) {
-			this.slider._minX = dojo.html.getAbsolutePosition(this.slider.constrainingContainerNode).x;
+			this.slider._minX = pos.x;
 		}
 		if (this.slider.isEnableY) {
-			this.slider._minY = dojo.html.getAbsolutePosition(this.slider.constrainingContainerNode).y;
+			this.slider._minY = pos.y;
 		}
 
 		var dragObj = this.createDragMoveObject ();
@@ -859,14 +859,13 @@
 	onDragMove: function (evt) {
 		this.updateDragOffset ();
 
-		var offset = dojo.html.getScroll().offset;
 		if (this.slider.isEnableX) {
-			var x = this.dragOffset.x + evt.pageX - this.slider._minX - offset.x;
+			var x = this.dragOffset.x + evt.pageX - this.slider._minX;
 			this.slider._snapX(x, this.slider._handleMove);
 		}
 
 		if (this.slider.isEnableY) {
-			var y = this.dragOffset.y + evt.pageY - this.slider._minY - offset.y;
+			var y = this.dragOffset.y + evt.pageY - this.slider._minY;
 			this.slider._snapY(y, this.slider._handleMove);
 		}
 		if(this.slider.activeDrag){

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Spinner.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Spinner.js?view=diff&rev=453979&r1=453978&r2=453979
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Spinner.js (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Spinner.js Sat Oct  7 11:22:33 2006
@@ -16,11 +16,15 @@
 dojo.require("dojo.html.layout");
 dojo.require("dojo.string");
 dojo.require("dojo.widget.*");
-dojo.require("dojo.widget.validate");
-
-// Mixin for validation widgets with a spinner
-// This class basically (conceptually) extends dojo.widget.validate.ValidationTextbox.
-// It modifies the template to have up/down arrows, and provides related handling code.
+dojo.require("dojo.widget.validate.IntegerTextbox");
+dojo.require("dojo.widget.validate.RealNumberTextbox");
+dojo.require("dojo.widget.validate.DateTextbox");
+
+dojo.require("dojo.experimental");
+
+// summary: Mixin for validation widgets with a spinner
+// description: This class basically (conceptually) extends dojo.widget.validate.ValidationTextbox.
+//	It modifies the template to have up/down arrows, and provides related handling code.
 dojo.declare(
 	"dojo.widget.Spinner",
 	null, 
@@ -48,7 +52,7 @@
 			var keyCode = evt.keyCode;
 
 			switch(keyCode){
- 			case k.KEY_DOWN_ARROW:
+				case k.KEY_DOWN_ARROW:
 					dojo.event.browser.stopEvent(evt);
 					this._downArrowPressed(evt);
 					return;
@@ -89,17 +93,13 @@
 		},
 
 		_pressButton: function(node){
-			with(node.style){
-				borderWidth = "1px 0px 0px 1px";
-				borderStyle = "inset";
-			}
+			node.style.borderWidth = "1px 0px 0px 1px";
+			node.style.borderStyle = "inset";
 		},
 
 		_releaseButton: function(node){
-			with(node.style){
-				borderWidth = "0px 1px 1px 0px";
-				borderStyle = "outset";
-			}
+			node.style.borderWidth = "0px 1px 1px 0px";
+			node.style.borderStyle = "outset";
 		},
 
 		_arrowPressed: function(evt, direction){
@@ -213,7 +213,7 @@
 		setCursorX: function(x){
 			try{
 				this.textbox.focus();
-				if(!x){ x = 0 }
+				if(!x){ x = 0; }
 				if(typeof this.textbox.selectionEnd == "number"){
 				this.textbox.selectionEnd = x;
 				}else if(this.textbox.createTextRange){
@@ -251,45 +251,43 @@
 	}
 );
 
-/*
-  ****** SpinnerIntegerTextbox ******
-
-  A subclass of IntegerTextbox.
-*/
 dojo.widget.defineWidget(
-	"dojo.widget.SpinnerIntegerTextbox",
+	"dojo.widget.IntegerSpinner",
 	[dojo.widget.validate.IntegerTextbox, dojo.widget.Spinner],
 {
-	// new subclass properties
+	// summary: an IntegerSpinner with +/- buttons
+
+	// int increment amount
 	delta: "1",
 
+	// 
 	adjustValue: function(direction, x){
-			var val = this.getValue().replace(/[^\-+\d]/g, "");
-			if(val.length == 0){ return; }
+		var val = this.getValue().replace(/[^\-+\d]/g, "");
+		if(val.length == 0){ return; }
 
-			var num = Math.min(Math.max((parseInt(val)+(parseInt(this.delta) * direction)), (this.flags.min?this.flags.min:-Infinity)), (this.flags.max?this.flags.max:+Infinity));
-			val = num.toString();
+		var num = Math.min(Math.max((parseInt(val)+(parseInt(this.delta) * direction)), (this.flags.min?this.flags.min:-Infinity)), (this.flags.max?this.flags.max:+Infinity));
+		val = num.toString();
 
-			if(num >= 0){
-				val = ((this.flags.signed == true)?'+':' ')+val; // make sure first char is a nondigit
-			}
+		if(num >= 0){
+			val = ((this.flags.signed == true)?'+':' ')+val; // make sure first char is a nondigit
+		}
 
-			if(this.flags.separator.length > 0){
-				for (var i=val.length-3; i > 1; i-=3){
-					val = val.substr(0,i)+this.flags.separator+val.substr(i);
-				}
+		if(this.flags.separator.length > 0){
+			for (var i=val.length-3; i > 1; i-=3){
+				val = val.substr(0,i)+this.flags.separator+val.substr(i);
 			}
+		}
 
-			if(val.substr(0,1) == ' '){ val = val.substr(1); } // remove space
+		if(val.substr(0,1) == ' '){ val = val.substr(1); } // remove space
 
-			this.setValue(val);
+		this.setValue(val);
 
-			return val.length;
+		return val.length;
 	}
 });
 
 /*
-  ****** SpinnerRealNumberTextbox ******
+  ****** RealNumberSpinner ******
 
   A subclass of RealNumberTextbox.
   @attr places    The exact number of decimal places.  If omitted, it's unlimited and optional.
@@ -297,8 +295,9 @@
   @attr eSigned   Is the exponent signed?  Can be true or false, if omitted the sign is optional.
 */
 dojo.widget.defineWidget(
-	"dojo.widget.SpinnerRealNumberTextbox",
+	"dojo.widget.RealNumberSpinner",
 	[dojo.widget.validate.RealNumberTextbox, dojo.widget.Spinner],
+	function(){ dojo.experimental("dojo.widget.RealNumberSpinner"); },
 {
 	// new subclass properties
 	delta: "1e1",
@@ -397,17 +396,13 @@
 	}
 });
 
-/*
-  ****** SpinnerTimeTextbox ******
-
-  A subclass of TimeTextbox.
-*/
-
 dojo.widget.defineWidget(
-	"dojo.widget.SpinnerTimeTextbox",
+	"dojo.widget.TimeSpinner",
 	[dojo.widget.validate.TimeTextbox, dojo.widget.Spinner],
+	function(){ dojo.experimental("dojo.widget.TimeSpinner"); },
 {
 	adjustValue: function(direction, x){
+	//FIXME: formatting should make use of dojo.date.format?
 		var val = this.getValue();
 		var format = (this.flags.format && this.flags.format.search(/[Hhmst]/) >= 0) ? this.flags.format : "hh:mm:ss t";
 		if(direction == 0 || !val.length || !this.isValid()){ return; }

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TabContainer.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TabContainer.js?view=diff&rev=453979&r1=453978&r2=453979
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TabContainer.js (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TabContainer.js Sat Oct  7 11:22:33 2006
@@ -31,7 +31,7 @@
 	
 	// String
 	//   If closebutton=="tab", then every tab gets a close button.
-	//   But this is deprecated.  Should just say tabCloseButton=true on each
+	//   DEPRECATED:  Should just say closable=true on each
 	//   pane you want to be closable.
 	closeButton: "none",
 
@@ -41,8 +41,20 @@
 
 	// String
 	//	initially selected tab (widgetId)
+	//	DEPRECATED: use selectedChild instead.
 	selectedTab: "",
 
+	postMixInProperties: function() {
+		if(this.selectedTab){
+			dojo.deprecated("selectedTab deprecated, use selectedChild instead, will be removed in", "0.5");
+			this.selectedChild=this.selectedTab;
+		}
+		if(this.closeButton!="none"){
+			dojo.deprecated("closeButton deprecated, use closable='true' on each child instead, will be removed in", "0.5");
+		}
+		dojo.widget.TabContainer.superclass.postMixInProperties.apply(this, arguments);
+	},
+
 	fillInTemplate: function() {
 		// create the tab list that will have a tab (a.k.a. tab button) for each tab panel
 		this.tablist = dojo.widget.createWidget("TabController",
@@ -55,12 +67,26 @@
 		dojo.widget.TabContainer.superclass.fillInTemplate.apply(this, arguments);
 	},
 
-	_setupPage: function(tab){
+	postCreate: function(args, frag) {
+		// Setup each page panel
+		dojo.lang.forEach(this.children, this._setupChild, this);
+
+		// size the container pane to take up the space not used by the tabs themselves
+		this.onResized();
+
+		// Display the selected page
+		if(this.selectedChildWidget){
+			this.selectChild(this.selectedChildWidget, true);
+		}
+	},
+
+	_setupChild: function(tab){
 		if(this.closeButton=="tab" || this.closeButton=="pane"){
-			tab.tabCloseButton=true;
+			// TODO: remove in 0.5
+			tab.closable=true;
 		}
 		dojo.html.addClass(tab.domNode, "dojoTabPane");
-		dojo.widget.TabContainer.superclass._setupPage.apply(this, arguments);
+		dojo.widget.TabContainer.superclass._setupChild.apply(this, arguments);
 	},
 
 	onResized: function(){
@@ -74,12 +100,16 @@
 			{domNode: this.containerNode, layoutAlign: "client"}
 		];
 		dojo.widget.html.layout(this.domNode, children);
-		
-		dojo.widget.TabContainer.superclass.onResized.apply(this, arguments);
+
+		if(this.selectedChildWidget){
+			var containerSize = dojo.html.getContentBox(this.containerNode);
+			this.selectedChildWidget.resizeTo(containerSize.width, containerSize.height);
+		}
 	},
 
 	selectTab: function(tab, _noRefresh, callingWidget){
-		this.selectPage(tab, _noRefresh, callingWidget);
+		dojo.deprecated("use selectChild() rather than selectTab(), selectTab() will be removed in", "0.5");
+		this.selectChild(tab, _noRefresh, callingWidget);
 	},
 
 	// Keystroke handling for keystrokes on the tab panel itself (that were bubbled up to me)
@@ -92,8 +122,8 @@
 			button.focus();
 			dojo.event.browser.stopEvent(e);
 		}else if(e.keyCode == e.KEY_DELETE && e.altKey){
-			if (this.closeButton == "tab" || this.closeButton == "pane" || this.selectedTabWidget.tabCloseButton){
-				this.closePage(this.selectedTabWidget);
+			if (this.selectedChildWidget.closable){
+				this.closeChild(this.selectedChildWidget);
 				dojo.event.browser.stopEvent(e);
 			}
 		}
@@ -152,7 +182,7 @@
 					+"</div>",
 
 	postMixInProperties: function(){
-		this.closeButtonStyle = this.closable ? "" : "display: none";
+		this.closeButtonStyle = this.closeButton ? "" : "display: none";
 		dojo.widget.TabContainer.superclass.postMixInProperties.apply(this, arguments);
 	},
 

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TaskBar.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TaskBar.js?view=diff&rev=453979&r1=453978&r2=453979
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TaskBar.js (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TaskBar.js Sat Oct  7 11:22:33 2006
@@ -17,20 +17,30 @@
 dojo.require("dojo.event.*");
 dojo.require("dojo.html.selection");
 
-// Icon associated w/a floating pane
+// summary
+//	Widget used internally by the TaskBar;
+//	shows an icon associated w/a floating pane
 dojo.widget.defineWidget(
 	"dojo.widget.TaskBarItem",
 	dojo.widget.HtmlWidget,
 {
-	// constructor arguments
+	// String
+	//	path of icon for associated floating pane
 	iconSrc: '',
+	
+	// String
+	//	name of associated floating pane
 	caption: 'Untitled',
-	window: null,
+
+	// String
+	//	widget id of associated floating pane
+	widgetId: "",
+
 	templatePath: dojo.uri.dojoUri("src/widget/templates/TaskBarItemTemplate.html"),
 	templateCssPath: dojo.uri.dojoUri("src/widget/templates/TaskBar.css"),
 
 	fillInTemplate: function() {
-		if ( this.iconSrc != '' ) {
+		if (this.iconSrc) {
 			var img = document.createElement("img");
 			img.src = this.iconSrc;
 			this.domNode.appendChild(img);
@@ -50,7 +60,8 @@
 	}
 });
 
-// Collection of widgets in a bar, like Windows task bar
+// summary:
+//	Displays an icon for each associated floating pane, like Windows task bar
 dojo.widget.defineWidget(
 	"dojo.widget.TaskBar",
 	dojo.widget.FloatingPane,
@@ -58,10 +69,14 @@
 		this._addChildStack = [];
 	},
 {
+	// TODO: this class extends floating pane merely to get the shadow;
+	//	it should extend HtmlWidget and then just call the shadow code directly
 	resizable: false,
 	titleBarDisplay: "none",
 
-	addChild: function(child) {
+	addChild: function(/*Widget*/ child) {
+		// summary: add taskbar item for specified FloatingPane
+		// TODO: this should not be called addChild(), as that has another meaning.
 		if(!this.containerNode){ 
 			this._addChildStack.push(child);
 		}else if(this._addChildStack.length > 0){

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Toolbar.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Toolbar.js?view=diff&rev=453979&r1=453978&r2=453979
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Toolbar.js (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Toolbar.js Sat Oct  7 11:22:33 2006
@@ -128,7 +128,7 @@
 
 /* Toolbar
  **********/
- 
+
 dojo.widget.defineWidget(
 	"dojo.widget.Toolbar",
 	dojo.widget.HtmlWidget,
@@ -168,7 +168,7 @@
 
 	_onclick: function(e) {
 		var widget = this._getItem(e.target);
-		if(widget && widget._onclick){ 
+		if(widget && widget._onclick){
 			widget._onclick(e);
 		}
 	},
@@ -704,17 +704,17 @@
 dojo.widget.defineWidget(
 	"dojo.widget.ToolbarDialog",
 	dojo.widget.ToolbarButton,
-{	
+{
 	fillInTemplate: function (args, frag) {
 		dojo.widget.ToolbarDialog.superclass.fillInTemplate.call(this, args, frag);
 		dojo.event.connect(this, "onSelect", this, "showDialog");
 		dojo.event.connect(this, "onDeselect", this, "hideDialog");
 	},
-	
+
 	showDialog: function (e) {
 		dojo.lang.setTimeout(dojo.event.connect, 1, document, "onmousedown", this, "deselect");
 	},
-	
+
 	hideDialog: function (e) {
 		dojo.event.disconnect(document, "onmousedown", this, "deselect");
 	}
@@ -756,11 +756,11 @@
 	},
 
 	// don't want events!
-	_onmouseover: null, 
-    _onmouseout: null, 
-    _onclick: null, 
-    _onmousedown: null, 
-    _onmouseup: null 
+	_onmouseover: null,
+    _onmouseout: null,
+    _onclick: null,
+    _onmousedown: null,
+    _onmouseup: null
 });
 
 /* ToolbarSpace
@@ -778,7 +778,7 @@
 });
 
 /* ToolbarSelect
- ******************/ 
+ ******************/
 
 dojo.widget.defineWidget(
 	"dojo.widget.ToolbarSelect",
@@ -919,3 +919,37 @@
 
 	return new dojo.widget.Icon(a,b,c,d);
 }
+
+/* ToolbarColorDialog
+ ******************/
+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();
+	}
+});
\ No newline at end of file

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Tree.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Tree.js?view=diff&rev=453979&r1=453978&r2=453979
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Tree.js (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Tree.js Sat Oct  7 11:22:33 2006
@@ -30,24 +30,15 @@
 
 dojo.deprecated("dojo.widget.Tree", "use TreeV3 instead", "0.5");
 
-
-// make it a tag
-dojo.widget.tags.addParseTreeHandler("dojo:Tree");
-
-
-dojo.widget.Tree = function() {
-	dojo.widget.HtmlWidget.call(this);
-
+dojo.widget.defineWidget("dojo.widget.Tree", dojo.widget.HtmlWidget, function() {
 	this.eventNames = {};
 
 	this.tree = this;
 	this.DNDAcceptTypes = [];
 	this.actionsDisabled = [];
 
-}
-dojo.inherits(dojo.widget.Tree, dojo.widget.HtmlWidget);
-
-dojo.lang.extend(dojo.widget.Tree, {
+},
+{
 	widgetType: "Tree",
 
 	eventNamesDefault: {

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeBasicController.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeBasicController.js?view=diff&rev=453979&r1=453978&r2=453979
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeBasicController.js (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeBasicController.js Sat Oct  7 11:22:33 2006
@@ -17,18 +17,7 @@
 
 dojo.deprecated("dojo.widget.TreeBasicController", "use TreeV3 and TreeBasicControllerV3 instead", "0.5");
 
-
-dojo.widget.tags.addParseTreeHandler("dojo:TreeBasicController");
-
-
-dojo.widget.TreeBasicController = function() {
-	dojo.widget.HtmlWidget.call(this);
-}
-
-dojo.inherits(dojo.widget.TreeBasicController, dojo.widget.HtmlWidget);
-
-
-dojo.lang.extend(dojo.widget.TreeBasicController, {
+dojo.widget.defineWidget("dojo.widget.TreeBasicController", dojo.widget.HtmlWidget, {
 	widgetType: "TreeBasicController",
 
 	DNDController: "",

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeContextMenu.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeContextMenu.js?view=diff&rev=453979&r1=453978&r2=453979
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeContextMenu.js (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeContextMenu.js Sat Oct  7 11:22:33 2006
@@ -19,26 +19,10 @@
 
 dojo.deprecated("dojo.widget.TreeContextMenu", "use TreeV3 and TreeContextMenuV3 instead", "0.5");
 
-
-dojo.widget.tags.addParseTreeHandler("dojo:TreeContextMenu");
-dojo.widget.tags.addParseTreeHandler("dojo:TreeMenuItem");
-
-
-
-dojo.widget.TreeContextMenu = function() {
-	dojo.widget.PopupMenu2.call(this);
-
+dojo.widget.defineWidget("dojo.widget.TreeContextMenu", dojo.widget.PopupMenu2, function() {
 	this.listenedTrees = [];
-
-}
-
-
-dojo.inherits(dojo.widget.TreeContextMenu, dojo.widget.PopupMenu2);
-
-dojo.lang.extend(dojo.widget.TreeContextMenu, {
-
-	widgetType: "TreeContextMenu",
-
+},
+{
 	open: function(x, y, parentMenu, explodeSrc){
 
 		var result = dojo.widget.PopupMenu2.prototype.open.apply(this, arguments);
@@ -142,24 +126,7 @@
 
 });
 
-
-
-
-
-
-dojo.widget.TreeMenuItem = function() {
-	dojo.widget.MenuItem2.call(this);
-
-}
-
-
-dojo.inherits(dojo.widget.TreeMenuItem, dojo.widget.MenuItem2);
-
-
-dojo.lang.extend(dojo.widget.TreeMenuItem, {
-
-	widgetType: "TreeMenuItem",
-
+dojo.widget.defineWidget("dojo.widget.TreeMenuItem", dojo.widget.MenuItem2, {
 	// treeActions menu item performs following actions (to be checked for permissions)
 	treeActions: "",
 

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeLoadingController.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeLoadingController.js?view=diff&rev=453979&r1=453978&r2=453979
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeLoadingController.js (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeLoadingController.js Sat Oct  7 11:22:33 2006
@@ -18,20 +18,7 @@
 
 dojo.deprecated("dojo.widget.TreeLoadingController", "use TreeV3 and TreeLoadingControllerV3 instead", "0.5");
 
-
-dojo.widget.tags.addParseTreeHandler("dojo:TreeLoadingController");
-
-
-dojo.widget.TreeLoadingController = function() {
-	dojo.widget.TreeBasicController.call(this);
-}
-
-dojo.inherits(dojo.widget.TreeLoadingController, dojo.widget.TreeBasicController);
-
-
-dojo.lang.extend(dojo.widget.TreeLoadingController, {
-	widgetType: "TreeLoadingController",
-
+dojo.widget.defineWidget("dojo.widget.TreeLoadingController", dojo.widget.TreeBasicController, {
 	RPCUrl: "",
 
 	RPCActionParam: "action", // used for GET for RPCUrl

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeNode.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeNode.js?view=diff&rev=453979&r1=453978&r2=453979
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeNode.js (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeNode.js Sat Oct  7 11:22:33 2006
@@ -14,21 +14,10 @@
 dojo.require("dojo.event.*");
 dojo.require("dojo.io.*");
 
-// make it a tag
-dojo.widget.tags.addParseTreeHandler("dojo:TreeNode");
-
-
-// # //////////
-
-dojo.widget.TreeNode = function() {
-	dojo.widget.HtmlWidget.call(this);
-
+dojo.widget.defineWidget("dojo.widget.TreeNode", dojo.widget.HtmlWidget, function() {
 	this.actionsDisabled = [];
-}
-
-dojo.inherits(dojo.widget.TreeNode, dojo.widget.HtmlWidget);
-
-dojo.lang.extend(dojo.widget.TreeNode, {
+},
+{
 	widgetType: "TreeNode",
 
 	loadStates: {

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeRPCController.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeRPCController.js?view=diff&rev=453979&r1=453978&r2=453979
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeRPCController.js (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeRPCController.js Sat Oct  7 11:22:33 2006
@@ -16,20 +16,9 @@
 dojo.require("dojo.io.*");
 dojo.require("dojo.widget.TreeLoadingController");
 
-
 dojo.deprecated("dojo.widget.TreeRPCController", "use TreeV3 and TreeRpcControllerV3 instead", "0.5");
 
-dojo.widget.tags.addParseTreeHandler("dojo:TreeRPCController");
-
-dojo.widget.TreeRPCController = function(){
-	dojo.widget.TreeLoadingController.call(this);
-}
-
-dojo.inherits(dojo.widget.TreeRPCController, dojo.widget.TreeLoadingController);
-
-dojo.lang.extend(dojo.widget.TreeRPCController, {
-	widgetType: "TreeRPCController",
-
+dojo.widget.defineWidget("dojo.widget.TreeRPCController", dojo.widget.TreeLoadingController, {
 	/**
 	 * Make request to server about moving children.
 	 *

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeSelector.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeSelector.js?view=diff&rev=453979&r1=453978&r2=453979
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeSelector.js (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeSelector.js Sat Oct  7 11:22:33 2006
@@ -15,24 +15,13 @@
 
 dojo.deprecated("dojo.widget.TreeSelector", "use TreeV3 and TreeSelectorV3 instead", "0.5");
 
-
-dojo.widget.tags.addParseTreeHandler("dojo:TreeSelector");
-
-
-dojo.widget.TreeSelector = function() {
-	dojo.widget.HtmlWidget.call(this);
-
-
+dojo.widget.defineWidget("dojo.widget.TreeSelector", dojo.widget.HtmlWidget, function() {
 	this.eventNames = {};
 
 	this.listenedTrees = [];
 
-}
-
-dojo.inherits(dojo.widget.TreeSelector, dojo.widget.HtmlWidget);
-
-
-dojo.lang.extend(dojo.widget.TreeSelector, {
+},
+{
 	widgetType: "TreeSelector",
 	selectedNode: null,
 

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Widget.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Widget.js?view=diff&rev=453979&r1=453978&r2=453979
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Widget.js (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Widget.js Sat Oct  7 11:22:33 2006
@@ -477,7 +477,12 @@
 							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);
+							dojo.event.kwConnect({
+								srcObj: this, 
+								srcFunc: x, 
+								adviceObj: this, 
+								adviceFunc: tn
+							});
 						}
 					}else if(dojo.lang.isArray(this[x])){ // typeof [] == "object"
 						this[x] = args[x].split(";");

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/charting/__package__.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/charting/__package__.js?view=auto&rev=453979
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/charting/__package__.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/charting/__package__.js Sat Oct  7 11:22:33 2006
@@ -0,0 +1,14 @@
+/*
+	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.charting.*");
+dojo.require("dojo.experimental");
+
+dojo.experimental("dojo.widget.charting is not for general use.");

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/charting/engine/Axis.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/charting/engine/Axis.js?view=auto&rev=453979
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/charting/engine/Axis.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/charting/engine/Axis.js Sat Oct  7 11:22:33 2006
@@ -0,0 +1,59 @@
+/*
+	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.charting.engine.Axis");
+dojo.require("dojo.lang.common");
+
+dojo.widget.charting.engine.Axis = function(/* string? */label, /* string? */scale){
+	var id = "dojo-charting-axis-"+dojo.widget.charting.engine.Axis.count++;
+	this.getId=function(){ return id; };
+	this.setId=function(key){ id = key; };
+	this.scale = scale || "linear";		//	linear || log
+	this.label = label || "";
+	this.showLabels = true;		//	show interval ticks.
+	this.nLabels = 3;			//	max ticks over range.
+	this.showLines = false;		//	if you want lines over the range of the plot area
+	this.showTicks = false;		//	if you want tick marks on the axis.
+	this.range = { upper : 0, lower : 0 };	//	range of individual axis.
+	this.origin = "min"; 			//	this can be any number, "min" or "max". min/max is translated on init.
+};
+dojo.widget.charting.engine.Axis.count = 0;
+
+dojo.extend(dojo.widget.charting.engine.Axis, {
+	//	TODO: implement log scaling.
+	getCoord: function(
+		/* float */val, 
+		/* dojo.widget.charting.engine.PlotArea */plotArea, 
+		/* dojo.widget.charting.engine.Plot */plot
+	){
+		//	summary
+		//	returns the coordinate of val based on this axis range, plot area and plot.
+		val = parseFloat(val, 10);
+		var area = plotArea.getArea();
+		if(plot.axisX == this){
+			var offset = 0 - this.range.lower;
+			var min = this.range.lower + offset;	//	FIXME: check this.
+			var max = this.range.upper + offset;
+			val += offset;
+			return (val*((area.right-area.left)/max))+area.left;	//	float
+		} else {
+			var max = this.range.upper;
+			var min = this.range.lower;
+			var offset = 0;
+			if(min<0){
+				offset += Math.abs(min);
+			}
+			max += offset; min += offset; val += offset;
+			var pmin = area.bottom;
+			var pmax = area.top;
+			return (((pmin-pmax)/(max-min))*(max-val))+pmax;
+		}
+	}
+});

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/charting/engine/Chart.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/charting/engine/Chart.js?view=auto&rev=453979
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/charting/engine/Chart.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/charting/engine/Chart.js Sat Oct  7 11:22:33 2006
@@ -0,0 +1,73 @@
+/*
+	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.charting.engine.Chart");
+dojo.require("dojo.lang.common");
+dojo.require("dojo.widget.charting.engine.PlotArea");
+
+dojo.widget.charting.engine.Chart = function(
+	/* HTMLElement? */node, 
+	/* string? */title, 
+	/* string? */description
+){
+	this.node = node || null;
+	this.title = title || "Chart";			//	pure string.
+	this.description = description || "";	//	HTML is allowed.
+	this.plotAreas = [];
+};
+
+dojo.extend(dojo.widget.charting.engine.Chart, {
+	//	methods
+	addPlotArea: function(/* object */obj, /* bool? */doRender){
+		//	we expect object to be: { plotArea, (x, y) or (top, left) }
+		if(obj.x && !obj.left){ obj.left = obj.x; }
+		if(obj.y && !obj.top){ obj.top = obj.y; }
+		this.plotAreas.push(obj);
+		if(doRender){ this.render(); }
+	},
+	
+	//	events
+	onInitialize:function(chart){ },
+	onRender:function(chart){ },
+	onDestroy:function(chart){ },
+
+	//	standard build methods
+	initialize: function(){
+		if(!this.node){ 
+			dojo.raise("dojo.widget.charting.engine.Chart.initialize: there must be a root node defined for the Chart."); 
+		}
+		this.destroy();
+		this.render();
+	},
+	render:function(){
+		if(this.node.style.position != "absolute"){
+			this.node.style.position = "relative";
+		}
+		for(var i=0; i<this.plotAreas.length; i++){
+			var area = this.plotAreas[i].plotArea;
+			var node = area.initialize();
+			node.style.position = "absolute";
+			node.style.top = this.plotAreas[i].top + "px";
+			node.style.left = this.plotAreas[i].left + "px";
+			this.node.appendChild(node);
+			area.render();
+		}
+	},
+	destroy: function(){
+		//	kill any existing plotAreas
+		for(var i=0; i<this.plotAreas.length; i++){
+			this.plotAreas[i].plotArea.destroy();
+		};
+		//	clean out any child nodes.
+		while(this.node && this.node.childNodes && this.node.childNodes.length > 0){ 
+			this.node.removeChild(this.node.childNodes[0]); 
+		}
+	}
+});

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/charting/engine/Plot.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/charting/engine/Plot.js?view=auto&rev=453979
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/charting/engine/Plot.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/charting/engine/Plot.js Sat Oct  7 11:22:33 2006
@@ -0,0 +1,94 @@
+/*
+	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.charting.engine.Plot");
+dojo.require("dojo.lang.common");
+dojo.require("dojo.widget.charting.engine.Axis");
+dojo.require("dojo.widget.charting.engine.Series");
+
+dojo.widget.charting.engine.RenderPlotSeries = { Singly:"single", Grouped:"grouped" };
+
+dojo.widget.charting.engine.Plot = function(
+	/* dojo.widget.charting.engine.Axis? */xaxis, 
+	/* dojo.widget.charting.engine.Axis? */yaxis, 
+	/* dojo.widget.charting.engine.Series[]? */series
+){
+	var id = "dojo-charting-plot-"+dojo.widget.charting.engine.Plot.count++;
+	this.getId=function(){ return id; };
+	this.setId=function(key){ id = key; };
+	this.axisX = null;
+	this.axisY = null;
+	this.series = [];
+	this.dataNode = null;
+
+	//	for bar charts, pie charts and stacked charts, change to Grouped.
+	this.renderType = dojo.widget.charting.engine.RenderPlotSeries.Singly;
+	if(xaxis){
+		this.setAxis(xaxis,"x");
+	}
+	if(yaxis){
+		this.setAxis(yaxis,"y");
+	}
+	if(series){
+		for(var i=0; i<series.length; i++){ this.addSeries(series[i]); }
+	}
+}
+dojo.widget.charting.engine.Plot.count=0;
+
+dojo.extend(dojo.widget.charting.engine.Plot, {
+	addSeries: function(
+		/* dojo.widget.charting.engine.Series || object */series,
+		/* function? */plotter
+	){
+		if(series.plotter){
+			this.series.push(series);
+		} else {
+			this.series.push({
+				data: series,
+				plotter: plotter || dojo.widget.charting.engine.Plotters["Default"]
+			});
+		}
+	},
+	setAxis: function(/* dojo.widget.charting.engine.Axis */axis, /* string */which){
+		if(which.toLowerCase()=="x"){ this.axisX = axis; }
+		else if(which.toLowerCase()=="y"){ this.axisY = axis; }
+	},
+	getRanges: function(){
+		//	summary
+		//	set the ranges on these axes.
+		var xmin, xmax, ymin, ymax;
+		xmin=ymin=Number.MAX_VALUE;
+		xmax=ymax=Number.MIN_VALUE;
+		for(var i=0; i<this.series.length; i++){
+			var values = this.series[i].data.evaluate();	//	full data range.
+			for(var j=0; j<values.length; j++){
+				var comp=values[j];
+				xmin=Math.min(comp.x, xmin);
+				ymin=Math.min(comp.y, ymin);
+				xmax=Math.max(comp.x, xmax);
+				ymax=Math.max(comp.y, ymax);
+			}
+		}
+		return {
+			x:{ upper: xmax, lower:xmin },
+			y:{ upper: ymax, lower:ymin },
+			toString:function(){
+				return "[ x:"+xmax+" - "+xmin+", y:"+ymax+" - "+ymin+"]";
+			}
+		};	//	object
+	},
+	destroy: function(){
+		var node=this.dataNode;
+		while(node && node.childNodes && node.childNodes.length > 0){
+			node.removeChild(node.childNodes[0]);
+		}
+		this.dataNode=null;
+	}
+});

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/charting/engine/PlotArea.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/charting/engine/PlotArea.js?view=auto&rev=453979
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/charting/engine/PlotArea.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/charting/engine/PlotArea.js Sat Oct  7 11:22:33 2006
@@ -0,0 +1,174 @@
+/*
+	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.charting.engine.PlotArea");
+dojo.require("dojo.lang.common");
+dojo.require("dojo.gfx.color");
+dojo.require("dojo.gfx.color.hsl");
+dojo.require("dojo.widget.charting.engine.Plot");
+
+dojo.widget.charting.engine.PlotArea = function(){
+	var id="dojo-charting-plotarea-"+dojo.widget.charting.engine.PlotArea.count++;
+	this.getId=function(){ return id; };
+	this.setId=function(key){ id = key; };
+	this.areaType = "standard"; 	//	standard || radar
+	this.plots = [];	//	plots that will be drawn on this area
+
+	this.size={ width:600, height:400 };
+	this.padding={ top:10, right:10, bottom:20, left:20 };
+
+	//	drawing node references.
+	this.nodes = {
+		main:null,
+		area:null,
+		background: null,
+		axes: null,
+		plots: null
+	};
+
+	//	this is preset for a limited color range (green to purple), 
+	//	anticipating a max of 32 series on this plot area.
+	//	if you need more flexibility, override these numbers.
+	this._color = { h: 140, s: 120, l: 120, step: 27 };
+};
+dojo.widget.charting.engine.PlotArea.count = 0;
+
+dojo.extend(dojo.widget.charting.engine.PlotArea, {
+	nextColor: function(){
+		var rgb=dojo.gfx.color.hsl2rgb(this._color.h, this._color.s, this._color.l);
+		this._color.h = (this._color.h + this._color.step)%360;
+		while(this._color.h < 140){ 
+			this._color.h += this._color.step; 
+		}
+		return dojo.gfx.color.rgb2hex(rgb[0], rgb[1], rgb[2]);
+	},
+	getArea:function(){
+		//	summary
+		//	return plot for drawing.
+		return {
+			left: this.padding.left,
+			right: this.size.width - this.padding.right,
+			top: this.padding.top,
+			bottom: this.size.height - this.padding.bottom,
+			toString:function(){ 
+				var a=[ this.top, this.right, this.bottom, this.left ];
+				return "["+a.join()+"]";
+			}
+		};
+	},
+	getAxes: function(){
+		//	summary
+		//	get the unique axes for this plot area.
+		var axes={};
+		for(var i=0; i<this.plots.length; i++){
+			var plot=this.plots[i];
+			axes[plot.axisX.getId()] = {
+				axis: plot.axisX,
+				drawAgainst: plot.axisY,
+				plot: plot,
+				plane: "x"
+			};
+			axes[plot.axisY.getId()] = {
+				axis: plot.axisY,
+				drawAgainst: plot.axisX,
+				plot: plot,
+				plane: "y"
+			};
+		}
+		return axes;
+	},
+	setAxesRanges: function(){
+		//	summary
+		//	find the ranges on all axes on this plotArea.
+		//	We do this because plots may have axes in common; if you
+		//	want to use this, make sure you do it *before* initialization.
+		var ranges={};
+		var axes={};
+		for(var i=0; i<this.plots.length; i++){
+			var plot = this.plots[i];
+			var ranges=plot.getRanges();
+			var x=ranges.x;
+			var y=ranges.y;
+			var ax, ay;
+			if(!axes[plot.axisX.getId()]){
+				axes[plot.axisX.getId()]=plot.axisX;
+				ranges[plot.axisX.getId()]={upper: x.upper, lower:x.lower};
+			}
+			ax=ranges[plot.axisX.getId()];
+			ax.upper=Math.max(ax.upper, x.upper);
+			ax.lower=Math.min(ax.lower, x.lower);
+
+			if(!axes[plot.axisY.getId()]){
+				axes[plot.axisY.getId()]=plot.axisY;
+				ranges[plot.axisY.getId()]={upper: y.upper, lower:y.lower};
+			}
+			ay=ranges[plot.axisY.getId()];
+			ay.upper=Math.max(ay.upper, y.upper);
+			ay.lower=Math.min(ay.lower, y.lower);
+		}
+		
+		//	now that we have all the max/min ranges, set the axes
+		for(var p in axes){
+			axes[p].range=ranges[p];
+		}
+	},
+
+	//	will be overridden by renderer, below.
+	render: function(/* object? */kwArgs, /* function? */applyToData){
+		if(!this.nodes.main
+			|| !this.nodes.area 
+			|| !this.nodes.background 
+			|| !this.nodes.plots 
+			|| !this.nodes.axes
+		){ this.initialize(); }
+
+		//	plot it.
+		for(var i=0; i<this.plots.length; i++){
+			var plot=this.plots[i];
+			this.nodes.plots.removeChild(plot.dataNode);
+			var target = this.initializePlot(plot);
+			switch(plot.renderType){
+				case dojo.widget.charting.engine.RenderPlotSeries.Grouped:	{
+					// ALWAYS plot using the first plotter, ignore any others.
+					target.appendChild(plot.series[0].plotter(this, plot, kwArgs, applyToData));
+					break;
+				}
+				case dojo.widget.charting.engine.RenderPlotSeries.Singly:
+				default: {
+					for(var j=0; j<plot.series.length; j++){
+						var series = plot.series[j];
+						var data = series.data.evaluate(kwArgs);
+						target.appendChild(series.plotter(data, this, plot, applyToData));
+					}
+				}
+			}
+			this.nodes.plots.appendChild(target);
+		}
+	},
+	destroy: function(){
+		//	kill any existing plots
+		for(var i=0; i<this.plots.length; i++){
+			this.plots[i].destroy();
+		};
+		//	clean out any child nodes.
+		for(var p in this.nodes){
+			var node=this.nodes[p];
+			if(!node) continue;
+			if(!node.childNodes) continue;
+			while(node.childNodes.length > 0){ 
+				node.removeChild(node.childNodes[0]); 
+			}
+			this.nodes[p]=null;
+		}
+	}
+});
+
+dojo["requireIf"](dojo.render.svg.capable, "dojo.widget.charting.engine.svg.PlotArea");
+dojo["requireIf"](!dojo.render.svg.capable && dojo.render.vml.capable, "dojo.widget.charting.engine.vml.PlotArea");

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/charting/engine/Plotters.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/charting/engine/Plotters.js?view=auto&rev=453979
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/charting/engine/Plotters.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/charting/engine/Plotters.js Sat Oct  7 11:22:33 2006
@@ -0,0 +1,19 @@
+/*
+	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.charting.engine.Plotters");
+
+/*	
+ *	Plotters is the placeholder; what will happen is that the proper renderer types
+ *	will be mixed into this object (as opposed to creating a new one).
+ */
+
+dojo["requireIf"](dojo.render.svg.capable, "dojo.widget.charting.engine.svg.Plotters");
+dojo["requireIf"](!dojo.render.svg.capable && dojo.render.vml.capable, "dojo.widget.charting.engine.vml.Plotters");

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/charting/engine/README.txt
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/charting/engine/README.txt?view=auto&rev=453979
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/charting/engine/README.txt (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/charting/engine/README.txt Sat Oct  7 11:22:33 2006
@@ -0,0 +1,46 @@
+Dojo Charting Engine
+=========================================================================
+The Dojo Charting Engine is a (fairly) complex object structure, designed
+to provide as much flexibility as possible in terms of chart construction.
+To this end, the engine details the following structure:
+
+Chart
+---PlotArea[]
+------Plot[]
+---------Axis (axisX)
+---------Axis (axisY)
+---------Series[]
+
+
+A Chart object is the main entity; it is the entire graphic.  A Chart may
+have any number of PlotArea objects, which are the basic canvas against 
+which data is plotted.  A PlotArea may have any number of Plot objects,
+which is a container representing up to 2 axes and any number of series
+to be plotted against those axes; a Series represents a binding against
+two fields from a data source (initial rev, this data source is always of
+type dojo.collections.Store but this will probably change once dojo.data
+is in production).
+
+The point of this structure is to allow for as much flexibility as possible
+in terms of what kinds of charts can be represented by the engine.  The
+current plan is to accomodate up to analytical financial charts, which tend
+to have 3 plot areas and any number of different types of axes on each one.
+
+The main exception to this is the pie chart, which will have it's own
+custom codebase.  Also, 3D charts are not accounted for at this time,
+although the only thing that will probably need to be altered to make
+that work would be Plot and Series (to accomodate the additional Z axis).
+
+Finally, a Plot will render its series[] through the use of Plotters, which
+are custom methods to render specific types of charts.
+-------------------------------------------------------------------------
+In terms of widgets, the basic concept is that there is a central, super-
+flexible Chart widget (Chart, oddly enough), and then any number of preset
+chart type widgets, that are basically built to serve a simple, easy 
+purpose.  For instance, if someone just needs to plot a series of lines,
+they would be better off using the LineChart widget; but if someone needed
+to plot a combo chart, that has 2 Y Axes (one linear, one log) against the
+same X Axis, using lines and areas, then they will want to use a Chart widget.
+Note also that unlike other widgets, the Charting engine *can* be called
+directly from script *without* the need for the actual widget engine to be
+loaded; the Chart widgets are thin wrappers around the charting engine.

Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/charting/engine/README.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/charting/engine/Series.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/charting/engine/Series.js?view=auto&rev=453979
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/charting/engine/Series.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/charting/engine/Series.js Sat Oct  7 11:22:33 2006
@@ -0,0 +1,195 @@
+/*
+	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.charting.engine.Series");
+dojo.require("dojo.lang.common");
+dojo.require("dojo.widget.charting.engine.Plotters");
+
+dojo.widget.charting.engine.Series = function(/* object? */kwArgs){
+	var args = kwArgs || { length:1 };
+	this.dataSource = args.dataSource || null;
+	this.bindings = { };
+	this.color = args.color;
+	this.label = args.label;
+
+	if(args.bindings){
+		for(var p in args.bindings){
+			this.addBinding(p, args.bindings[p]);
+		}
+	}
+};
+
+dojo.extend(dojo.widget.charting.engine.Series, {
+	bind:function(src, bindings){
+		this.dataSource = src;
+		this.bindings = bindings;
+		this.onBind();
+	},
+	addBinding:function(name, binding){
+		this.bindings[name] = binding;
+	},
+	evaluate:function(kwArgs){
+		var ret = [];
+		var a = this.dataSource.getData();
+		var l = a.length;
+		var start = 0;
+		var end = l;
+		
+		/*	Allow for ranges.  Can be done in one of two ways:
+		 *	1. { from, to } as 0-based indices
+		 *	2. { length } as num of data points to get; a negative
+		 *		value will start from the end of the data set.
+		 *	No kwArg object means the full data set will be evaluated
+		 *		and returned.
+		 */
+		if(kwArgs){
+			if(kwArgs.from){ 
+				start = Math.max(kwArgs.from,0);
+				if(kwArgs.to){ 
+					end = Math.min(kwArgs.to, end);
+				}
+			}
+			else if(kwArgs.length){
+				if(kwArgs.length < 0){
+					//	length points from end
+					start = Math.max((end + length),0);
+				} else {
+					end = Math.min((start + length), end);
+				}
+			}
+		}
+
+		for(var i=start; i<end; i++){
+			var o = { src: a[i], series: this };
+			for(var p in this.bindings){
+				o[p] = this.dataSource.getField(a[i], this.bindings[p]);
+			}
+			ret.push(o);
+		}
+
+		//	sort by the x axis, if available.
+		if(typeof(ret[0].x) != "undefined"){
+			ret.sort(function(a,b){
+				if(a.x > b.x) return 1;
+				if(a.x < b.x) return -1;
+				return 0;
+			});
+		}
+		return ret;	//	array
+	},
+
+	//	trends
+	trends:{
+		createRange: function(values, len){
+			var idx = values.length-1;
+			var length = (len||values.length);
+			return { "index": idx, "length": length, "start":Math.max(idx-length,0) };
+		},
+
+		mean: function(values, len){
+			var range = this.createRange(values, len);
+			if(range.index<0){ return 0; }
+			var total = 0;
+			var count = 0;
+			for(var i=range.index; i>=range.start; i--){
+				total += values[i].y; 
+				count++;
+			}
+			total /= Math.max(count,1);
+			return total;
+		},
+
+		variance: function(values,len){
+			var range = this.createRange(values,len);
+			if(range.index < 0){ return 0; }
+			var total = 0;
+			var square = 0;
+			var count = 0;
+			for(var i=range.index; i>=range.start; i--){
+				total += values[i].y;
+				square += Math.pow(values[i].y, 2);
+				count++;
+			}
+			return (square/count)-Math.pow(total/count,2);
+		},
+
+		standardDeviation: function(values, len){
+			return Math.sqrt(this.getVariance(values, len));
+		},
+
+		max: function(values, len){
+			var range = this.createRange(values, len);
+			if(range.index < 0){ return 0; }
+			var max = Number.MIN_VALUE;
+			for (var i=range.index; i>=range.start; i--){
+				max = Math.max(values[i].y,max);
+			}
+			return max;
+		},
+
+		min: function(values, len){
+			var range=this.createRange(values, len);
+			if(range.index < 0){ return 0; }
+			var min = Number.MAX_VALUE;
+			for(var i=range.index; i>=range.start; i--){
+				min = Math.min(values[i].y, min);
+			}
+			return min;
+		},
+
+		median: function(values, len){
+			var range = this.createRange(values, len);
+			if(range.index<0){ return 0; }
+			var a = [];
+			for (var i=range.index; i>=range.start; i--){
+				var b=false;
+				for(var j=0; j<a.length; j++){
+					if(values[i].y == a[j]){
+						b = true;
+						break;
+					}
+				}
+				if(!b){ 
+					a.push(values[i].y); 
+				}
+			}
+			a.sort();
+			if(a.length > 0){ 
+				return a[Math.ceil(a.length / 2)]; 
+			}
+			return 0;
+		},
+
+		mode: function(values, len){
+			var range=this.createRange(values, len);
+			if(range.index<0){ return 0; }
+			var o = {};
+			var ret = 0
+			var median = Number.MIN_VALUE;
+			for(var i=range.index; i>=range.start; i--){
+				if (!o[values[i].y]){
+					o[values[i].y] = 1;
+				} else { 
+					o[values[i].y]++;
+				}
+			}
+			for(var p in o){
+				if(median < o[p]){ 
+					median = o[p]; 
+					ret=p; 
+				}
+			}
+			return ret;
+		}
+	},
+
+	//	events
+	onBind:function(){ }
+});