| /* |
| 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 = {dojoRoot:dojo.hostenv.getBaseScriptUri(), dojoWidgetModuleUri:dojo.uri.moduleUri("dojo.widget"), baseScriptUri:dojo.hostenv.getBaseScriptUri()}; |
| dojo.widget.fillFromTemplateCache = function (obj, templatePath, templateString, avoidCache) { |
| var tpath = templatePath || obj.templatePath; |
| var tmplts = dojo.widget._templateCache; |
| if (!tpath && !obj["widgetType"]) { |
| 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.templateString) { |
| obj.templateString = this._sanitizeTemplateString(obj.templateString); |
| } |
| if ((!obj.templateNode) && (!avoidCache)) { |
| obj.templateNode = ts["node"]; |
| } |
| if ((!obj.templateNode) && (!obj.templateString) && (tpath)) { |
| var tstring = this._sanitizeTemplateString(dojo.hostenv.getText(tpath)); |
| obj.templateString = tstring; |
| if (!avoidCache) { |
| tmplts[wt]["string"] = tstring; |
| } |
| } |
| if ((!ts["string"]) && (!avoidCache)) { |
| ts.string = obj.templateString; |
| } |
| }; |
| dojo.widget._sanitizeTemplateString = function (tString) { |
| if (tString) { |
| 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 = ""; |
| } |
| return tString; |
| }; |
| dojo.widget._templateCache.dummyCount = 0; |
| dojo.widget.attachProperties = ["dojoAttachPoint", "id"]; |
| dojo.widget.eventAttachProperty = "dojoAttachEvent"; |
| dojo.widget.onBuildProperty = "dojoOnBuild"; |
| dojo.widget.waiNames = ["waiRole", "waiState"]; |
| dojo.widget.wai = {waiRole:{name:"waiRole", "namespace":"http://www.w3.org/TR/xhtml2", alias:"x2", prefix:"wairole:"}, waiState:{name:"waiState", "namespace":"http://www.w3.org/2005/07/aaa", alias:"aaa", prefix:""}, setAttr:function (node, ns, attr, 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 (node, ns, attr) { |
| if (dojo.render.html.ie) { |
| return node.getAttribute(this[ns].alias + ":" + attr); |
| } else { |
| return node.getAttributeNS(this[ns]["namespace"], attr); |
| } |
| }, removeAttr:function (node, ns, attr) { |
| var success = true; |
| 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, targetObj, events) { |
| 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; |
| } |
| var nodes = rootNode.all || rootNode.getElementsByTagName("*"); |
| var _this = targetObj; |
| for (var x = -1; x < nodes.length; x++) { |
| var baseNode = (x == -1) ? rootNode : nodes[x]; |
| 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) { |
| 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) { |
| 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); |
| } |
| } |
| for (var y = 0; y < events.length; y++) { |
| var evtVal = baseNode.getAttribute(events[y]); |
| if ((evtVal) && (evtVal.length)) { |
| var thisFunc = null; |
| var domEvt = events[y].substr(4); |
| 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); |
| } |
| } |
| } |
| } |
| 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 { |
| 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) { |
| 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; |
| }; |
| dojo.declare("dojo.widget.DomWidget", dojo.widget.Widget, function () { |
| if ((arguments.length > 0) && (typeof arguments[0] == "object")) { |
| this.create(arguments[0]); |
| } |
| }, {templateNode:null, templateString:null, templateCssString:null, preventClobber:false, domNode:null, containerNode:null, widgetsInTemplate:false, addChild:function (widget, overrideContainerNode, pos, ref, insertIndex) { |
| if (!this.isContainer) { |
| 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; |
| }, addWidgetAsDirectChild:function (widget, overrideContainerNode, pos, ref, insertIndex) { |
| 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); |
| if (!ref) { |
| cn.appendChild(widget.domNode); |
| } else { |
| if (pos == "insertAtIndex") { |
| dojo.dom.insertAtIndex(widget.domNode, ref.parentNode, insertIndex); |
| } else { |
| if ((pos == "after") && (ref === cn.lastChild)) { |
| cn.appendChild(widget.domNode); |
| } else { |
| dojo.dom.insertAtPosition(widget.domNode, cn, pos); |
| } |
| } |
| } |
| }, registerChild:function (widget, insertionIndex) { |
| widget.dojoInsertionIndex = insertionIndex; |
| var idx = -1; |
| for (var i = 0; i < this.children.length; i++) { |
| if (this.children[i].dojoInsertionIndex <= insertionIndex) { |
| idx = i; |
| } |
| } |
| this.children.splice(idx + 1, 0, widget); |
| widget.parent = this; |
| widget.addedTo(this, idx + 1); |
| delete dojo.widget.manager.topWidgets[widget.widgetId]; |
| }, removeChild:function (widget) { |
| dojo.dom.removeNode(widget.domNode); |
| return dojo.widget.DomWidget.superclass.removeChild.call(this, widget); |
| }, getFragNodeRef:function (frag) { |
| if (!frag) { |
| return 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"]; |
| }, postInitialize:function (args, frag, parentComp) { |
| var sourceNodeRef = this.getFragNodeRef(frag); |
| if (parentComp && (parentComp.snarfChildDomOutput || !sourceNodeRef)) { |
| parentComp.addWidgetAsDirectChild(this, "", "insertAtIndex", "", args["dojoinsertionindex"], sourceNodeRef); |
| } else { |
| if (sourceNodeRef) { |
| if (this.domNode && (this.domNode !== sourceNodeRef)) { |
| this._sourceNodeRef = dojo.dom.replaceNode(sourceNodeRef, this.domNode); |
| } |
| } |
| } |
| 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; |
| var subnodes = this.domNode.getElementsByTagName("*"); |
| for (var i = 0; i < subnodes.length; i++) { |
| if (subnodes[i].getAttribute("dojoAttachPoint") == "subContainerWidget") { |
| subContainerNode = subnodes[i]; |
| } |
| if (subnodes[i].getAttribute("dojoType")) { |
| subnodes[i].setAttribute("isSubWidget", true); |
| } |
| } |
| if (this.isContainer && !this.containerNode) { |
| if (subContainerNode) { |
| var src = this.getFragNodeRef(frag); |
| if (src) { |
| dojo.dom.moveChildren(src, subContainerNode); |
| 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); |
| dojo.widget.getParser().createSubComponents(templatefrag, this); |
| 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); |
| } |
| } |
| } |
| 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) { |
| 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"]) { |
| this[widget.extraArgs["dojoattachpoint"]] = widget; |
| } |
| } |
| } |
| if (this.isContainer && !frag["dojoDontFollow"]) { |
| dojo.widget.getParser().createSubComponents(frag, this); |
| } |
| }, buildRendering:function (args, frag) { |
| var ts = dojo.widget._templateCache[this.widgetType]; |
| 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"]))))) { |
| this.buildFromTemplate(args, frag); |
| } else { |
| this.domNode = this.getFragNodeRef(frag); |
| } |
| this.fillInTemplate(args, frag); |
| }, buildFromTemplate:function (args, frag) { |
| var avoidCache = false; |
| if (args["templatepath"]) { |
| 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 = this.templateString; |
| if ((!this.templateNode) && (this.templateString)) { |
| matches = this.templateString.match(/\$\{([^\}]+)\}/g); |
| if (matches) { |
| var hash = this.strings || {}; |
| for (var key in dojo.widget.defaultStrings) { |
| if (dojo.lang.isUndefined(hash[key])) { |
| hash[key] = dojo.widget.defaultStrings[key]; |
| } |
| } |
| 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); |
| while (value.indexOf("\"") > -1) { |
| value = value.replace("\"", """); |
| } |
| tstr = tstr.replace(matches[i], value); |
| } |
| } |
| } else { |
| 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]; |
| } |
| } |
| this.domNode = node; |
| this.attachTemplateNodes(); |
| if (this.isContainer && this.containerNode) { |
| var src = this.getFragNodeRef(frag); |
| if (src) { |
| dojo.dom.moveChildren(src, this.containerNode); |
| } |
| } |
| }, attachTemplateNodes:function (baseNode, targetObj) { |
| if (!baseNode) { |
| baseNode = this.domNode; |
| } |
| if (!targetObj) { |
| targetObj = this; |
| } |
| return dojo.widget.attachTemplateNodes(baseNode, targetObj, dojo.widget.getDojoEventsFromStr(this.templateString)); |
| }, fillInTemplate:function () { |
| }, destroyRendering:function () { |
| try { |
| dojo.dom.destroyNode(this.domNode); |
| delete this.domNode; |
| } |
| catch (e) { |
| } |
| if (this._sourceNodeRef) { |
| try { |
| dojo.dom.destroyNode(this._sourceNodeRef); |
| } |
| catch (e) { |
| } |
| } |
| }, createNodesFromText:function () { |
| dojo.unimplemented("dojo.widget.DomWidget.createNodesFromText"); |
| }}); |
| |