You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by ja...@apache.org on 2007/02/19 18:56:37 UTC

svn commit: r509273 [32/50] - in /ofbiz/trunk/framework/images/webapp/images: ./ dojo/ dojo/src/ dojo/src/animation/ dojo/src/cal/ dojo/src/charting/ dojo/src/charting/svg/ dojo/src/charting/vml/ dojo/src/collections/ dojo/src/crypto/ dojo/src/data/ do...

Added: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/DomWidget.js
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/DomWidget.js?view=auto&rev=509273
==============================================================================
--- ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/DomWidget.js (added)
+++ ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/DomWidget.js Mon Feb 19 09:56:06 2007
@@ -0,0 +1,902 @@
+/*
+	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.DomWidget");
+
+dojo.require("dojo.event.*");
+dojo.require("dojo.widget.Widget");
+dojo.require("dojo.dom");
+dojo.require("dojo.html.style");
+dojo.require("dojo.xml.Parse");
+dojo.require("dojo.uri.*");
+dojo.require("dojo.lang.func");
+dojo.require("dojo.lang.extras");
+
+dojo.widget._cssFiles = {};
+dojo.widget._cssStrings = {};
+dojo.widget._templateCache = {};
+
+dojo.widget.defaultStrings = {
+	// summary: a mapping of strings that are used in template variable replacement
+	dojoRoot: dojo.hostenv.getBaseScriptUri(),
+	baseScriptUri: dojo.hostenv.getBaseScriptUri()
+};
+
+dojo.widget.fillFromTemplateCache = function(obj, templatePath, templateString, avoidCache){
+	// summary:
+	//		static method to build from a template w/ or w/o a real widget in
+	//		place
+	// obj: DomWidget
+	//		an instance of dojo.widget.DomWidget to initialize the template for
+	// templatePath: String
+	//		the URL to get the template from. dojo.uri.Uri is often passed as well.
+	// templateString: String?
+	//		a string to use in lieu of fetching the template from a URL
+	// avoidCache: Boolean?
+	//		should the template system not use whatever is in the cache and
+	//		always use the passed templatePath or templateString?
+
+	// dojo.debug("avoidCache:", avoidCache);
+	var tpath = templatePath || obj.templatePath;
+
+	var tmplts = dojo.widget._templateCache;
+	if(!tpath && !obj["widgetType"]) { // don't have a real template here
+		do {
+			var dummyName = "__dummyTemplate__" + dojo.widget._templateCache.dummyCount++;
+		} while(tmplts[dummyName]);
+		obj.widgetType = dummyName;
+	}
+	var wt = tpath?tpath.toString():obj.widgetType;
+
+	var ts = tmplts[wt];
+	if(!ts){
+		tmplts[wt] = {"string": null, "node": null};
+		if(avoidCache){
+			ts = {};
+		}else{
+			ts = tmplts[wt];
+		}
+	}
+	if((!obj.templateString)&&(!avoidCache)){
+		obj.templateString = templateString || ts["string"];
+	}
+	if((!obj.templateNode)&&(!avoidCache)){
+		obj.templateNode = ts["node"];
+	}
+	if((!obj.templateNode)&&(!obj.templateString)&&(tpath)){
+		// fetch a text fragment and assign it to templateString
+		// NOTE: we rely on blocking IO here!
+		var tstring = dojo.hostenv.getText(tpath);
+		if(tstring){
+			// strip <?xml ...?> declarations so that external SVG and XML
+			// documents can be added to a document without worry
+			tstring = tstring.replace(/^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im, "");
+			var matches = tstring.match(/<body[^>]*>\s*([\s\S]+)\s*<\/body>/im);
+			if(matches){
+				tstring = matches[1];
+			}
+		}else{
+			tstring = "";
+		}
+
+		obj.templateString = tstring;
+		if(!avoidCache){
+			tmplts[wt]["string"] = tstring;
+		}
+	}
+	if((!ts["string"])&&(!avoidCache)){
+		ts.string = obj.templateString;
+	}
+}
+dojo.widget._templateCache.dummyCount = 0;
+
+// Array: list of properties to search for node-to-property mappings
+dojo.widget.attachProperties = ["dojoAttachPoint", "id"];
+
+// String: name of the property to use for mapping DOM events to widget functions
+dojo.widget.eventAttachProperty = "dojoAttachEvent";
+
+// String: property name of code to evaluate when the widget is constructed
+dojo.widget.onBuildProperty = "dojoOnBuild";
+
+// Array:  possible accessibility values to set on widget elements - role or state
+dojo.widget.waiNames  = ["waiRole", "waiState"];
+
+dojo.widget.wai = {
+	// summary: Contains functions to set accessibility roles and states
+	//		onto widget elements
+	waiRole: { 	
+				// name: String:
+				//		information for mapping accessibility role
+				name: "waiRole", 
+				// namespace: String:
+				//		URI of the namespace for the set of roles
+				"namespace": "http://www.w3.org/TR/xhtml2", 
+				// alias: String:
+				//		The alias to assign the namespace
+				alias: "x2",
+				// prefix: String:
+				//		The prefix to assign to the role value
+				prefix: "wairole:"
+	},
+	waiState: { 
+				// name: String:
+				//		information for mapping accessibility state
+				name: "waiState", 
+				// namespace: String:
+				//		URI of the namespace for the set of states
+				"namespace": "http://www.w3.org/2005/07/aaa", 
+				// alias: String:
+				//		The alias to assign the namespace
+				alias: "aaa",
+				// prefix: String:
+				//		empty string - state value does not require prefix
+				prefix: ""
+	},
+	setAttr: function(/*DomNode*/node, /*String*/ ns, /*String*/ attr, /*String|Boolean*/value){
+		// summary: Use appropriate API to set the role or state attribute onto the element.
+		// description: In IE use the generic setAttribute() api.  Append a namespace
+		//   alias to the attribute name and appropriate prefix to the value. 
+		//   Otherwise, use the setAttribueNS api to set the namespaced attribute. Also
+		//   add the appropriate prefix to the attribute value.
+		if(dojo.render.html.ie){
+			node.setAttribute(this[ns].alias+":"+ attr, this[ns].prefix+value);
+		}else{
+			node.setAttributeNS(this[ns]["namespace"], attr, this[ns].prefix+value);
+		}
+	},
+
+	getAttr: function(/*DomNode*/ node, /*String*/ ns, /*String|Boolena*/ attr){
+		// Summary:  Use the appropriate API to retrieve the role or state value
+		// Description: In IE use the generic getAttribute() api.  An alias value 
+		// 	was added to the attribute name to simulate a namespace when the attribute
+		//  was set.  Otherwise use the getAttributeNS() api to retrieve the state value
+		if(dojo.render.html.ie){
+			return node.getAttribute(this[ns].alias+":"+attr);
+		}else{
+			return node.getAttributeNS(this[ns]["namespace"], attr);
+		}
+	},
+	removeAttr: function(/*DomNode*/ node, /*String*/ ns, /*String|Boolena*/ attr){
+		// summary:  Use the appropriate API to remove the role or state value
+		// description: In IE use the generic removeAttribute() api.  An alias value 
+		// 	was added to the attribute name to simulate a namespace when the attribute
+		//  was set.  Otherwise use the removeAttributeNS() api to remove the state value
+		var success = true; //only IE returns a value
+		if(dojo.render.html.ie){
+			 success = node.removeAttribute(this[ns].alias+":"+attr);
+		}else{
+			node.removeAttributeNS(this[ns]["namespace"], attr);
+		}
+		return success;
+	}
+};
+
+dojo.widget.attachTemplateNodes = function(rootNode, /*Widget*/ targetObj, events ){
+	// summary:
+	//		map widget properties and functions to the handlers specified in
+	//		the dom node and it's descendants. This function iterates over all
+	//		nodes and looks for these properties:
+	//			* dojoAttachPoint
+	//			* dojoAttachEvent	
+	//			* waiRole
+	//			* waiState
+	//			* any "dojoOn*" proprties passed in the events array
+	// rootNode: DomNode
+	//		the node to search for properties. All children will be searched.
+	// events: Array
+	//		a list of properties generated from getDojoEventsFromStr.
+
+	// FIXME: this method is still taking WAAAY too long. We need ways of optimizing:
+	//	a.) what we are looking for on each node
+	//	b.) the nodes that are subject to interrogation (use xpath instead?)
+	//	c.) how expensive event assignment is (less eval(), more connect())
+	// var start = new Date();
+	var elementNodeType = dojo.dom.ELEMENT_NODE;
+
+	function trim(str){
+		return str.replace(/^\s+|\s+$/g, "");
+	}
+
+	if(!rootNode){ 
+		rootNode = targetObj.domNode;
+	}
+
+	if(rootNode.nodeType != elementNodeType){
+		return;
+	}
+	// alert(events.length);
+
+	var nodes = rootNode.all || rootNode.getElementsByTagName("*");
+	var _this = targetObj;
+	for(var x=-1; x<nodes.length; x++){
+		var baseNode = (x == -1) ? rootNode : nodes[x];
+		// FIXME: is this going to have capitalization problems?  Could use getAttribute(name, 0); to get attributes case-insensitve
+		var attachPoint = [];
+		if(!targetObj.widgetsInTemplate || !baseNode.getAttribute('dojoType')){
+			for(var y=0; y<this.attachProperties.length; y++){
+				var tmpAttachPoint = baseNode.getAttribute(this.attachProperties[y]);
+				if(tmpAttachPoint){
+					attachPoint = tmpAttachPoint.split(";");
+					for(var z=0; z<attachPoint.length; z++){
+						if(dojo.lang.isArray(targetObj[attachPoint[z]])){
+							targetObj[attachPoint[z]].push(baseNode);
+						}else{
+							targetObj[attachPoint[z]]=baseNode;
+						}
+					}
+					break;
+				}
+			}
+
+			var attachEvent = baseNode.getAttribute(this.eventAttachProperty);
+			if(attachEvent){
+				// NOTE: we want to support attributes that have the form
+				// "domEvent: nativeEvent; ..."
+				var evts = attachEvent.split(";");
+				for(var y=0; y<evts.length; y++){
+					if((!evts[y])||(!evts[y].length)){ continue; }
+					var thisFunc = null;
+					var tevt = trim(evts[y]);
+					if(evts[y].indexOf(":") >= 0){
+						// oh, if only JS had tuple assignment
+						var funcNameArr = tevt.split(":");
+						tevt = trim(funcNameArr[0]);
+						thisFunc = trim(funcNameArr[1]);
+					}
+					if(!thisFunc){
+						thisFunc = tevt;
+					}
+	
+					var tf = function(){ 
+						var ntf = new String(thisFunc);
+						return function(evt){
+							if(_this[ntf]){
+								_this[ntf](dojo.event.browser.fixEvent(evt, this));
+							}
+						};
+					}();
+					dojo.event.browser.addListener(baseNode, tevt, tf, false, true);
+					// dojo.event.browser.addListener(baseNode, tevt, dojo.lang.hitch(_this, thisFunc));
+				}
+			}
+	
+			for(var y=0; y<events.length; y++){
+				//alert(events[x]);
+				var evtVal = baseNode.getAttribute(events[y]);
+				if((evtVal)&&(evtVal.length)){
+					var thisFunc = null;
+					var domEvt = events[y].substr(4); // clober the "dojo" prefix
+					thisFunc = trim(evtVal);
+					var funcs = [thisFunc];
+					if(thisFunc.indexOf(";")>=0){
+						funcs = dojo.lang.map(thisFunc.split(";"), trim);
+					}
+					for(var z=0; z<funcs.length; z++){
+						if(!funcs[z].length){ continue; }
+						var tf = function(){ 
+							var ntf = new String(funcs[z]);
+							return function(evt){
+								if(_this[ntf]){
+									_this[ntf](dojo.event.browser.fixEvent(evt, this));
+								}
+							}
+						}();
+						dojo.event.browser.addListener(baseNode, domEvt, tf, false, true);
+						// dojo.event.browser.addListener(baseNode, domEvt, dojo.lang.hitch(_this, funcs[z]));
+					}
+				}
+			}
+		}
+		// continue;
+
+		// FIXME: we need to put this into some kind of lookup structure
+		// instead of direct assignment
+		var tmpltPoint = baseNode.getAttribute(this.templateProperty);
+		if(tmpltPoint){
+			targetObj[tmpltPoint]=baseNode;
+		}
+
+		dojo.lang.forEach(dojo.widget.waiNames, function(name){
+			var wai = dojo.widget.wai[name];
+			var val = baseNode.getAttribute(wai.name);
+			if(val){
+				if(val.indexOf('-') == -1){ 
+					dojo.widget.wai.setAttr(baseNode, wai.name, "role", val);
+				}else{
+					// this is a state-value pair
+					var statePair = val.split('-');
+					dojo.widget.wai.setAttr(baseNode, wai.name, statePair[0], statePair[1]);
+				}
+			}
+		}, this);
+
+		var onBuild = baseNode.getAttribute(this.onBuildProperty);
+		if(onBuild){
+			eval("var node = baseNode; var widget = targetObj; "+onBuild);
+		}
+	}
+
+}
+
+dojo.widget.getDojoEventsFromStr = function(str){
+	// summary:
+	//		generates a list of properties with names that match the form
+	//		dojoOn*
+	// str: String
+	//		the template string to search
+	
+	// var lstr = str.toLowerCase();
+	var re = /(dojoOn([a-z]+)(\s?))=/gi;
+	var evts = str ? str.match(re)||[] : [];
+	var ret = [];
+	var lem = {};
+	for(var x=0; x<evts.length; x++){
+		if(evts[x].length < 1){ continue; }
+		var cm = evts[x].replace(/\s/, "");
+		cm = (cm.slice(0, cm.length-1));
+		if(!lem[cm]){
+			lem[cm] = true;
+			ret.push(cm);
+		}
+	}
+	return ret; // Array
+}
+
+dojo.declare("dojo.widget.DomWidget", 
+	dojo.widget.Widget,
+	function(){
+		// summary:
+		//		dojo.widget.DomWidget is the superclass that provides behavior for all
+		//		DOM-based renderers, including HtmlWidget and SvgWidget. DomWidget
+		//		implements the templating system that most widget authors use to define
+		//		the UI for their widgets.
+		if((arguments.length>0)&&(typeof arguments[0] == "object")){
+			this.create(arguments[0]);
+		}
+	},
+	{							 
+		// templateNode: DomNode
+		//		a node that represents the widget template. Pre-empts both templateString and templatePath.
+		templateNode: null,
+
+		// templateString String:
+		//		a string that represents the widget template. Pre-empts the
+		//		templatePath. In builds that have their strings "interned", the
+		//		templatePath is converted to an inline templateString, thereby
+		//		preventing a synchronous network call.
+		templateString: null,
+
+		// templateCssString String:
+		//		a string that represents the CSS for the widgettemplate.
+		//		Pre-empts the templateCssPath. In builds that have their
+		//		strings "interned", the templateCssPath is converted to an
+		//		inline templateCssString, thereby preventing a synchronous
+		//		network call.
+		templateCssString: null,
+
+		// preventClobber Boolean:
+		//		should the widget not replace the node from which it was
+		//		constructed? Widgets that apply behaviors to pre-existing parts
+		//		of a page can be implemented easily by setting this to "true".
+		//		In these cases, the domNode property will point to the node
+		//		which the widget was created from.
+		preventClobber: false,
+
+		// domNode DomNode:
+		//		this is our visible representation of the widget! Other DOM
+		//		Nodes may by assigned to other properties, usually through the
+		//		template system's dojoAttachPonit syntax, but the domNode
+		//		property is the canonical "top level" node in widget UI.
+		domNode: null, 
+
+		// containerNode DomNode:
+		//		holds child elements. "containerNode" is generally set via a
+		//		dojoAttachPoint assignment and it designates where widgets that
+		//		are defined as "children" of the parent will be placed
+		//		visually.
+		containerNode: null,
+
+		// widgetsInTemplate Boolean:
+		//		should we parse the template to find widgets that might be
+		//		declared in markup inside it? false by default.
+		widgetsInTemplate: false,
+
+		addChild: function(/*Widget*/	widget, overrideContainerNode, pos, ref, insertIndex){
+			// summary:
+			//		Process the given child widget, inserting it's dom node as
+			//		a child of our dom node
+			// overrideContainerNode: DomNode?
+			//		a non-default container node for the widget
+			// pos: String?
+			//		can be one of "before", "after", "first", or "last". This
+			//		has the same meaning as in dojo.dom.insertAtPosition()
+			// ref: DomNode?
+			//		a node to place the widget relative to
+			// insertIndex: int?
+			//		DOM index, same meaning as in dojo.dom.insertAtIndex()
+			// returns: the widget that was inserted
+
+			// FIXME: should we support addition at an index in the children arr and
+			// order the display accordingly? Right now we always append.
+			if(!this.isContainer){ // we aren't allowed to contain other widgets, it seems
+				dojo.debug("dojo.widget.DomWidget.addChild() attempted on non-container widget");
+				return null;
+			}else{
+				if(insertIndex == undefined){
+					insertIndex = this.children.length;
+				}
+				this.addWidgetAsDirectChild(widget, overrideContainerNode, pos, ref, insertIndex);
+				this.registerChild(widget, insertIndex);
+			}
+			return widget; // Widget
+		},
+		
+		addWidgetAsDirectChild: function(/*Widget*/	widget, overrideContainerNode, pos, ref, insertIndex){
+			// summary:
+			//		Process the given child widget, inserting it's dom node as
+			//		a child of our dom node
+			// overrideContainerNode: DomNode
+			//		a non-default container node for the widget
+			// pos: String?
+			//		can be one of "before", "after", "first", or "last". This
+			//		has the same meaning as in dojo.dom.insertAtPosition()
+			// ref: DomNode?
+			//		a node to place the widget relative to
+			// insertIndex: int?
+			//		DOM index, same meaning as in dojo.dom.insertAtIndex()
+			if((!this.containerNode)&&(!overrideContainerNode)){
+				this.containerNode = this.domNode;
+			}
+			var cn = (overrideContainerNode) ? overrideContainerNode : this.containerNode;
+			if(!pos){ pos = "after"; }
+			if(!ref){ 
+				if(!cn){ cn = dojo.body(); }
+				ref = cn.lastChild; 
+			}
+			if(!insertIndex) { insertIndex = 0; }
+			widget.domNode.setAttribute("dojoinsertionindex", insertIndex);
+
+			// insert the child widget domNode directly underneath my domNode, in the
+			// specified position (by default, append to end)
+			if(!ref){
+				cn.appendChild(widget.domNode);
+			}else{
+				// FIXME: was this meant to be the (ugly hack) way to support insert @ index?
+				//dojo.dom[pos](widget.domNode, ref, insertIndex);
+
+				// CAL: this appears to be the intended way to insert a node at a given position...
+				if (pos == 'insertAtIndex'){
+					// dojo.debug("idx:", insertIndex, "isLast:", ref === cn.lastChild);
+					dojo.dom.insertAtIndex(widget.domNode, ref.parentNode, insertIndex);
+				}else{
+					// dojo.debug("pos:", pos, "isLast:", ref === cn.lastChild);
+					if((pos == "after")&&(ref === cn.lastChild)){
+						cn.appendChild(widget.domNode);
+					}else{
+						dojo.dom.insertAtPosition(widget.domNode, cn, pos);
+					}
+				}
+			}
+		},
+
+		registerChild: function(widget, insertionIndex){
+			// summary: record that given widget descends from me
+			// widget: Widget
+			//		the widget that is now a child
+			// insertionIndex: int
+			//		where in the children[] array to place it
+
+			// we need to insert the child at the right point in the parent's 
+			// 'children' array, based on the insertionIndex
+
+			widget.dojoInsertionIndex = insertionIndex;
+
+			var idx = -1;
+			for(var i=0; i<this.children.length; i++){
+
+				//This appears to fix an out of order issue in the case of mixed
+				//markup and programmatically added children.  Previously, if a child
+				//existed from markup, and another child was addChild()d without specifying
+				//any additional parameters, it would end up first in the list, when in fact
+				//it should be after.  I can't see cases where this would break things, but
+				//I could see no other obvious solution. -dustin
+
+				if (this.children[i].dojoInsertionIndex <= insertionIndex){
+					idx = i;
+				}
+			}
+
+			this.children.splice(idx+1, 0, widget);
+
+			widget.parent = this;
+			widget.addedTo(this, idx+1);
+			
+			// If this widget was created programatically, then it was erroneously added
+			// to dojo.widget.manager.topWidgets.  Fix that here.
+			delete dojo.widget.manager.topWidgets[widget.widgetId];
+		},
+
+		removeChild: function(/*Widget*/ widget){
+			// summary: detach child domNode from parent domNode
+			dojo.dom.removeNode(widget.domNode);
+
+			// remove child widget from parent widget 
+			return dojo.widget.DomWidget.superclass.removeChild.call(this, widget); // Widget
+		},
+
+		getFragNodeRef: function(frag){
+			// summary:
+			//		returns the source node, if any, that the widget was
+			//		declared from
+			// frag: Object
+			//		an opaque data structure generated by the first-pass parser
+			if(!frag){return null;} // null
+			if(!frag[this.getNamespacedType()]){
+				dojo.raise("Error: no frag for widget type " + this.getNamespacedType() 
+					+ ", id " + this.widgetId
+					+ " (maybe a widget has set it's type incorrectly)");
+			}
+			return frag[this.getNamespacedType()]["nodeRef"]; // DomNode
+		},
+		
+		postInitialize: function(/*Object*/ args, /*Object*/ frag, /*Widget*/ parentComp){
+			// summary:
+			//		Replace the source domNode with the generated dom
+			//		structure, and register the widget with its parent.
+			//		This is an implementation of the stub function defined in
+			//		dojo.widget.Widget.
+			
+			//dojo.profile.start(this.widgetType + " postInitialize");
+			
+			var sourceNodeRef = this.getFragNodeRef(frag);
+			// Stick my generated dom into the output tree
+			//alert(this.widgetId + ": replacing " + sourceNodeRef + " with " + this.domNode.innerHTML);
+			if (parentComp && (parentComp.snarfChildDomOutput || !sourceNodeRef)){
+				// Add my generated dom as a direct child of my parent widget
+				// This is important for generated widgets, and also cases where I am generating an
+				// <li> node that can't be inserted back into the original DOM tree
+				parentComp.addWidgetAsDirectChild(this, "", "insertAtIndex", "",  args["dojoinsertionindex"], sourceNodeRef);
+			} else if (sourceNodeRef){
+				// Do in-place replacement of the my source node with my generated dom
+				if(this.domNode && (this.domNode !== sourceNodeRef)){
+					this._sourceNodeRef = dojo.dom.replaceNode(sourceNodeRef, this.domNode);
+				}
+			}
+
+			// Register myself with my parent, or with the widget manager if
+			// I have no parent
+			// TODO: the code below erroneously adds all programatically generated widgets
+			// to topWidgets (since we don't know who the parent is until after creation finishes)
+			if ( parentComp ) {
+				parentComp.registerChild(this, args.dojoinsertionindex);
+			} else {
+				dojo.widget.manager.topWidgets[this.widgetId]=this;
+			}
+
+			if(this.widgetsInTemplate){
+				var parser = new dojo.xml.Parse();
+
+				var subContainerNode;
+				//TODO: use xpath here?
+				var subnodes = this.domNode.getElementsByTagName("*");
+				for(var i=0;i<subnodes.length;i++){
+					if(subnodes[i].getAttribute('dojoAttachPoint') == 'subContainerWidget'){
+						subContainerNode = subnodes[i];
+//						break;
+					}
+					if(subnodes[i].getAttribute('dojoType')){
+						subnodes[i].setAttribute('isSubWidget', true);
+					}
+				}
+				if (this.isContainer && !this.containerNode){
+					//no containerNode is available, which means a widget is used as a container. find it here and move
+					//all dom nodes defined in the main html page as children of this.domNode into the actual container
+					//widget's node (at this point, the subwidgets defined in the template file is not parsed yet)
+					if(subContainerNode){
+						var src = this.getFragNodeRef(frag);
+						if (src){
+							dojo.dom.moveChildren(src, subContainerNode);
+							//do not need to follow children nodes in the main html page, as they
+							//will be dealt with in the subContainerWidget
+							frag['dojoDontFollow'] = true;
+						}
+					}else{
+						dojo.debug("No subContainerWidget node can be found in template file for widget "+this);
+					}
+				}
+
+				var templatefrag = parser.parseElement(this.domNode, null, true);
+				// createSubComponents not createComponents because frag has already been created
+				dojo.widget.getParser().createSubComponents(templatefrag, this);
+	
+				//find all the sub widgets defined in the template file of this widget
+				var subwidgets = [];
+				var stack = [this];
+				var w;
+				while((w = stack.pop())){
+					for(var i = 0; i < w.children.length; i++){
+						var cwidget = w.children[i];
+						if(cwidget._processedSubWidgets || !cwidget.extraArgs['issubwidget']){ continue; }
+						subwidgets.push(cwidget);
+						if(cwidget.isContainer){
+							stack.push(cwidget);
+						}
+					}
+				}
+	
+				//connect event to this widget/attach dom node
+				for(var i = 0; i < subwidgets.length; i++){
+					var widget = subwidgets[i];
+					if(widget._processedSubWidgets){
+						dojo.debug("This should not happen: widget._processedSubWidgets is already true!");
+						return;
+					}
+					widget._processedSubWidgets = true;
+					if(widget.extraArgs['dojoattachevent']){
+						var evts = widget.extraArgs['dojoattachevent'].split(";");
+						for(var j=0; j<evts.length; j++){
+							var thisFunc = null;
+							var tevt = dojo.string.trim(evts[j]);
+							if(tevt.indexOf(":") >= 0){
+								// oh, if only JS had tuple assignment
+								var funcNameArr = tevt.split(":");
+								tevt = dojo.string.trim(funcNameArr[0]);
+								thisFunc = dojo.string.trim(funcNameArr[1]);
+							}
+							if(!thisFunc){
+								thisFunc = tevt;
+							}
+							if(dojo.lang.isFunction(widget[tevt])){
+								dojo.event.kwConnect({
+									srcObj: widget, 
+									srcFunc: tevt, 
+									targetObj: this, 
+									targetFunc: thisFunc
+								});
+							}else{
+								alert(tevt+" is not a function in widget "+widget);
+							}
+						}
+					}
+	
+					if(widget.extraArgs['dojoattachpoint']){
+						//don't attach widget.domNode here, as we do not know which
+						//dom node we should connect to (in checkbox widget case, 
+						//it is inputNode). So we make the widget itself available
+						this[widget.extraArgs['dojoattachpoint']] = widget;
+					}
+				}
+			}
+
+			//dojo.profile.end(this.widgetType + " postInitialize");
+
+			// Expand my children widgets
+			/* dojoDontFollow is important for a very special case
+			 * basically if you have a widget that you instantiate from script
+			 * and that widget is a container, and it contains a reference to a parent
+			 * instance, the parser will start recursively parsing until the browser
+			 * complains.  So the solution is to set an initialization property of 
+			 * dojoDontFollow: true and then it won't recurse where it shouldn't
+			 */
+			if(this.isContainer && !frag["dojoDontFollow"]){
+				//alert("recurse from " + this.widgetId);
+				// build any sub-components with us as the parent
+				dojo.widget.getParser().createSubComponents(frag, this);
+			}
+		},
+
+		// method over-ride
+		buildRendering: function(/*Object*/ args, /*Object*/ frag){
+			// summary:
+			//		Construct the UI for this widget, generally from a
+			//		template. This can be over-ridden for custom UI creation to
+			//		to side-step the template system.  This is an
+			//		implementation of the stub function defined in
+			//		dojo.widget.Widget.
+
+			// DOM widgets construct themselves from a template
+			var ts = dojo.widget._templateCache[this.widgetType];
+			
+			// Handle style for this widget here, as even if templatePath
+			// is not set, style specified by templateCssString or templateCssPath
+			// should be applied. templateCssString has higher priority
+			// than templateCssPath
+			if(args["templatecsspath"]){
+				args["templateCssPath"] = args["templatecsspath"];
+			}
+			var cpath = args["templateCssPath"] || this.templateCssPath;
+			if(cpath && !dojo.widget._cssFiles[cpath.toString()]){
+				if((!this.templateCssString)&&(cpath)){
+					this.templateCssString = dojo.hostenv.getText(cpath);
+					this.templateCssPath = null;
+				}
+				dojo.widget._cssFiles[cpath.toString()] = true;
+			}
+		
+			if((this["templateCssString"])&&(!dojo.widget._cssStrings[this.templateCssString])){
+				dojo.html.insertCssText(this.templateCssString, null, cpath);
+				dojo.widget._cssStrings[this.templateCssString] = true;
+			}
+			if(	
+				(!this.preventClobber)&&(
+					(this.templatePath)||
+					(this.templateNode)||
+					(
+						(this["templateString"])&&(this.templateString.length) 
+					)||
+					(
+						(typeof ts != "undefined")&&( (ts["string"])||(ts["node"]) )
+					)
+				)
+			){
+				// if it looks like we can build the thing from a template, do it!
+				this.buildFromTemplate(args, frag);
+			}else{
+				// otherwise, assign the DOM node that was the source of the widget
+				// parsing to be the root node
+				this.domNode = this.getFragNodeRef(frag);
+			}
+			this.fillInTemplate(args, frag); 	// this is where individual widgets
+												// will handle population of data
+												// from properties, remote data
+												// sets, etc.
+		},
+
+		buildFromTemplate: function(/*Object*/ args, /*Object*/ frag){
+			// summary:
+			//		Called by buildRendering, creates the actual UI in a DomWidget.
+
+			// var start = new Date();
+			// copy template properties if they're already set in the templates object
+			// dojo.debug("buildFromTemplate:", this);
+			var avoidCache = false;
+			if(args["templatepath"]){
+//				avoidCache = true;
+				args["templatePath"] = args["templatepath"];
+			}
+			dojo.widget.fillFromTemplateCache(	this, 
+												args["templatePath"], 
+												null,
+												avoidCache);
+			var ts = dojo.widget._templateCache[this.templatePath?this.templatePath.toString():this.widgetType];
+			if((ts)&&(!avoidCache)){
+				if(!this.templateString.length){
+					this.templateString = ts["string"];
+				}
+				if(!this.templateNode){
+					this.templateNode = ts["node"];
+				}
+			}
+			var matches = false;
+			var node = null;
+			// var tstr = new String(this.templateString); 
+			var tstr = this.templateString; 
+			// attempt to clone a template node, if there is one
+			if((!this.templateNode)&&(this.templateString)){
+				matches = this.templateString.match(/\$\{([^\}]+)\}/g);
+				if(matches) {
+					// if we do property replacement, don't create a templateNode
+					// to clone from.
+					var hash = this.strings || {};
+					// FIXME: should this hash of default replacements be cached in
+					// templateString?
+					for(var key in dojo.widget.defaultStrings) {
+						if(dojo.lang.isUndefined(hash[key])) {
+							hash[key] = dojo.widget.defaultStrings[key];
+						}
+					}
+					// FIXME: this is a lot of string munging. Can we make it faster?
+					for(var i = 0; i < matches.length; i++) {
+						var key = matches[i];
+						key = key.substring(2, key.length-1);
+						var kval = (key.substring(0, 5) == "this.") ? dojo.lang.getObjPathValue(key.substring(5), this) : hash[key];
+						var value;
+						if((kval)||(dojo.lang.isString(kval))){
+							value = new String((dojo.lang.isFunction(kval)) ? kval.call(this, key, this.templateString) : kval);
+							// Safer substitution, see heading "Attribute values" in  
+							// http://www.w3.org/TR/REC-html40/appendix/notes.html#h-B.3.2
+							while (value.indexOf("\"") > -1) {
+								value=value.replace("\"","&quot;");
+							}
+							tstr = tstr.replace(matches[i], value);
+						}
+					}
+				}else{
+					// otherwise, we are required to instantiate a copy of the template
+					// string if one is provided.
+					
+					// FIXME: need to be able to distinguish here what should be done
+					// or provide a generic interface across all DOM implementations
+					// FIMXE: this breaks if the template has whitespace as its first 
+					// characters
+					// node = this.createNodesFromText(this.templateString, true);
+					// this.templateNode = node[0].cloneNode(true); // we're optimistic here
+					this.templateNode = this.createNodesFromText(this.templateString, true)[0];
+					if(!avoidCache){
+						ts.node = this.templateNode;
+					}
+				}
+			}
+			if((!this.templateNode)&&(!matches)){ 
+				dojo.debug("DomWidget.buildFromTemplate: could not create template");
+				return false;
+			}else if(!matches){
+				node = this.templateNode.cloneNode(true);
+				if(!node){ return false; }
+			}else{
+				node = this.createNodesFromText(tstr, true)[0];
+			}
+
+			// recurse through the node, looking for, and attaching to, our
+			// attachment points which should be defined on the template node.
+
+			this.domNode = node;
+			// dojo.profile.start("attachTemplateNodes");
+			this.attachTemplateNodes();
+			// dojo.profile.end("attachTemplateNodes");
+		
+			// relocate source contents to templated container node
+			// this.containerNode must be able to receive children, or exceptions will be thrown
+			if (this.isContainer && this.containerNode){
+				var src = this.getFragNodeRef(frag);
+				if (src){
+					dojo.dom.moveChildren(src, this.containerNode);
+				}
+			}
+		},
+
+		attachTemplateNodes: function(baseNode, targetObj){
+			// summary: 
+			//		hooks up event handlers and property/node linkages. Calls
+			//		dojo.widget.attachTemplateNodes to do all the hard work.
+			// baseNode: DomNode
+			//		defaults to "this.domNode"
+			// targetObj: Widget
+			//		defaults to "this"
+			if(!baseNode){ baseNode = this.domNode; }
+			if(!targetObj){ targetObj = this; }
+			return dojo.widget.attachTemplateNodes(baseNode, targetObj, 
+						dojo.widget.getDojoEventsFromStr(this.templateString));
+		},
+
+		fillInTemplate: function(){
+			// summary:
+			//		stub function! sub-classes may use as a default UI
+			//		initializer function. The UI rendering will be available by
+			//		the time this is called from buildRendering. If
+			//		buildRendering is over-ridden, this function may not be
+			//		fired!
+
+			// dojo.unimplemented("dojo.widget.DomWidget.fillInTemplate");
+		},
+		
+		// method over-ride
+		destroyRendering: function(){
+			// summary: UI destructor.  Destroy the dom nodes associated w/this widget.
+			try{
+				dojo.dom.destroyNode(this.domNode);
+				delete this.domNode;
+			}catch(e){ /* squelch! */ }
+			if(this._sourceNodeRef){
+				try{
+					dojo.dom.destroyNode(this._sourceNodeRef);
+				}catch(e){ /* squelch! */ }
+			}
+		},
+
+		createNodesFromText: function(){
+			// summary
+			//	Attempts to create a set of nodes based on the structure of the passed text.
+			//	Implemented in HtmlWidget and SvgWidget.
+			dojo.unimplemented("dojo.widget.DomWidget.createNodesFromText");
+		}
+	}
+);

Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/DomWidget.js
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/DomWidget.js
------------------------------------------------------------------------------
    svn:keywords = "Date Rev Author URL Id"

Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/DomWidget.js
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/DropdownContainer.js
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/DropdownContainer.js?view=auto&rev=509273
==============================================================================
--- ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/DropdownContainer.js (added)
+++ ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/DropdownContainer.js Mon Feb 19 09:56:06 2007
@@ -0,0 +1,118 @@
+/*
+	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.DropdownContainer");
+dojo.require("dojo.widget.*");
+dojo.require("dojo.widget.HtmlWidget");
+dojo.require("dojo.widget.PopupContainer");
+dojo.require("dojo.event.*");
+dojo.require("dojo.html.layout");
+dojo.require("dojo.html.display");
+dojo.require("dojo.html.iframe");
+dojo.require("dojo.html.util");
+
+dojo.widget.defineWidget(
+	"dojo.widget.DropdownContainer",
+	dojo.widget.HtmlWidget,
+	{
+		// summary:
+		//		provides an input box and a button for a dropdown.
+		//		In subclass, the dropdown can be specified.
+
+		// inputWidth: String: width of the input box
+		inputWidth: "7em",
+
+		// id: String: id of this widget
+		id: "",
+
+		// inputId: String: id of the input box
+		inputId: "",
+
+		// inputName: String: name of the input box
+		inputName: "",
+
+		// iconURL: dojo.uri.Uri: icon for the dropdown button
+		iconURL: dojo.uri.dojoUri("src/widget/templates/images/combo_box_arrow.png"),
+
+		// copyClass:
+		//		should we use the class properties on the source node instead
+		//		of our own styles?
+		copyClasses: false,
+
+		// iconAlt: dojo.uri.Uri: alt text for the dropdown button icon
+		iconAlt: "",
+
+		// containerToggle: String: toggle property of the dropdown
+		containerToggle: "plain",
+
+		// containerToggleDuration: Integer: toggle duration property of the dropdown
+		containerToggleDuration: 150,
+
+		templateString: '<span style="white-space:nowrap"><input type="hidden" name="" value="" dojoAttachPoint="valueNode" /><input name="" type="text" value="" style="vertical-align:middle;" dojoAttachPoint="inputNode" autocomplete="off" /> <img src="${this.iconURL}" alt="${this.iconAlt}" dojoAttachEvent="onclick:onIconClick" dojoAttachPoint="buttonNode" style="vertical-align:middle; cursor:pointer; cursor:hand" /></span>',
+		templateCssPath: "",
+		isContainer: true,
+
+		attachTemplateNodes: function(){
+			// summary: use attachTemplateNodes to specify containerNode, as fillInTemplate is too late for this
+			dojo.widget.DropdownContainer.superclass.attachTemplateNodes.apply(this, arguments);
+			this.popup = dojo.widget.createWidget("PopupContainer", {toggle: this.containerToggle, toggleDuration: this.containerToggleDuration});
+			this.containerNode = this.popup.domNode;
+		},
+
+		fillInTemplate: function(args, frag){
+			this.domNode.appendChild(this.popup.domNode);
+			if(this.id) { this.domNode.id = this.id; }
+			if(this.inputId){ this.inputNode.id = this.inputId; }
+			if(this.inputName){ this.inputNode.name = this.inputName; }
+			this.inputNode.style.width = this.inputWidth;
+			this.inputNode.disabled = this.disabled;
+
+			if(this.copyClasses){
+				this.inputNode.style = "";
+				this.inputNode.className = this.getFragNodeRef(frag).className;
+			}
+
+
+			dojo.event.connect(this.inputNode, "onchange", this, "onInputChange");
+		},
+
+		onIconClick: function(/*Event*/ evt){
+			if(this.disabled) return;
+			if(!this.popup.isShowingNow){
+				this.popup.open(this.inputNode, this, this.buttonNode);
+			}else{
+				this.popup.close();
+			}
+		},
+
+		hideContainer: function(){
+			// summary: hide the dropdown
+			if(this.popup.isShowingNow){
+				this.popup.close();
+			}
+		},
+
+		onInputChange: function(){
+			// summary: signal for changes in the input box
+		},
+		
+		enable: function() {
+			// summary: enable this widget to accept user input
+			this.inputNode.disabled = false;
+			dojo.widget.DropdownContainer.superclass.enable.apply(this, arguments);
+		},
+		
+		disable: function() {
+			// summary: lock this widget so that the user can't change the value
+			this.inputNode.disabled = true;
+			dojo.widget.DropdownContainer.superclass.disable.apply(this, arguments);
+		}
+	}
+);

Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/DropdownContainer.js
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/DropdownContainer.js
------------------------------------------------------------------------------
    svn:keywords = "Date Rev Author URL Id"

Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/DropdownContainer.js
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/DropdownDatePicker.js
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/DropdownDatePicker.js?view=auto&rev=509273
==============================================================================
--- ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/DropdownDatePicker.js (added)
+++ ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/DropdownDatePicker.js Mon Feb 19 09:56:06 2007
@@ -0,0 +1,239 @@
+/*
+	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.DropdownDatePicker");
+
+dojo.require("dojo.widget.*");
+dojo.require("dojo.widget.DropdownContainer");
+dojo.require("dojo.widget.DatePicker");
+dojo.require("dojo.event.*");
+dojo.require("dojo.html.*");
+dojo.require("dojo.date.format");
+dojo.require("dojo.date.serialize");
+dojo.require("dojo.string.common");
+dojo.require("dojo.i18n.common");
+dojo.requireLocalization("dojo.widget", "DropdownDatePicker", null, "ROOT");
+
+
+dojo.widget.defineWidget(
+	"dojo.widget.DropdownDatePicker",
+	dojo.widget.DropdownContainer,
+	{
+		/*
+		summary: 
+			A form input for entering dates with a pop-up dojo.widget.DatePicker to aid in selection
+		
+			description: 
+				This is DatePicker in a DropdownContainer, it supports all features of DatePicker.
+		
+				The value displayed in the widget is localized according to the default algorithm provided
+				in dojo.date.format and dojo.date.parse.  It is possible to customize the user-visible formatting
+				with either the formatLength or displayFormat attributes.  The value sent to the server is
+				typically a locale-independent value in a hidden field as defined by the name attribute.
+				RFC3339 representation is used by default, but other options are available with saveFormat.
+		
+			usage: 
+				var ddp = dojo.widget.createWidget("DropdownDatePicker", {},   
+				dojo.byId("DropdownDatePickerNode")); 
+		 	 
+				<input dojoType="DropdownDatePicker">
+		*/
+
+		iconURL: dojo.uri.dojoUri("src/widget/templates/images/dateIcon.gif"),
+
+		// formatLength: String
+		// 	Type of formatting used for visual display, appropriate to locale (choice of long, short, medium or full)
+		//  See dojo.date.format for details.
+		formatLength: "short",
+
+		// displayFormat: String
+		//	A pattern used for the visual display of the formatted date, e.g. dd/MM/yyyy.
+		//	Setting this overrides the default locale-specific settings as well as the formatLength
+		//	attribute.  See dojo.date.format for a reference which defines the formatting patterns.
+		displayFormat: "",
+
+		dateFormat: "", // deprecated, will be removed for 0.5
+
+		// saveFormat: String
+		//	Formatting scheme used when submitting the form element.  This formatting is used in a hidden
+		//  field (name) intended for server use, and is therefore typically locale-independent.
+		//  By default, uses rfc3339 style date formatting (rfc)
+		//	Use a pattern string like displayFormat or one of the following:
+		//	rfc|iso|posix|unix
+		saveFormat: "",
+
+		// value: String|Date
+		//	form value property in rfc3339 format. If =='today', will use today's date
+		value: "",
+
+		// name: String
+		// 	name of the form element, used to create a hidden field by this name for form element submission.
+		name: "",
+
+		// Implement various attributes from DatePicker
+
+		// displayWeeks: Integer
+		//	number of weeks to display 
+		displayWeeks: 6,
+
+		// adjustWeeks: Boolean
+		//	if true, weekly size of calendar changes to accomodate the month if false, 42 day format is used
+		adjustWeeks: false,
+
+		// startDate: String|Date
+		//	first available date in the calendar set
+		startDate: "1492-10-12",
+
+		// endDate: String|Date
+		//	last available date in the calendar set
+		endDate: "2941-10-12",
+
+		// weekStartsOn: Integer
+		//	adjusts the first day of the week 0==Sunday..6==Saturday
+		weekStartsOn: "",
+
+		// staticDisplay: Boolean
+		//	disable all incremental controls, must pick a date in the current display
+		staticDisplay: false,
+		
+		postMixInProperties: function(localProperties, frag){
+			// summary: see dojo.widget.DomWidget
+
+			dojo.widget.DropdownDatePicker.superclass.postMixInProperties.apply(this, arguments);
+			var messages = dojo.i18n.getLocalization("dojo.widget", "DropdownDatePicker", this.lang);
+			this.iconAlt = messages.selectDate;
+
+			//FIXME: should this be if/else/else?
+			if(typeof(this.value)=='string'&&this.value.toLowerCase()=='today'){
+				this.value = new Date();
+			}
+			if(this.value && isNaN(this.value)){
+				var orig = this.value;
+				this.value = dojo.date.fromRfc3339(this.value);
+				if(!this.value){this.value = new Date(orig); dojo.deprecated("dojo.widget.DropdownDatePicker", "date attributes must be passed in Rfc3339 format", "0.5");}
+			}
+			if(this.value && !isNaN(this.value)){
+				this.value = new Date(this.value);
+			}
+		},
+
+		fillInTemplate: function(args, frag){
+			// summary: see dojo.widget.DomWidget
+			dojo.widget.DropdownDatePicker.superclass.fillInTemplate.call(this, args, frag);
+			//attributes to be passed on to DatePicker
+			var dpArgs = {widgetContainerId: this.widgetId, lang: this.lang, value: this.value,
+				startDate: this.startDate, endDate: this.endDate, displayWeeks: this.displayWeeks,
+				weekStartsOn: this.weekStartsOn, adjustWeeks: this.adjustWeeks, staticDisplay: this.staticDisplay};
+
+			//build the args for DatePicker based on the public attributes of DropdownDatePicker
+			this.datePicker = dojo.widget.createWidget("DatePicker", dpArgs, this.containerNode, "child");
+			dojo.event.connect(this.datePicker, "onValueChanged", this, "_updateText");
+			
+			if(this.value){
+				this._updateText();
+			}
+			this.containerNode.explodeClassName = "calendarBodyContainer";
+			this.valueNode.name=this.name;
+		},
+
+		getValue: function(){
+			// summary: return current date in RFC 3339 format
+			return this.valueNode.value; /*String*/
+		},
+
+		getDate: function(){
+			// summary: return current date as a Date object
+			return this.datePicker.value; /*Date*/
+		},
+
+		setValue: function(/*Date|String*/rfcDate){
+			//summary: set the current date from RFC 3339 formatted string or a date object, synonymous with setDate
+			this.setDate(rfcDate);
+		},
+
+		setDate: function(/*Date|String*/dateObj){
+			// summary: set the current date and update the UI
+			this.datePicker.setDate(dateObj);
+			this._syncValueNode();
+		},
+	
+		_updateText: function(){
+			// summary: updates the <input> field according to the current value (ie, displays the formatted date)
+			if(this.dateFormat){
+				dojo.deprecated("dojo.widget.DropdownDatePicker",
+				"Must use displayFormat attribute instead of dateFormat.  See dojo.date.format for specification.", "0.5");
+				this.inputNode.value = dojo.date.strftime(this.datePicker.value, this.dateFormat, this.lang);
+			}else if(this.datePicker.value){
+				this.inputNode.value = dojo.date.format(this.datePicker.value,
+					{formatLength:this.formatLength, datePattern:this.displayFormat, selector:'dateOnly', locale:this.lang});
+			}else{
+				this.inputNode.value = "";
+			}
+
+			if(this.value < this.datePicker.startDate||this.value>this.datePicker.endDate){
+				this.inputNode.value = "";
+			}
+			this._syncValueNode();
+			this.onValueChanged(this.getDate());
+			this.hideContainer();
+		},
+
+		onValueChanged: function(/*Date*/dateObj){
+			//summary: triggered when this.value is changed
+		},
+		
+		onInputChange: function(){
+			// summary: callback when user manually types a date into the <input> field
+			if(this.dateFormat){
+				dojo.deprecated("dojo.widget.DropdownDatePicker",
+				"Cannot parse user input.  Must use displayFormat attribute instead of dateFormat.  See dojo.date.format for specification.", "0.5");
+			}else{
+				var input = dojo.string.trim(this.inputNode.value);
+				if(input){
+					var inputDate = dojo.date.parse(input,
+							{formatLength:this.formatLength, datePattern:this.displayFormat, selector:'dateOnly', locale:this.lang});			
+					if(inputDate){
+						this.setDate(inputDate);
+					}
+				} else {
+					this.valueNode.value = input;
+				}
+			}
+			// If the date entered didn't parse, reset to the old date.  KISS, for now.
+			//TODO: usability?  should we provide more feedback somehow? an error notice?
+			// seems redundant to do this if the parse failed, but at least until we have validation,
+			// this will fix up the display of entries like 01/32/2006
+			if(input){ this._updateText(); }
+		},
+
+		_syncValueNode: function(){
+			var date = this.datePicker.value;
+				var value = "";
+			switch(this.saveFormat.toLowerCase()){
+				case "rfc": case "iso": case "":
+					value = dojo.date.toRfc3339(date, 'dateOnly');
+					break;
+				case "posix": case "unix":
+					value = Number(date);
+					break;
+				default:
+					if(date){
+						value = dojo.date.format(date, {datePattern:this.saveFormat, selector:'dateOnly', locale:this.lang});
+					}
+			}
+			this.valueNode.value = value;
+		},
+		
+		destroy: function(/*Boolean*/finalize){
+			this.datePicker.destroy(finalize);
+			dojo.widget.DropdownDatePicker.superclass.destroy.apply(this, arguments);
+		}
+	}
+);

Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/DropdownDatePicker.js
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/DropdownDatePicker.js
------------------------------------------------------------------------------
    svn:keywords = "Date Rev Author URL Id"

Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/DropdownDatePicker.js
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/DropdownTimePicker.js
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/DropdownTimePicker.js?view=auto&rev=509273
==============================================================================
--- ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/DropdownTimePicker.js (added)
+++ ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/DropdownTimePicker.js Mon Feb 19 09:56:06 2007
@@ -0,0 +1,242 @@
+/*
+	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.DropdownTimePicker");
+
+dojo.require("dojo.widget.*");
+dojo.require("dojo.widget.DropdownContainer");
+dojo.require("dojo.widget.TimePicker");
+dojo.require("dojo.event.*");
+dojo.require("dojo.html.*");
+dojo.require("dojo.date.format");
+dojo.require("dojo.date.serialize");
+dojo.require("dojo.i18n.common");
+dojo.requireLocalization("dojo.widget", "DropdownTimePicker", null, "ROOT");
+
+dojo.widget.defineWidget(
+	"dojo.widget.DropdownTimePicker",
+	dojo.widget.DropdownContainer,
+	{
+		/*
+		summary: 
+			A form input for entering times with a pop-up dojo.widget.TimePicker to aid in selection
+		
+			description: 
+				This is TimePicker in a DropdownContainer, it supports all features of TimeePicker.
+		
+				It is possible to customize the user-visible formatting with either the formatLength or 
+				displayFormat attributes.  The value sent to the server is typically a locale-independent 
+				value in a hidden field as defined by the name attribute. RFC3339 representation is used 
+				by default, but other options are available with saveFormat.
+		
+			usage: 
+				var dtp = dojo.widget.createWidget("DropdownTimePicker", {},   
+				dojo.byId("DropdownTimePickerNode")); 
+		 	 
+				<input dojoType="DropdownTimePicker">
+		*/
+
+		// iconURL: URL
+		//	path of icon for button to display time picker widget
+		iconURL: dojo.uri.dojoUri("src/widget/templates/images/timeIcon.gif"),
+		
+		// formatLength: String
+		//	Type of formatting used for visual display, appropriate to locale (choice of long, short, medium or full)
+		//	See dojo.date.format for details.
+		formatLength: "short",
+
+		// displayFormat: String
+		//	A pattern used for the visual display of the formatted date.
+		//	Setting this overrides the default locale-specific settings as well as the formatLength
+		//	attribute.  See dojo.date.format for a reference which defines the formatting patterns.
+		displayFormat: "",
+
+		timeFormat: "", // deprecated, will be removed for 0.5
+
+//FIXME: need saveFormat attribute support
+		// saveFormat: String
+		//	Formatting scheme used when submitting the form element.  This formatting is used in a hidden
+		//  field (name) intended for server use, and is therefore typically locale-independent.
+		//  By default, uses rfc3339 style date formatting (rfc)
+		//	Use a pattern string like displayFormat or one of the following:
+		//	rfc|iso|posix|unix
+		saveFormat: "",
+
+		// value: String|Date
+		//	form value property in rfc3339 format. ex: 12:00
+		value: "",
+
+		// name: String
+		// 	name of the form element, used to create a hidden field by this name for form element submission.
+		name: "",
+
+		postMixInProperties: function() {
+			// summary: see dojo.widget.DomWidget
+			dojo.widget.DropdownTimePicker.superclass.postMixInProperties.apply(this, arguments);
+			var messages = dojo.i18n.getLocalization("dojo.widget", "DropdownTimePicker", this.lang);
+			this.iconAlt = messages.selectTime;
+
+			//FIXME: should this be if/else/else?
+			if(typeof(this.value)=='string'&&this.value.toLowerCase()=='today'){
+				this.value = new Date();
+			}
+			if(this.value && isNaN(this.value)){
+				var orig = this.value;
+				this.value = dojo.date.fromRfc3339(this.value);
+				if(!this.value){
+					var d = dojo.date.format(new Date(), { selector: "dateOnly", datePattern: "yyyy-MM-dd" });
+					var c = orig.split(":");
+					for(var i = 0; i < c.length; ++i){
+						if(c[i].length == 1) c[i] = "0" + c[i];
+					}
+					orig = c.join(":");
+					this.value = dojo.date.fromRfc3339(d + "T" + orig);
+					dojo.deprecated("dojo.widget.DropdownTimePicker", "time attributes must be passed in Rfc3339 format", "0.5");
+				}
+			}
+			if(this.value && !isNaN(this.value)){
+				this.value = new Date(this.value);
+			}
+		},
+
+		fillInTemplate: function(){
+			// summary: see dojo.widget.DomWidget
+
+			dojo.widget.DropdownTimePicker.superclass.fillInTemplate.apply(this, arguments);
+
+			var value = "";
+			if(this.value instanceof Date) {
+				value = this.value;
+			} else if(this.value) {
+				var orig = this.value;
+				var d = dojo.date.format(new Date(), { selector: "dateOnly", datePattern: "yyyy-MM-dd" });
+				var c = orig.split(":");
+				for(var i = 0; i < c.length; ++i){
+					if(c[i].length == 1) c[i] = "0" + c[i];
+				}
+				orig = c.join(":");
+				value = dojo.date.fromRfc3339(d + "T" + orig);
+			}
+			
+			var tpArgs = { widgetContainerId: this.widgetId, lang: this.lang, value: value };
+			this.timePicker = dojo.widget.createWidget("TimePicker", tpArgs, this.containerNode, "child");
+			
+			dojo.event.connect(this.timePicker, "onValueChanged", this, "_updateText");
+			
+			if(this.value){
+				this._updateText();
+			}
+			this.containerNode.style.zIndex = this.zIndex;
+			this.containerNode.explodeClassName = "timeContainer";
+			this.valueNode.name = this.name;
+		},
+		
+		getValue: function(){
+			// summary: return current time in time-only portion of RFC 3339 format
+			return this.valueNode.value; /*String*/
+		},
+
+		getTime: function(){
+			// summary: return current time as a Date object
+			return this.timePicker.storedTime; /*Date*/
+		},
+
+		setValue: function(/*Date|String*/rfcDate){
+			//summary: set the current time from RFC 3339 formatted string or a date object, synonymous with setTime
+			this.setTime(rfcDate);
+		},
+
+		setTime: function(/*Date|String*/dateObj){
+			// summary: set the current time and update the UI
+			var value = "";
+			if(dateObj instanceof Date) {
+				value = dateObj;
+			} else if(this.value) {
+				var orig = this.value;
+				var d = dojo.date.format(new Date(), { selector: "dateOnly", datePattern: "yyyy-MM-dd" });
+				var c = orig.split(":");
+				for(var i = 0; i < c.length; ++i){
+					if(c[i].length == 1) c[i] = "0" + c[i];
+				}
+				orig = c.join(":");
+				value = dojo.date.fromRfc3339(d + "T" + orig);
+			}
+
+			this.timePicker.setTime(value);
+			this._syncValueNode();
+		},
+	
+		_updateText: function(){
+			// summary: updates the <input> field according to the current value (ie, displays the formatted date)
+			if(this.timePicker.selectedTime.anyTime){
+				this.inputNode.value = "";
+			}else if(this.timeFormat){
+				dojo.deprecated("dojo.widget.DropdownTimePicker",
+				"Must use displayFormat attribute instead of timeFormat.  See dojo.date.format for specification.", "0.5");
+				this.inputNode.value = dojo.date.strftime(this.timePicker.time, this.timeFormat, this.lang);
+			}else{
+				this.inputNode.value = dojo.date.format(this.timePicker.time,
+					{formatLength:this.formatLength, timePattern:this.displayFormat, selector:'timeOnly', locale:this.lang});
+			}
+			this._syncValueNode();
+			this.onValueChanged(this.getTime());
+			this.hideContainer();
+		},
+
+		onValueChanged: function(/*Date*/dateObj){
+			// summary: triggered when this.value is changed
+		},
+		
+		onInputChange: function(){
+			// summary: callback when user manually types a time into the <input> field
+			if(this.dateFormat){
+				dojo.deprecated("dojo.widget.DropdownTimePicker",
+				"Cannot parse user input.  Must use displayFormat attribute instead of dateFormat.  See dojo.date.format for specification.", "0.5");
+			}else{
+				var input = dojo.string.trim(this.inputNode.value);
+				if(input){
+					var inputTime = dojo.date.parse(input,
+							{formatLength:this.formatLength, timePattern:this.displayFormat, selector:'timeOnly', locale:this.lang});			
+					if(inputTime){
+						this.setTime(inputTime);
+					}
+				} else {
+					this.valueNode.value = input;
+				}
+			}
+			// If the time entered didn't parse, reset to the old time.  KISS, for now.
+			//TODO: usability?  should we provide more feedback somehow? an error notice?
+			// seems redundant to do this if the parse failed, but at least until we have validation,
+			// this will fix up the display of entries like 01/32/2006
+			if(input){ this._updateText(); }
+		},
+
+		_syncValueNode: function(){
+			var time = this.timePicker.time;
+			var value;
+			switch(this.saveFormat.toLowerCase()){
+				case "rfc": case "iso": case "":
+					value = dojo.date.toRfc3339(time, 'timeOnly');
+					break;
+				case "posix": case "unix":
+					value = Number(time);
+					break;
+				default:
+					value = dojo.date.format(time, {datePattern:this.saveFormat, selector:'timeOnly', locale:this.lang});
+			}
+			this.valueNode.value = value;
+		},
+		
+		destroy: function(/*Boolean*/finalize){
+			this.timePicker.destroy(finalize);
+			dojo.widget.DropdownTimePicker.superclass.destroy.apply(this, arguments);
+		}
+	}
+);

Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/DropdownTimePicker.js
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/DropdownTimePicker.js
------------------------------------------------------------------------------
    svn:keywords = "Date Rev Author URL Id"

Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/DropdownTimePicker.js
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/Editor.js
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/Editor.js?view=auto&rev=509273
==============================================================================
--- ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/Editor.js (added)
+++ ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/Editor.js Mon Feb 19 09:56:06 2007
@@ -0,0 +1,534 @@
+/*
+	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
+*/
+
+/* TODO:
+ * - font selector
+ * - test, bug fix, more features :)
+*/
+dojo.provide("dojo.widget.Editor");
+dojo.deprecated("dojo.widget.Editor", "is replaced by dojo.widget.Editor2", "0.5");
+
+dojo.require("dojo.io.*");
+dojo.require("dojo.widget.*");
+dojo.require("dojo.widget.Toolbar");
+dojo.require("dojo.widget.RichText");
+dojo.require("dojo.widget.ColorPalette");
+dojo.require("dojo.string.extras");
+
+dojo.widget.tags.addParseTreeHandler("dojo:Editor");
+
+dojo.widget.Editor = function() {
+	dojo.widget.HtmlWidget.call(this);
+	this.contentFilters = [];
+	this._toolbars = [];
+}
+dojo.inherits(dojo.widget.Editor, dojo.widget.HtmlWidget);
+
+dojo.widget.Editor.itemGroups = {
+	textGroup: ["bold", "italic", "underline", "strikethrough"],
+	blockGroup: ["formatBlock", "fontName", "fontSize"],
+	justifyGroup: ["justifyleft", "justifycenter", "justifyright"],
+	commandGroup: ["save", "cancel"],
+	colorGroup: ["forecolor", "hilitecolor"],
+	listGroup: ["insertorderedlist", "insertunorderedlist"],
+	indentGroup: ["outdent", "indent"],
+	linkGroup: ["createlink", "insertimage", "inserthorizontalrule"]
+};
+
+dojo.widget.Editor.formatBlockValues = {
+	"Normal": "p",
+	"Main heading": "h2",
+	"Sub heading": "h3",
+	"Sub sub heading": "h4",
+	"Preformatted": "pre"
+};
+
+dojo.widget.Editor.fontNameValues = {
+	"Arial": "Arial, Helvetica, sans-serif",
+	"Verdana": "Verdana, sans-serif",
+	"Times New Roman": "Times New Roman, serif",
+	"Courier": "Courier New, monospace"
+};
+
+dojo.widget.Editor.fontSizeValues = {
+	"1 (8 pt)" : "1",
+	"2 (10 pt)": "2",
+	"3 (12 pt)": "3",
+	"4 (14 pt)": "4",
+	"5 (18 pt)": "5",
+	"6 (24 pt)": "6",
+	"7 (36 pt)": "7"
+};
+
+dojo.widget.Editor.defaultItems = [
+	"commandGroup", "|", "blockGroup", "|", "textGroup", "|", "colorGroup", "|", "justifyGroup", "|", "listGroup", "indentGroup", "|", "linkGroup"
+];
+
+// ones we support by default without asking the RichText component
+// NOTE: you shouldn't put buttons like bold, italic, etc in here
+dojo.widget.Editor.supportedCommands = ["save", "cancel", "|", "-", "/", " "];
+
+dojo.lang.extend(dojo.widget.Editor, {
+	widgetType: "Editor",
+
+	saveUrl: "",
+	saveMethod: "post",
+	saveArgName: "editorContent",
+	closeOnSave: false,
+	items: dojo.widget.Editor.defaultItems,
+	formatBlockItems: dojo.lang.shallowCopy(dojo.widget.Editor.formatBlockValues),
+	fontNameItems: dojo.lang.shallowCopy(dojo.widget.Editor.fontNameValues),
+	fontSizeItems: dojo.lang.shallowCopy(dojo.widget.Editor.fontSizeValues),
+
+	// used to get the properties of an item if it is given as a string
+	getItemProperties: function(name) {
+		var props = {};
+		switch(name.toLowerCase()) {
+			case "bold":
+			case "italic":
+			case "underline":
+			case "strikethrough":
+				props.toggleItem = true;
+				break;
+
+			case "justifygroup":
+				props.defaultButton = "justifyleft";
+				props.preventDeselect = true;
+				props.buttonGroup = true;
+				break;
+
+			case "listgroup":
+				props.buttonGroup = true;
+				break;
+
+			case "save":
+			case "cancel":
+				props.label = dojo.string.capitalize(name);
+				break;
+
+			case "forecolor":
+			case "hilitecolor":
+				props.name = name;
+				props.toggleItem = true; // FIXME: they aren't exactly toggle items
+				props.icon = this.getCommandImage(name);
+				break;
+
+			case "formatblock":
+				props.name = "formatBlock";
+				props.values = this.formatBlockItems;
+				break;
+
+			case "fontname":
+				props.name = "fontName";
+				props.values = this.fontNameItems;
+
+			case "fontsize":
+				props.name = "fontSize";
+				props.values = this.fontSizeItems;
+		}
+		return props;
+	},
+
+	validateItems: true, // set to false to add items, regardless of support
+	focusOnLoad: true,
+	minHeight: "1em",
+
+	_richText: null, // RichText widget
+	_richTextType: "RichText",
+
+	_toolbarContainer: null, // ToolbarContainer widget
+	_toolbarContainerType: "ToolbarContainer",
+
+	_toolbars: [],
+	_toolbarType: "Toolbar",
+
+	_toolbarItemType: "ToolbarItem",
+
+	buildRendering: function(args, frag) {
+		// get the node from args/frag
+		var node = frag["dojo:"+this.widgetType.toLowerCase()]["nodeRef"];
+		var trt = dojo.widget.createWidget(this._richTextType, {
+			focusOnLoad: this.focusOnLoad,
+			minHeight: this.minHeight
+		}, node)
+		var _this = this;
+		// this appears to fix a weird timing bug on Safari
+		setTimeout(function(){
+			_this.setRichText(trt);
+
+			_this.initToolbar();
+
+			_this.fillInTemplate(args, frag);
+		}, 0);
+	},
+
+	setRichText: function(richText) {
+		if(this._richText && this._richText == richText) {
+			dojo.debug("Already set the richText to this richText!");
+			return;
+		}
+
+		if(this._richText && !this._richText.isClosed) {
+			dojo.debug("You are switching richTexts yet you haven't closed the current one. Losing reference!");
+		}
+		this._richText = richText;
+		dojo.event.connect(this._richText, "close", this, "onClose");
+		dojo.event.connect(this._richText, "onLoad", this, "onLoad");
+		dojo.event.connect(this._richText, "onDisplayChanged", this, "updateToolbar");
+		if(this._toolbarContainer) {
+			this._toolbarContainer.enable();
+			this.updateToolbar(true);
+		}
+	},
+
+	initToolbar: function() {
+		// var tic = new Date();
+		if(this._toolbarContainer) { return; } // only create it once
+		this._toolbarContainer = dojo.widget.createWidget(this._toolbarContainerType);
+		var tb = this.addToolbar();
+		var last = true;
+		for(var i = 0; i < this.items.length; i++) {
+			if(this.items[i] == "\n") { // new row
+				tb = this.addToolbar();
+			} else {
+				if((this.items[i] == "|")&&(!last)){
+					last = true;
+				}else{
+					last = this.addItem(this.items[i], tb);
+				}
+			}
+		}
+		this.insertToolbar(this._toolbarContainer.domNode, this._richText.domNode);
+		// alert(new Date - tic);
+	},
+
+	// allow people to override this so they can make their own placement logic
+	insertToolbar: function(tbNode, richTextNode) {
+		dojo.html.insertBefore(tbNode, richTextNode);
+		//dojo.html.insertBefore(this._toolbarContainer.domNode, this._richText.domNode);
+	},
+
+	addToolbar: function(toolbar) {
+		this.initToolbar();
+		if(!(toolbar instanceof dojo.widget.Toolbar)) {
+			toolbar = dojo.widget.createWidget(this._toolbarType);
+		}
+		this._toolbarContainer.addChild(toolbar);
+		this._toolbars.push(toolbar);
+		return toolbar;
+	},
+
+	addItem: function(item, tb, dontValidate) {
+		if(!tb) { tb = this._toolbars[0]; }
+		var cmd = ((item)&&(!dojo.lang.isUndefined(item["getValue"]))) ?  cmd = item["getValue"](): item;
+
+		var groups = dojo.widget.Editor.itemGroups;
+		if(item instanceof dojo.widget.ToolbarItem) {
+			tb.addChild(item);
+		} else if(groups[cmd]) {
+			var group = groups[cmd];
+			var worked = true;
+			if(cmd == "justifyGroup" || cmd == "listGroup") {
+				var btnGroup = [cmd];
+				for(var i = 0 ; i < group.length; i++) {
+					if(dontValidate || this.isSupportedCommand(group[i])) {
+						btnGroup.push(this.getCommandImage(group[i]));
+					}else{
+						worked = false;
+					}
+				}
+				if(btnGroup.length){
+					/*
+					// the addChild interface is assinine. Work around it.
+					var tprops = this.getItemProperties(cmd);
+					var tmpGroup = dojo.widget.createWidget("ToolbarButtonGroup", tprops);
+					dojo.debug(btnGroup);
+					dojo.event.connect(tmpGroup, "onClick", this, "_action");
+					dojo.event.connect(tmpGroup, "onChangeSelect", this, "_action");
+					*/
+					var btn = tb.addChild(btnGroup, null, this.getItemProperties(cmd));
+					dojo.event.connect(btn, "onClick", this, "_action");
+					dojo.event.connect(btn, "onChangeSelect", this, "_action");
+				}
+				return worked;
+			} else {
+				for(var i = 0; i < group.length; i++) {
+					if(!this.addItem(group[i], tb)){
+						worked = false;
+					}
+				}
+				return worked;
+			}
+		} else {
+			if((!dontValidate)&&(!this.isSupportedCommand(cmd))){
+				return false;
+			}
+			if(dontValidate || this.isSupportedCommand(cmd)) {
+				cmd = cmd.toLowerCase();
+				if(cmd == "formatblock") {
+					var select = dojo.widget.createWidget("ToolbarSelect", {
+						name: "formatBlock",
+						values: this.formatBlockItems
+					});
+					tb.addChild(select);
+					var _this = this;
+					dojo.event.connect(select, "onSetValue", function(item, value) {
+						_this.onAction("formatBlock", value);
+					});
+				} else if(cmd == "fontname") {
+					var select = dojo.widget.createWidget("ToolbarSelect", {
+						name: "fontName",
+						values: this.fontNameItems
+					});
+					tb.addChild(select);
+					dojo.event.connect(select, "onSetValue", dojo.lang.hitch(this, function(item, value) {
+						this.onAction("fontName", value);
+					}));
+				} else if(cmd == "fontsize") {
+					var select = dojo.widget.createWidget("ToolbarSelect", {
+						name: "fontSize",
+						values: this.fontSizeItems
+					});
+					tb.addChild(select);
+					dojo.event.connect(select, "onSetValue", dojo.lang.hitch(this, function(item, value) {
+						this.onAction("fontSize", value);
+					}));
+				} else if(dojo.lang.inArray(cmd, ["forecolor", "hilitecolor"])) {
+					var btn = tb.addChild(dojo.widget.createWidget("ToolbarColorDialog", this.getItemProperties(cmd)));
+					dojo.event.connect(btn, "onSetValue", this, "_setValue");
+				} else {
+					var btn = tb.addChild(this.getCommandImage(cmd), null, this.getItemProperties(cmd));
+					if(cmd == "save"){
+						dojo.event.connect(btn, "onClick", this, "_save");
+					}else if(cmd == "cancel"){
+						dojo.event.connect(btn, "onClick", this, "_close");
+					} else {
+						dojo.event.connect(btn, "onClick", this, "_action");
+						dojo.event.connect(btn, "onChangeSelect", this, "_action");
+					}
+				}
+			}
+		}
+		return true;
+	},
+
+	enableToolbar: function() {
+		if(this._toolbarContainer) {
+			this._toolbarContainer.domNode.style.display = "";
+			this._toolbarContainer.enable();
+		}
+	},
+
+	disableToolbar: function(hide){
+		if(hide){
+			if(this._toolbarContainer){
+				this._toolbarContainer.domNode.style.display = "none";
+			}
+		}else{
+			if(this._toolbarContainer){
+				this._toolbarContainer.disable();
+			}
+		}
+	},
+
+	_updateToolbarLastRan: null,
+	_updateToolbarTimer: null,
+	_updateToolbarFrequency: 500,
+
+	updateToolbar: function(force) {
+		if(!this._toolbarContainer) { return; }
+
+		// keeps the toolbar from updating too frequently
+		// TODO: generalize this functionality?
+		var diff = new Date() - this._updateToolbarLastRan;
+		if(!force && this._updateToolbarLastRan && (diff < this._updateToolbarFrequency)) {
+			clearTimeout(this._updateToolbarTimer);
+			var _this = this;
+			this._updateToolbarTimer = setTimeout(function() {
+				_this.updateToolbar();
+			}, this._updateToolbarFrequency/2);
+			return;
+		} else {
+			this._updateToolbarLastRan = new Date();
+		}
+		// end frequency checker
+
+		var items = this._toolbarContainer.getItems();
+		for(var i = 0; i < items.length; i++) {
+			var item = items[i];
+			if(item instanceof dojo.widget.ToolbarSeparator) { continue; }
+			var cmd = item._name;
+			if (cmd == "save" || cmd == "cancel") { continue; }
+			else if(cmd == "justifyGroup") {
+				try {
+					if(!this._richText.queryCommandEnabled("justifyleft")) {
+						item.disable(false, true);
+					} else {
+						item.enable(false, true);
+						var jitems = item.getItems();
+						for(var j = 0; j < jitems.length; j++) {
+							var name = jitems[j]._name;
+							var value = this._richText.queryCommandValue(name);
+							if(typeof value == "boolean" && value) {
+								value = name;
+								break;
+							} else if(typeof value == "string") {
+								value = "justify"+value;
+							} else {
+								value = null;
+							}
+						}
+						if(!value) { value = "justifyleft"; } // TODO: query actual style
+						item.setValue(value, false, true);
+					}
+				} catch(err) {}
+			} else if(cmd == "listGroup") {
+				var litems = item.getItems();
+				for(var j = 0; j < litems.length; j++) {
+					this.updateItem(litems[j]);
+				}
+			} else {
+				this.updateItem(item);
+			}
+		}
+	},
+
+	updateItem: function(item) {
+		try {
+			var cmd = item._name;
+			var enabled = this._richText.queryCommandEnabled(cmd);
+			item.setEnabled(enabled, false, true);
+
+			var active = this._richText.queryCommandState(cmd);
+			if(active && cmd == "underline") {
+				// don't activate underlining if we are on a link
+				active = !this._richText.queryCommandEnabled("unlink");
+			}
+			item.setSelected(active, false, true);
+			return true;
+		} catch(err) {
+			return false;
+		}
+	},
+
+	supportedCommands: dojo.widget.Editor.supportedCommands.concat(),
+
+	isSupportedCommand: function(cmd) {
+		// FIXME: how do we check for ActiveX?
+		var yes = dojo.lang.inArray(cmd, this.supportedCommands);
+		if(!yes) {
+			try {
+				var richText = this._richText || dojo.widget.HtmlRichText.prototype;
+				yes = richText.queryCommandAvailable(cmd);
+			} catch(E) {}
+		}
+		return yes;
+	},
+
+	getCommandImage: function(cmd) {
+		if(cmd == "|") {
+			return cmd;
+		} else {
+			return dojo.uri.dojoUri("src/widget/templates/buttons/" + cmd + ".gif");
+		}
+	},
+
+	_action: function(e) {
+		this._fire("onAction", e.getValue());
+	},
+
+	_setValue: function(a, b) {
+		this._fire("onAction", a.getValue(), b);
+	},
+
+	_save: function(e){
+		// FIXME: how should this behave when there's a larger form in play?
+		if(!this._richText.isClosed){
+			if(this.saveUrl.length){
+				var content = {};
+				content[this.saveArgName] = this.getHtml();
+				dojo.io.bind({
+					method: this.saveMethod,
+					url: this.saveUrl,
+					content: content
+				});
+			}else{
+				dojo.debug("please set a saveUrl for the editor");
+			}
+			if(this.closeOnSave){
+				this._richText.close(e.getName().toLowerCase() == "save");
+			}
+		}
+	},
+
+	_close: function(e) {
+		if(!this._richText.isClosed) {
+			this._richText.close(e.getName().toLowerCase() == "save");
+		}
+	},
+
+	onAction: function(cmd, value) {
+		switch(cmd) {
+			case "createlink":
+				if(!(value = prompt("Please enter the URL of the link:", "http://"))) {
+					return;
+				}
+				break;
+			case "insertimage":
+				if(!(value = prompt("Please enter the URL of the image:", "http://"))) {
+					return;
+				}
+				break;
+		}
+		this._richText.execCommand(cmd, value);
+	},
+
+	fillInTemplate: function(args, frag) {
+		// dojo.event.connect(this, "onResized", this._richText, "onResized");
+	},
+
+	_fire: function(eventName) {
+		if(dojo.lang.isFunction(this[eventName])) {
+			var args = [];
+			if(arguments.length == 1) {
+				args.push(this);
+			} else {
+				for(var i = 1; i < arguments.length; i++) {
+					args.push(arguments[i]);
+				}
+			}
+			this[eventName].apply(this, args);
+		}
+	},
+
+	getHtml: function(){
+		this._richText.contentFilters = this._richText.contentFilters.concat(this.contentFilters);
+		return this._richText.getEditorContent();
+	},
+
+	getEditorContent: function(){
+		return this.getHtml();
+	},
+
+	onClose: function(save, hide){
+		this.disableToolbar(hide);
+		if(save) {
+			this._fire("onSave");
+		} else {
+			this._fire("onCancel");
+		}
+	},
+
+	// events baby!
+	onLoad: function(){},
+	onSave: function(){},
+	onCancel: function(){}
+});
+

Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/Editor.js
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/Editor.js
------------------------------------------------------------------------------
    svn:keywords = "Date Rev Author URL Id"

Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/Editor.js
------------------------------------------------------------------------------
    svn:mime-type = text/plain