📄 widget.js
字号:
for(var y in this){ lcArgs[((new String(y)).toLowerCase())] = y; } dojo.widget.lcArgsCache[this.widgetType] = lcArgs; } var visited = {}; for(var x in args){ if(!this[x]){ // check the cache for properties var y = lcArgs[(new String(x)).toLowerCase()]; if(y){ args[y] = args[x]; x = y; } } if(visited[x]){ continue; } visited[x] = true; if((typeof this[x]) != (typeof undef)){ if(typeof args[x] != "string"){ this[x] = args[x]; }else{ if(dojo.lang.isString(this[x])){ this[x] = args[x]; }else if(dojo.lang.isNumber(this[x])){ this[x] = new Number(args[x]); // FIXME: what if NaN is the result? }else if(dojo.lang.isBoolean(this[x])){ this[x] = (args[x].toLowerCase()=="false") ? false : true; }else if(dojo.lang.isFunction(this[x])){ // FIXME: need to determine if always over-writing instead // of attaching here is appropriate. I suspect that we // might want to only allow attaching w/ action items. // RAR, 1/19/05: I'm going to attach instead of // over-write here. Perhaps function objects could have // some sort of flag set on them? Or mixed-into objects // could have some list of non-mutable properties // (although I'm not sure how that would alleviate this // particular problem)? // this[x] = new Function(args[x]); // after an IRC discussion last week, it was decided // that these event handlers should execute in the // context of the widget, so that the "this" pointer // takes correctly. // argument that contains no punctuation other than . is // considered a function spec, not code if(args[x].search(/[^\w\.]+/i) == -1){ this[x] = dojo.evalObjPath(args[x], false); }else{ var tn = dojo.lang.nameAnonFunc(new Function(args[x]), this); dojo.event.kwConnect({ srcObj: this, srcFunc: x, adviceObj: this, adviceFunc: tn }); } }else if(dojo.lang.isArray(this[x])){ // typeof [] == "object" this[x] = args[x].split(";"); } else if (this[x] instanceof Date) { this[x] = new Date(Number(args[x])); // assume timestamp }else if(typeof this[x] == "object"){ // FIXME: should we be allowing extension here to handle // other object types intelligently? // if we defined a URI, we probably want to allow plain strings // to override it if (this[x] instanceof dojo.uri.Uri){ this[x] = args[x]; }else{ // FIXME: unlike all other types, we do not replace the // object with a new one here. Should we change that? var pairs = args[x].split(";"); for(var y=0; y<pairs.length; y++){ var si = pairs[y].indexOf(":"); if((si != -1)&&(pairs[y].length>si)){ this[x][pairs[y].substr(0, si).replace(/^\s+|\s+$/g, "")] = pairs[y].substr(si+1); } } } }else{ // the default is straight-up string assignment. When would // we ever hit this? this[x] = args[x]; } } }else{ // collect any extra 'non mixed in' args this.extraArgs[x.toLowerCase()] = args[x]; } } // dojo.profile.end("mixInProperties"); }, postMixInProperties: function(/*Object*/args, /*Object*/frag, /*Widget*/parent){ // summary: // stub function. Can be over-ridden to handle advanced property // casting and object configuration. }, initialize: function(/*Object*/args, /*Object*/frag, /*Widget*/parent){ // summary: stub function. return false; // dojo.unimplemented("dojo.widget.Widget.initialize"); }, postInitialize: function(/*Object*/args, /*Object*/frag, /*Widget*/parent){ // summary: stub function. return false; }, postCreate: function(/*Object*/args, /*Object*/frag, /*Widget*/parent){ // summary: stub function. return false; }, uninitialize: function(){ // summary: // stub function. Over-ride to implement custom widget tear-down // behavior. return false; }, buildRendering: function(/*Object*/args, /*Object*/frag, /*Widget*/parent){ // summary: stub function. SUBCLASSES MUST IMPLEMENT dojo.unimplemented("dojo.widget.Widget.buildRendering, on "+this.toString()+", "); return false; }, destroyRendering: function(){ // summary: stub function. SUBCLASSES MUST IMPLEMENT dojo.unimplemented("dojo.widget.Widget.destroyRendering"); return false; }, cleanUp: function(){ // summary: // stub function for destruction finalization. SUBCLASSES MUST // IMPLEMENT dojo.unimplemented("dojo.widget.Widget.cleanUp"); return false; }, addedTo: function(/*Widget*/parent){ // summary: // stub function this is just a signal that can be caught // parent: instance of dojo.widget.Widget that we were added to }, addChild: function(child){ // summary: stub function. SUBCLASSES MUST IMPLEMENT dojo.unimplemented("dojo.widget.Widget.addChild"); return false; }, // Detach the given child widget from me, but don't destroy it removeChild: function(/*Widget*/widget){ // summary: // removes the passed widget instance from this widget but does // not destroy it for(var x=0; x<this.children.length; x++){ if(this.children[x] === widget){ this.children.splice(x, 1); break; } } return widget; // Widget }, resize: function(/*String or int*/width, /*String or int*/height){ // summary: // both width and height may be set as percentages. The setWidth // and setHeight functions attempt to determine if the passed // param is specified in percentage or native units. Integers // without a measurement are assumed to be in the native unit of // measure. // width: // the width, either in native measures, or as a percentage. If as // percentage, pass it as a string in the form "30%". // height: // the height, either in native measures, or as a percentage. If as // percentage, pass it as a string in the form "30%". this.setWidth(width); this.setHeight(height); }, setWidth: function(/*String or int*/width){ // summary: like it says on the tin... // width: // the width, either in native measures, or as a percentage. If as // percentage, pass it as a string in the form "30%". if((typeof width == "string")&&(width.substr(-1) == "%")){ this.setPercentageWidth(width); }else{ this.setNativeWidth(width); } }, setHeight: function(/*String or int*/height){ // summary: like it says on the tin... // height: // the height, either in native measures, or as a percentage. If // as percentage, pass it as a string in the form "30%". if((typeof height == "string")&&(height.substr(-1) == "%")){ this.setPercentageHeight(height); }else{ this.setNativeHeight(height); } }, setPercentageHeight: function(/*int*/height){ // summary: stub function. SUBCLASSES MUST IMPLEMENT return false; }, setNativeHeight: function(/*int*/height){ // summary: stub function. SUBCLASSES MUST IMPLEMENT return false; }, setPercentageWidth: function(/*int*/width){ // summary: stub function. SUBCLASSES MUST IMPLEMENT return false; }, setNativeWidth: function(/*int*/width){ // summary: stub function. SUBCLASSES MUST IMPLEMENT return false; }, getPreviousSibling: function(){ // summary: // returns null if this is the first child of the parent, // otherwise returns the next sibling to the "left". var idx = this.getParentIndex(); // first node is idx=0 not found is idx<0 if (idx<=0) return null; return this.parent.children[idx-1]; // Widget }, getSiblings: function(){ // summary: gets an array of all children of our parent, including "this" return this.parent.children; // Array }, getParentIndex: function(){ // summary: what index are we at in the parent's children array? return dojo.lang.indexOf(this.parent.children, this, true); // int }, getNextSibling: function(){ // summary: // returns null if this is the last child of the parent, // otherwise returns the next sibling to the "right". var idx = this.getParentIndex(); if (idx == this.parent.children.length-1){return null;} // last node if (idx < 0){return null;} // not found return this.parent.children[idx+1]; // Widget }});// Lower case name cache: listing of the lower case elements in each widget.// We can't store the lcArgs in the widget itself because if B subclasses A,// then B.prototype.lcArgs might return A.prototype.lcArgs, which is not what we// wantdojo.widget.lcArgsCache = {};// TODO: should have a more general way to add tags or tag libraries?// TODO: need a default tags class to inherit from for things like getting propertySets// TODO: parse properties/propertySets into component attributes// TODO: parse subcomponents// TODO: copy/clone raw markup fragments/nodes as appropriatedojo.widget.tags = {};dojo.widget.tags.addParseTreeHandler = function(/*String*/type){ // summary: deprecated! dojo.deprecated("addParseTreeHandler", ". ParseTreeHandlers are now reserved for components. Any unfiltered DojoML tag without a ParseTreeHandler is assumed to be a widget", "0.5"); /* var ltype = type.toLowerCase(); this[ltype] = function(fragment, widgetParser, parentComp, insertionIndex, localProps){ var _ltype = ltype; dojo.profile.start(_ltype); var n = dojo.widget.buildWidgetFromParseTree(ltype, fragment, widgetParser, parentComp, insertionIndex, localProps); dojo.profile.end(_ltype); return n; } */}//dojo.widget.tags.addParseTreeHandler("dojo:widget");dojo.widget.tags["dojo:propertyset"] = function(fragment, widgetParser, parentComp){ // FIXME: Is this needed? // FIXME: Not sure that this parses into the structure that I want it to parse into... // FIXME: add support for nested propertySets var properties = widgetParser.parseProperties(fragment["dojo:propertyset"]);}// FIXME: need to add the <dojo:connect />dojo.widget.tags["dojo:connect"] = function(fragment, widgetParser, parentComp){ var properties = widgetParser.parseProperties(fragment["dojo:connect"]);}// FIXME: if we know the insertion point (to a reasonable location), why then do we:// - create a template node// - clone the template node// - render the clone and set properties// - remove the clone from the render tree// - place the clone// this is quite dumbdojo.widget.buildWidgetFromParseTree = function(/*String*/ type, /*Object*/ frag, /*dojo.widget.Parse*/ parser, /*Widget, optional*/ parentComp, /*int, optional*/ insertionIndex, /*Object*/ localProps){ // summary: creates a tree of widgets from the data structure produced by the first-pass parser (frag) // test for accessibility mode dojo.a11y.setAccessibleMode(); //dojo.profile.start("buildWidgetFromParseTree"); // FIXME: for codepath from createComponentFromScript, we are now splitting a path // that we already split and then joined var stype = type.split(":"); stype = (stype.length == 2) ? stype[1] : type; // FIXME: we don't seem to be doing anything with this! // var propertySets = parser.getPropertySets(frag); var localProperties = localProps || parser.parseProperties(frag[frag["ns"]+":"+stype]); var twidget = dojo.widget.manager.getImplementation(stype,null,null,frag["ns"]); if(!twidget){ throw new Error('cannot find "' + type + '" widget'); }else if (!twidget.create){ throw new Error('"' + type + '" widget object has no "create" method and does not appear to implement *Widget'); } localProperties["dojoinsertionindex"] = insertionIndex; // FIXME: we lose no less than 5ms in construction! var ret = twidget.create(localProperties, frag, parentComp, frag["ns"]); // dojo.profile.end("buildWidgetFromParseTree"); return ret;}dojo.widget.defineWidget = function(/*String*/ widgetClass, /*String*/ renderer, /*function||array*/ superclasses, /*function*/ init, /*Object*/ props){ // summary: Create a widget constructor function (aka widgetClass) // widgetClass: the location in the object hierarchy to place the new widget class constructor // renderer: usually "html", determines when this delcaration will be used // superclasses: // can be either a single function or an array of functions to be // mixed in as superclasses. If an array, only the first will be used // to set prototype inheritance. // init: an optional constructor function. Will be called after superclasses are mixed in. // props: a map of properties and functions to extend the class prototype with // This meta-function does parameter juggling for backward compat and overloading // if 4th argument is a string, we are using the old syntax // old sig: widgetClass, superclasses, props (object), renderer (string), init (function) if(dojo.lang.isString(arguments[3])){ dojo.widget._defineWidget(arguments[0], arguments[3], arguments[1], arguments[4], arguments[2]); }else{ // widgetClass var args = [ arguments[0] ], p = 3; if(dojo.lang.isString(arguments[1])){ // renderer, superclass args.push(arguments[1], arguments[2]); }else{ // superclass args.push('', arguments[1]); p = 2; } if(dojo.lang.isFunction(arguments[p])){ // init (function), props (object) args.push(arguments[p], arguments[p+1]); }else{ // props (object) args.push(null, arguments[p]); } dojo.widget._defineWidget.apply(this, args); }}dojo.widget.defineWidget.renderers = "html|svg|vml";dojo.widget._defineWidget = function(widgetClass /*string*/, renderer /*string*/, superclasses /*function||array*/, init /*function*/, props /*object*/){ // FIXME: uncomment next line to test parameter juggling ... remove when confidence improves // dojo.debug('(c:)' + widgetClass + '\n\n(r:)' + renderer + '\n\n(i:)' + init + '\n\n(p:)' + props); // widgetClass takes the form foo.bar.baz<.renderer>.WidgetName (e.g. foo.bar.baz.WidgetName or foo.bar.baz.html.WidgetName) var module = widgetClass.split("."); var type = module.pop(); // type <= WidgetName, module <= foo.bar.baz<.renderer> var regx = "\\.(" + (renderer ? renderer + '|' : '') + dojo.widget.defineWidget.renderers + ")\\."; var r = widgetClass.search(new RegExp(regx)); module = (r < 0 ? module.join(".") : widgetClass.substr(0, r)); // deprecated in favor of namespace system, remove for 0.5 dojo.widget.manager.registerWidgetPackage(module); var pos = module.indexOf("."); var nsName = (pos > -1) ? module.substring(0,pos) : module; // FIXME: hrm, this might make things simpler //dojo.widget.tags.addParseTreeHandler(nsName+":"+type.toLowerCase()); props=(props)||{}; props.widgetType = type; if((!init)&&(props["classConstructor"])){ init = props.classConstructor; delete props.classConstructor; } dojo.declare(widgetClass, superclasses, init, props);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -