mirror of
https://git.tt-rss.org/git/tt-rss.git
synced 2025-12-20 17:51:29 +00:00
upgrade Dojo to 1.6.1
This commit is contained in:
826
lib/dijit/_WidgetBase.js
Normal file
826
lib/dijit/_WidgetBase.js
Normal file
@@ -0,0 +1,826 @@
|
||||
/*
|
||||
Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
|
||||
Available via Academic Free License >= 2.1 OR the modified BSD license.
|
||||
see: http://dojotoolkit.org/license for details
|
||||
*/
|
||||
|
||||
|
||||
if(!dojo._hasResource["dijit._WidgetBase"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dijit._WidgetBase"] = true;
|
||||
dojo.provide("dijit._WidgetBase");
|
||||
dojo.require("dijit._base.manager");
|
||||
dojo.require("dojo.Stateful");
|
||||
|
||||
|
||||
(function(){
|
||||
|
||||
dojo.declare("dijit._WidgetBase", dojo.Stateful, {
|
||||
// summary:
|
||||
// Future base class for all Dijit widgets.
|
||||
// _Widget extends this class adding support for various features needed by desktop.
|
||||
|
||||
// id: [const] String
|
||||
// A unique, opaque ID string that can be assigned by users or by the
|
||||
// system. If the developer passes an ID which is known not to be
|
||||
// unique, the specified ID is ignored and the system-generated ID is
|
||||
// used instead.
|
||||
id: "",
|
||||
|
||||
// lang: [const] String
|
||||
// Rarely used. Overrides the default Dojo locale used to render this widget,
|
||||
// as defined by the [HTML LANG](http://www.w3.org/TR/html401/struct/dirlang.html#adef-lang) attribute.
|
||||
// Value must be among the list of locales specified during by the Dojo bootstrap,
|
||||
// formatted according to [RFC 3066](http://www.ietf.org/rfc/rfc3066.txt) (like en-us).
|
||||
lang: "",
|
||||
|
||||
// dir: [const] String
|
||||
// Bi-directional support, as defined by the [HTML DIR](http://www.w3.org/TR/html401/struct/dirlang.html#adef-dir)
|
||||
// attribute. Either left-to-right "ltr" or right-to-left "rtl". If undefined, widgets renders in page's
|
||||
// default direction.
|
||||
dir: "",
|
||||
|
||||
// class: String
|
||||
// HTML class attribute
|
||||
"class": "",
|
||||
|
||||
// style: String||Object
|
||||
// HTML style attributes as cssText string or name/value hash
|
||||
style: "",
|
||||
|
||||
// title: String
|
||||
// HTML title attribute.
|
||||
//
|
||||
// For form widgets this specifies a tooltip to display when hovering over
|
||||
// the widget (just like the native HTML title attribute).
|
||||
//
|
||||
// For TitlePane or for when this widget is a child of a TabContainer, AccordionContainer,
|
||||
// etc., it's used to specify the tab label, accordion pane title, etc.
|
||||
title: "",
|
||||
|
||||
// tooltip: String
|
||||
// When this widget's title attribute is used to for a tab label, accordion pane title, etc.,
|
||||
// this specifies the tooltip to appear when the mouse is hovered over that text.
|
||||
tooltip: "",
|
||||
|
||||
// baseClass: [protected] String
|
||||
// Root CSS class of the widget (ex: dijitTextBox), used to construct CSS classes to indicate
|
||||
// widget state.
|
||||
baseClass: "",
|
||||
|
||||
// srcNodeRef: [readonly] DomNode
|
||||
// pointer to original DOM node
|
||||
srcNodeRef: null,
|
||||
|
||||
// domNode: [readonly] DomNode
|
||||
// This is our visible representation of the widget! Other DOM
|
||||
// Nodes may by assigned to other properties, usually through the
|
||||
// template system's dojoAttachPoint syntax, but the domNode
|
||||
// property is the canonical "top level" node in widget UI.
|
||||
domNode: null,
|
||||
|
||||
// containerNode: [readonly] DomNode
|
||||
// Designates where children of the source DOM node will be placed.
|
||||
// "Children" in this case refers to both DOM nodes and widgets.
|
||||
// For example, for myWidget:
|
||||
//
|
||||
// | <div dojoType=myWidget>
|
||||
// | <b> here's a plain DOM node
|
||||
// | <span dojoType=subWidget>and a widget</span>
|
||||
// | <i> and another plain DOM node </i>
|
||||
// | </div>
|
||||
//
|
||||
// containerNode would point to:
|
||||
//
|
||||
// | <b> here's a plain DOM node
|
||||
// | <span dojoType=subWidget>and a widget</span>
|
||||
// | <i> and another plain DOM node </i>
|
||||
//
|
||||
// In templated widgets, "containerNode" is set via a
|
||||
// dojoAttachPoint assignment.
|
||||
//
|
||||
// containerNode must be defined for any widget that accepts innerHTML
|
||||
// (like ContentPane or BorderContainer or even Button), and conversely
|
||||
// is null for widgets that don't, like TextBox.
|
||||
containerNode: null,
|
||||
|
||||
/*=====
|
||||
// _started: Boolean
|
||||
// startup() has completed.
|
||||
_started: false,
|
||||
=====*/
|
||||
|
||||
// attributeMap: [protected] Object
|
||||
// attributeMap sets up a "binding" between attributes (aka properties)
|
||||
// of the widget and the widget's DOM.
|
||||
// Changes to widget attributes listed in attributeMap will be
|
||||
// reflected into the DOM.
|
||||
//
|
||||
// For example, calling set('title', 'hello')
|
||||
// on a TitlePane will automatically cause the TitlePane's DOM to update
|
||||
// with the new title.
|
||||
//
|
||||
// attributeMap is a hash where the key is an attribute of the widget,
|
||||
// and the value reflects a binding to a:
|
||||
//
|
||||
// - DOM node attribute
|
||||
// | focus: {node: "focusNode", type: "attribute"}
|
||||
// Maps this.focus to this.focusNode.focus
|
||||
//
|
||||
// - DOM node innerHTML
|
||||
// | title: { node: "titleNode", type: "innerHTML" }
|
||||
// Maps this.title to this.titleNode.innerHTML
|
||||
//
|
||||
// - DOM node innerText
|
||||
// | title: { node: "titleNode", type: "innerText" }
|
||||
// Maps this.title to this.titleNode.innerText
|
||||
//
|
||||
// - DOM node CSS class
|
||||
// | myClass: { node: "domNode", type: "class" }
|
||||
// Maps this.myClass to this.domNode.className
|
||||
//
|
||||
// If the value is an array, then each element in the array matches one of the
|
||||
// formats of the above list.
|
||||
//
|
||||
// There are also some shorthands for backwards compatibility:
|
||||
// - string --> { node: string, type: "attribute" }, for example:
|
||||
// | "focusNode" ---> { node: "focusNode", type: "attribute" }
|
||||
// - "" --> { node: "domNode", type: "attribute" }
|
||||
attributeMap: {id:"", dir:"", lang:"", "class":"", style:"", title:""},
|
||||
|
||||
// _blankGif: [protected] String
|
||||
// Path to a blank 1x1 image.
|
||||
// Used by <img> nodes in templates that really get their image via CSS background-image.
|
||||
_blankGif: (dojo.config.blankGif || dojo.moduleUrl("dojo", "resources/blank.gif")).toString(),
|
||||
|
||||
//////////// INITIALIZATION METHODS ///////////////////////////////////////
|
||||
|
||||
postscript: function(/*Object?*/params, /*DomNode|String*/srcNodeRef){
|
||||
// summary:
|
||||
// Kicks off widget instantiation. See create() for details.
|
||||
// tags:
|
||||
// private
|
||||
this.create(params, srcNodeRef);
|
||||
},
|
||||
|
||||
create: function(/*Object?*/params, /*DomNode|String?*/srcNodeRef){
|
||||
// summary:
|
||||
// Kick off the life-cycle of a widget
|
||||
// params:
|
||||
// Hash of initialization parameters for widget, including
|
||||
// scalar values (like title, duration etc.) and functions,
|
||||
// typically callbacks like onClick.
|
||||
// srcNodeRef:
|
||||
// If a srcNodeRef (DOM node) is specified:
|
||||
// - use srcNodeRef.innerHTML as my contents
|
||||
// - if this is a behavioral widget then apply behavior
|
||||
// to that srcNodeRef
|
||||
// - otherwise, replace srcNodeRef with my generated DOM
|
||||
// tree
|
||||
// description:
|
||||
// Create calls a number of widget methods (postMixInProperties, buildRendering, postCreate,
|
||||
// etc.), some of which of you'll want to override. See http://docs.dojocampus.org/dijit/_Widget
|
||||
// for a discussion of the widget creation lifecycle.
|
||||
//
|
||||
// Of course, adventurous developers could override create entirely, but this should
|
||||
// only be done as a last resort.
|
||||
// tags:
|
||||
// private
|
||||
|
||||
// store pointer to original DOM tree
|
||||
this.srcNodeRef = dojo.byId(srcNodeRef);
|
||||
|
||||
// For garbage collection. An array of handles returned by Widget.connect()
|
||||
// Each handle returned from Widget.connect() is an array of handles from dojo.connect()
|
||||
this._connects = [];
|
||||
|
||||
// For garbage collection. An array of handles returned by Widget.subscribe()
|
||||
// The handle returned from Widget.subscribe() is the handle returned from dojo.subscribe()
|
||||
this._subscribes = [];
|
||||
|
||||
// mix in our passed parameters
|
||||
if(this.srcNodeRef && (typeof this.srcNodeRef.id == "string")){ this.id = this.srcNodeRef.id; }
|
||||
if(params){
|
||||
this.params = params;
|
||||
dojo._mixin(this, params);
|
||||
}
|
||||
this.postMixInProperties();
|
||||
|
||||
// generate an id for the widget if one wasn't specified
|
||||
// (be sure to do this before buildRendering() because that function might
|
||||
// expect the id to be there.)
|
||||
if(!this.id){
|
||||
this.id = dijit.getUniqueId(this.declaredClass.replace(/\./g,"_"));
|
||||
}
|
||||
dijit.registry.add(this);
|
||||
|
||||
this.buildRendering();
|
||||
|
||||
if(this.domNode){
|
||||
// Copy attributes listed in attributeMap into the [newly created] DOM for the widget.
|
||||
// Also calls custom setters for all attributes with custom setters.
|
||||
this._applyAttributes();
|
||||
|
||||
// If srcNodeRef was specified, then swap out original srcNode for this widget's DOM tree.
|
||||
// For 2.0, move this after postCreate(). postCreate() shouldn't depend on the
|
||||
// widget being attached to the DOM since it isn't when a widget is created programmatically like
|
||||
// new MyWidget({}). See #11635.
|
||||
var source = this.srcNodeRef;
|
||||
if(source && source.parentNode && this.domNode !== source){
|
||||
source.parentNode.replaceChild(this.domNode, source);
|
||||
}
|
||||
}
|
||||
|
||||
if(this.domNode){
|
||||
// Note: for 2.0 may want to rename widgetId to dojo._scopeName + "_widgetId",
|
||||
// assuming that dojo._scopeName even exists in 2.0
|
||||
this.domNode.setAttribute("widgetId", this.id);
|
||||
}
|
||||
this.postCreate();
|
||||
|
||||
// If srcNodeRef has been processed and removed from the DOM (e.g. TemplatedWidget) then delete it to allow GC.
|
||||
if(this.srcNodeRef && !this.srcNodeRef.parentNode){
|
||||
delete this.srcNodeRef;
|
||||
}
|
||||
|
||||
this._created = true;
|
||||
},
|
||||
|
||||
_applyAttributes: function(){
|
||||
// summary:
|
||||
// Step during widget creation to copy all widget attributes to the
|
||||
// DOM as per attributeMap and _setXXXAttr functions.
|
||||
// description:
|
||||
// Skips over blank/false attribute values, unless they were explicitly specified
|
||||
// as parameters to the widget, since those are the default anyway,
|
||||
// and setting tabIndex="" is different than not setting tabIndex at all.
|
||||
//
|
||||
// It processes the attributes in the attribute map first, and then
|
||||
// it goes through and processes the attributes for the _setXXXAttr
|
||||
// functions that have been specified
|
||||
// tags:
|
||||
// private
|
||||
var condAttrApply = function(attr, scope){
|
||||
if((scope.params && attr in scope.params) || scope[attr]){
|
||||
scope.set(attr, scope[attr]);
|
||||
}
|
||||
};
|
||||
|
||||
// Do the attributes in attributeMap
|
||||
for(var attr in this.attributeMap){
|
||||
condAttrApply(attr, this);
|
||||
}
|
||||
|
||||
// And also any attributes with custom setters
|
||||
dojo.forEach(this._getSetterAttributes(), function(a){
|
||||
if(!(a in this.attributeMap)){
|
||||
condAttrApply(a, this);
|
||||
}
|
||||
}, this);
|
||||
},
|
||||
|
||||
_getSetterAttributes: function(){
|
||||
// summary:
|
||||
// Returns list of attributes with custom setters for this widget
|
||||
var ctor = this.constructor;
|
||||
if(!ctor._setterAttrs){
|
||||
var r = (ctor._setterAttrs = []),
|
||||
attrs,
|
||||
proto = ctor.prototype;
|
||||
for(var fxName in proto){
|
||||
if(dojo.isFunction(proto[fxName]) && (attrs = fxName.match(/^_set([a-zA-Z]*)Attr$/)) && attrs[1]){
|
||||
r.push(attrs[1].charAt(0).toLowerCase() + attrs[1].substr(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
return ctor._setterAttrs; // String[]
|
||||
},
|
||||
|
||||
postMixInProperties: function(){
|
||||
// summary:
|
||||
// Called after the parameters to the widget have been read-in,
|
||||
// but before the widget template is instantiated. Especially
|
||||
// useful to set properties that are referenced in the widget
|
||||
// template.
|
||||
// tags:
|
||||
// protected
|
||||
},
|
||||
|
||||
buildRendering: function(){
|
||||
// summary:
|
||||
// Construct the UI for this widget, setting this.domNode
|
||||
// description:
|
||||
// Most widgets will mixin `dijit._Templated`, which implements this
|
||||
// method.
|
||||
// tags:
|
||||
// protected
|
||||
|
||||
if(!this.domNode){
|
||||
// Create root node if it wasn't created by _Templated
|
||||
this.domNode = this.srcNodeRef || dojo.create('div');
|
||||
}
|
||||
|
||||
// baseClass is a single class name or occasionally a space-separated list of names.
|
||||
// Add those classes to the DOMNode. If RTL mode then also add with Rtl suffix.
|
||||
// TODO: make baseClass custom setter
|
||||
if(this.baseClass){
|
||||
var classes = this.baseClass.split(" ");
|
||||
if(!this.isLeftToRight()){
|
||||
classes = classes.concat( dojo.map(classes, function(name){ return name+"Rtl"; }));
|
||||
}
|
||||
dojo.addClass(this.domNode, classes);
|
||||
}
|
||||
},
|
||||
|
||||
postCreate: function(){
|
||||
// summary:
|
||||
// Processing after the DOM fragment is created
|
||||
// description:
|
||||
// Called after the DOM fragment has been created, but not necessarily
|
||||
// added to the document. Do not include any operations which rely on
|
||||
// node dimensions or placement.
|
||||
// tags:
|
||||
// protected
|
||||
},
|
||||
|
||||
startup: function(){
|
||||
// summary:
|
||||
// Processing after the DOM fragment is added to the document
|
||||
// description:
|
||||
// Called after a widget and its children have been created and added to the page,
|
||||
// and all related widgets have finished their create() cycle, up through postCreate().
|
||||
// This is useful for composite widgets that need to control or layout sub-widgets.
|
||||
// Many layout widgets can use this as a wiring phase.
|
||||
this._started = true;
|
||||
},
|
||||
|
||||
//////////// DESTROY FUNCTIONS ////////////////////////////////
|
||||
|
||||
destroyRecursive: function(/*Boolean?*/ preserveDom){
|
||||
// summary:
|
||||
// Destroy this widget and its descendants
|
||||
// description:
|
||||
// This is the generic "destructor" function that all widget users
|
||||
// should call to cleanly discard with a widget. Once a widget is
|
||||
// destroyed, it is removed from the manager object.
|
||||
// preserveDom:
|
||||
// If true, this method will leave the original DOM structure
|
||||
// alone of descendant Widgets. Note: This will NOT work with
|
||||
// dijit._Templated widgets.
|
||||
|
||||
this._beingDestroyed = true;
|
||||
this.destroyDescendants(preserveDom);
|
||||
this.destroy(preserveDom);
|
||||
},
|
||||
|
||||
destroy: function(/*Boolean*/ preserveDom){
|
||||
// summary:
|
||||
// Destroy this widget, but not its descendants.
|
||||
// This method will, however, destroy internal widgets such as those used within a template.
|
||||
// preserveDom: Boolean
|
||||
// If true, this method will leave the original DOM structure alone.
|
||||
// Note: This will not yet work with _Templated widgets
|
||||
|
||||
this._beingDestroyed = true;
|
||||
this.uninitialize();
|
||||
var d = dojo,
|
||||
dfe = d.forEach,
|
||||
dun = d.unsubscribe;
|
||||
dfe(this._connects, function(array){
|
||||
dfe(array, d.disconnect);
|
||||
});
|
||||
dfe(this._subscribes, function(handle){
|
||||
dun(handle);
|
||||
});
|
||||
|
||||
// destroy widgets created as part of template, etc.
|
||||
dfe(this._supportingWidgets || [], function(w){
|
||||
if(w.destroyRecursive){
|
||||
w.destroyRecursive();
|
||||
}else if(w.destroy){
|
||||
w.destroy();
|
||||
}
|
||||
});
|
||||
|
||||
this.destroyRendering(preserveDom);
|
||||
dijit.registry.remove(this.id);
|
||||
this._destroyed = true;
|
||||
},
|
||||
|
||||
destroyRendering: function(/*Boolean?*/ preserveDom){
|
||||
// summary:
|
||||
// Destroys the DOM nodes associated with this widget
|
||||
// preserveDom:
|
||||
// If true, this method will leave the original DOM structure alone
|
||||
// during tear-down. Note: this will not work with _Templated
|
||||
// widgets yet.
|
||||
// tags:
|
||||
// protected
|
||||
|
||||
if(this.bgIframe){
|
||||
this.bgIframe.destroy(preserveDom);
|
||||
delete this.bgIframe;
|
||||
}
|
||||
|
||||
if(this.domNode){
|
||||
if(preserveDom){
|
||||
dojo.removeAttr(this.domNode, "widgetId");
|
||||
}else{
|
||||
dojo.destroy(this.domNode);
|
||||
}
|
||||
delete this.domNode;
|
||||
}
|
||||
|
||||
if(this.srcNodeRef){
|
||||
if(!preserveDom){
|
||||
dojo.destroy(this.srcNodeRef);
|
||||
}
|
||||
delete this.srcNodeRef;
|
||||
}
|
||||
},
|
||||
|
||||
destroyDescendants: function(/*Boolean?*/ preserveDom){
|
||||
// summary:
|
||||
// Recursively destroy the children of this widget and their
|
||||
// descendants.
|
||||
// preserveDom:
|
||||
// If true, the preserveDom attribute is passed to all descendant
|
||||
// widget's .destroy() method. Not for use with _Templated
|
||||
// widgets.
|
||||
|
||||
// get all direct descendants and destroy them recursively
|
||||
dojo.forEach(this.getChildren(), function(widget){
|
||||
if(widget.destroyRecursive){
|
||||
widget.destroyRecursive(preserveDom);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
uninitialize: function(){
|
||||
// summary:
|
||||
// Stub function. Override to implement custom widget tear-down
|
||||
// behavior.
|
||||
// tags:
|
||||
// protected
|
||||
return false;
|
||||
},
|
||||
|
||||
////////////////// GET/SET, CUSTOM SETTERS, ETC. ///////////////////
|
||||
|
||||
_setClassAttr: function(/*String*/ value){
|
||||
// summary:
|
||||
// Custom setter for the CSS "class" attribute
|
||||
// tags:
|
||||
// protected
|
||||
var mapNode = this[this.attributeMap["class"] || 'domNode'];
|
||||
dojo.replaceClass(mapNode, value, this["class"]);
|
||||
this._set("class", value);
|
||||
},
|
||||
|
||||
_setStyleAttr: function(/*String||Object*/ value){
|
||||
// summary:
|
||||
// Sets the style attribute of the widget according to value,
|
||||
// which is either a hash like {height: "5px", width: "3px"}
|
||||
// or a plain string
|
||||
// description:
|
||||
// Determines which node to set the style on based on style setting
|
||||
// in attributeMap.
|
||||
// tags:
|
||||
// protected
|
||||
|
||||
var mapNode = this[this.attributeMap.style || 'domNode'];
|
||||
|
||||
// Note: technically we should revert any style setting made in a previous call
|
||||
// to his method, but that's difficult to keep track of.
|
||||
|
||||
if(dojo.isObject(value)){
|
||||
dojo.style(mapNode, value);
|
||||
}else{
|
||||
if(mapNode.style.cssText){
|
||||
mapNode.style.cssText += "; " + value;
|
||||
}else{
|
||||
mapNode.style.cssText = value;
|
||||
}
|
||||
}
|
||||
|
||||
this._set("style", value);
|
||||
},
|
||||
|
||||
_attrToDom: function(/*String*/ attr, /*String*/ value){
|
||||
// summary:
|
||||
// Reflect a widget attribute (title, tabIndex, duration etc.) to
|
||||
// the widget DOM, as specified in attributeMap.
|
||||
// Note some attributes like "type"
|
||||
// cannot be processed this way as they are not mutable.
|
||||
//
|
||||
// tags:
|
||||
// private
|
||||
|
||||
var commands = this.attributeMap[attr];
|
||||
dojo.forEach(dojo.isArray(commands) ? commands : [commands], function(command){
|
||||
|
||||
// Get target node and what we are doing to that node
|
||||
var mapNode = this[command.node || command || "domNode"]; // DOM node
|
||||
var type = command.type || "attribute"; // class, innerHTML, innerText, or attribute
|
||||
|
||||
switch(type){
|
||||
case "attribute":
|
||||
if(dojo.isFunction(value)){ // functions execute in the context of the widget
|
||||
value = dojo.hitch(this, value);
|
||||
}
|
||||
|
||||
// Get the name of the DOM node attribute; usually it's the same
|
||||
// as the name of the attribute in the widget (attr), but can be overridden.
|
||||
// Also maps handler names to lowercase, like onSubmit --> onsubmit
|
||||
var attrName = command.attribute ? command.attribute :
|
||||
(/^on[A-Z][a-zA-Z]*$/.test(attr) ? attr.toLowerCase() : attr);
|
||||
|
||||
dojo.attr(mapNode, attrName, value);
|
||||
break;
|
||||
case "innerText":
|
||||
mapNode.innerHTML = "";
|
||||
mapNode.appendChild(dojo.doc.createTextNode(value));
|
||||
break;
|
||||
case "innerHTML":
|
||||
mapNode.innerHTML = value;
|
||||
break;
|
||||
case "class":
|
||||
dojo.replaceClass(mapNode, value, this[attr]);
|
||||
break;
|
||||
}
|
||||
}, this);
|
||||
},
|
||||
|
||||
get: function(name){
|
||||
// summary:
|
||||
// Get a property from a widget.
|
||||
// name:
|
||||
// The property to get.
|
||||
// description:
|
||||
// Get a named property from a widget. The property may
|
||||
// potentially be retrieved via a getter method. If no getter is defined, this
|
||||
// just retrieves the object's property.
|
||||
// For example, if the widget has a properties "foo"
|
||||
// and "bar" and a method named "_getFooAttr", calling:
|
||||
// | myWidget.get("foo");
|
||||
// would be equivalent to writing:
|
||||
// | widget._getFooAttr();
|
||||
// and:
|
||||
// | myWidget.get("bar");
|
||||
// would be equivalent to writing:
|
||||
// | widget.bar;
|
||||
var names = this._getAttrNames(name);
|
||||
return this[names.g] ? this[names.g]() : this[name];
|
||||
},
|
||||
|
||||
set: function(name, value){
|
||||
// summary:
|
||||
// Set a property on a widget
|
||||
// name:
|
||||
// The property to set.
|
||||
// value:
|
||||
// The value to set in the property.
|
||||
// description:
|
||||
// Sets named properties on a widget which may potentially be handled by a
|
||||
// setter in the widget.
|
||||
// For example, if the widget has a properties "foo"
|
||||
// and "bar" and a method named "_setFooAttr", calling:
|
||||
// | myWidget.set("foo", "Howdy!");
|
||||
// would be equivalent to writing:
|
||||
// | widget._setFooAttr("Howdy!");
|
||||
// and:
|
||||
// | myWidget.set("bar", 3);
|
||||
// would be equivalent to writing:
|
||||
// | widget.bar = 3;
|
||||
//
|
||||
// set() may also be called with a hash of name/value pairs, ex:
|
||||
// | myWidget.set({
|
||||
// | foo: "Howdy",
|
||||
// | bar: 3
|
||||
// | })
|
||||
// This is equivalent to calling set(foo, "Howdy") and set(bar, 3)
|
||||
|
||||
if(typeof name === "object"){
|
||||
for(var x in name){
|
||||
this.set(x, name[x]);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
var names = this._getAttrNames(name);
|
||||
if(this[names.s]){
|
||||
// use the explicit setter
|
||||
var result = this[names.s].apply(this, Array.prototype.slice.call(arguments, 1));
|
||||
}else{
|
||||
// if param is specified as DOM node attribute, copy it
|
||||
if(name in this.attributeMap){
|
||||
this._attrToDom(name, value);
|
||||
}
|
||||
this._set(name, value);
|
||||
}
|
||||
return result || this;
|
||||
},
|
||||
|
||||
_attrPairNames: {}, // shared between all widgets
|
||||
_getAttrNames: function(name){
|
||||
// summary:
|
||||
// Helper function for get() and set().
|
||||
// Caches attribute name values so we don't do the string ops every time.
|
||||
// tags:
|
||||
// private
|
||||
|
||||
var apn = this._attrPairNames;
|
||||
if(apn[name]){ return apn[name]; }
|
||||
var uc = name.charAt(0).toUpperCase() + name.substr(1);
|
||||
return (apn[name] = {
|
||||
n: name+"Node",
|
||||
s: "_set"+uc+"Attr",
|
||||
g: "_get"+uc+"Attr"
|
||||
});
|
||||
},
|
||||
|
||||
_set: function(/*String*/ name, /*anything*/ value){
|
||||
// summary:
|
||||
// Helper function to set new value for specified attribute, and call handlers
|
||||
// registered with watch() if the value has changed.
|
||||
var oldValue = this[name];
|
||||
this[name] = value;
|
||||
if(this._watchCallbacks && this._created && value !== oldValue){
|
||||
this._watchCallbacks(name, oldValue, value);
|
||||
}
|
||||
},
|
||||
|
||||
toString: function(){
|
||||
// summary:
|
||||
// Returns a string that represents the widget
|
||||
// description:
|
||||
// When a widget is cast to a string, this method will be used to generate the
|
||||
// output. Currently, it does not implement any sort of reversible
|
||||
// serialization.
|
||||
return '[Widget ' + this.declaredClass + ', ' + (this.id || 'NO ID') + ']'; // String
|
||||
},
|
||||
|
||||
getDescendants: function(){
|
||||
// summary:
|
||||
// Returns all the widgets contained by this, i.e., all widgets underneath this.containerNode.
|
||||
// This method should generally be avoided as it returns widgets declared in templates, which are
|
||||
// supposed to be internal/hidden, but it's left here for back-compat reasons.
|
||||
|
||||
return this.containerNode ? dojo.query('[widgetId]', this.containerNode).map(dijit.byNode) : []; // dijit._Widget[]
|
||||
},
|
||||
|
||||
getChildren: function(){
|
||||
// summary:
|
||||
// Returns all the widgets contained by this, i.e., all widgets underneath this.containerNode.
|
||||
// Does not return nested widgets, nor widgets that are part of this widget's template.
|
||||
return this.containerNode ? dijit.findWidgets(this.containerNode) : []; // dijit._Widget[]
|
||||
},
|
||||
|
||||
connect: function(
|
||||
/*Object|null*/ obj,
|
||||
/*String|Function*/ event,
|
||||
/*String|Function*/ method){
|
||||
// summary:
|
||||
// Connects specified obj/event to specified method of this object
|
||||
// and registers for disconnect() on widget destroy.
|
||||
// description:
|
||||
// Provide widget-specific analog to dojo.connect, except with the
|
||||
// implicit use of this widget as the target object.
|
||||
// Events connected with `this.connect` are disconnected upon
|
||||
// destruction.
|
||||
// returns:
|
||||
// A handle that can be passed to `disconnect` in order to disconnect before
|
||||
// the widget is destroyed.
|
||||
// example:
|
||||
// | var btn = new dijit.form.Button();
|
||||
// | // when foo.bar() is called, call the listener we're going to
|
||||
// | // provide in the scope of btn
|
||||
// | btn.connect(foo, "bar", function(){
|
||||
// | console.debug(this.toString());
|
||||
// | });
|
||||
// tags:
|
||||
// protected
|
||||
|
||||
var handles = [dojo._connect(obj, event, this, method)];
|
||||
this._connects.push(handles);
|
||||
return handles; // _Widget.Handle
|
||||
},
|
||||
|
||||
disconnect: function(/* _Widget.Handle */ handles){
|
||||
// summary:
|
||||
// Disconnects handle created by `connect`.
|
||||
// Also removes handle from this widget's list of connects.
|
||||
// tags:
|
||||
// protected
|
||||
for(var i=0; i<this._connects.length; i++){
|
||||
if(this._connects[i] == handles){
|
||||
dojo.forEach(handles, dojo.disconnect);
|
||||
this._connects.splice(i, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
subscribe: function(
|
||||
/*String*/ topic,
|
||||
/*String|Function*/ method){
|
||||
// summary:
|
||||
// Subscribes to the specified topic and calls the specified method
|
||||
// of this object and registers for unsubscribe() on widget destroy.
|
||||
// description:
|
||||
// Provide widget-specific analog to dojo.subscribe, except with the
|
||||
// implicit use of this widget as the target object.
|
||||
// example:
|
||||
// | var btn = new dijit.form.Button();
|
||||
// | // when /my/topic is published, this button changes its label to
|
||||
// | // be the parameter of the topic.
|
||||
// | btn.subscribe("/my/topic", function(v){
|
||||
// | this.set("label", v);
|
||||
// | });
|
||||
var handle = dojo.subscribe(topic, this, method);
|
||||
|
||||
// return handles for Any widget that may need them
|
||||
this._subscribes.push(handle);
|
||||
return handle;
|
||||
},
|
||||
|
||||
unsubscribe: function(/*Object*/ handle){
|
||||
// summary:
|
||||
// Unsubscribes handle created by this.subscribe.
|
||||
// Also removes handle from this widget's list of subscriptions
|
||||
for(var i=0; i<this._subscribes.length; i++){
|
||||
if(this._subscribes[i] == handle){
|
||||
dojo.unsubscribe(handle);
|
||||
this._subscribes.splice(i, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
isLeftToRight: function(){
|
||||
// summary:
|
||||
// Return this widget's explicit or implicit orientation (true for LTR, false for RTL)
|
||||
// tags:
|
||||
// protected
|
||||
return this.dir ? (this.dir == "ltr") : dojo._isBodyLtr(); //Boolean
|
||||
},
|
||||
|
||||
placeAt: function(/* String|DomNode|_Widget */reference, /* String?|Int? */position){
|
||||
// summary:
|
||||
// Place this widget's domNode reference somewhere in the DOM based
|
||||
// on standard dojo.place conventions, or passing a Widget reference that
|
||||
// contains and addChild member.
|
||||
//
|
||||
// description:
|
||||
// A convenience function provided in all _Widgets, providing a simple
|
||||
// shorthand mechanism to put an existing (or newly created) Widget
|
||||
// somewhere in the dom, and allow chaining.
|
||||
//
|
||||
// reference:
|
||||
// The String id of a domNode, a domNode reference, or a reference to a Widget posessing
|
||||
// an addChild method.
|
||||
//
|
||||
// position:
|
||||
// If passed a string or domNode reference, the position argument
|
||||
// accepts a string just as dojo.place does, one of: "first", "last",
|
||||
// "before", or "after".
|
||||
//
|
||||
// If passed a _Widget reference, and that widget reference has an ".addChild" method,
|
||||
// it will be called passing this widget instance into that method, supplying the optional
|
||||
// position index passed.
|
||||
//
|
||||
// returns:
|
||||
// dijit._Widget
|
||||
// Provides a useful return of the newly created dijit._Widget instance so you
|
||||
// can "chain" this function by instantiating, placing, then saving the return value
|
||||
// to a variable.
|
||||
//
|
||||
// example:
|
||||
// | // create a Button with no srcNodeRef, and place it in the body:
|
||||
// | var button = new dijit.form.Button({ label:"click" }).placeAt(dojo.body());
|
||||
// | // now, 'button' is still the widget reference to the newly created button
|
||||
// | dojo.connect(button, "onClick", function(e){ console.log('click'); });
|
||||
//
|
||||
// example:
|
||||
// | // create a button out of a node with id="src" and append it to id="wrapper":
|
||||
// | var button = new dijit.form.Button({},"src").placeAt("wrapper");
|
||||
//
|
||||
// example:
|
||||
// | // place a new button as the first element of some div
|
||||
// | var button = new dijit.form.Button({ label:"click" }).placeAt("wrapper","first");
|
||||
//
|
||||
// example:
|
||||
// | // create a contentpane and add it to a TabContainer
|
||||
// | var tc = dijit.byId("myTabs");
|
||||
// | new dijit.layout.ContentPane({ href:"foo.html", title:"Wow!" }).placeAt(tc)
|
||||
|
||||
if(reference.declaredClass && reference.addChild){
|
||||
reference.addChild(this, position);
|
||||
}else{
|
||||
dojo.place(this.domNode, reference, position);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
})();
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user