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