363 lines
11 KiB
JavaScript
363 lines
11 KiB
JavaScript
define("dijit/_Widget", [
|
|
"dojo/aspect", // aspect.around
|
|
"dojo/_base/config", // config.isDebug
|
|
"dojo/_base/connect", // connect.connect
|
|
"dojo/_base/declare", // declare
|
|
"dojo/has",
|
|
"dojo/_base/kernel", // kernel.deprecated
|
|
"dojo/_base/lang", // lang.hitch
|
|
"dojo/query",
|
|
"dojo/ready",
|
|
"./registry", // registry.byNode
|
|
"./_WidgetBase",
|
|
"./_OnDijitClickMixin",
|
|
"./_FocusMixin",
|
|
"dojo/uacss", // browser sniffing (included for back-compat; subclasses may be using)
|
|
"./hccss" // high contrast mode sniffing (included to set CSS classes on <body>, module ret value unused)
|
|
], function(aspect, config, connect, declare, has, kernel, lang, query, ready,
|
|
registry, _WidgetBase, _OnDijitClickMixin, _FocusMixin){
|
|
|
|
|
|
// module:
|
|
// dijit/_Widget
|
|
|
|
|
|
function connectToDomNode(){
|
|
// summary:
|
|
// If user connects to a widget method === this function, then they will
|
|
// instead actually be connecting the equivalent event on this.domNode
|
|
}
|
|
|
|
// Trap dojo.connect() calls to connectToDomNode methods, and redirect to _Widget.on()
|
|
function aroundAdvice(originalConnect){
|
|
return function(obj, event, scope, method){
|
|
if(obj && typeof event == "string" && obj[event] == connectToDomNode){
|
|
return obj.on(event.substring(2).toLowerCase(), lang.hitch(scope, method));
|
|
}
|
|
return originalConnect.apply(connect, arguments);
|
|
};
|
|
}
|
|
aspect.around(connect, "connect", aroundAdvice);
|
|
if(kernel.connect){
|
|
aspect.around(kernel, "connect", aroundAdvice);
|
|
}
|
|
|
|
var _Widget = declare("dijit._Widget", [_WidgetBase, _OnDijitClickMixin, _FocusMixin], {
|
|
// summary:
|
|
// Old base class for widgets. New widgets should extend `dijit/_WidgetBase` instead
|
|
// description:
|
|
// Old Base class for Dijit widgets.
|
|
//
|
|
// Extends _WidgetBase, adding support for:
|
|
//
|
|
// - declaratively/programatically specifying widget initialization parameters like
|
|
// onMouseMove="foo" that call foo when this.domNode gets a mousemove event
|
|
// - ondijitclick:
|
|
// Support new data-dojo-attach-event="ondijitclick: ..." that is triggered by a mouse click or a SPACE/ENTER keypress
|
|
// - focus related functions:
|
|
// In particular, the onFocus()/onBlur() callbacks. Driven internally by
|
|
// dijit/_base/focus.js.
|
|
// - deprecated methods
|
|
// - onShow(), onHide(), onClose()
|
|
//
|
|
// Also, by loading code in dijit/_base, turns on:
|
|
//
|
|
// - browser sniffing (putting browser class like `dj_ie` on `<html>` node)
|
|
// - high contrast mode sniffing (add `dijit_a11y` class to `<body>` if machine is in high contrast mode)
|
|
|
|
|
|
////////////////// DEFERRED CONNECTS ///////////////////
|
|
|
|
onClick: connectToDomNode,
|
|
/*=====
|
|
onClick: function(event){
|
|
// summary:
|
|
// Connect to this function to receive notifications of mouse click events.
|
|
// event:
|
|
// mouse Event
|
|
// tags:
|
|
// callback
|
|
},
|
|
=====*/
|
|
onDblClick: connectToDomNode,
|
|
/*=====
|
|
onDblClick: function(event){
|
|
// summary:
|
|
// Connect to this function to receive notifications of mouse double click events.
|
|
// event:
|
|
// mouse Event
|
|
// tags:
|
|
// callback
|
|
},
|
|
=====*/
|
|
onKeyDown: connectToDomNode,
|
|
/*=====
|
|
onKeyDown: function(event){
|
|
// summary:
|
|
// Connect to this function to receive notifications of keys being pressed down.
|
|
// event:
|
|
// key Event
|
|
// tags:
|
|
// callback
|
|
},
|
|
=====*/
|
|
onKeyPress: connectToDomNode,
|
|
/*=====
|
|
onKeyPress: function(event){
|
|
// summary:
|
|
// Connect to this function to receive notifications of printable keys being typed.
|
|
// event:
|
|
// key Event
|
|
// tags:
|
|
// callback
|
|
},
|
|
=====*/
|
|
onKeyUp: connectToDomNode,
|
|
/*=====
|
|
onKeyUp: function(event){
|
|
// summary:
|
|
// Connect to this function to receive notifications of keys being released.
|
|
// event:
|
|
// key Event
|
|
// tags:
|
|
// callback
|
|
},
|
|
=====*/
|
|
onMouseDown: connectToDomNode,
|
|
/*=====
|
|
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: connectToDomNode,
|
|
/*=====
|
|
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: connectToDomNode,
|
|
/*=====
|
|
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: connectToDomNode,
|
|
/*=====
|
|
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: connectToDomNode,
|
|
/*=====
|
|
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: connectToDomNode,
|
|
/*=====
|
|
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: connectToDomNode,
|
|
/*=====
|
|
onMouseUp: function(event){
|
|
// summary:
|
|
// Connect to this function to receive notifications of when the mouse button is released.
|
|
// event:
|
|
// mouse Event
|
|
// tags:
|
|
// callback
|
|
},
|
|
=====*/
|
|
|
|
constructor: function(params /*===== ,srcNodeRef =====*/){
|
|
// summary:
|
|
// Create the widget.
|
|
// params: Object|null
|
|
// Hash of initialization parameters for widget, including scalar values (like title, duration etc.)
|
|
// and functions, typically callbacks like onClick.
|
|
// The hash can contain any of the widget's properties, excluding read-only properties.
|
|
// srcNodeRef: DOMNode|String?
|
|
// 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
|
|
|
|
// extract parameters like onMouseMove that should connect directly to this.domNode
|
|
this._toConnect = {};
|
|
for(var name in params){
|
|
if(this[name] === connectToDomNode){
|
|
this._toConnect[name.replace(/^on/, "").toLowerCase()] = params[name];
|
|
delete params[name];
|
|
}
|
|
}
|
|
},
|
|
|
|
postCreate: function(){
|
|
this.inherited(arguments);
|
|
|
|
// perform connection from this.domNode to user specified handlers (ex: onMouseMove)
|
|
for(var name in this._toConnect){
|
|
this.on(name, this._toConnect[name]);
|
|
}
|
|
delete this._toConnect;
|
|
},
|
|
|
|
on: function(/*String|Function*/ type, /*Function*/ func){
|
|
if(this[this._onMap(type)] === connectToDomNode){
|
|
// Use connect.connect() rather than on() to get handling for "onmouseenter" on non-IE,
|
|
// normalization of onkeypress/onkeydown to behave like firefox, etc.
|
|
// Also, need to specify context as "this" rather than the default context of the DOMNode
|
|
// Remove in 2.0.
|
|
return connect.connect(this.domNode, type.toLowerCase(), this, func);
|
|
}
|
|
return this.inherited(arguments);
|
|
},
|
|
|
|
_setFocusedAttr: function(val){
|
|
// Remove this method in 2.0 (or sooner), just here to set _focused == focused, for back compat
|
|
// (but since it's a private variable we aren't required to keep supporting it).
|
|
this._focused = val;
|
|
this._set("focused", val);
|
|
},
|
|
|
|
////////////////// DEPRECATED METHODS ///////////////////
|
|
|
|
setAttribute: function(/*String*/ attr, /*anything*/ value){
|
|
// summary:
|
|
// Deprecated. Use set() instead.
|
|
// tags:
|
|
// deprecated
|
|
kernel.deprecated(this.declaredClass+"::setAttribute(attr, value) is deprecated. Use set() instead.", "", "2.0");
|
|
this.set(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:
|
|
// This method is deprecated, use get() or set() directly.
|
|
|
|
// Print deprecation warning but only once per calling function
|
|
if(config.isDebug){
|
|
var alreadyCalledHash = arguments.callee._ach || (arguments.callee._ach = {}),
|
|
caller = (arguments.callee.caller || "unknown caller").toString();
|
|
if(!alreadyCalledHash[caller]){
|
|
kernel.deprecated(this.declaredClass + "::attr() is deprecated. Use get() or set() instead, called from " +
|
|
caller, "", "2.0");
|
|
alreadyCalledHash[caller] = true;
|
|
}
|
|
}
|
|
|
|
var args = arguments.length;
|
|
if(args >= 2 || typeof name === "object"){ // setter
|
|
return this.set.apply(this, arguments);
|
|
}else{ // getter
|
|
return this.get(name);
|
|
}
|
|
},
|
|
|
|
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.
|
|
|
|
kernel.deprecated(this.declaredClass+"::getDescendants() is deprecated. Use getChildren() instead.", "", "2.0");
|
|
return this.containerNode ? query('[widgetId]', this.containerNode).map(registry.byNode) : []; // dijit/_WidgetBase[]
|
|
},
|
|
|
|
////////////////// MISCELLANEOUS METHODS ///////////////////
|
|
|
|
_onShow: function(){
|
|
// summary:
|
|
// Internal method called when this widget is made visible.
|
|
// See `onShow` for details.
|
|
this.onShow();
|
|
},
|
|
|
|
onShow: function(){
|
|
// summary:
|
|
// Called when this widget becomes the selected pane in a
|
|
// `dijit/layout/TabContainer`, `dijit/layout/StackContainer`,
|
|
// `dijit/layout/AccordionContainer`, etc.
|
|
//
|
|
// Also called to indicate display of a `dijit.Dialog`, `dijit.TooltipDialog`, or `dijit.TitlePane`.
|
|
// tags:
|
|
// callback
|
|
},
|
|
|
|
onHide: function(){
|
|
// summary:
|
|
// Called when another widget becomes the selected pane in a
|
|
// `dijit/layout/TabContainer`, `dijit/layout/StackContainer`,
|
|
// `dijit/layout/AccordionContainer`, etc.
|
|
//
|
|
// Also called to indicate hide of a `dijit.Dialog`, `dijit.TooltipDialog`, or `dijit.TitlePane`.
|
|
// tags:
|
|
// callback
|
|
},
|
|
|
|
onClose: function(){
|
|
// summary:
|
|
// Called when this widget is being displayed as a popup (ex: a Calendar popped
|
|
// up from a DateTextBox), and it is hidden.
|
|
// This is called from the dijit.popup code, and should not be called directly.
|
|
//
|
|
// Also used as a parameter for children of `dijit/layout/StackContainer` or subclasses.
|
|
// Callback if a user tries to close the child. Child will be closed if this function returns true.
|
|
// tags:
|
|
// extension
|
|
|
|
return true; // Boolean
|
|
}
|
|
});
|
|
|
|
// For back-compat, remove in 2.0.
|
|
if(has("dijit-legacy-requires")){
|
|
ready(0, function(){
|
|
var requires = ["dijit/_base"];
|
|
require(requires); // use indirection so modules not rolled into a build
|
|
});
|
|
}
|
|
return _Widget;
|
|
});
|