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("\"","""); + } + 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, |
Free forum by Nabble | Edit this page |