cacert-testmgr/external/ZendFramework-1.9.5/externals/dojo/dijit/_Widget.js

1009 lines
31 KiB
JavaScript
Raw Normal View History

dojo.provide("dijit._Widget");
//>>excludeStart("dijitBaseExclude", kwArgs.customDijitBase == "true");
dojo.require( "dijit._base" );
//>>excludeEnd("dijitBaseExclude");
dojo.connect(dojo, "connect",
function(/*Widget*/ widget, /*String*/ event){
if(widget && dojo.isFunction(widget._onConnect)){
widget._onConnect(event);
}
});
dijit._connectOnUseEventHandler = function(/*Event*/ event){};
(function(){
var _attrReg = {};
var getAttrReg = function(dc){
if(!_attrReg[dc]){
var r = [];
var attrs;
var proto = dojo.getObject(dc).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));
}
}
_attrReg[dc] = r;
}
return _attrReg[dc]||[];
}
dojo.declare("dijit._Widget", null, {
// summary:
// Base class for all dijit widgets.
// 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
// Unsupported by Dijit, but here for completeness. Dijit only supports setting text direction on the
// entire document.
// 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".
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, used to specify the title of tabs, accordion panes, etc.
title: "",
// 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,
// 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 attr('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 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:""},
// _deferredConnects: [protected] Object
// attributeMap addendum for event handlers that should be connected only on first use
_deferredConnects: {
onClick: "",
onDblClick: "",
onKeyDown: "",
onKeyPress: "",
onKeyUp: "",
onMouseMove: "",
onMouseDown: "",
onMouseOut: "",
onMouseOver: "",
onMouseLeave: "",
onMouseEnter: "",
onMouseUp: ""},
onClick: dijit._connectOnUseEventHandler,
/*=====
onClick: function(event){
// summary:
// Connect to this function to receive notifications of mouse click events.
// event:
// mouse Event
// tags:
// callback
},
=====*/
onDblClick: dijit._connectOnUseEventHandler,
/*=====
onDblClick: function(event){
// summary:
// Connect to this function to receive notifications of mouse double click events.
// event:
// mouse Event
// tags:
// callback
},
=====*/
onKeyDown: dijit._connectOnUseEventHandler,
/*=====
onKeyDown: function(event){
// summary:
// Connect to this function to receive notifications of keys being pressed down.
// event:
// key Event
// tags:
// callback
},
=====*/
onKeyPress: dijit._connectOnUseEventHandler,
/*=====
onKeyPress: function(event){
// summary:
// Connect to this function to receive notifications of printable keys being typed.
// event:
// key Event
// tags:
// callback
},
=====*/
onKeyUp: dijit._connectOnUseEventHandler,
/*=====
onKeyUp: function(event){
// summary:
// Connect to this function to receive notifications of keys being released.
// event:
// key Event
// tags:
// callback
},
=====*/
onMouseDown: dijit._connectOnUseEventHandler,
/*=====
onMouseDown: function(event){
// summary:
// Connect to this function to receive notifications of when the mouse button is pressed down.
// event:
// mouse Event
// tags:
// callback
},
=====*/
onMouseMove: dijit._connectOnUseEventHandler,
/*=====
onMouseMove: function(event){
// summary:
// Connect to this function to receive notifications of when the mouse moves over nodes contained within this widget.
// event:
// mouse Event
// tags:
// callback
},
=====*/
onMouseOut: dijit._connectOnUseEventHandler,
/*=====
onMouseOut: function(event){
// summary:
// Connect to this function to receive notifications of when the mouse moves off of nodes contained within this widget.
// event:
// mouse Event
// tags:
// callback
},
=====*/
onMouseOver: dijit._connectOnUseEventHandler,
/*=====
onMouseOver: function(event){
// summary:
// Connect to this function to receive notifications of when the mouse moves onto nodes contained within this widget.
// event:
// mouse Event
// tags:
// callback
},
=====*/
onMouseLeave: dijit._connectOnUseEventHandler,
/*=====
onMouseLeave: function(event){
// summary:
// Connect to this function to receive notifications of when the mouse moves off of this widget.
// event:
// mouse Event
// tags:
// callback
},
=====*/
onMouseEnter: dijit._connectOnUseEventHandler,
/*=====
onMouseEnter: function(event){
// summary:
// Connect to this function to receive notifications of when the mouse moves onto this widget.
// event:
// mouse Event
// tags:
// callback
},
=====*/
onMouseUp: dijit._connectOnUseEventHandler,
/*=====
onMouseUp: function(event){
// summary:
// Connect to this function to receive notifications of when the mouse button is released.
// event:
// mouse Event
// tags:
// callback
},
=====*/
// Constants used in templates
// _blankGif: [protected] URL
// Used by <img> nodes in templates that really get there image via CSS background-image
_blankGif: (dojo.config.blankGif || dojo.moduleUrl("dojo", "resources/blank.gif")),
//////////// 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:
// To understand the process by which widgets are instantiated, it
// is critical to understand what other methods create calls and
// which of them you'll want to override. Of course, adventurous
// developers could override create entirely, but this should
// only be done as a last resort.
//
// Below is a list of the methods that are called, in the order
// they are fired, along with notes about what they do and if/when
// you should over-ride them in your widget:
//
// * postMixInProperties:
// | * a stub function that you can over-ride to modify
// variables that may have been naively assigned by
// mixInProperties
// * widget is added to manager object here
// * buildRendering:
// | * Subclasses use this method to handle all UI initialization
// Sets this.domNode. Templated widgets do this automatically
// and otherwise it just uses the source dom node.
// * postCreate:
// | * a stub function that you can over-ride to modify take
// actions once the widget has been placed in the UI
// 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 = [];
// To avoid double-connects, remove entries from _deferredConnects
// that have been setup manually by a subclass (ex, by dojoAttachEvent).
// If a subclass has redefined a callback (ex: onClick) then assume it's being
// connected to manually.
this._deferredConnects = dojo.clone(this._deferredConnects);
for(var attr in this.attributeMap){
delete this._deferredConnects[attr]; // can't be in both attributeMap and _deferredConnects
}
for(attr in this._deferredConnects){
if(this[attr] !== dijit._connectOnUseEventHandler){
delete this._deferredConnects[attr]; // redefined, probably dojoAttachEvent exists
}
}
//mixin 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.
this._applyAttributes();
var source = this.srcNodeRef;
if(source && source.parentNode){
source.parentNode.replaceChild(this.domNode, source);
}
// If the developer has specified a handler as a widget parameter
// (ex: new Button({onClick: ...})
// then naturally need to connect from dom node to that handler immediately,
for(attr in this.params){
this._onConnect(attr);
}
}
if(this.domNode){
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.attr(attr, scope[attr]);
}
};
for(var attr in this.attributeMap){
condAttrApply(attr, this);
}
dojo.forEach(getAttrReg(this.declaredClass), function(a){
if(!(a in this.attributeMap)){
condAttrApply(a, this);
}
}, this);
},
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. Most
// widgets will mixin `dijit._Templated`, which implements this
// method.
// tags:
// protected
this.domNode = this.srcNodeRef || dojo.create('div');
},
postCreate: function(){
// summary:
// Called after a widget's dom has been setup
// tags:
// protected
},
startup: function(){
// summary:
// Called after a widget's children, and other widgets on the page, have been created.
// Provides an opportunity to manipulate any children before they are displayed.
// 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 it's descendants. This is the generic
// "destructor" function that all widget users should call to
// cleanly discard with a widget. Once a widget is destroyed, it's
// 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.destroyDescendants(preserveDom);
this.destroy(preserveDom);
},
destroy: function(/*Boolean*/ preserveDom){
// summary:
// Destroy this widget, but not its descendants.
// 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.uninitialize();
dojo.forEach(this._connects, function(array){
dojo.forEach(array, dojo.disconnect);
});
// destroy widgets created as part of template, etc.
dojo.forEach(this._supportingWidgets||[], function(w){
if(w.destroy){
w.destroy();
}
});
this.destroyRendering(preserveDom);
dijit.registry.remove(this.id);
},
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;
},
////////////////// MISCELLANEOUS METHODS ///////////////////
onFocus: function(){
// summary:
// Called when the widget becomes "active" because
// it or a widget inside of it either has focus, or has recently
// been clicked.
// tags:
// callback
},
onBlur: function(){
// summary:
// Called when the widget stops being "active" because
// focus moved to something outside of it, or the user
// clicked somewhere outside of it, or the widget was
// hidden.
// tags:
// callback
},
_onFocus: function(e){
// summary:
// This is where widgets do processing for when they are active,
// such as changing CSS classes. See onFocus() for more details.
// tags:
// protected
this.onFocus();
},
_onBlur: function(){
// summary:
// This is where widgets do processing for when they stop being active,
// such as changing CSS classes. See onBlur() for more details.
// tags:
// protected
this.onBlur();
},
_onConnect: function(/*String*/ event){
// summary:
// Called when someone connects to one of my handlers.
// "Turn on" that handler if it isn't active yet.
//
// This is also called for every single initialization parameter
// so need to do nothing for parameters like "id".
// tags:
// private
if(event in this._deferredConnects){
var mapNode = this[this._deferredConnects[event]||'domNode'];
this.connect(mapNode, event.toLowerCase(), event);
delete this._deferredConnects[event];
}
},
_setClassAttr: function(/*String*/ value){
// summary:
// Custom setter for the CSS "class" attribute
// tags:
// protected
var mapNode = this[this.attributeMap["class"]||'domNode'];
dojo.removeClass(mapNode, this["class"])
this["class"] = value;
dojo.addClass(mapNode, value);
},
_setStyleAttr: function(/*String||Object*/ value){
// summary:
// Sets the style attribut 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["style"] = value;
},
setAttribute: function(/*String*/ attr, /*anything*/ value){
// summary:
// Deprecated. Use attr() instead.
// tags:
// deprecated
dojo.deprecated(this.declaredClass+"::setAttribute() is deprecated. Use attr() instead.", "", "2.0");
this.attr(attr, value);
},
_attrToDom: function(/*String*/ attr, /*String*/ value){
// summary:
// Reflect a widget attribute (title, tabIndex, duration etc.) to
// the widget DOM, as specified in attributeMap.
//
// description:
// Also sets this["attr"] to the new value.
// 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, or attribute
switch(type){
case "attribute":
if(dojo.isFunction(value)){ // functions execute in the context of the widget
value = dojo.hitch(this, value);
}
if(/^on[A-Z][a-zA-Z]*$/.test(attr)){ // eg. onSubmit needs to be onsubmit
attr = attr.toLowerCase();
}
dojo.attr(mapNode, attr, value);
break;
case "innerHTML":
mapNode.innerHTML = value;
break;
case "class":
dojo.removeClass(mapNode, this[attr]);
dojo.addClass(mapNode, value);
break;
}
}, this);
this[attr] = value;
},
attr: function(/*String|Object*/name, /*Object?*/value){
// summary:
// Set or get properties on a widget instance.
// name:
// The property to get or set. If an object is passed here and not
// a string, its keys are used as names of attributes to be set
// and the value of the object as values to set in the widget.
// value:
// Optional. If provided, attr() operates as a setter. If omitted,
// the current value of the named property is returned.
// description:
// Get or set named properties on a widget. If no value is
// provided, the current value of the attribute is returned,
// potentially via a getter method. If a value is provided, then
// the method acts as a setter, assigning the value to the name,
// potentially calling any explicitly provided setters to handle
// the operation. For instance, if the widget has properties "foo"
// and "bar" and a method named "_setFooAttr", calling:
// | myWidget.attr("foo", "Howdy!");
// would be equivalent to calling:
// | widget._setFooAttr("Howdy!");
// while calling:
// | myWidget.attr("bar", "Howdy!");
// would be the same as writing:
// | widget.bar = "Howdy!";
// It also tries to copy the changes to the widget's DOM according
// to settings in attributeMap (see description of `dijit._Widget.attributeMap`
// for details)
// For example, calling:
// | myTitlePane.attr("title", "Howdy!");
// will do
// | myTitlePane.title = "Howdy!";
// | myTitlePane.title.innerHTML = "Howdy!";
// It works for dom node attributes too. Calling
// | widget.attr("disabled", true)
// will set the disabled attribute on the widget's focusNode,
// among other housekeeping for a change in disabled state.
// open questions:
// - how to handle build shortcut for attributes which want to map
// into DOM attributes?
// - what relationship should setAttribute()/attr() have to
// layout() calls?
var args = arguments.length;
if(args == 1 && !dojo.isString(name)){
for(var x in name){ this.attr(x, name[x]); }
return this;
}
var names = this._getAttrNames(name);
if(args == 2){ // setter
if(this[names.s]){
// use the explicit setter
return this[names.s](value) || this;
}else{
// if param is specified as DOM node attribute, copy it
if(name in this.attributeMap){
this._attrToDom(name, value);
}
// FIXME: what about function assignments? Any way to connect() here?
this[name] = value;
}
return this;
}else{ // getter
if(this[names.g]){
return this[names.g]();
}else{
return this[name];
}
}
},
_attrPairNames: {}, // shared between all widgets
_getAttrNames: function(name){
// summary:
// Helper function for Widget.attr().
// 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"
};
},
toString: function(){
// summary:
// Returns a string that represents the widget. 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 reversable
// serialization.
return '[Widget ' + this.declaredClass + ', ' + (this.id || 'NO ID') + ']'; // String
},
getDescendants: function(){
// summary:
// Returns all the widgets that 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.
if(this.containerNode){
var list = dojo.query('[widgetId]', this.containerNode);
return list.map(dijit.byNode); // Array
}else{
return [];
}
},
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.
if(this.containerNode){
return dijit.findWidgets(this.containerNode);
}else{
return [];
}
},
// nodesWithKeyClick: [private] String[]
// List of nodes that correctly handle click events via native browser support,
// and don't need dijit's help
nodesWithKeyClick: ["input", "button"],
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.
// This version of connect also provides a special "ondijitclick"
// event which triggers on a click or space-up, enter-down in IE
// or enter press in FF (since often can't cancel enter onkeydown
// in FF)
// 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 d = dojo;
var dc = dojo.connect;
var handles =[];
if(event == "ondijitclick"){
// add key based click activation for unsupported nodes.
if(!this.nodesWithKeyClick[obj.nodeName]){
var m = d.hitch(this, method);
handles.push(
dc(obj, "onkeydown", this, function(e){
if(!d.isFF && e.keyCode == d.keys.ENTER &&
!e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey){
return m(e);
}else if(e.keyCode == d.keys.SPACE){
// stop space down as it causes IE to scroll
// the browser window
d.stopEvent(e);
}
}),
dc(obj, "onkeyup", this, function(e){
if(e.keyCode == d.keys.SPACE &&
!e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey){ return m(e); }
})
);
if(d.isFF){
handles.push(
dc(obj, "onkeypress", this, function(e){
if(e.keyCode == d.keys.ENTER &&
!e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey){ return m(e); }
})
);
}
}
event = "onclick";
}
handles.push(dc(obj, event, this, method));
// return handles for FormElement and ComboBox
this._connects.push(handles);
return handles;
},
disconnect: function(/*Object*/ handles){
// summary:
// Disconnects handle created by this.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;
}
}
},
isLeftToRight: function(){
// summary:
// Checks the page for text direction
// tags:
// protected
return dojo._isBodyLtr(); //Boolean
},
isFocusable: function(){
// summary:
// Return true if this widget can currently be focused
// and false if not
return this.focus && (dojo.style(this.domNode, "display") != "none");
},
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;
}
});
})();