You are viewing a plain text version of this content. The canonical link for it is here.
Posted to xap-commits@incubator.apache.org by jm...@apache.org on 2006/06/27 22:49:06 UTC

svn commit: r417618 [15/19] - in /incubator/xap/trunk/src/dojo/src: ./ lfx/ logging/ rpc/ selection/ storage/ string/ text/ undo/ uri/ uuid/ widget/ widget/html/ widget/svg/ widget/templates/ widget/templates/buttons/ widget/templates/images/ widget/te...

Added: incubator/xap/trunk/src/dojo/src/widget/html/Checkbox.js
URL: http://svn.apache.org/viewvc/incubator/xap/trunk/src/dojo/src/widget/html/Checkbox.js?rev=417618&view=auto
==============================================================================
--- incubator/xap/trunk/src/dojo/src/widget/html/Checkbox.js (added)
+++ incubator/xap/trunk/src/dojo/src/widget/html/Checkbox.js Tue Jun 27 15:48:54 2006
@@ -0,0 +1,105 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.require("dojo.widget.Checkbox");
+dojo.provide("dojo.widget.html.Checkbox");
+
+// FIXME: the input doesn't get taken out of the tab list (i think)
+// FIXME: the image doesn't get into the tab list (needs to steal the tabindex value from the input)
+
+dojo.widget.html.Checkbox = function(){
+	dojo.widget.HtmlWidget.call(this);
+}
+
+dojo.inherits(dojo.widget.html.Checkbox, dojo.widget.HtmlWidget);
+
+dojo.lang.extend(dojo.widget.html.Checkbox, {
+	widgetType: "Checkbox",
+
+	_testImg: null,
+
+	_events: [
+		"onclick",
+		"onfocus",
+		"onblur",
+		"onselect",
+		"onchange",
+		"onclick",
+		"ondblclick",
+		"onmousedown",
+		"onmouseup",
+		"onmouseover",
+		"onmousemove",
+		"onmouseout",
+		"onkeypress",
+		"onkeydown",
+		"onkeyup"
+	],
+
+	srcOn: dojo.uri.dojoUri('src/widget/templates/check_on.gif'),
+	srcOff: dojo.uri.dojoUri('src/widget/templates/check_off.gif'),
+
+	fillInTemplate: function(){
+
+		// FIXME: if images are disabled, we DON'T want to swap out the element
+		// we can use the usual 'load image to check' trick
+		// i don't know what image we can check yet, so we'll skip this for now...
+
+		// this._testImg = document.createElement("img");
+		// document.body.appendChild(this._testImg);
+		// this._testImg.src = "spacer.gif?cachebust=" + new Date().valueOf();
+		// dojo.connect(this._testImg, 'onload', this, 'onImagesLoaded');
+
+		this.onImagesLoaded();
+	},
+
+	onImagesLoaded: function(){
+
+		// FIXME: if we actually check for loading images, remove the thing here
+		// document.body.removeChild(this._testImg);
+
+		// 'hide' the checkbox
+		this.domNode.style.position = "absolute";
+		this.domNode.style.left = "-9000px";
+
+		// create a replacement image
+		this.imgNode = document.createElement("img");
+		dojo.html.addClass(this.imgNode, "dojoHtmlCheckbox");
+		this.updateImgSrc();
+		dojo.event.connect(this.imgNode, 'onclick', this, 'onClick');
+		dojo.event.connect(this.domNode, 'onchange', this, 'onChange');
+		this.domNode.parentNode.insertBefore(this.imgNode, this.domNode.nextSibling)
+
+		// real ugly - make sure the image has all the events that the checkbox did
+		for(var i=0; i<this._events.length; i++){
+			if(this.domNode[this._events[i]]){
+				dojo.event.connect(	this.imgNode, this._events[i], 
+									this.domNode[this._events[i]]);
+			}
+		}
+	},
+
+	onClick: function(){
+
+		this.domNode.checked = !this.domNode.checked ? true : false;
+		this.updateImgSrc();
+	},
+
+	onChange: function(){
+
+		this.updateImgSrc();
+	},
+
+	updateImgSrc: function(){
+
+		this.imgNode.src = this.domNode.checked ? this.srcOn : this.srcOff;
+	}
+});
+

Propchange: incubator/xap/trunk/src/dojo/src/widget/html/Checkbox.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/xap/trunk/src/dojo/src/widget/html/ComboBox.js
URL: http://svn.apache.org/viewvc/incubator/xap/trunk/src/dojo/src/widget/html/ComboBox.js?rev=417618&view=auto
==============================================================================
--- incubator/xap/trunk/src/dojo/src/widget/html/ComboBox.js (added)
+++ incubator/xap/trunk/src/dojo/src/widget/html/ComboBox.js Tue Jun 27 15:48:54 2006
@@ -0,0 +1,607 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.html.ComboBox");
+dojo.require("dojo.widget.ComboBox");
+dojo.require("dojo.widget.*");
+dojo.require("dojo.io.*");
+dojo.require("dojo.lfx.*");
+dojo.require("dojo.dom");
+dojo.require("dojo.html");
+dojo.require("dojo.string");
+dojo.require("dojo.widget.html.stabile");
+
+dojo.widget.html.ComboBox = function(){
+	dojo.widget.ComboBox.call(this);
+	dojo.widget.HtmlWidget.call(this);
+
+	this.autoComplete = true;
+	this.formInputName = "";
+	this.name = ""; // clone in the name from the DOM node
+	this.textInputNode = null;
+	this.comboBoxValue = null;
+	this.comboBoxSelectionValue = null;
+	this.optionsListWrapper = null;
+	this.optionsListNode = null;
+	this.downArrowNode = null;
+	this.cbTableNode = null;
+	this.searchTimer = null;
+	this.searchDelay = 100;
+	this.dataUrl = "";
+	// maxListLength limits list to X visible rows, scroll on rest 
+	this.maxListLength = 8; 
+	// mode can also be "remote" for JSON-returning live search or "html" for
+	// dumber live search
+	this.mode = "local"; 
+	this.selectedResult = null;
+	this._highlighted_option = null;
+	this._prev_key_backspace = false;
+	this._prev_key_esc = false;
+	this._result_list_open = false;
+	this._gotFocus = false;
+	this._mouseover_list = false;
+
+}
+
+dojo.inherits(dojo.widget.html.ComboBox, dojo.widget.HtmlWidget);
+
+// copied from superclass since we can't really over-ride via prototype
+dojo.lang.extend(dojo.widget.html.ComboBox, dojo.widget.ComboBox.defaults);
+
+dojo.lang.extend(dojo.widget.html.ComboBox, {
+
+
+	templatePath: dojo.uri.dojoUri("src/widget/templates/HtmlComboBox.html"),
+	templateCssPath: dojo.uri.dojoUri("src/widget/templates/HtmlComboBox.css"),
+
+	setValue: function(value) {
+		this.comboBoxValue.value = value;
+		if (this.textInputNode.value != value) { // prevent mucking up of selection
+			this.textInputNode.value = value;
+		}
+		dojo.widget.html.stabile.setState(this.widgetId, this.getState(), true);
+	},
+
+	getValue: function() {
+		return this.comboBoxValue.value;
+	},
+
+	getState: function() {
+		return {value: this.getValue()};
+	},
+
+	setState: function(state) {
+		this.setValue(state.value);
+	},
+
+	getCaretPos: function(element){
+		// khtml 3.5.2 has selection* methods as does webkit nightlies from 2005-06-22
+		if(dojo.lang.isNumber(element.selectionStart)){
+			// FIXME: this is totally borked on Moz < 1.3. Any recourse?
+			return element.selectionStart;
+		}else if(dojo.render.html.ie){
+			// in the case of a mouse click in a popup being handled,
+			// then the document.selection is not the textarea, but the popup
+			// var r = document.selection.createRange();
+			// hack to get IE 6 to play nice. What a POS browser.
+			var tr = document.selection.createRange().duplicate();
+			var ntr = element.createTextRange();
+			tr.move("character",0);
+			ntr.move("character",0);
+			try {
+				// If control doesnt have focus, you get an exception.
+				// Seems to happen on reverse-tab, but can also happen on tab (seems to be a race condition - only happens sometimes).
+				// There appears to be no workaround for this - googled for quite a while.
+				ntr.setEndPoint("EndToEnd", tr);
+				return String(ntr.text).replace(/\r/g,"").length;
+			} catch (e) {
+				return 0; // If focus has shifted, 0 is fine for caret pos.
+			}
+			
+		}
+	},
+
+	setCaretPos: function(element, location){
+		location = parseInt(location);
+		this.setSelectedRange(element, location, location);
+	},
+
+	setSelectedRange: function(element, start, end){
+		if(!end){ end = element.value.length; }  // NOTE: Strange - should be able to put caret at start of text?
+		// Mozilla
+		// parts borrowed from http://www.faqts.com/knowledge_base/view.phtml/aid/13562/fid/130
+		if(element.setSelectionRange){
+			element.focus();
+			element.setSelectionRange(start, end);
+		}else if(element.createTextRange){ // IE
+			var range = element.createTextRange();
+			with(range){
+				collapse(true);
+				moveEnd('character', end);
+				moveStart('character', start);
+				select();
+			}
+		}else{ //otherwise try the event-creation hack (our own invention)
+			// do we need these?
+			element.value = element.value;
+			element.blur();
+			element.focus();
+			// figure out how far back to go
+			var dist = parseInt(element.value.length)-end;
+			var tchar = String.fromCharCode(37);
+			var tcc = tchar.charCodeAt(0);
+			for(var x = 0; x < dist; x++){
+				var te = document.createEvent("KeyEvents");
+				te.initKeyEvent("keypress", true, true, null, false, false, false, false, tcc, tcc);
+				twe.dispatchEvent(te);
+			}
+		}
+	},
+
+	// does the keyboard related stuff
+	_handleKeyEvents: function(evt){
+		if(evt.ctrlKey || evt.altKey){ return; }
+
+		// reset these
+		this._prev_key_backspace = false;
+		this._prev_key_esc = false;
+
+		var k = dojo.event.browser.keys;
+		var doSearch = true;
+
+		// mozilla quirk 
+		// space has no keyCode in mozilla
+		var keyCode = evt.keyCode;
+		if(keyCode==0 && evt.charCode==k.KEY_SPACE){
+			keyCode = k.KEY_SPACE;
+		}
+		switch(keyCode){
+ 			case k.KEY_DOWN_ARROW:
+				if(!this._result_list_open){
+					this.startSearchFromInput();
+				}
+				this.highlightNextOption();
+				dojo.event.browser.stopEvent(evt);
+				return;
+			case k.KEY_UP_ARROW:
+				this.highlightPrevOption();
+				dojo.event.browser.stopEvent(evt);
+				return;
+			case k.KEY_ENTER:
+				// prevent to send form if we press enter with list open
+				if(this._result_list_open){
+					dojo.event.browser.stopEvent(evt);
+				}
+				// falltrough
+			case k.KEY_TAB:
+				// using linux alike tab for autocomplete
+				if(!this.autoComplete && this._result_list_open && this._highlighted_option){
+					dojo.event.browser.stopEvent(evt);
+					this.selectOption({ 'target': this._highlighted_option, 'noHide': true });
+
+					// put caret last
+					this.setSelectedRange(this.textInputNode, this.textInputNode.value.length, null);
+				}else{
+					this.selectOption();
+					return;
+				}
+				break;
+			case k.KEY_SPACE:
+				if(this._result_list_open && this._highlighted_option){
+					dojo.event.browser.stopEvent(evt);
+					this.selectOption();
+					this.hideResultList();
+					return;
+				}
+				break;
+			case k.KEY_ESCAPE:
+				this.hideResultList();
+				this._prev_key_esc = true;
+				return;
+			case k.KEY_BACKSPACE:
+				this._prev_key_backspace = true;
+				if(!this.textInputNode.value.length){
+					this.hideResultList();
+					doSearch = false;
+				}
+				break;
+			case k.KEY_RIGHT_ARROW: // falltrough
+			case k.KEY_LEFT_ARROW: // falltrough
+			case k.KEY_SHIFT:
+				doSearch = false;
+				break;
+			default:// non char keys (F1-F12 etc..)  shouldnt open list
+				if(evt.charCode==0){
+					doSearch = false;
+				}
+		}
+
+// 		this.setValue(this.textInputNode.value);
+		if(this.searchTimer){
+			clearTimeout(this.searchTimer);
+		}
+		if(doSearch){
+			// if we have gotten this far we dont want to keep our highlight
+			this.blurOptionNode();
+
+			// need to wait a tad before start search so that the event bubbels through DOM and we have value visible
+			this.searchTimer = setTimeout(dojo.lang.hitch(this, this.startSearchFromInput), this.searchDelay);
+		}
+	},
+
+	onKeyDown: function(evt){
+		// IE needs to stop keyDown others need to stop keyPress
+		if(!document.createEvent){ // only IE
+			this._handleKeyEvents(evt);
+		}
+		// FIXME: What about ESC ??
+	},
+
+	onKeyPress: function(evt){
+		if(document.createEvent){ // never IE
+			this._handleKeyEvents(evt);
+		}
+	},
+
+	onKeyUp: function(evt){
+		this.setValue(this.textInputNode.value);
+	},
+
+	setSelectedValue: function(value){
+		// FIXME, not sure what to do here!
+		this.comboBoxSelectionValue.value = value;
+		this.hideResultList();
+	},
+
+	// opera, khtml, safari doesnt support node.scrollIntoView(), workaround
+	scrollIntoView: function(){
+		var node = this._highlighted_option;
+		var parent = this.optionsListNode;
+		// dont rely on that node.scrollIntoView works just because the function is there
+		// it doesnt work in Konqueror or Opera even though the function is there and probably
+		// not safari either
+		// dont like browser sniffs implementations but sometimes you have to use it
+		if(dojo.render.html.ie || dojo.render.html.mozilla){
+			// IE, mozilla
+			node.scrollIntoView(false);	
+		}else{
+			var parentBottom = parent.scrollTop + dojo.style.getInnerHeight(parent);
+			var nodeBottom = node.offsetTop + dojo.style.getOuterHeight(node);
+			if(parentBottom < nodeBottom){
+				parent.scrollTop += (nodeBottom - parentBottom);
+			}else if(parent.scrollTop > node.offsetTop){
+				parent.scrollTop -= (parent.scrollTop - node.offsetTop);
+			}
+		}
+	},
+
+	// does the actual highlight
+	focusOptionNode: function(node){
+		if(this._highlighted_option != node){
+			this.blurOptionNode();
+			this._highlighted_option = node;
+			dojo.html.addClass(this._highlighted_option, "dojoComboBoxItemHighlight");
+		}
+	},
+
+	// removes highlight on highlighted
+	blurOptionNode: function(){
+		if(this._highlighted_option){
+			dojo.html.removeClass(this._highlighted_option, "dojoComboBoxItemHighlight");
+			this._highlighted_option = null;
+		}
+	},
+
+	highlightNextOption: function(){
+		if((!this._highlighted_option) || !this._highlighted_option.parentNode){
+			this.focusOptionNode(this.optionsListNode.firstChild);
+		}else if(this._highlighted_option.nextSibling){
+			this.focusOptionNode(this._highlighted_option.nextSibling);
+		}
+		this.scrollIntoView();
+	},
+
+	highlightPrevOption: function(){
+		if(this._highlighted_option && this._highlighted_option.previousSibling){
+			this.focusOptionNode(this._highlighted_option.previousSibling);
+		}else{
+			this._highlighted_option = null;
+			this.hideResultList();
+			return;
+		}
+		this.scrollIntoView();
+	},
+
+	itemMouseOver: function(evt){
+		this.focusOptionNode(evt.target);
+		dojo.html.addClass(this._highlighted_option, "dojoComboBoxItemHighlight");
+	},
+
+	itemMouseOut: function(evt){
+		this.blurOptionNode();
+	},
+
+	fillInTemplate: function(args, frag){
+		// FIXME: need to get/assign DOM node names for form participation here.
+		this.comboBoxValue.name = this.name;
+		this.comboBoxSelectionValue.name = this.name+"_selected";
+
+		// NOTE: this doesn't copy style info inherited from classes;
+		// it's just primitive support for direct style setting
+		var source = this.getFragNodeRef(frag);
+		if ( source.style ){
+			// get around opera wich doesnt have cssText, and IE wich bugs on setAttribute 
+			if(dojo.lang.isUndefined(source.style.cssText)){ 
+				this.domNode.setAttribute("style", source.getAttribute("style")); 
+			}else{
+				this.domNode.style.cssText = source.style.cssText; 
+			}
+		}
+
+		// FIXME: add logic
+		this.dataProvider = new dojo.widget.ComboBoxDataProvider();
+
+		if(!dojo.string.isBlank(this.dataUrl)){
+			if("local" == this.mode){
+				var _this = this;
+				dojo.io.bind({
+					url: this.dataUrl,
+					load: function(type, data, evt){ 
+						if(type=="load"){
+							if(!dojo.lang.isArray(data)){
+								var arrData = [];
+								for(var key in data){
+									arrData.push([data[key], key]);
+								}
+								data = arrData;
+							}
+							_this.dataProvider.setData(data);
+						}
+					},
+					mimetype: "text/json"
+				});
+			}else if("remote" == this.mode){
+				this.dataProvider = new dojo.widget.incrementalComboBoxDataProvider(this.dataUrl);
+			}
+		}else{
+			// check to see if we can populate the list from <option> elements
+			var node = frag["dojo:"+this.widgetType.toLowerCase()]["nodeRef"];
+			if((node)&&(node.nodeName.toLowerCase() == "select")){
+				// NOTE: we're not handling <optgroup> here yet
+				var opts = node.getElementsByTagName("option");
+				var ol = opts.length;
+				var data = [];
+				for(var x=0; x<ol; x++){
+					var keyValArr = [new String(opts[x].innerHTML), new String(opts[x].value)];
+					data.push(keyValArr);
+					if(opts[x].selected){ 
+						this.setValue(keyValArr[0]); 
+						this.comboBoxSelectionValue.value = keyValArr[1];
+					}
+				}
+				this.dataProvider.setData(data);
+			}
+		}
+
+		// Prevent IE bleed-through problem
+		this.optionsIframe = new dojo.html.BackgroundIframe(this.optionsListWrapper);
+		this.optionsIframe.size([0,0,0,0]);
+	},
+
+
+	focus: function(){
+		// summary
+		//	set focus to input node from code
+		this.tryFocus();
+	},
+
+	openResultList: function(results){
+		this.clearResultList();
+		if(!results.length){
+			this.hideResultList();
+		}
+
+		if(	(this.autoComplete)&&
+			(results.length)&&
+			(!this._prev_key_backspace)&&
+			(this.textInputNode.value.length > 0)){
+			var cpos = this.getCaretPos(this.textInputNode);
+			// only try to extend if we added the last charachter at the end of the input
+			if((cpos+1) > this.textInputNode.value.length){
+				// only add to input node as we would overwrite Capitalisation of chars
+				this.textInputNode.value += results[0][0].substr(cpos);
+				// build a new range that has the distance from the earlier
+				// caret position to the end of the first string selected
+				this.setSelectedRange(this.textInputNode, cpos, this.textInputNode.value.length);
+			}
+		}
+
+		var even = true;
+		while(results.length){
+			var tr = results.shift();
+			if(tr){
+				var td = document.createElement("div");
+				td.appendChild(document.createTextNode(tr[0]));
+				td.setAttribute("resultName", tr[0]);
+				td.setAttribute("resultValue", tr[1]);
+				td.className = "dojoComboBoxItem "+((even) ? "dojoComboBoxItemEven" : "dojoComboBoxItemOdd");
+				even = (!even);
+				this.optionsListNode.appendChild(td);
+				dojo.event.connect(td, "onmouseover", this, "itemMouseOver");
+				dojo.event.connect(td, "onmouseout", this, "itemMouseOut");
+			}
+		}
+
+		// show our list (only if we have content, else nothing)
+		this.showResultList();
+	},
+
+	onFocusInput: function(){
+		this._hasFocus = true;
+	},
+
+	onBlurInput: function(){
+		this._hasFocus = false;
+		this._handleBlurTimer(true, 100);
+	},
+
+	// collect all blur timers issues here
+	_handleBlurTimer: function(/*Boolean*/clear, /*Number*/ millisec){
+		if(this.blurTimer && (clear || millisec)){
+			clearTimeout(this.blurTimer);
+		}
+		if(millisec){ // we ignore that zero is false and never sets as that never happens in this widget
+			this.blurTimer = dojo.lang.setTimeout(this, "checkBlurred", millisec);
+		}
+	},
+
+	// these 2 are needed in IE and Safari as inputTextNode looses focus when scrolling optionslist
+	_onMouseOver: function(evt){
+		if(!this._mouseover_list){
+			this._handleBlurTimer(true, 0);
+			this._mouseover_list = true;
+		}
+	},
+
+	_onMouseOut:function(evt){
+		var relTarget = evt.relatedTarget;
+		if(!relTarget || relTarget.parentNode!=this.optionsListNode){
+			this._mouseover_list = false;
+			this._handleBlurTimer(true, 100);
+			this.tryFocus();
+		}
+	},
+
+	checkBlurred: function(){
+		if(!this._hasFocus && !this._mouseover_list){
+			this.hideResultList();
+		}
+	},
+
+	sizeBackgroundIframe: function(){
+		var w = dojo.style.getOuterWidth(this.optionsListNode);
+		var h = dojo.style.getOuterHeight(this.optionsListNode);
+		if( w==0 || h==0 ){
+			// need more time to calculate size
+			dojo.lang.setTimeout(this, "sizeBackgroundIframe", 100);
+			return;
+		}
+		if(this._result_list_open){
+			this.optionsIframe.size([0,0,w,h]);
+		}
+	},
+
+	selectOption: function(evt){
+		if(!evt){
+			evt = { target: this._highlighted_option };
+		}
+
+		if(!dojo.dom.isDescendantOf(evt.target, this.optionsListNode)){
+			return;
+		}
+
+		var tgt = evt.target;
+		while((tgt.nodeType!=1)||(!tgt.getAttribute("resultName"))){
+			tgt = tgt.parentNode;
+			if(tgt === document.body){
+				return false;
+			}
+		}
+
+		this.textInputNode.value = tgt.getAttribute("resultName");
+		this.selectedResult = [tgt.getAttribute("resultName"), tgt.getAttribute("resultValue")];
+		this.setValue(tgt.getAttribute("resultName"));
+		this.comboBoxSelectionValue.value = tgt.getAttribute("resultValue");
+		if(!evt.noHide){
+			this.hideResultList();
+			this.setSelectedRange(this.textInputNode, 0, null);
+		}
+		this.tryFocus();
+	},
+
+	clearResultList: function(){
+		var oln = this.optionsListNode;
+		while(oln.firstChild){
+			dojo.event.disconnect(oln.firstChild, "onmouseover", this, "itemMouseOver");
+			dojo.event.disconnect(oln.firstChild, "onmouseout", this, "itemMouseOut");
+			oln.removeChild(oln.firstChild);
+		}
+	},
+
+	hideResultList: function(){
+		if(this._result_list_open){
+			this._result_list_open = false;
+			this.optionsIframe.size([0,0,0,0]);
+			dojo.lfx.fadeHide(this.optionsListNode, 200).play();
+		}
+	},
+
+	showResultList: function(){
+		// Our dear friend IE doesnt take max-height so we need to calculate that on our own every time
+		var childs = this.optionsListNode.childNodes;
+		if(childs.length){
+			var visibleCount = this.maxListLength;
+			if(childs.length < visibleCount){
+				visibleCount = childs.length;
+			}
+
+			with(this.optionsListNode.style){
+				display = "";
+				height = ((visibleCount) ? (dojo.style.getOuterHeight(childs[0]) * visibleCount) : 0)+"px";
+				width = dojo.html.getOuterWidth(this.cbTableNode)+"px";
+			}
+			// only fadein once (flicker)
+			if(!this._result_list_open){
+				dojo.html.setOpacity(this.optionsListNode, 0);
+				dojo.lfx.fadeIn(this.optionsListNode, 200).play();
+			}
+			
+			// prevent IE bleed through
+			this._iframeTimer = dojo.lang.setTimeout(this, "sizeBackgroundIframe", 200);
+			this._result_list_open = true;
+		}else{
+			this.hideResultList();
+		}
+	},
+
+	handleArrowClick: function(){
+		this._handleBlurTimer(true, 0);
+		this.tryFocus();
+		if(this._result_list_open){
+			this.hideResultList();
+		}else{
+			this.startSearchFromInput();
+		}
+	},
+
+	tryFocus: function(){
+		try {    
+			this.textInputNode.focus();
+		} catch (e) {
+			// element isnt focusable if disabled, or not visible etc - not easy to test for.
+ 		};
+	},
+	
+	startSearchFromInput: function(){
+		this.startSearch(this.textInputNode.value);
+	},
+
+	postCreate: function(){
+		dojo.event.connect(this, "startSearch", this.dataProvider, "startSearch");
+		dojo.event.connect(this.dataProvider, "provideSearchResults", this, "openResultList");
+		dojo.event.connect(this.textInputNode, "onblur", this, "onBlurInput");
+		dojo.event.connect(this.textInputNode, "onfocus", this, "onFocusInput");
+
+		var s = dojo.widget.html.stabile.getState(this.widgetId);
+		if (s) {
+			this.setState(s);
+		}
+	}
+});

Propchange: incubator/xap/trunk/src/dojo/src/widget/html/ComboBox.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/xap/trunk/src/dojo/src/widget/html/ContentPane.js
URL: http://svn.apache.org/viewvc/incubator/xap/trunk/src/dojo/src/widget/html/ContentPane.js?rev=417618&view=auto
==============================================================================
--- incubator/xap/trunk/src/dojo/src/widget/html/ContentPane.js (added)
+++ incubator/xap/trunk/src/dojo/src/widget/html/ContentPane.js Tue Jun 27 15:48:54 2006
@@ -0,0 +1,508 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.html.ContentPane");
+
+dojo.require("dojo.widget.*");
+dojo.require("dojo.io.*");
+dojo.require("dojo.widget.HtmlWidget");
+dojo.require("dojo.widget.ContentPane");
+dojo.require("dojo.string");
+dojo.require("dojo.string.extras");
+dojo.require("dojo.style");
+
+dojo.widget.html.ContentPane = function(){
+	dojo.widget.HtmlWidget.call(this);
+}
+dojo.inherits(dojo.widget.html.ContentPane, dojo.widget.HtmlWidget);
+
+dojo.lang.extend(dojo.widget.html.ContentPane, {
+	widgetType: "ContentPane",
+	isContainer: true,
+
+	// remote loading options
+	href: "",
+	extractContent: true,
+	parseContent: true,
+	cacheContent: true,
+	preload: false,			// force load of data even if pane is hidden
+	refreshOnShow: false,
+	handler: "",			// generate pane content from a java function
+	executeScripts: false,	// if true scripts in content will be evaled after content is set and parsed
+	scriptScope: null,		// scopeContainer for downloaded scripts
+
+		// If the user want a global in the remote script he/she just omitts the var
+		// examples:
+		//--------------------------
+		// these gets collected by scriptScope and is reached by dojo.widget.byId('..').scriptScope.myCustomproperty
+		//	this.myString = "dojo is a great javascript toolkit!";
+		//
+		//	this.alertMyString = function(){
+		//		alert(myString);
+		//	}
+		// -------------------------
+		// these go into the global namespace (window) notice lack of var, equiv to window.myString
+		//	myString = "dojo is a javascript toolkit!";
+		//
+		//	alertMyString = function(){
+		//		alert(myString);
+		// }
+
+
+	// private
+	_remoteStyles: null,	// array of stylenodes inserted to document head
+							// by remote content, used when we clean up for new content
+
+	_callOnUnLoad: false,		// used by setContent and _handleDefults, makes sure onUnLoad is only called once
+
+
+	postCreate: function(args, frag, parentComp){
+		if ( this.handler != "" ){
+			this.setHandler(this.handler);
+		}
+		if(this.isShowing()||this.preload){ this.loadContents(); }
+	},
+
+	show: function(){
+		// if refreshOnShow is true, reload the contents every time; otherwise, load only the first time
+		if(this.refreshOnShow){
+			this.refresh();
+		}else{
+			this.loadContents();
+		}
+		dojo.widget.html.ContentPane.superclass.show.call(this);
+	},
+
+	refresh: function(){
+		this.isLoaded=false;
+		this.loadContents();
+	},
+
+	loadContents: function() {
+		if ( this.isLoaded ){
+			return;
+		}
+		this.isLoaded=true;
+		if ( dojo.lang.isFunction(this.handler)) {
+			this._runHandler();
+		} else if ( this.href != "" ) {
+			this._downloadExternalContent(this.href, this.cacheContent);
+		}
+	},
+
+	
+	setUrl: function(/*String*/ url) {
+		// summary:
+		// 	Reset the (external defined) content of this pane and replace with new url
+		this.href = url;
+		this.isLoaded = false;
+		if ( this.preload || this.isShowing() ){
+			this.loadContents();
+		}
+	},
+
+	_downloadExternalContent: function(url, useCache) {
+		this._handleDefaults("Loading...", "onDownloadStart");
+		var self = this;
+		dojo.io.bind({
+			url: url,
+			useCache: useCache,
+			preventCache: !useCache,
+			mimetype: "text/html",
+			handler: function(type, data, e) {
+				if(type == "load") {
+					self.onDownloadEnd.call(self, url, data);
+				} else {
+					// works best when from a live serveer instead of from file system
+					self._handleDefaults.call(self, "Error loading '" + url + "' (" + e.status + " "+  e.statusText + ")", "onDownloadError");
+					self.onLoad();
+				}
+			}
+		});
+	},
+
+	// called when setContent is finished
+	onLoad: function(e){ /*stub*/ },
+
+	// called before old content is cleared
+	onUnLoad: function(e){ 
+			this.scriptScope = null;
+	},
+
+	destroy: function(){
+		// make sure we call onUnLoad
+		this.onUnLoad();
+		dojo.widget.html.ContentPane.superclass.destroy.call(this);
+	},
+
+	// 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*/ },
+
+	// called when download error occurs, preventDefault-able
+	onDownloadError: function(e){ /*stub*/ },
+
+	// called before download starts, preventDefault-able
+	onDownloadStart: function(e){ /*stub*/ },
+
+	// called when download is finished
+	onDownloadEnd: function(url, data){
+		data = this.splitAndFixPaths(data, url);
+		this.setContent(data);
+	},
+
+	// usefull if user wants to prevent default behaviour ie: _setContent("Error...")
+	_handleDefaults: function(e, handler, useAlert){
+		if(!handler){ handler = "onContentError"; }
+		if(dojo.lang.isString(e)){
+			e = {
+				"text": e,
+				"toString": function(){ return this.text; }
+			}
+		}
+		if(typeof e.returnValue != "boolean"){
+			e.returnValue = true; 
+		}
+		if(typeof e.preventDefault != "function"){
+			e.preventDefault = function(){
+				this.returnValue = false;
+			}
+		}
+		// call our handler
+		this[handler](e);
+		if(e.returnValue){
+			if(useAlert){
+				alert(e.toString());
+			}else{
+				if(this._callOnUnLoad){
+					this.onUnLoad(); // makes sure scripts can clean up after themselves, before we setContent
+				}
+				this._callOnUnLoad = false; // makes sure we dont try to call onUnLoad again on this event,
+											// ie onUnLoad before 'Loading...' but not before clearing 'Loading...'
+				this._setContent(e.toString());
+			}
+		}
+	},
+
+	
+	splitAndFixPaths: function(/*String*/s, /*dojo.uri.Uri?*/url){
+		// summary:
+		// 	fixes all remote 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
+
+		if(!url) { url = "./"; } // point to this page if not set
+		if(!s) { return ""; }
+
+		// fix up paths in data
+		var titles = []; var scripts = []; var linkStyles = [];
+		var styles = []; var remoteScripts = []; var requires = [];
+
+		// khtml is much more picky about dom faults, you can't for example attach a style node under body of document
+		// must go into head, as does a title node, so we need to cut out those tags
+		// cut out title tags
+		var match = [];
+		while(match){
+			match = s.match(/<title[^>]*>([\s\S]*?)<\/title>/i); // can't match with dot as that 
+			if(!match){ break;}					//doesnt match newline in js
+			titles.push(match[1]);
+			s = s.replace(/<title[^>]*>[\s\S]*?<\/title>/i, "");
+		}
+
+		// cut out <style> url(...) </style>, as that bails out in khtml
+		var match = [];
+		while(match){
+			match = s.match(/<style[^>]*>([\s\S]*?)<\/style>/i);
+			if(!match){ break; }
+			styles.push(dojo.style.fixPathsInCssText(match[1], url));
+			s = s.replace(/<style[^>]*?>[\s\S]*?<\/style>/i, "");
+		}
+
+		// attributepaths one tag can have multiple paths example:
+		// <input src="..." style="url(..)"/> or <a style="url(..)" href="..">
+		// strip out the tag and run fix on that.
+		// this guarantees that we won't run replace another tag's attribute + it was easier do
+		var pos = 0; var pos2 = 0; var stop = 0 ;var str = ""; var fixedPath = "";
+		var attr = []; var fix = ""; var tagFix = ""; var tag = ""; var regex = ""; 
+		while(pos>-1){
+			pos = s.search(/<[a-z][a-z0-9]*[^>]*\s(?:(?:src|href|style)=[^>])+[^>]*>/i);
+			if(pos==-1){ break; }
+			str += s.substring(0, pos);
+			s = s.substring(pos, s.length);
+			tag = s.match(/^<[a-z][a-z0-9]*[^>]*>/i)[0];
+			s = s.substring(tag.length, s.length);
+
+			// loop through attributes
+			pos2 = 0; tagFix = ""; fix = ""; regex = ""; var regexlen = 0;
+			while(pos2!=-1){
+				// slices up before next attribute check, values from previous loop
+				tagFix += tag.substring(0, pos2) + fix;
+				tag = tag.substring(pos2+regexlen, tag.length);
+
+				// fix next attribute or bail out when done
+				// hopefully this charclass covers most urls
+				attr = tag.match(/ (src|href|style)=(['"]?)([\w()\[\]\/.,\\'"-:;#=&?\s@]+?)\2/i);
+				if(!attr){ break; }
+
+				switch(attr[1].toLowerCase()){
+					case "src":// falltrough
+					case "href":
+						// this hopefully covers most common protocols
+						if(attr[3].search(/^(?:[#]|(?:(?:https?|ftps?|file|javascript|mailto|news):))/)==-1){
+							fixedPath = (new dojo.uri.Uri(url, attr[3]).toString());
+						} else {
+							pos2 = pos2 + attr[3].length;
+							continue;
+						}
+						break;
+					case "style":// style
+						fixedPath = dojo.style.fixPathsInCssText(attr[3], url);
+						break;
+					default:
+						pos2 = pos2 + attr[3].length;
+						continue;
+				}
+
+				regex = " " + attr[1] + "=" + attr[2] + attr[3] + attr[2];
+				regexlen = regex.length;
+				fix = " " + attr[1] + "=" + attr[2] + fixedPath + attr[2];
+				pos2 = tag.search(new RegExp(dojo.string.escapeRegExp(regex)));
+			}
+			str += tagFix + tag;
+			pos = 0; // reset for next mainloop
+		}
+		s = str+s;
+
+		// cut out all script tags, push them into scripts array
+		match = []; var tmp = [];
+		while(match){
+			match = s.match(/<script([^>]*)>([\s\S]*?)<\/script>/i);
+			if(!match){ break; }
+			if(match[1]){
+				attr = match[1].match(/src=(['"]?)([^"']*)\1/i);
+				if(attr){
+					// remove a dojo.js or dojo.js.uncompressed.js from remoteScripts
+					// we declare all files with dojo.js as bad, regardless of folder
+					var tmp = attr[2].search(/.*(\bdojo\b(?:\.uncompressed)?\.js)$/);
+					if(tmp > -1){
+						dojo.debug("Security note! inhibit:"+attr[2]+" from  beeing loaded again.");
+					}else{
+						remoteScripts.push(attr[2]);
+					}
+				}
+			}
+			if(match[2]){
+				// strip out all djConfig variables from script tags nodeValue
+				// this is ABSOLUTLY needed as reinitialize djConfig after dojo is initialised
+				// makes a dissaster greater than Titanic, update remove writeIncludes() to
+				var sc = match[2].replace(/(?:var )?\bdjConfig\b(?:[\s]*=[\s]*\{[^}]+\}|\.[\w]*[\s]*=[\s]*[^;\n]*)?;?|dojo\.hostenv\.writeIncludes\(\s*\);?/g, "");
+				if(!sc){ continue; }
+
+				// cut out all dojo.require (...) calls, if we have execute 
+				// scripts false widgets dont get there require calls
+				// does suck out possible widgetpackage registration as well
+				tmp = [];
+				while(tmp && requires.length<100){
+					tmp = sc.match(/dojo\.(?:(?:require(?:After)?(?:If)?)|(?:widget\.(?:manager\.)?registerWidgetPackage)|(?:(?:hostenv\.)?setModulePrefix))\((['"]).*?\1\)\s*;?/);
+					if(!tmp){ break;}
+					requires.push(tmp[0]);
+					sc = sc.replace(tmp[0], "");
+				}
+				scripts.push(sc);
+			}
+			s = s.replace(/<script[^>]*>[\s\S]*?<\/script>/i, "");
+		}
+
+		// scan for scriptScope in html eventHandlers and replace with link to this pane
+		if(this.executeScripts){
+			var regex = /(<[a-zA-Z][a-zA-Z0-9]*\s[^>]*\S=(['"])[^>]*[^\.\]])scriptScope([^>]*>)/;
+			var pos = 0;var str = "";match = [];var cit = "";
+			while(pos > -1){
+				pos = s.search(regex);
+				if(pos > -1){
+					cit = ((RegExp.$2=="'") ? '"': "'");
+					str += s.substring(0, pos);
+					s = s.substr(pos).replace(regex, "$1dojo.widget.byId("+ cit + this.widgetId + cit + ").scriptScope$3");
+				}
+			}
+			s = str + s;
+		}
+
+		// cut out all <link rel="stylesheet" href="..">
+		match = [];
+		while(match){
+			match = s.match(/<link ([^>]*rel=['"]?stylesheet['"]?[^>]*)>/i);
+			if(!match){ break; }
+			attr = match[1].match(/href=(['"]?)([^'">]*)\1/i);
+			if(attr){
+				linkStyles.push(attr[2]);
+			}
+			s = s.replace(new RegExp(match[0]), "");
+		}
+
+		return {"xml": s, // Object
+			"styles": styles,
+			"linkStyles": linkStyles,
+			"titles": titles,
+			"requires": 	requires,
+			"scripts": scripts,
+			"remoteScripts": remoteScripts,
+			"url": url};
+	},
+
+	
+	_setContent: function(/*String*/ xml){
+		// summary: 
+		//		private internal function without path regExpCheck and no onLoad calls aftervards
+
+		// remove old children from current content
+		this.destroyChildren();
+
+		// remove old stylenodes from HEAD
+		if(this._remoteStyles){
+			for(var i = 0; i < this._remoteStyles.length; i++){
+				if(this._remoteStyles[i] && this._remoteStyles.parentNode){
+					this._remoteStyles[i].parentNode.removeChild(this._remoteStyles[i]);
+				}
+			}
+			this._remoteStyles = null;
+		}
+
+		var node = this.containerNode || this.domNode;
+		try{
+			if(typeof xml != "string"){
+				node.innerHTML = "";
+				node.appendChild(xml);
+			}else{
+				node.innerHTML = xml;
+			}
+		} catch(e){
+			e = "Could'nt load html:"+e;
+			this._handleDefaults(e, "onContentError");
+		}
+	},
+
+	setContent: function(/*String*/ data){
+		// summary:
+		// 	Destroys old content and setting new content, and possibly initialize any widgets within 'data'
+
+		if(this._callOnUnLoad){ // this tells a remote script clean up after itself
+			this.onUnLoad();
+		}
+		this._callOnUnLoad = true;
+
+		if(!data || dojo.dom.isNode(data)){
+			// if we do a clean using setContent(""); or setContent(#node) bypass all parseing, extractContent etc
+			this._setContent(data);
+		}else{
+			// need to run splitAndFixPaths? ie. manually setting content
+			 if(!data.xml){
+				data = this.splitAndFixPaths(data);
+			}
+			if(this.extractContent) {
+				var matches = data.xml.match(/<body[^>]*>\s*([\s\S]+)\s*<\/body>/im);
+				if(matches) { data.xml = matches[1]; }
+			}
+			// insert styleNodes, from <style>....
+			for(var i = 0; i < data.styles.length; i++){
+				if(i==0){ 
+					this._remoteStyles = []; 
+				}
+				this._remoteStyles.push(dojo.style.insertCssText(data.styles[i]));
+			}
+			// insert styleNodes, from <link href="...">
+			for(var i = 0; i < data.linkStyles.length; i++){
+				if(i==0){ 
+					this._remoteStyles = []; 
+				}
+				this._remoteStyles.push(dojo.style.insertCssFile(data.linkStyles[i]));
+			}
+			this._setContent(data.xml);
+
+			if(this.parseContent){
+				for(var i = 0; i < data.requires.length; i++){
+					try{ 
+						eval(data.requires[i]);
+					} catch(e){
+						this._handleDefaults(e, "onContentError", true);
+					}
+				}
+				var node = this.containerNode || this.domNode;
+				var parser = new dojo.xml.Parse();
+				var frag = parser.parseElement(node, null, true);
+				// createSubComponents not createComponents because frag has already been created
+				dojo.widget.getParser().createSubComponents(frag, this);
+			}
+
+			if(this.executeScripts){
+				this._executeScripts(data);
+			}
+		}
+		this.onResized(); // move this here so that resize is called when we set "" to reset sizing code
+		this.onLoad(); // tell system that we have finished
+	},
+
+	// Generate pane content from given java function
+	setHandler: function(handler) {
+		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
+			this._handleDefaults("Unable to set handler, '" + handler + "' not a function.", "onExecError", true);
+			return;
+		}
+		this.handler = function() {
+			return fcn.apply(this, arguments);
+		}
+	},
+
+	_runHandler: function() {
+		if(dojo.lang.isFunction(this.handler)) {
+			this.handler(this, this.domNode);
+			return false;
+		}
+		return true;
+	},
+
+	_executeScripts: function(data) {
+		// do remoteScripts first
+		var self = this;
+		for(var i = 0; i < data.remoteScripts.length; i++){
+			dojo.io.bind({
+				"url": data.remoteScripts[i],
+				"useCash":	this.cacheContent,
+				"load":     function(type, scriptStr){
+						dojo.lang.hitch(self, data.scripts.push(scriptStr));
+				},
+				"error":    function(type, error){
+						self._handleDefaults.call(self, type + " downloading remote script", "onExecError", true);
+				},
+				"mimetype": "text/plain",
+				"sync":     true
+			});
+		}
+
+		var scripts = "";
+		for(var i = 0; i < data.scripts.length; i++){
+			scripts += data.scripts[i];
+		}
+
+			// initialize a new anonymous container for our script, dont make it part of this widgets scope chain
+			// instead send in a variable that points to this widget, usefull to connect events to onLoad, onUnLoad etc..
+			this.scriptScope = null;
+			this.scriptScope = new (new Function('_container_', scripts+'; return this;'))(self);
+	try{
+		}catch(e){
+			this._handleDefaults("Error running scripts from content:\n"+e, "onExecError", true);
+		}
+	}
+});
+
+dojo.widget.tags.addParseTreeHandler("dojo:ContentPane");

Propchange: incubator/xap/trunk/src/dojo/src/widget/html/ContentPane.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/xap/trunk/src/dojo/src/widget/html/ContextMenu.js
URL: http://svn.apache.org/viewvc/incubator/xap/trunk/src/dojo/src/widget/html/ContextMenu.js?rev=417618&view=auto
==============================================================================
--- incubator/xap/trunk/src/dojo/src/widget/html/ContextMenu.js (added)
+++ incubator/xap/trunk/src/dojo/src/widget/html/ContextMenu.js Tue Jun 27 15:48:54 2006
@@ -0,0 +1,166 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.html.ContextMenu");
+dojo.require("dojo.html");
+dojo.require("dojo.widget.HtmlWidget");
+dojo.require("dojo.widget.ContextMenu");
+dojo.require("dojo.lang");
+
+dojo.widget.html.ContextMenu = function(){
+	dojo.widget.ContextMenu.call(this);
+	dojo.widget.HtmlWidget.call(this);
+
+	this.isShowing = 0;
+	this.templatePath = dojo.uri.dojoUri("src/widget/templates/HtmlContextMenuTemplate.html");
+	this.templateCssPath = dojo.uri.dojoUri("src/widget/templates/Menu.css");
+
+	this.targetNodeIds = []; // fill this with nodeIds upon widget creation and it only responds to those nodes
+
+	// default event detection method 
+	var eventType = "oncontextmenu"; 
+
+	var doc = document.documentElement  || document.body; 
+
+	var _blockHide = false; 
+
+	this.fillInTemplate = function(args, frag){
+
+		var func = "onOpen";
+		var attached = false;
+
+		// connect with rightclick if oncontextmenu is not around
+		// NOTE: It would be very nice to have a dojo.event.browser.supportsEvent here
+		// NOTE: Opera does not have rightclick events, it is listed here only because
+		//     it bails out when connecting with oncontextmenu event
+
+		if((dojo.render.html.khtml && !dojo.render.html.safari) || (dojo.render.html.opera)){
+			eventType = "onmousedown";
+			func = "_checkRightClick";
+		}
+
+		// attach event listeners to our selected nodes
+		for(var i=0; i<this.targetNodeIds.length; i++){
+			var node = document.getElementById(this.targetNodeIds[i]);
+			if(node){
+				dojo.event.connect(node, eventType, this, func);
+				attached = true;
+			}else{
+				// remove this nodeId
+				dojo.debug("Couldent find "+this.targetNodeIds[i]+", cant do ContextMenu on this node");
+				this.targetNodeIds.splice(i,1);
+			}
+		}
+
+		// if we got attached to a node, hide on all non node contextevents
+		if(attached){ func = "_canHide"; }
+
+		dojo.event.connect(doc, eventType, this, func);
+	}
+
+	this.onOpen = function(evt){
+		// if (this.isShowing){ this.onHide(evt); } // propably not needed
+		this.isShowing = 1;
+
+		// if I do this, I cant preventDefault in khtml
+		//evt = dojo.event.browser.fixEvent(evt);
+ 
+		// stop default contextmenu, needed in khtml
+		if (evt.preventDefault){ evt.preventDefault(); }
+
+		// need to light up this one before we check width and height
+		this.domNode.style.left = "-9999px";
+		this.domNode.style.top  = "-9999px";
+		this.domNode.style.display = "block";
+
+		// calculate if menu is going to apear within window
+		// or if its partially out of visable area
+		with(dojo.html){
+
+			var menuW = getInnerWidth(this.domNode);
+			var menuH = getInnerHeight(this.domNode);
+
+			var viewport = getViewportSize();
+			var scrolloffset = getScrollOffset();
+		}
+
+		var minX = viewport[0];
+		var minY = viewport[1];
+
+		var maxX = (viewport[0] + scrolloffset[0]) - menuW;
+		var maxY = (viewport[1] + scrolloffset[1]) - menuH;
+
+		var posX = evt.clientX + scrolloffset[0];
+		var posY = evt.clientY + scrolloffset[1];
+
+		if (posX > maxX){ posX = posX - menuW; }
+		if (posY > maxY){ posY = posY - menuH; }
+
+		this.domNode.style.left = posX + "px";
+		this.domNode.style.top = posY + "px";
+
+
+		// block the onclick that follows this particular right click
+		// not if the eventtrigger is documentElement and always when
+		// we use onmousedown hack
+		_blockHide = (evt.currentTarget!=doc || eventType=='onmousedown');
+
+		//return false; // we propably doesnt need to return false as we dont stop the event as we did before
+	}
+
+	/*
+	* _canHide is meant to block the onHide call that follows the event that triggered
+	* onOpen. This is (hopefully) faster that event.connect and event.disconnect every
+	* time the code executes and it makes connecting with onmousedown event possible
+	* and we dont have to stop the event from bubbling further.
+	*
+	* this code is moved into a separete function because it makes it possible for the
+	* user to connect to a onHide event, if anyone would like that.
+	*/
+
+	this._canHide = function(evt){
+		// block the onclick that follows the same event that turn on contextmenu
+		if(_blockHide){
+			// the onclick check is needed to prevent displaying multiple
+			// menus when we have 2 or more contextmenus loaded and are using
+			// the onmousedown hack
+			if(evt.type=='click' || eventType=='oncontextmenu'){
+				_blockHide = false;
+				return;
+			}else{
+				return;
+			}
+		}
+
+		this.onHide(evt);
+	}
+	
+	this.onHide = function(evt){
+		// FIXME: use whatever we use to do more general style setting?
+		this.domNode.style.display = "none";
+		//dojo.event.disconnect(doc, "onclick", this, "onHide");
+		this.isShowing = 0;
+	}
+
+	// callback for rightclicks, needed for browsers that doesnt implement oncontextmenu, konqueror and more? 
+	this._checkRightClick = function(evt){ 
+
+		// for some reason konq comes here even when we are not clicking on the attached nodes 
+		// added check for targetnode 
+		if (evt.button==2 && (this.targetNodeIds.length==0 || (evt.currentTarget.id!="" && dojo.lang.inArray(this.targetNodeIds, evt.currentTarget.id)))){
+
+			return this.onOpen(evt);
+		}
+	}
+
+	dojo.event.connect(doc, "onclick", this, "_canHide");
+}
+
+dojo.inherits(dojo.widget.html.ContextMenu, dojo.widget.HtmlWidget);

Propchange: incubator/xap/trunk/src/dojo/src/widget/html/ContextMenu.js
------------------------------------------------------------------------------
    svn:eol-style = native

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

Added: incubator/xap/trunk/src/dojo/src/widget/html/DebugConsole.js
URL: http://svn.apache.org/viewvc/incubator/xap/trunk/src/dojo/src/widget/html/DebugConsole.js?rev=417618&view=auto
==============================================================================
--- incubator/xap/trunk/src/dojo/src/widget/html/DebugConsole.js (added)
+++ incubator/xap/trunk/src/dojo/src/widget/html/DebugConsole.js Tue Jun 27 15:48:54 2006
@@ -0,0 +1,31 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.html.DebugConsole");
+
+dojo.require("dojo.widget.*");
+dojo.require("dojo.widget.FloatingPane");
+
+dojo.widget.html.DebugConsole= function(){
+
+	dojo.widget.html.FloatingPane.call(this);
+	dojo.widget.DebugConsole.call(this);
+}
+
+dojo.inherits(dojo.widget.html.DebugConsole, dojo.widget.html.FloatingPane);
+
+dojo.lang.extend(dojo.widget.html.DebugConsole, {
+	fillInTemplate: function() {
+		dojo.widget.html.DebugConsole.superclass.fillInTemplate.apply(this, arguments);
+		this.containerNode.id = "debugConsoleClientPane";
+		djConfig.isDebug = true;
+		djConfig.debugContainerId = this.containerNode.id;
+	}
+});

Added: incubator/xap/trunk/src/dojo/src/widget/html/DemoEngine.js
URL: http://svn.apache.org/viewvc/incubator/xap/trunk/src/dojo/src/widget/html/DemoEngine.js?rev=417618&view=auto
==============================================================================
--- incubator/xap/trunk/src/dojo/src/widget/html/DemoEngine.js (added)
+++ incubator/xap/trunk/src/dojo/src/widget/html/DemoEngine.js Tue Jun 27 15:48:54 2006
@@ -0,0 +1,293 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.html.DemoEngine");
+dojo.require("dojo.widget.*");
+dojo.require("dojo.widget.HtmlWidget");
+dojo.require("dojo.lfx.*");
+dojo.require("dojo.style");
+dojo.require("dojo.io.*");
+dojo.require("dojo.widget.Button");
+dojo.require("dojo.widget.TabContainer");
+dojo.require("dojo.widget.ContentPane");
+
+dojo.widget.html.DemoEngine = function(){
+	dojo.widget.HtmlWidget.call(this);
+	this.widgetType = "DemoEngine";
+
+	this.templatePath = dojo.uri.dojoUri("src/widget/templates/DemoEngine.html");
+
+	this.demoEngineClass="demoEngine";
+
+	this.navigationNode="";
+	this.navigationClass="demoEngineNavigation";
+
+	this.collapseToNode="";
+	this.collapseToClass="collapseTo";
+
+	this.menuNavigationNode="";
+	this.menuNavigationClass="demoEngineMenuNavigation";
+
+	this.demoNavigationNode="";
+	this.demoNavigationClass="demoEngineDemoNavigation";
+
+	this.demoListWrapperClass="demoListWrapper";
+	this.demoListContainerClass="demoListContainer";
+	this.demoSummaryClass = "demoSummary";
+	this.demoSummaryBoxClass="demoSummaryBox";
+	this.demoListScreenshotClass="screenshot";
+	this.demoListSummaryContainerClass="summaryContainer";
+	this.demoSummaryClass="summary";
+	this.demoViewLinkClass="view";	
+
+	this.demoContainerNode="";
+	this.demoContainerClass="demoEngineDemoContainer";
+
+	this.demoHeaderNode="";
+	this.demoHeaderClass="demoEngineDemoHeader";
+
+	this.collapsedMenuNode="";
+	this.collapsedMenuClass="demoEngineCollapsedMenu";
+	this.collapsedMenuButton="";
+
+	this.aboutNode="";
+	this.aboutClass="demoEngineAbout";
+
+	this.demoPaneNode="";	
+	this.demoTabContainer="";
+
+	this.viewLinkImage="viewDemo.png";
+	this.dojoDemosImage = "dojoDemos.gif";
+	this.dojoDemosImageNode="";
+
+	this.registry = function() {};	
+}
+
+dojo.inherits(dojo.widget.html.DemoEngine, dojo.widget.HtmlWidget);
+
+dojo.lang.extend(dojo.widget.html.DemoEngine, {
+	postCreate: function() {
+		dojo.html.addClass(this.domNode, this.demoEngineClass);
+		dojo.html.addClass(this.navigationNode, this.navigationClass);
+		dojo.html.addClass(this.collapseToNode, this.collapseToClass);
+		dojo.html.addClass(this.menuNavigationNode, this.menuNavigationClass);
+		dojo.html.addClass(this.demoNavigationNode, this.demoListWrapperClass);
+		dojo.html.addClass(this.collapsedMenuNode, this.collapsedMenuClass);
+		dojo.html.addClass(this.demoHeaderNode, this.demoHeaderClass);
+		dojo.html.addClass(this.demoContainerNode, this.demoContainerClass);
+
+		// Make sure navigation node is hidden and opaque
+		//dojo.style.hide(this.navigationNode);
+		//dojo.style.setOpacity(this.navigationNode, 0);
+
+		//Make sure demoNavigationNode is hidden and opaque;
+		dojo.style.hide(this.demoNavigationNode);
+		dojo.style.setOpacity(this.demoNavigationNode,0);
+
+		//Make sure demoContainerNode is hidden and opaque
+		dojo.style.hide(this.demoContainerNode);
+		dojo.style.setOpacity(this.demoContainerNode,0);
+
+		//Populate the menu
+		this.buildMenu();
+
+		//show navigationNode
+		//dojo.lfx.html.fadeShow(this.navigationNode, 500).play();
+
+		//turn demoPaneNode into a tabset
+		this.demoTabContainer = dojo.widget.createWidget("TabContainer",{},this.demoPaneNode);	
+
+	},
+
+	buildMenu: function() {
+		dojo.html.removeChildren(this.menuNavigationNode);
+
+		dojo.io.bind({
+			url: "demoRegistry.json",
+			load: dojo.lang.hitch(this, "_buildMenu"),
+			mimetype: "text/json"
+		});
+	},
+
+	_buildMenu: function(type, data) {
+		this.registry = data;
+		dojo.debug("_buildMenu");
+
+		dojo.lang.forEach(this.registry.navigation, dojo.lang.hitch(this,function(category) {
+			this._addMenuItem(category);
+		}));
+	},
+
+	_addMenuItem: function(category) {
+		dojo.debug("Adding button for " + category.name);
+		var newCat = dojo.widget.createWidget("Button");
+		newCat.containerNode.innerHTML=category.name;
+		this.menuNavigationNode.appendChild(newCat.domNode);
+		dojo.event.connect(newCat,"onClick", this, "selectCategory");
+	},
+
+	selectCategory: function(e) {
+		dojo.debug("Selecting: " + e.target.innerHTML);
+		var showDemoNav = dojo.lfx.html.fadeShow(this.demoNavigationNode, 600);
+		var moveMenuNav = dojo.lfx.html.slideTo(this.menuNavigationNode,[0,0], 250);
+
+		dojo.html.removeChildren(this.demoNavigationNode);
+	
+		dojo.lfx.combine(showDemoNav, moveMenuNav).play()	
+
+		for (var x = 0 ; x< this.registry.navigation.length; x++) {
+			if (this.registry.navigation[x].name == e.target.innerHTML) {
+				for (var y=0; y< this.registry.navigation[x].demos.length; y++) {
+					dojo.debug("demo: " + this.registry.navigation[x].demos[y]);
+					var d = this.registry.definitions[this.registry.navigation[x].demos[y]];
+
+					//var demoListWrapper = document.createElement("div");
+					//dojo.html.addClass(demoListWrapper,this.demoListWrapperClass);
+					//this.demoNavigationNode.appendChild(demoListWrapper);
+
+					var demoListContainer=document.createElement("div");
+					dojo.html.addClass(demoListContainer, this.demoListContainerClass);
+					this.demoNavigationNode.appendChild(demoListContainer);
+
+					var demoSummary = document.createElement("div");
+					dojo.html.addClass(demoSummary,this.demoSummaryClass);
+					demoListContainer.appendChild(demoSummary);
+
+					var demoSummaryBox = document.createElement("div");
+					dojo.html.addClass(demoSummaryBox, this.demoSummaryBoxClass);
+					demoSummary.appendChild(demoSummaryBox);
+
+					var table = document.createElement("table");
+					table.width="100%";
+					table.cellSpacing="0";
+					table.cellPadding="0";
+					table.border="0";
+					demoSummaryBox.appendChild(table);
+
+					var tbody = document.createElement("tbody");
+					table.appendChild(tbody);
+
+					var tr= document.createElement("tr");
+					tbody.appendChild(tr);
+
+					var screenshotTd = document.createElement("td");
+					dojo.html.addClass(screenshotTd,this.demoListScreenshotClass);
+					screenshotTd.valign="top";
+					screenshotTd.demoName = this.registry.navigation[x].demos[y];
+					tr.appendChild(screenshotTd);
+
+					var ss = document.createElement("img");
+					ss.src=d.thumbnail;
+					screenshotTd.appendChild(ss);
+
+					var summaryTd = document.createElement("td");
+					dojo.html.addClass(summaryTd,this.demoListSummaryContainerClass);
+					summaryTd.vAlign="top";
+					tr.appendChild(summaryTd);
+
+					var name = document.createElement("h1");
+					name.appendChild(document.createTextNode(this.registry.navigation[x].demos[y]));
+					summaryTd.appendChild(name);
+
+					var summary = document.createElement("div");
+					dojo.html.addClass(summary, this.demoSummaryClass);		
+					summaryTd.appendChild(summary);
+
+					var desc = document.createElement("p");
+					desc.appendChild(document.createTextNode(d.description));
+					summary.appendChild(desc);
+					
+					var viewDiv = document.createElement("div");
+					dojo.html.addClass(viewDiv, this.demoViewLinkClass);
+					summary.appendChild(viewDiv);
+				
+					var viewLink = document.createElement("img");
+					viewLink.src = this.viewLinkImage;
+					viewLink.demoName = this.registry.navigation[x].demos[y];
+					viewDiv.appendChild(viewLink);	
+							
+					dojo.event.connect(viewLink, "onclick", this, "launchDemo");
+					dojo.event.connect(screenshotTd, "onclick", this, "launchDemo");
+				}
+			}
+		}
+	},
+
+	showIframe: function(e) {
+		dojo.lfx.html.fadeShow(e.currentTarget,250).play();
+	},
+
+	launchDemo: function(e) {
+		dojo.debug("Launching Demo: " + e.currentTarget.parentNode.parentNode.parentNode.firstChild.innerHTML);
+		var demo = e.currentTarget.demoName;
+
+		//implode = dojo.lfx.html.implode(this.navigationNode, this.collapsedMenuNode,1500);
+		//show = dojo.lfx.html.fadeShow(this.demoContainerNode,1500);
+		dojo.style.setOpacity(this.demoContainerNode, 0);
+		hide = dojo.lfx.html.fadeHide(this.navigationNode, 500);
+		show = dojo.lfx.html.fadeShow(this.demoContainerNode,500);
+		//dojo.style.setOpacity(this.demoContainerNode, 0);
+		//dojo.style.show(this.demoContainerNode);
+		dojo.lfx.combine(hide,show).play();
+
+		this.demoTabContainer.destroyChildren();
+
+		demoIframe = document.createElement("iframe");
+		demoIframe.src=this.registry.definitions[demo].url;
+
+		dojo.html.removeChildren(this.aboutNode);
+		var name = document.createElement("h1");
+		var about= document.createElement("h2");
+		name.appendChild(document.createTextNode(demo));
+		about.appendChild(document.createTextNode(this.registry.definitions[demo].description));
+		this.aboutNode.appendChild(name);
+		this.aboutNode.appendChild(about);
+
+		liveDemo = dojo.widget.createWidget("ContentPane",{label: "Live Demo"});
+		liveDemo.domNode.appendChild(demoIframe);
+
+		this.demoTabContainer.addChild(liveDemo);
+		demoIframe.parentNode.style.display="inline";
+		demoIframe.parentNode.parentNode.style.overflow="hidden";
+		dojo.io.bind({
+			url: this.registry.definitions[demo].url,
+			mimetype: "text/plain",
+			load: dojo.lang.hitch(this, function(type,data,e) {
+				source = document.createElement("textarea");
+				source.appendChild(document.createTextNode(data));
+				var sourcePane = dojo.widget.createWidget("ContentPane",{label: "Source"});
+				source.rows="20";
+				sourcePane.domNode.appendChild(source);
+				this.demoTabContainer.addChild(sourcePane);
+				dojo.style.show(sourcePane.domNode);
+
+				//let the text area take care of the scrolling 
+				sourcePane.domNode.style.overflow="hidden";
+				
+			})
+		});
+
+		this.demoTabContainer.selectTab(liveDemo);
+	},
+
+	expandDemoNavigation: function(e) {
+		dojo.debug("re expanding navigation");
+		//dojo.style.hide(this.demoContainerNode);
+		//explode = dojo.lfx.html.explode(this.navigationNode,this.collapseToNode,1000);
+		//dojo.style.show(this.navigationNode);
+		//hide = dojo.lfx.html.fadeHide(this.demoContainerNode,250);
+
+		show = dojo.lfx.html.fadeShow(this.navigationNode, 1000);
+		hide = dojo.lfx.html.fadeHide(this.demoContainerNode, 1000);
+		dojo.lfx.combine(show,hide).play();
+	}
+});
+
+dojo.widget.tags.addParseTreeHandler("dojo:DemoEngine");

Added: incubator/xap/trunk/src/dojo/src/widget/html/DocPane.js
URL: http://svn.apache.org/viewvc/incubator/xap/trunk/src/dojo/src/widget/html/DocPane.js?rev=417618&view=auto
==============================================================================
--- incubator/xap/trunk/src/dojo/src/widget/html/DocPane.js (added)
+++ incubator/xap/trunk/src/dojo/src/widget/html/DocPane.js Tue Jun 27 15:48:54 2006
@@ -0,0 +1,162 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.html.DocPane");
+
+dojo.require("dojo.widget.*");
+dojo.require("dojo.io.*");
+dojo.require("dojo.event.*");
+dojo.require("dojo.widget.HtmlWidget");
+
+dojo.widget.html.DocPane = function(){
+	dojo.widget.HtmlWidget.call(this);
+
+	this.templatePath = dojo.uri.dojoUri("src/widget/templates/HtmlDocPane.html");
+	this.templateCSSPath = dojo.uri.dojoUri("src/widget/templates/HtmlDocPane.css");
+	this.widgetType = "DocPane";
+	this.isContainer = true;
+
+	this.select;
+	this.result;
+	this.fn;
+	this.fnLink;
+	this.count;
+	this.row;
+	this.summary;
+	this.description;
+	this.variables;
+	this.vRow;
+	this.vLink;
+	this.vDesc;
+	this.parameters;
+	this.pRow;
+	this.pLink;
+	this.pDesc;
+	this.pOpt;
+	this.pType;
+	this.source;
+
+	dojo.event.topic.subscribe("docResults", this, "onDocResults");
+	dojo.event.topic.subscribe("docFunctionDetail", this, "onDocSelectFunction");
+}
+
+dojo.inherits(dojo.widget.html.DocPane, dojo.widget.HtmlWidget);
+
+dojo.lang.extend(dojo.widget.html.DocPane, {
+	fillInTemplate: function(){
+		this.homeSave = this.containerNode.cloneNode(true);
+		this.selectSave = dojo.dom.removeNode(this.select);
+		this.resultSave = dojo.dom.removeNode(this.result);
+		this.rowParent = this.row.parentNode;
+		this.rowSave = dojo.dom.removeNode(this.row);
+		this.vParent = this.vRow.parentNode;
+		this.vSave = dojo.dom.removeNode(this.vRow);
+		this.pParent = this.pRow.parentNode;
+		this.pSave = dojo.dom.removeNode(this.pRow);
+	},
+
+	onDocSelectFunction: function(message){
+		var appends = [];
+		dojo.dom.removeChildren(this.domNode);
+		this.fn.innerHTML = message.name;
+		this.description.innerHTML = message.doc.description;
+
+		this.variables.style.display = "block";
+		var all = [];
+		if(message.meta){
+			if(message.meta.variables){
+				all = message.meta.variables;
+			}
+			if(message.meta.this_variables){
+				all = all.concat(message.meta.this_variables);
+			}
+			if(message.meta.child_variables){
+				all = all.concat(message.meta.child_variables);
+			}
+		}
+		if(!all.length){
+			this.variables.style.display = "none";
+		}else{
+			for(var i = 0, one; one = all[i]; i++){
+				this.vLink.innerHTML = one;
+				this.vDesc.parentNode.style.display = "none";
+				appends.push(this.vParent.appendChild(this.vSave.cloneNode(true)));
+			}
+		}
+		
+		this.parameters.style.display = "none";
+		for(var param in message.meta.params){
+			this.parameters.style.display = "block";		
+			this.pLink.innerHTML = param;
+			this.pOpt.style.display = "none";
+			if(message.meta.params[param].opt){
+				this.pOpt.style.display = "inline";				
+			}
+			this.pType.parentNode.style.display = "none";
+			if(message.meta.params[param].type){
+				this.pType.parentNode.style.display = "inline";
+				this.pType.innerHTML = message.meta.params[param].type;
+			}
+			this.pDesc.parentNode.style.display = "none";			
+			if(message.doc.parameters[param] && message.doc.parameters[param].description){
+				this.pDesc.parentNode.style.display = "inline";
+				this.pDesc.innerHTML = message.doc.parameters[param].description;
+			}
+			appends.push(this.pParent.appendChild(this.pSave.cloneNode(true)));
+		}
+
+		dojo.dom.removeChildren(this.source);
+		this.source.appendChild(document.createTextNode(message.meta.sig + "{\r\n\t" + message.src.replace(/\n/g, "\r\n\t") + "\r\n}"));
+		
+		this.domNode.appendChild(this.selectSave.cloneNode(true));
+
+		for(var i = 0, append; append = appends[i]; i++){
+			dojo.dom.removeNode(append);
+		}
+	},
+
+	onDocResults: function(message){
+		dojo.dom.removeChildren(this.domNode);
+
+		this.count.innerHTML = message.docResults.length;
+		var appends = [];
+		for(var i = 0, row; row = message.docResults[i]; i++){
+			this.fnLink.innerHTML = row.name;
+			this.fnLink.href = "#" + row.name;
+			if(row.id){
+				this.fnLink.href = this.fnLink.href + "," + row.id;	
+			}
+			this.summary.parentNode.style.display = "none";
+			if(row.summary){
+				this.summary.parentNode.style.display = "inline";				
+				this.summary.innerHTML = row.summary;
+			}
+			appends.push(this.rowParent.appendChild(this.rowSave.cloneNode(true)));
+		}
+		
+		function makeSelect(x){
+			return function(e) {
+				dojo.event.topic.publish("docSelectFunction", x);
+			}
+		}
+
+		this.domNode.appendChild(this.resultSave.cloneNode(true));
+		var as = this.domNode.getElementsByTagName("a");
+		for(var i = 0, a; a = as[i]; i++){
+			dojo.event.connect(a, "onclick", makeSelect(message.docResults[i]));
+		}
+		
+		for(var i = 0, append; append = appends[i]; i++){
+			this.rowParent.removeChild(append);
+		}
+	}
+});
+
+dojo.widget.tags.addParseTreeHandler("dojo:DocPane");

Propchange: incubator/xap/trunk/src/dojo/src/widget/html/DocPane.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/xap/trunk/src/dojo/src/widget/html/GoogleMap.js
URL: http://svn.apache.org/viewvc/incubator/xap/trunk/src/dojo/src/widget/html/GoogleMap.js?rev=417618&view=auto
==============================================================================
--- incubator/xap/trunk/src/dojo/src/widget/html/GoogleMap.js (added)
+++ incubator/xap/trunk/src/dojo/src/widget/html/GoogleMap.js Tue Jun 27 15:48:54 2006
@@ -0,0 +1,181 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.html.GoogleMap");
+dojo.require("dojo.event.*");
+dojo.require("dojo.html");
+dojo.require("dojo.math");
+dojo.require("dojo.widget.HtmlWidget");
+dojo.require("dojo.widget.GoogleMap");
+
+(function(){
+	var gkey = djConfig["gMapKey"]||djConfig["googleMapKey"];
+	if(!dojo.hostenv.post_load_){
+		var tag = "<scr"+"ipt src='http://maps.google.com/maps?file=api&amp;v=2&amp;key="+gkey+"'></scri"+"pt>";
+		if(!dj_global["GMap2"]){ // prevent multi-inclusion
+			document.write(tag);
+		}
+	}else{
+		dojo.debug("cannot initialize map system after the page has been loaded! Please either manually include the script block provided by Google in your page or require() the GoogleMap widget before onload has fired");
+	}
+})();
+
+dojo.widget.html.GoogleMap=function(){
+	dojo.widget.HtmlWidget.call(this);
+	dojo.widget.GoogleMap.call(this);
+
+	var gm=dojo.widget.GoogleMap;
+
+	this.map=null;
+	this.data=[];
+	this.datasrc="";
+	// FIXME: this is pehraps the stupidest way to specify this enum I can think of
+	this.controls=[gm.Controls.LargeMap,gm.Controls.Scale,gm.Controls.MapType];
+};
+dojo.inherits(dojo.widget.html.GoogleMap, dojo.widget.HtmlWidget);
+
+dojo.lang.extend(dojo.widget.html.GoogleMap, {
+	templatePath:null,
+	templateCssPath:null,
+
+	setControls:function(){
+		var c=dojo.widget.GoogleMap.Controls;
+		for(var i=0; i<this.controls.length; i++){
+			var type=this.controls[i];
+			switch(type){
+				case c.LargeMap:{
+					this.map.addControl(new GLargeMapControl());
+					break;
+				}
+				case c.SmallMap:{
+					this.map.addControl(new GSmallMapControl());
+					break;
+				}
+				case c.SmallZoom:{
+					this.map.addControl(new GSmallZoomControl());
+					break;
+				}
+				case c.Scale:{
+					this.map.addControl(new GScaleControl());
+					break;
+				}
+				case c.MapType:{
+					this.map.addControl(new GMapTypeControl());
+					break;
+				}
+				case c.Overview:{
+					this.map.addControl(new GOverviewMapControl());
+					break;
+				}
+				default:{
+					break;
+				}
+			}
+		}
+	},
+	
+	findCenter:function(bounds){
+		var clat=(bounds.getNorthEast().lat()+bounds.getSouthWest().lat())/2;
+		var clng=(bounds.getNorthEast().lng()+bounds.getSouthWest().lng())/2;
+		return (new GLatLng(clat,clng));
+	},
+
+	createPinpoint:function(pt,overlay){
+		var m=new GMarker(pt);
+		if(overlay){
+			GEvent.addListener(m,"click",function(){
+				m.openInfoWindowHtml("<div>"+overlay+"</div>");
+			});
+		}
+		return m;
+	},
+
+	parse:function(table){
+		this.data=[];
+
+		//	get the column indices
+		var h=table.getElementsByTagName("thead")[0];
+		if(!h){
+			return;
+		}
+
+		var a=[];
+		var cols=h.getElementsByTagName("td");
+		if(cols.length==0){
+			cols=h.getElementsByTagName("th");
+		}
+		for(var i=0; i<cols.length; i++){
+			var c=cols[i].innerHTML.toLowerCase();
+			if(c=="long") c="lng";
+			a.push(c);
+		}
+		
+		//	parse the data
+		var b=table.getElementsByTagName("tbody")[0];
+		if(!b){
+			return;
+		}
+		for(var i=0; i<b.childNodes.length; i++){
+			if(!(b.childNodes[i].nodeName&&b.childNodes[i].nodeName.toLowerCase()=="tr")){
+				continue;
+			}
+			var cells=b.childNodes[i].getElementsByTagName("td");
+			var o={};
+			for(var j=0; j<a.length; j++){
+				var col=a[j];
+				if(col=="lat"||col=="lng"){
+					o[col]=parseFloat(cells[j].innerHTML);					
+				}else{
+					o[col]=cells[j].innerHTML;
+				}
+			}
+			this.data.push(o);
+		}
+	},
+	render:function(){
+		var bounds=new GLatLngBounds();
+		var d=this.data;
+		var pts=[];
+		for(var i=0; i<d.length; i++){
+			bounds.extend(new GLatLng(d[i].lat,d[i].lng));
+		}
+
+		this.map.setCenter(this.findCenter(bounds), this.map.getBoundsZoomLevel(bounds));
+
+		for(var i=0; i<this.data.length; i++){
+			var p=new GLatLng(this.data[i].lat,this.data[i].lng);
+			var d=this.data[i].description||null;
+			var m=this.createPinpoint(p,d);
+			this.map.addOverlay(m);
+		}
+	},
+	
+
+	initialize:function(args, frag){
+		if(!GMap2){
+			dojo.raise("dojo.widget.GoogleMap: The Google Map script must be included (with a proper API key) in order to use this widget.");
+		}
+		if(this.datasrc){
+			this.parse(dojo.byId(this.datasrc));
+		}
+		else if(this.domNode.getElementsByTagName("table")[0]){
+			this.parse(this.domNode.getElementsByTagName("table")[0]);
+		}
+	},
+	postCreate:function(){
+		//	clean the domNode before creating the map.
+		while(this.domNode.childNodes.length>0){
+			this.domNode.removeChild(this.domNode.childNodes[0]);
+		}
+		this.map=new GMap2(this.domNode);
+		this.render();
+		this.setControls();
+	}
+});

Added: incubator/xap/trunk/src/dojo/src/widget/html/LinkPane.js
URL: http://svn.apache.org/viewvc/incubator/xap/trunk/src/dojo/src/widget/html/LinkPane.js?rev=417618&view=auto
==============================================================================
--- incubator/xap/trunk/src/dojo/src/widget/html/LinkPane.js (added)
+++ incubator/xap/trunk/src/dojo/src/widget/html/LinkPane.js Tue Jun 27 15:48:54 2006
@@ -0,0 +1,60 @@
+/*
+	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.LinkPane");
+dojo.provide("dojo.widget.html.LinkPane");
+
+//
+// a div that loads from a URL.  (Similar to an iframe, but
+// it's in the same environment as the main window)
+//
+
+dojo.require("dojo.widget.LinkPane");
+dojo.require("dojo.widget.*");
+dojo.require("dojo.event.*");
+dojo.require("dojo.io.*");
+dojo.require("dojo.widget.ContentPane");
+dojo.require("dojo.html");
+dojo.require("dojo.style");
+dojo.require("dojo.dom");
+dojo.require("dojo.string");
+
+
+dojo.widget.html.LinkPane = function(){
+	dojo.widget.html.ContentPane.call(this);
+}
+
+dojo.inherits(dojo.widget.html.LinkPane, dojo.widget.html.ContentPane);
+
+dojo.lang.extend(dojo.widget.html.LinkPane, {
+	widgetType: "LinkPane",
+
+	// I'm using a template because the user may specify the input as
+	// <a href="foo.html">label</a>, in which case we need to get rid of the
+	// <a> because we don't want a link.
+	templateString: '<div class="dojoLinkPane"></div>',
+
+	fillInTemplate: function(args, frag){
+		var source = this.getFragNodeRef(frag);
+
+		// If user has specified node contents, they become the label
+		// (the link must be plain text)
+		this.label += source.innerHTML;
+
+		// Copy style info from input node to output node
+		// get around opera wich doesnt have cssText, and IE wich bugs on setAttribute
+		if(dojo.lang.isUndefined(source.style.cssText)){
+			this.domNode.setAttribute("style", source.getAttribute("style"));
+		}else{
+			this.domNode.style.cssText = source.style.cssText;
+		}
+		dojo.html.addClass(this.domNode, dojo.html.getClass(source));
+	}
+});

Added: incubator/xap/trunk/src/dojo/src/widget/html/Menu.js
URL: http://svn.apache.org/viewvc/incubator/xap/trunk/src/dojo/src/widget/html/Menu.js?rev=417618&view=auto
==============================================================================
--- incubator/xap/trunk/src/dojo/src/widget/html/Menu.js (added)
+++ incubator/xap/trunk/src/dojo/src/widget/html/Menu.js Tue Jun 27 15:48:54 2006
@@ -0,0 +1,51 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.require("dojo.widget.Menu");
+dojo.provide("dojo.widget.html.Menu");
+
+/* HtmlMenu
+ ***********/
+ 
+dojo.widget.html.Menu = function(){
+	dojo.widget.html.Menu.superclass.constructor.call(this);
+	this.items = [];
+}
+dojo.inherits(dojo.widget.html.Menu, dojo.widget.HtmlWidget);
+
+dojo.lang.extend(dojo.widget.html.Menu, {
+	widgetType: "Menu",
+	isContainer: true,
+
+	// copy children widgets output directly to parent (this node), to avoid
+	// errors trying to insert an <li> under a <div>
+	snarfChildDomOutput: true,
+
+	templateString: '<ul></ul>',
+	templateCssPath: dojo.uri.dojoUri("src/widget/templates/Menu.css"),
+	
+	fillInTemplate: function (args, frag){
+		//dojo.widget.HtmlMenu.superclass.fillInTemplate.apply(this, arguments);
+		this.domNode.className = "dojoMenu";
+	},
+	
+ 
+	_register: function (item ) {
+		dojo.event.connect(item, "onSelect", this, "onSelect");
+		this.items.push(item);
+	},
+
+	push: function (item) {
+		this.domNode.appendChild(item.domNode);
+		this._register(item);
+	}
+
+});
+

Propchange: incubator/xap/trunk/src/dojo/src/widget/html/Menu.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/xap/trunk/src/dojo/src/widget/html/MenuItem.js
URL: http://svn.apache.org/viewvc/incubator/xap/trunk/src/dojo/src/widget/html/MenuItem.js?rev=417618&view=auto
==============================================================================
--- incubator/xap/trunk/src/dojo/src/widget/html/MenuItem.js (added)
+++ incubator/xap/trunk/src/dojo/src/widget/html/MenuItem.js Tue Jun 27 15:48:54 2006
@@ -0,0 +1,60 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.html.MenuItem");
+
+/* HtmlMenuItem
+ ***************/
+
+dojo.widget.html.MenuItem = function(){
+	dojo.widget.HtmlWidget.call(this);
+}
+dojo.inherits(dojo.widget.html.MenuItem, dojo.widget.HtmlWidget);
+
+dojo.lang.extend(dojo.widget.html.MenuItem, {
+	widgetType: "MenuItem",
+	templateString: '<li class="dojoMenuItem" dojoAttachEvent="onMouseOver; onMouseOut; onMouseDown; onMouseUp; onClick;"></li>',
+	title: "",
+
+	fillInTemplate: function(args, frag){
+		dojo.html.disableSelection(this.domNode);
+
+		if(!dojo.string.isBlank(this.title)){
+			this.domNode.appendChild(document.createTextNode(this.title));
+		}else{
+			this.domNode.appendChild(frag["dojo:"+this.widgetType.toLowerCase()]["nodeRef"]);
+		}
+	},
+	
+	onMouseOver: function(e){
+		dojo.html.addClass(this.domNode, "dojoMenuItemHover");
+	},
+	
+	onMouseOut: function(e){
+		dojo.html.removeClass(this.domNode, "dojoMenuItemHover");
+	},
+	
+	onClick: function(e){ this.onSelect(this, e); },
+	onMouseDown: function(e){},
+	onMouseUp: function(e){},
+	
+	// By default, when I am clicked, click the item inside of me
+	onSelect: function (item, e) {
+		var child = dojo.dom.getFirstChildElement(this.domNode);
+		if(child){
+			if(child.click){
+				child.click();
+			}else if(child.href){
+				location.href = child.href;
+			}
+		}
+	}
+});
+

Propchange: incubator/xap/trunk/src/dojo/src/widget/html/MenuItem.js
------------------------------------------------------------------------------
    svn:eol-style = native