_Widget.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. define("dijit/_Widget", [
  2. "dojo/aspect", // aspect.around
  3. "dojo/_base/config", // config.isDebug
  4. "dojo/_base/connect", // connect.connect
  5. "dojo/_base/declare", // declare
  6. "dojo/_base/kernel", // kernel.deprecated
  7. "dojo/_base/lang", // lang.hitch
  8. "dojo/query",
  9. "dojo/ready",
  10. "./registry", // registry.byNode
  11. "./_WidgetBase",
  12. "./_OnDijitClickMixin",
  13. "./_FocusMixin",
  14. "dojo/uacss", // browser sniffing (included for back-compat; subclasses may be using)
  15. "./hccss" // high contrast mode sniffing (included to set CSS classes on <body>, module ret value unused)
  16. ], function(aspect, config, connect, declare, kernel, lang, query, ready,
  17. registry, _WidgetBase, _OnDijitClickMixin, _FocusMixin){
  18. /*=====
  19. var _WidgetBase = dijit._WidgetBase;
  20. var _OnDijitClickMixin = dijit._OnDijitClickMixin;
  21. var _FocusMixin = dijit._FocusMixin;
  22. =====*/
  23. // module:
  24. // dijit/_Widget
  25. // summary:
  26. // Old base for widgets. New widgets should extend _WidgetBase instead
  27. function connectToDomNode(){
  28. // summary:
  29. // If user connects to a widget method === this function, then they will
  30. // instead actually be connecting the equivalent event on this.domNode
  31. }
  32. // Trap dojo.connect() calls to connectToDomNode methods, and redirect to _Widget.on()
  33. function aroundAdvice(originalConnect){
  34. return function(obj, event, scope, method){
  35. if(obj && typeof event == "string" && obj[event] == connectToDomNode){
  36. return obj.on(event.substring(2).toLowerCase(), lang.hitch(scope, method));
  37. }
  38. return originalConnect.apply(connect, arguments);
  39. };
  40. }
  41. aspect.around(connect, "connect", aroundAdvice);
  42. if(kernel.connect){
  43. aspect.around(kernel, "connect", aroundAdvice);
  44. }
  45. var _Widget = declare("dijit._Widget", [_WidgetBase, _OnDijitClickMixin, _FocusMixin], {
  46. // summary:
  47. // Base class for all Dijit widgets.
  48. //
  49. // Extends _WidgetBase, adding support for:
  50. // - declaratively/programatically specifying widget initialization parameters like
  51. // onMouseMove="foo" that call foo when this.domNode gets a mousemove event
  52. // - ondijitclick
  53. // Support new data-dojo-attach-event="ondijitclick: ..." that is triggered by a mouse click or a SPACE/ENTER keypress
  54. // - focus related functions
  55. // In particular, the onFocus()/onBlur() callbacks. Driven internally by
  56. // dijit/_base/focus.js.
  57. // - deprecated methods
  58. // - onShow(), onHide(), onClose()
  59. //
  60. // Also, by loading code in dijit/_base, turns on:
  61. // - browser sniffing (putting browser id like .dj_ie on <html> node)
  62. // - high contrast mode sniffing (add .dijit_a11y class to <body> if machine is in high contrast mode)
  63. ////////////////// DEFERRED CONNECTS ///////////////////
  64. onClick: connectToDomNode,
  65. /*=====
  66. onClick: function(event){
  67. // summary:
  68. // Connect to this function to receive notifications of mouse click events.
  69. // event:
  70. // mouse Event
  71. // tags:
  72. // callback
  73. },
  74. =====*/
  75. onDblClick: connectToDomNode,
  76. /*=====
  77. onDblClick: function(event){
  78. // summary:
  79. // Connect to this function to receive notifications of mouse double click events.
  80. // event:
  81. // mouse Event
  82. // tags:
  83. // callback
  84. },
  85. =====*/
  86. onKeyDown: connectToDomNode,
  87. /*=====
  88. onKeyDown: function(event){
  89. // summary:
  90. // Connect to this function to receive notifications of keys being pressed down.
  91. // event:
  92. // key Event
  93. // tags:
  94. // callback
  95. },
  96. =====*/
  97. onKeyPress: connectToDomNode,
  98. /*=====
  99. onKeyPress: function(event){
  100. // summary:
  101. // Connect to this function to receive notifications of printable keys being typed.
  102. // event:
  103. // key Event
  104. // tags:
  105. // callback
  106. },
  107. =====*/
  108. onKeyUp: connectToDomNode,
  109. /*=====
  110. onKeyUp: function(event){
  111. // summary:
  112. // Connect to this function to receive notifications of keys being released.
  113. // event:
  114. // key Event
  115. // tags:
  116. // callback
  117. },
  118. =====*/
  119. onMouseDown: connectToDomNode,
  120. /*=====
  121. onMouseDown: function(event){
  122. // summary:
  123. // Connect to this function to receive notifications of when the mouse button is pressed down.
  124. // event:
  125. // mouse Event
  126. // tags:
  127. // callback
  128. },
  129. =====*/
  130. onMouseMove: connectToDomNode,
  131. /*=====
  132. onMouseMove: function(event){
  133. // summary:
  134. // Connect to this function to receive notifications of when the mouse moves over nodes contained within this widget.
  135. // event:
  136. // mouse Event
  137. // tags:
  138. // callback
  139. },
  140. =====*/
  141. onMouseOut: connectToDomNode,
  142. /*=====
  143. onMouseOut: function(event){
  144. // summary:
  145. // Connect to this function to receive notifications of when the mouse moves off of nodes contained within this widget.
  146. // event:
  147. // mouse Event
  148. // tags:
  149. // callback
  150. },
  151. =====*/
  152. onMouseOver: connectToDomNode,
  153. /*=====
  154. onMouseOver: function(event){
  155. // summary:
  156. // Connect to this function to receive notifications of when the mouse moves onto nodes contained within this widget.
  157. // event:
  158. // mouse Event
  159. // tags:
  160. // callback
  161. },
  162. =====*/
  163. onMouseLeave: connectToDomNode,
  164. /*=====
  165. onMouseLeave: function(event){
  166. // summary:
  167. // Connect to this function to receive notifications of when the mouse moves off of this widget.
  168. // event:
  169. // mouse Event
  170. // tags:
  171. // callback
  172. },
  173. =====*/
  174. onMouseEnter: connectToDomNode,
  175. /*=====
  176. onMouseEnter: function(event){
  177. // summary:
  178. // Connect to this function to receive notifications of when the mouse moves onto this widget.
  179. // event:
  180. // mouse Event
  181. // tags:
  182. // callback
  183. },
  184. =====*/
  185. onMouseUp: connectToDomNode,
  186. /*=====
  187. onMouseUp: function(event){
  188. // summary:
  189. // Connect to this function to receive notifications of when the mouse button is released.
  190. // event:
  191. // mouse Event
  192. // tags:
  193. // callback
  194. },
  195. =====*/
  196. constructor: function(params){
  197. // extract parameters like onMouseMove that should connect directly to this.domNode
  198. this._toConnect = {};
  199. for(var name in params){
  200. if(this[name] === connectToDomNode){
  201. this._toConnect[name.replace(/^on/, "").toLowerCase()] = params[name];
  202. delete params[name];
  203. }
  204. }
  205. },
  206. postCreate: function(){
  207. this.inherited(arguments);
  208. // perform connection from this.domNode to user specified handlers (ex: onMouseMove)
  209. for(var name in this._toConnect){
  210. this.on(name, this._toConnect[name]);
  211. }
  212. delete this._toConnect;
  213. },
  214. on: function(/*String*/ type, /*Function*/ func){
  215. if(this[this._onMap(type)] === connectToDomNode){
  216. // Use connect.connect() rather than on() to get handling for "onmouseenter" on non-IE, etc.
  217. // Also, need to specify context as "this" rather than the default context of the DOMNode
  218. return connect.connect(this.domNode, type.toLowerCase(), this, func);
  219. }
  220. return this.inherited(arguments);
  221. },
  222. _setFocusedAttr: function(val){
  223. // Remove this method in 2.0 (or sooner), just here to set _focused == focused, for back compat
  224. // (but since it's a private variable we aren't required to keep supporting it).
  225. this._focused = val;
  226. this._set("focused", val);
  227. },
  228. ////////////////// DEPRECATED METHODS ///////////////////
  229. setAttribute: function(/*String*/ attr, /*anything*/ value){
  230. // summary:
  231. // Deprecated. Use set() instead.
  232. // tags:
  233. // deprecated
  234. kernel.deprecated(this.declaredClass+"::setAttribute(attr, value) is deprecated. Use set() instead.", "", "2.0");
  235. this.set(attr, value);
  236. },
  237. attr: function(/*String|Object*/name, /*Object?*/value){
  238. // summary:
  239. // Set or get properties on a widget instance.
  240. // name:
  241. // The property to get or set. If an object is passed here and not
  242. // a string, its keys are used as names of attributes to be set
  243. // and the value of the object as values to set in the widget.
  244. // value:
  245. // Optional. If provided, attr() operates as a setter. If omitted,
  246. // the current value of the named property is returned.
  247. // description:
  248. // This method is deprecated, use get() or set() directly.
  249. // Print deprecation warning but only once per calling function
  250. if(config.isDebug){
  251. var alreadyCalledHash = arguments.callee._ach || (arguments.callee._ach = {}),
  252. caller = (arguments.callee.caller || "unknown caller").toString();
  253. if(!alreadyCalledHash[caller]){
  254. kernel.deprecated(this.declaredClass + "::attr() is deprecated. Use get() or set() instead, called from " +
  255. caller, "", "2.0");
  256. alreadyCalledHash[caller] = true;
  257. }
  258. }
  259. var args = arguments.length;
  260. if(args >= 2 || typeof name === "object"){ // setter
  261. return this.set.apply(this, arguments);
  262. }else{ // getter
  263. return this.get(name);
  264. }
  265. },
  266. getDescendants: function(){
  267. // summary:
  268. // Returns all the widgets contained by this, i.e., all widgets underneath this.containerNode.
  269. // This method should generally be avoided as it returns widgets declared in templates, which are
  270. // supposed to be internal/hidden, but it's left here for back-compat reasons.
  271. kernel.deprecated(this.declaredClass+"::getDescendants() is deprecated. Use getChildren() instead.", "", "2.0");
  272. return this.containerNode ? query('[widgetId]', this.containerNode).map(registry.byNode) : []; // dijit._Widget[]
  273. },
  274. ////////////////// MISCELLANEOUS METHODS ///////////////////
  275. _onShow: function(){
  276. // summary:
  277. // Internal method called when this widget is made visible.
  278. // See `onShow` for details.
  279. this.onShow();
  280. },
  281. onShow: function(){
  282. // summary:
  283. // Called when this widget becomes the selected pane in a
  284. // `dijit.layout.TabContainer`, `dijit.layout.StackContainer`,
  285. // `dijit.layout.AccordionContainer`, etc.
  286. //
  287. // Also called to indicate display of a `dijit.Dialog`, `dijit.TooltipDialog`, or `dijit.TitlePane`.
  288. // tags:
  289. // callback
  290. },
  291. onHide: function(){
  292. // summary:
  293. // Called when another widget becomes the selected pane in a
  294. // `dijit.layout.TabContainer`, `dijit.layout.StackContainer`,
  295. // `dijit.layout.AccordionContainer`, etc.
  296. //
  297. // Also called to indicate hide of a `dijit.Dialog`, `dijit.TooltipDialog`, or `dijit.TitlePane`.
  298. // tags:
  299. // callback
  300. },
  301. onClose: function(){
  302. // summary:
  303. // Called when this widget is being displayed as a popup (ex: a Calendar popped
  304. // up from a DateTextBox), and it is hidden.
  305. // This is called from the dijit.popup code, and should not be called directly.
  306. //
  307. // Also used as a parameter for children of `dijit.layout.StackContainer` or subclasses.
  308. // Callback if a user tries to close the child. Child will be closed if this function returns true.
  309. // tags:
  310. // extension
  311. return true; // Boolean
  312. }
  313. });
  314. // For back-compat, remove in 2.0.
  315. if(!kernel.isAsync){
  316. ready(0, function(){
  317. var requires = ["dijit/_base"];
  318. require(requires); // use indirection so modules not rolled into a build
  319. });
  320. }
  321. return _Widget;
  322. });