?? widget.js
字號:
/* 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.Widget");dojo.provide("dojo.widget.tags");dojo.require("dojo.lang.func");dojo.require("dojo.lang.array");dojo.require("dojo.lang.extras");dojo.require("dojo.lang.declare");dojo.require("dojo.widget.Manager");dojo.require("dojo.event.*");dojo.declare("dojo.widget.Widget", null, { initializer: function() { // these properties aren't primitives and need to be created on a per-item // basis. this.children = []; // this.selection = new dojo.widget.Selection(); // FIXME: need to replace this with context menu stuff this.extraArgs = {}; }, // FIXME: need to be able to disambiguate what our rendering context is // here! // // needs to be a string with the end classname. Every subclass MUST // over-ride. // // base widget properties parent: null, // obviously, top-level and modal widgets should set these appropriately isTopLevel: false, isModal: false, isEnabled: true, isHidden: false, isContainer: false, // can we contain other widgets? widgetId: "", widgetType: "Widget", // used for building generic widgets toString: function() { return '[Widget ' + this.widgetType + ', ' + (this.widgetId || 'NO ID') + ']'; }, repr: function(){ return this.toString(); }, enable: function(){ // should be over-ridden this.isEnabled = true; }, disable: function(){ // should be over-ridden this.isEnabled = false; }, hide: function(){ // should be over-ridden this.isHidden = true; }, show: function(){ // should be over-ridden this.isHidden = false; }, onResized: function(){ // Clients should override this function to do special processing, // then call this.notifyChildrenOfResize() to notify children of resize this.notifyChildrenOfResize(); }, notifyChildrenOfResize: function(){ for(var i=0; i<this.children.length; i++){ var child = this.children[i]; //dojo.debug(this.widgetId + " resizing child " + child.widgetId); if( child.onResized ){ child.onResized(); } } }, create: function(args, fragment, parentComp){ // dojo.debug(this.widgetType, "create"); this.satisfyPropertySets(args, fragment, parentComp); // dojo.debug(this.widgetType, "-> mixInProperties"); this.mixInProperties(args, fragment, parentComp); // dojo.debug(this.widgetType, "-> postMixInProperties"); this.postMixInProperties(args, fragment, parentComp); // dojo.debug(this.widgetType, "-> dojo.widget.manager.add"); dojo.widget.manager.add(this); // dojo.debug(this.widgetType, "-> buildRendering"); this.buildRendering(args, fragment, parentComp); // dojo.debug(this.widgetType, "-> initialize"); this.initialize(args, fragment, parentComp); // dojo.debug(this.widgetType, "-> postInitialize"); this.postInitialize(args, fragment, parentComp); // dojo.debug(this.widgetType, "-> postCreate"); this.postCreate(args, fragment, parentComp); // dojo.debug(this.widgetType, "done!"); return this; }, // Destroy this widget and it's descendants destroy: function(finalize){ // FIXME: this is woefully incomplete this.destroyChildren(); this.uninitialize(); this.destroyRendering(finalize); dojo.widget.manager.removeById(this.widgetId); }, // Destroy the children of this widget, and their descendents destroyChildren: function(){ while(this.children.length > 0){ var tc = this.children[0]; this.removeChild(tc); tc.destroy(); } }, getChildrenOfType: function(type, recurse){ var ret = []; var isFunc = dojo.lang.isFunction(type); if(!isFunc){ type = type.toLowerCase(); } for(var x=0; x<this.children.length; x++){ if(isFunc){ if(this.children[x] instanceof type){ ret.push(this.children[x]); } }else{ if(this.children[x].widgetType.toLowerCase() == type){ ret.push(this.children[x]); } } if(recurse){ ret = ret.concat(this.children[x].getChildrenOfType(type, recurse)); } } return ret; }, getDescendants: function(){ var result = []; var stack = [this]; var elem; while (elem = stack.pop()){ result.push(elem); dojo.lang.forEach(elem.children, function(elem) { stack.push(elem); }); } return result; }, satisfyPropertySets: function(args){ // dojo.profile.start("satisfyPropertySets"); // get the default propsets for our component type /* var typePropSets = []; // FIXME: need to pull these from somewhere! var localPropSets = []; // pull out propsets from the parser's return structure // for(var x=0; x<args.length; x++){ // } for(var x=0; x<typePropSets.length; x++){ } for(var x=0; x<localPropSets.length; x++){ } */ // dojo.profile.end("satisfyPropertySets"); return args; }, mixInProperties: function(args, frag){ if((args["fastMixIn"])||(frag["fastMixIn"])){ // dojo.profile.start("mixInProperties_fastMixIn"); // fast mix in assumes case sensitivity, no type casting, etc... // dojo.lang.mixin(this, args); for(var x in args){ this[x] = args[x]; } // dojo.profile.end("mixInProperties_fastMixIn"); return; } // dojo.profile.start("mixInProperties"); /* * the actual mix-in code attempts to do some type-assignment based on * PRE-EXISTING properties of the "this" object. When a named property * of a propset is located, it is first tested to make sure that the * current object already "has one". Properties which are undefined in * the base widget are NOT settable here. The next step is to try to * determine type of the pre-existing property. If it's a string, the * property value is simply assigned. If a function, the property is * replaced with a "new Function()" declaration. If an Array, the * system attempts to split the string value on ";" chars, and no * further processing is attempted (conversion of array elements to a * integers, for instance). If the property value is an Object * (testObj.constructor === Object), the property is split first on ";" * chars, secondly on ":" chars, and the resulting key/value pairs are * assigned to an object in a map style. The onus is on the property * user to ensure that all property values are converted to the * expected type before usage. */ var undef; // NOTE: we cannot assume that the passed properties are case-correct // (esp due to some browser bugs). Therefore, we attempt to locate // properties for assignment regardless of case. This may cause // problematic assignments and bugs in the future and will need to be // documented with big bright neon lights. // FIXME: fails miserably if a mixin property has a default value of null in // a widget // NOTE: caching lower-cased args in the prototype is only // acceptable if the properties are invariant. // if we have a name-cache, get it var lcArgs = dojo.widget.lcArgsCache[this.widgetType]; if ( lcArgs == null ){ // build a lower-case property name cache if we don't have one lcArgs = {}; 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.connect(this, x, this, tn); }
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -