]>
Commit | Line | Data |
---|---|---|
6527f429 DM |
1 | /**\r |
2 | * Base class for all Ext components.\r | |
3 | *\r | |
4 | * The Component base class has built-in support for basic hide/show and enable/disable\r | |
5 | * and size control behavior.\r | |
6 | *\r | |
7 | * ## xtypes\r | |
8 | *\r | |
9 | * Every component has a specific xtype, which is its Ext-specific type name, along with\r | |
10 | * methods for checking the xtype like {@link #getXType} and {@link #isXType}. See the\r | |
11 | * [Component Guide][../../../core_concepts/components.html] for more information on xtypes \r | |
12 | * and the Component hierarchy.\r | |
13 | *\r | |
14 | * ## Finding components\r | |
15 | *\r | |
16 | * All Components are registered with the {@link Ext.ComponentManager} on construction so\r | |
17 | * that they can be referenced at any time via {@link Ext#getCmp Ext.getCmp}, passing the\r | |
18 | * {@link #id}.\r | |
19 | *\r | |
20 | * Additionally the {@link Ext.ComponentQuery} provides a CSS-selectors-like way to look\r | |
21 | * up components by their xtype and many other attributes. For example the following code\r | |
22 | * will find all textfield components inside component with `id: 'myform'`:\r | |
23 | *\r | |
24 | * Ext.ComponentQuery.query('#myform textfield');\r | |
25 | *\r | |
26 | * ## Extending Ext.Component\r | |
27 | *\r | |
28 | * All subclasses of Component may participate in the automated Ext component\r | |
29 | * life cycle of creation, rendering and destruction which is provided by the\r | |
30 | * {@link Ext.container.Container Container} class. Components may be added to a Container\r | |
31 | * through the {@link Ext.container.Container#cfg-items items} config option at the time\r | |
32 | * the Container is created, or they may be added dynamically via the\r | |
33 | * {@link Ext.container.Container#method-add add} method.\r | |
34 | *\r | |
35 | * All user-developed visual widgets that are required to participate in automated\r | |
36 | * life cycle and size management should subclass Component.\r | |
37 | *\r | |
38 | * See the Creating new UI controls chapter in [Component Guide][../../../core_concepts/components.html] \r | |
39 | * for details on how and to either extend or augment Ext JS base classes to create custom Components.\r | |
40 | *\r | |
41 | * ## The Ext.Component class by itself\r | |
42 | *\r | |
43 | * Usually one doesn't need to instantiate the Ext.Component class. There are subclasses\r | |
44 | * which implement specialized use cases, covering most application needs. However it is\r | |
45 | * possible to instantiate a base Component, and it can be rendered to document, or handled\r | |
46 | * by layouts as the child item of a Container:\r | |
47 | *\r | |
48 | * @example\r | |
49 | * Ext.create('Ext.Component', {\r | |
50 | * html: 'Hello world!',\r | |
51 | * width: 300,\r | |
52 | * height: 200,\r | |
53 | * padding: 20,\r | |
54 | * style: {\r | |
55 | * color: '#FFFFFF',\r | |
56 | * backgroundColor:'#000000'\r | |
57 | * },\r | |
58 | * renderTo: Ext.getBody()\r | |
59 | * });\r | |
60 | *\r | |
61 | * The Component above creates its encapsulating `div` upon render, and use the configured\r | |
62 | * HTML as content. More complex internal structure may be created using the\r | |
63 | * {@link #renderTpl} configuration, although to display database-derived mass data, it is\r | |
64 | * recommended that an ExtJS data-backed Component such as a {@link Ext.view.View View},\r | |
65 | * {@link Ext.grid.Panel GridPanel}, or {@link Ext.tree.Panel TreePanel} be used.\r | |
66 | */\r | |
67 | Ext.define('Ext.Component', {\r | |
68 | alternateClassName: 'Ext.AbstractComponent',\r | |
69 | \r | |
70 | xtype: [\r | |
71 | 'component',\r | |
72 | 'box'\r | |
73 | ],\r | |
74 | \r | |
75 | requires: [\r | |
76 | 'Ext.ComponentQuery',\r | |
77 | 'Ext.ComponentManager',\r | |
78 | 'Ext.util.ProtoElement',\r | |
79 | 'Ext.dom.CompositeElement',\r | |
80 | 'Ext.scroll.Scroller',\r | |
81 | 'Ext.scroll.TouchScroller',\r | |
82 | 'Ext.scroll.DomScroller'\r | |
83 | ],\r | |
84 | \r | |
85 | // Note that Floating must be mixed in before Positionable.\r | |
86 | mixins: [\r | |
87 | 'Ext.mixin.Inheritable',\r | |
88 | 'Ext.util.Floating',\r | |
89 | 'Ext.util.Positionable',\r | |
90 | 'Ext.util.Observable',\r | |
91 | 'Ext.mixin.ComponentDelegation',\r | |
92 | 'Ext.mixin.Bindable',\r | |
93 | 'Ext.util.Animate',\r | |
94 | 'Ext.util.ElementContainer',\r | |
95 | 'Ext.util.Renderable',\r | |
96 | 'Ext.state.Stateful',\r | |
97 | 'Ext.util.Focusable',\r | |
98 | 'Ext.mixin.Accessible',\r | |
99 | 'Ext.util.KeyboardInteractive'\r | |
100 | ],\r | |
101 | \r | |
102 | uses: [\r | |
103 | 'Ext.overrides.*',\r | |
104 | 'Ext.Element',\r | |
105 | 'Ext.DomHelper',\r | |
106 | 'Ext.XTemplate',\r | |
107 | 'Ext.ComponentLoader',\r | |
108 | 'Ext.layout.Context',\r | |
109 | 'Ext.layout.Layout',\r | |
110 | 'Ext.layout.component.Auto',\r | |
111 | 'Ext.LoadMask',\r | |
112 | 'Ext.ZIndexManager',\r | |
113 | 'Ext.util.DelayedTask',\r | |
114 | 'Ext.resizer.Resizer',\r | |
115 | 'Ext.util.ComponentDragger'\r | |
116 | ],\r | |
117 | \r | |
118 | statics: {\r | |
119 | AUTO_ID: 1000,\r | |
120 | \r | |
121 | pendingLayouts: null,\r | |
122 | \r | |
123 | layoutSuspendCount: 0,\r | |
124 | \r | |
125 | // Collapse/expand directions\r | |
126 | DIRECTION_TOP: 'top',\r | |
127 | DIRECTION_RIGHT: 'right',\r | |
128 | DIRECTION_BOTTOM: 'bottom',\r | |
129 | DIRECTION_LEFT: 'left',\r | |
130 | \r | |
131 | VERTICAL_DIRECTION_Re: /^(?:top|bottom)$/,\r | |
132 | \r | |
133 | // RegExp whih specifies characters in an xtype which must be translated to '-' when generating auto IDs.\r | |
134 | // This includes dot, comma and whitespace\r | |
135 | INVALID_ID_CHARS_Re: /[\.,\s]/g,\r | |
136 | \r | |
137 | /**\r | |
138 | * @property {String} ariaHighContrastModeCls CSS class to be applied\r | |
139 | * to the document body when High Contrast mode is detected in Windows.\r | |
140 | * @private\r | |
141 | */\r | |
142 | ariaHighContrastModeCls: Ext.baseCSSPrefix + 'aria-highcontrast',\r | |
143 | \r | |
144 | /**\r | |
145 | * Cancels layout of a component.\r | |
146 | * @param {Ext.Component} comp\r | |
147 | */\r | |
148 | cancelLayout: function(comp, isDestroying) {\r | |
149 | var context = this.runningLayoutContext || this.pendingLayouts;\r | |
150 | \r | |
151 | if (context) {\r | |
152 | context.cancelComponent(comp, false, isDestroying);\r | |
153 | }\r | |
154 | },\r | |
155 | \r | |
156 | /**\r | |
157 | * Find the Widget or Component to which the given Element belongs.\r | |
158 | *\r | |
159 | * @param {Ext.dom.Element/HTMLElement} el The element from which to start to find an owning Component.\r | |
160 | * @param {Ext.dom.Element/HTMLElement} [limit] The element at which to stop upward searching for an\r | |
161 | * owning Component, or the number of Components to traverse before giving up.\r | |
162 | * Defaults to the document's HTML element.\r | |
163 | * @param {String} [selector] An optional {@link Ext.ComponentQuery} selector to filter the target.\r | |
164 | * @return {Ext.Component/null} Component, or null\r | |
165 | */\r | |
166 | fromElement: function(node, limit, selector) {\r | |
167 | return Ext.ComponentManager.fromElement(node, limit, selector);\r | |
168 | },\r | |
169 | \r | |
170 | /**\r | |
171 | * Performs all pending layouts that were scheduled while\r | |
172 | * {@link Ext.Component#suspendLayouts suspendLayouts} was in effect.\r | |
173 | * @static\r | |
174 | */\r | |
175 | flushLayouts: function () {\r | |
176 | var me = this,\r | |
177 | context = me.pendingLayouts;\r | |
178 | \r | |
179 | if (context && context.invalidQueue.length) {\r | |
180 | me.pendingLayouts = null;\r | |
181 | me.runningLayoutContext = context;\r | |
182 | \r | |
183 | Ext.override(context, {\r | |
184 | runComplete: function () {\r | |
185 | // we need to release the layout queue before running any of the\r | |
186 | // finishedLayout calls because they call afterComponentLayout\r | |
187 | // which can re-enter by calling updateLayout/doComponentLayout.\r | |
188 | me.runningLayoutContext = null;\r | |
189 | \r | |
190 | var result = this.callParent(); // not "me" here!\r | |
191 | if (Ext.GlobalEvents.hasListeners.afterlayout) {\r | |
192 | Ext.GlobalEvents.fireEvent('afterlayout');\r | |
193 | }\r | |
194 | return result;\r | |
195 | }\r | |
196 | });\r | |
197 | \r | |
198 | context.run();\r | |
199 | }\r | |
200 | },\r | |
201 | \r | |
202 | /**\r | |
203 | * Resumes layout activity in the whole framework.\r | |
204 | *\r | |
205 | * {@link Ext#suspendLayouts} is alias of {@link Ext.Component#suspendLayouts}.\r | |
206 | *\r | |
207 | * @param {Boolean} [flush=false] `true` to perform all the pending layouts. This can also be\r | |
208 | * achieved by calling {@link Ext.Component#flushLayouts flushLayouts} directly.\r | |
209 | * @static\r | |
210 | */\r | |
211 | resumeLayouts: function (flush) {\r | |
212 | if (this.layoutSuspendCount && ! --this.layoutSuspendCount) {\r | |
213 | if (flush) {\r | |
214 | this.flushLayouts();\r | |
215 | }\r | |
216 | if (Ext.GlobalEvents.hasListeners.resumelayouts) {\r | |
217 | Ext.GlobalEvents.fireEvent('resumelayouts');\r | |
218 | }\r | |
219 | }\r | |
220 | },\r | |
221 | \r | |
222 | /**\r | |
223 | * Stops layouts from happening in the whole framework.\r | |
224 | *\r | |
225 | * It's useful to suspend the layout activity while updating multiple components and\r | |
226 | * containers:\r | |
227 | *\r | |
228 | * Ext.suspendLayouts();\r | |
229 | * // batch of updates...\r | |
230 | * Ext.resumeLayouts(true);\r | |
231 | *\r | |
232 | * {@link Ext#suspendLayouts} is alias of {@link Ext.Component#suspendLayouts}.\r | |
233 | *\r | |
234 | * See also {@link Ext#batchLayouts} for more abstract way of doing this.\r | |
235 | *\r | |
236 | * @static\r | |
237 | */\r | |
238 | suspendLayouts: function () {\r | |
239 | ++this.layoutSuspendCount;\r | |
240 | },\r | |
241 | \r | |
242 | /**\r | |
243 | * Updates layout of a component.\r | |
244 | *\r | |
245 | * @param {Ext.Component} comp The component to update.\r | |
246 | * @param {Boolean} [defer=false] `true` to just queue the layout if this component.\r | |
247 | * @static\r | |
248 | */\r | |
249 | updateLayout: function (comp, defer) {\r | |
250 | var me = this,\r | |
251 | running = me.runningLayoutContext,\r | |
252 | pending;\r | |
253 | \r | |
254 | if (running) {\r | |
255 | running.queueInvalidate(comp);\r | |
256 | } else {\r | |
257 | pending = me.pendingLayouts || (me.pendingLayouts = new Ext.layout.Context());\r | |
258 | pending.queueInvalidate(comp);\r | |
259 | \r | |
260 | if (!defer && !me.layoutSuspendCount && !comp.isLayoutSuspended()) {\r | |
261 | me.flushLayouts();\r | |
262 | }\r | |
263 | }\r | |
264 | }\r | |
265 | },\r | |
266 | \r | |
267 | // <editor-fold desc="Config">\r | |
268 | // ***********************************************************************************\r | |
269 | // Begin Config\r | |
270 | // ***********************************************************************************\r | |
271 | \r | |
272 | // We do not want "_hidden" style backing properties.\r | |
273 | $configPrefixed: false,\r | |
274 | // We also want non-config system properties to go to the instance.\r | |
275 | $configStrict: false,\r | |
276 | \r | |
277 | config: {\r | |
278 | /**\r | |
279 | * @cfg {Object} data\r | |
280 | * The initial set of data to apply to the `{@link #tpl}` to update the content\r | |
281 | * area of the Component.\r | |
282 | *\r | |
283 | * @since 3.4.0\r | |
284 | */\r | |
285 | data: null,\r | |
286 | \r | |
287 | /**\r | |
288 | * @cfg {Boolean} modelValidation\r | |
289 | * This config enables binding to your `{@link Ext.data.Model#validators}`. This\r | |
290 | * is only processed by form fields (e.g., `Ext.form.field.Text`) at present, but\r | |
291 | * this setting is inherited and so can be set on a parent container.\r | |
292 | *\r | |
293 | * When set to `true` by a component or not set by a component but inherited from\r | |
294 | * an ancestor container, `Ext.data.Validation` records are used to automatically\r | |
295 | * bind validation results for any form field to which a `value` is bound.\r | |
296 | *\r | |
297 | * While this config can be set arbitrarily high in the component hierarchy, doing\r | |
298 | * so can create a lot overhead if most of your form fields do not actually rely on\r | |
299 | * `validators` in your data model.\r | |
300 | *\r | |
301 | * Using this setting for a form that is bound to an `Ext.data.Model` might look\r | |
302 | * like this:\r | |
303 | *\r | |
304 | * {\r | |
305 | * xtype: 'panel',\r | |
306 | * modelValidation: true,\r | |
307 | * items: [{\r | |
308 | * xtype: 'textfield',\r | |
309 | * bind: '{theUser.firstName}'\r | |
310 | * },{\r | |
311 | * xtype: 'textfield',\r | |
312 | * bind: '{theUser.lastName}'\r | |
313 | * },{\r | |
314 | * xtype: 'textfield',\r | |
315 | * bind: '{theUser.phoneNumber}'\r | |
316 | * },{\r | |
317 | * xtype: 'textfield',\r | |
318 | * bind: '{theUser.email}'\r | |
319 | * }]\r | |
320 | * }\r | |
321 | *\r | |
322 | * The above is equivalent to the following manual binding of validation:\r | |
323 | *\r | |
324 | * {\r | |
325 | * xtype: 'panel',\r | |
326 | * items: [{\r | |
327 | * xtype: 'textfield',\r | |
328 | * bind: {\r | |
329 | * value: '{theUser.firstName}'\r | |
330 | * validation: '{theUser.validation.firstName}'\r | |
331 | * }\r | |
332 | * },{\r | |
333 | * xtype: 'textfield',\r | |
334 | * bind: {\r | |
335 | * value: '{theUser.lastName}'\r | |
336 | * validation: '{theUser.validation.lastName}'\r | |
337 | * }\r | |
338 | * },{\r | |
339 | * xtype: 'textfield',\r | |
340 | * bind: {\r | |
341 | * value: '{theUser.phoneNumber}'\r | |
342 | * validation: '{theUser.validation.phoneNumber}'\r | |
343 | * }\r | |
344 | * },{\r | |
345 | * xtype: 'textfield',\r | |
346 | * bind: {\r | |
347 | * value: '{theUser.email}'\r | |
348 | * validation: '{theUser.validation.email}'\r | |
349 | * }\r | |
350 | * }]\r | |
351 | * }\r | |
352 | *\r | |
353 | * Notice that "validation" is a pseudo-association defined for all entities. See\r | |
354 | * `{@link Ext.data.Model#getValidation}` for further details.\r | |
355 | */\r | |
356 | \r | |
357 | /**\r | |
358 | * @cfg {Number} maxHeight\r | |
359 | * The maximum value in pixels which this Component will set its height to.\r | |
360 | *\r | |
361 | * **Warning:** This will override any size management applied by layout managers.\r | |
362 | */\r | |
363 | maxHeight: null,\r | |
364 | \r | |
365 | /**\r | |
366 | * @cfg {Number} maxWidth\r | |
367 | * The maximum value in pixels which this Component will set its width to.\r | |
368 | *\r | |
369 | * **Warning:** This will override any size management applied by layout managers.\r | |
370 | */\r | |
371 | maxWidth: null,\r | |
372 | \r | |
373 | /**\r | |
374 | * @cfg {Number} minHeight\r | |
375 | * The minimum value in pixels which this Component will set its height to.\r | |
376 | *\r | |
377 | * **Warning:** This will override any size management applied by layout managers.\r | |
378 | */\r | |
379 | minHeight: null,\r | |
380 | \r | |
381 | /**\r | |
382 | * @cfg {Number} minWidth\r | |
383 | * The minimum value in pixels which this Component will set its width to.\r | |
384 | *\r | |
385 | * **Warning:** This will override any size management applied by layout managers.\r | |
386 | */\r | |
387 | minWidth: null,\r | |
388 | \r | |
389 | /**\r | |
390 | * @cfg {Boolean/String/Object} scrollable\r | |
391 | * Configuration options to make this Component scrollable. Acceptable values are:\r | |
392 | *\r | |
393 | * - `true` to enable auto scrolling.\r | |
394 | * - `false` (or `null`) to disable scrolling - this is the default.\r | |
395 | * - `x` or `horizontal` to enable horizontal scrolling only\r | |
396 | * - `y` or `vertical` to enable vertical scrolling only\r | |
397 | *\r | |
398 | * Also accepts a configuration object for a `{@link Ext.scroll.Scroller}` if\r | |
399 | * if advanced configuration is needed.\r | |
400 | *\r | |
401 | * The getter for this config returns the {@link Ext.scroll.Scroller Scroller}\r | |
402 | * instance. You can use the Scroller API to read or manipulate the scroll position:\r | |
403 | *\r | |
404 | * // scrolls the component to 5 on the x axis and 10 on the y axis\r | |
405 | * component.getScrollable().scrollTo(5, 10);\r | |
406 | */\r | |
407 | scrollable: null\r | |
408 | },\r | |
409 | \r | |
410 | defaultBindProperty: 'html',\r | |
411 | \r | |
412 | /**\r | |
413 | * @cfg {String} [alignTarget]\r | |
414 | * A Component or Element by which to position this component according to the {@link #defaultAlign}.\r | |
415 | * Defaults to the owning Container.\r | |
416 | *\r | |
417 | * *Only applicable if this component is {@link #cfg-floating}*\r | |
418 | *\r | |
419 | * *Used upon first show*.\r | |
420 | */\r | |
421 | alignTarget: null,\r | |
422 | \r | |
423 | /**\r | |
424 | * @cfg {String} anchor\r | |
425 | * @inheritDoc Ext.layout.container.Anchor\r | |
426 | */\r | |
427 | \r | |
428 | /**\r | |
429 | * @cfg {String/Object} autoEl\r | |
430 | * A tag name or {@link Ext.dom.Helper DomHelper} spec used to create the {@link #getEl Element} which will\r | |
431 | * encapsulate this Component.\r | |
432 | *\r | |
433 | * You do not normally need to specify this. For the base classes {@link Ext.Component} and\r | |
434 | * {@link Ext.container.Container}, this defaults to **'div'**. The more complex Sencha classes use a more\r | |
435 | * complex DOM structure specified by their own {@link #renderTpl}s.\r | |
436 | *\r | |
437 | * This is intended to allow the developer to create application-specific utility Components encapsulated by\r | |
438 | * different DOM elements. Example usage:\r | |
439 | *\r | |
440 | * {\r | |
441 | * xtype: 'component',\r | |
442 | * autoEl: {\r | |
443 | * tag: 'img',\r | |
444 | * src: 'http://www.example.com/example.jpg'\r | |
445 | * }\r | |
446 | * }, {\r | |
447 | * xtype: 'component',\r | |
448 | * autoEl: {\r | |
449 | * tag: 'blockquote',\r | |
450 | * html: 'autoEl is cool!'\r | |
451 | * }\r | |
452 | * }, {\r | |
453 | * xtype: 'container',\r | |
454 | * autoEl: 'ul',\r | |
455 | * cls: 'ux-unordered-list',\r | |
456 | * items: {\r | |
457 | * xtype: 'component',\r | |
458 | * autoEl: 'li',\r | |
459 | * html: 'First list item'\r | |
460 | * }\r | |
461 | * }\r | |
462 | *\r | |
463 | * @since 2.3.0\r | |
464 | */\r | |
465 | \r | |
466 | /**\r | |
467 | * @cfg {Boolean/String/HTMLElement/Ext.dom.Element} autoRender\r | |
468 | * This config is intended mainly for non-{@link #cfg-floating} Components which may or may not be shown. Instead of using\r | |
469 | * {@link #renderTo} in the configuration, and rendering upon construction, this allows a Component to render itself\r | |
470 | * upon first _{@link Ext.Component#method-show show}_. If {@link #cfg-floating} is `true`, the value of this config is omitted as if it is `true`.\r | |
471 | *\r | |
472 | * Specify as `true` to have this Component render to the document body upon first show.\r | |
473 | *\r | |
474 | * Specify as an element, or the ID of an element to have this Component render to a specific element upon first\r | |
475 | * show.\r | |
476 | */\r | |
477 | autoRender: false,\r | |
478 | \r | |
479 | /**\r | |
480 | * @cfg {Boolean} [autoScroll=false]\r | |
481 | * `true` to use overflow:'auto' on the components layout element and show scroll bars automatically when necessary,\r | |
482 | * `false` to clip any overflowing content.\r | |
483 | *\r | |
484 | * This should not be combined with {@link #overflowX} or {@link #overflowY}.\r | |
485 | * @deprecated 5.1.0 Use {@link #scrollable} instead\r | |
486 | */\r | |
487 | \r | |
488 | /**\r | |
489 | * @cfg {Boolean} autoShow\r | |
490 | * `true` to automatically show the component upon creation. This config option may only be used for\r | |
491 | * {@link #cfg-floating} components or components that use {@link #autoRender}.\r | |
492 | *\r | |
493 | * @since 2.3.0\r | |
494 | */\r | |
495 | autoShow: false,\r | |
496 | \r | |
497 | /**\r | |
498 | * @cfg {String} [baseCls='x-component']\r | |
499 | * The base CSS class to apply to this component's element. This will also be prepended to elements within this\r | |
500 | * component like Panel's body will get a class `x-panel-body`. This means that if you create a subclass of Panel, and\r | |
501 | * you want it to get all the Panels styling for the element and the body, you leave the `baseCls` `x-panel` and use\r | |
502 | * `componentCls` to add specific styling for this component.\r | |
503 | */\r | |
504 | baseCls: Ext.baseCSSPrefix + 'component',\r | |
505 | \r | |
506 | /**\r | |
507 | * @cfg {Number/String/Boolean} border\r | |
508 | * Specifies the border size for this component. The border can be a single numeric value to apply to all sides or it can\r | |
509 | * be a CSS style specification for each style, for example: '10 5 3 10' (top, right, bottom, left).\r | |
510 | *\r | |
511 | * For components that have no border by default, setting this won't make the border appear by itself.\r | |
512 | * You also need to specify border color and style:\r | |
513 | *\r | |
514 | * border: 5,\r | |
515 | * style: {\r | |
516 | * borderColor: 'red',\r | |
517 | * borderStyle: 'solid'\r | |
518 | * }\r | |
519 | *\r | |
520 | * To turn off the border, use `border: false`.\r | |
521 | */\r | |
522 | \r | |
523 | /**\r | |
524 | * @cfg {Object/String[]/Object[]} childEls\r | |
525 | * @inheritdoc Ext.util.ElementContainer#childEls\r | |
526 | */\r | |
527 | childEls: {\r | |
528 | frameTable: { frame: true },\r | |
529 | frameTL: { frame: 'tl' },\r | |
530 | frameTC: { frame: 'tc' },\r | |
531 | frameTR: { frame: 'tr' },\r | |
532 | frameML: { frame: 'ml' },\r | |
533 | frameBody: { frame: 'mc' },\r | |
534 | frameMR: { frame: 'mr' },\r | |
535 | frameBL: { frame: 'bl' },\r | |
536 | frameBC: { frame: 'bc' },\r | |
537 | frameBR: { frame: 'br' }\r | |
538 | },\r | |
539 | \r | |
540 | /**\r | |
541 | * @cfg {String/String[]} [cls='']\r | |
542 | * An optional extra CSS class that will be added to this component's Element. \r | |
543 | * The value can be a string, a list of strings separated by spaces, or an array of strings. This can be useful \r | |
544 | * for adding customized styles to the component or any of its children using standard CSS rules.\r | |
545 | *\r | |
546 | * @since 1.1.0\r | |
547 | */\r | |
548 | \r | |
549 | /**\r | |
550 | * @cfg {Number} [columnWidth]\r | |
551 | * Defines the column width inside {@link Ext.layout.container.Column column layout}.\r | |
552 | *\r | |
553 | * The columnWidth property is always evaluated as a percentage and must be a decimal value greater than 0 and \r | |
554 | * less than 1 (e.g., .25). See the description at the top of {@link Ext.layout.container.Column column layout} for \r | |
555 | * additional usage details when combining width and columnWidth configs within the layout.\r | |
556 | */\r | |
557 | \r | |
558 | /**\r | |
559 | * @cfg {String} componentCls\r | |
560 | * CSS Class to be added to a components root level element to give distinction to it via styling.\r | |
561 | */\r | |
562 | \r | |
563 | // @cmd-auto-dependency { aliasPrefix : "layout." }\r | |
564 | /**\r | |
565 | * @cfg {String/Object} componentLayout\r | |
566 | * The sizing and positioning of a Component's internal Elements is the responsibility of the Component's layout\r | |
567 | * manager which sizes a Component's internal structure in response to the Component being sized.\r | |
568 | *\r | |
569 | * Generally, developers will not use this configuration as all provided Components which need their internal\r | |
570 | * elements sizing (Such as {@link Ext.form.field.Base input fields}) come with their own componentLayout managers.\r | |
571 | *\r | |
572 | * The {@link Ext.layout.container.Auto default layout manager} will be used on instances of the base Ext.Component\r | |
573 | * class which simply sizes the Component's encapsulating element to the height and width specified in the\r | |
574 | * {@link #setSize} method.\r | |
575 | * \r | |
576 | */\r | |
577 | componentLayout: 'autocomponent',\r | |
578 | \r | |
579 | /**\r | |
580 | * @cfg {Object/String} constraintInsets\r | |
581 | * An object or a string (in TRBL order) specifying insets from the configured {@link #constrainTo constrain region}\r | |
582 | * within which this component must be constrained when positioning or sizing.\r | |
583 | * example:\r | |
584 | *\r | |
585 | * constraintInsets: '10 10 10 10' // Constrain with 10px insets from parent\r | |
586 | */\r | |
587 | \r | |
588 | /**\r | |
589 | * @cfg {Ext.util.Region/Ext.dom.Element} constrainTo\r | |
590 | * A {@link Ext.util.Region Region} (or an element from which a Region measurement will be read) which is used\r | |
591 | * to constrain the component. Only applies when the component is floating.\r | |
592 | */\r | |
593 | \r | |
594 | /**\r | |
595 | * @cfg {String} contentEl\r | |
596 | * Specify an existing HTML element, or the `id` of an existing HTML element to use as the content for this component.\r | |
597 | *\r | |
598 | * This config option is used to take an existing HTML element and place it in the layout element of a new component\r | |
599 | * (it simply moves the specified DOM element _after the Component is rendered_ to use as the content.\r | |
600 | *\r | |
601 | * **Notes:**\r | |
602 | *\r | |
603 | * The specified HTML element is appended to the layout element of the component _after any configured\r | |
604 | * {@link #html HTML} has been inserted_, and so the document will not contain this element at the time\r | |
605 | * the {@link #event-render} event is fired.\r | |
606 | *\r | |
607 | * The specified HTML element used will not participate in any **`{@link Ext.container.Container#layout layout}`**\r | |
608 | * scheme that the Component may use. It is just HTML. Layouts operate on child\r | |
609 | * **`{@link Ext.container.Container#cfg-items items}`**.\r | |
610 | *\r | |
611 | * Add either the `x-hidden` or the `x-hidden-display` CSS class to prevent a brief flicker of the content before it\r | |
612 | * is rendered to the panel.\r | |
613 | *\r | |
614 | * @since 3.4.0\r | |
615 | */\r | |
616 | \r | |
617 | /**\r | |
618 | * @cfg {String} [defaultAlign="c-c"]\r | |
619 | * The default {@link Ext.util.Positionable#getAlignToXY Ext.dom.Element#getAlignToXY} anchor position value for this component\r | |
620 | * relative to its {@link #alignTarget} (which defaults to its owning Container).\r | |
621 | *\r | |
622 | * _Only applicable if this component is {@link #cfg-floating}_\r | |
623 | *\r | |
624 | * *Used upon first show*.\r | |
625 | */\r | |
626 | defaultAlign: 'c-c',\r | |
627 | \r | |
628 | /**\r | |
629 | * @cfg {Boolean} disabled\r | |
630 | * `true` to disable the component.\r | |
631 | * @since 2.3.0\r | |
632 | */\r | |
633 | disabled: false,\r | |
634 | \r | |
635 | // http://www.w3.org/TR/html5/disabled-elements.html\r | |
636 | disabledRe: /^(?:button|input|select|textarea|optgroup|option|fieldset)$/i,\r | |
637 | \r | |
638 | nonMaskableRe: (function () {\r | |
639 | var re = ['input', 'select', 'textarea', 'optgroup', 'option', 'table'];\r | |
640 | \r | |
641 | // All IE browsers 9 and below except for IE 9 standards.\r | |
642 | if (Ext.isIE9m && !(Ext.isIE9 && !Ext.isIEQuirks)) {\r | |
643 | // <p>.insertAdjacentHTML('BeforeEnd', '<div>...</div>') yields\r | |
644 | // 'Invalid source HTML for this operation' in all IEs not IE 9 standards.\r | |
645 | re.push('p');\r | |
646 | }\r | |
647 | \r | |
648 | return new RegExp('^(?:' + re.join('|') + ')$', 'i');\r | |
649 | }()),\r | |
650 | \r | |
651 | /**\r | |
652 | * @cfg {String} [disabledCls='x-item-disabled']\r | |
653 | * CSS class to add when the Component is disabled.\r | |
654 | */\r | |
655 | disabledCls: Ext.baseCSSPrefix + 'item-disabled',\r | |
656 | \r | |
657 | /**\r | |
658 | * @cfg {'top'/'bottom'/'left'/'right'} dock\r | |
659 | * The side of the {@link Ext.panel.Panel panel} where this component is to be \r | |
660 | * docked when specified in the panel's \r | |
661 | * {@link Ext.panel.Panel#dockedItems dockedItems} config.\r | |
662 | * \r | |
663 | * Possible values are:\r | |
664 | * \r | |
665 | * - top\r | |
666 | * - bottom\r | |
667 | * - left\r | |
668 | * - right\r | |
669 | */\r | |
670 | \r | |
671 | /**\r | |
672 | * @cfg {Boolean/Object} [draggable=false]\r | |
673 | * Specify as true to make a {@link #cfg-floating} Component draggable using the Component's encapsulating element as\r | |
674 | * the drag handle.\r | |
675 | *\r | |
676 | * This may also be specified as a config object for the {@link Ext.util.ComponentDragger ComponentDragger} which is\r | |
677 | * instantiated to perform dragging.\r | |
678 | *\r | |
679 | * For example to create a Component which may only be dragged around using a certain internal element as the drag\r | |
680 | * handle, use the delegate option:\r | |
681 | *\r | |
682 | * new Ext.Component({\r | |
683 | * constrain: true,\r | |
684 | * floating: true,\r | |
685 | * style: {\r | |
686 | * backgroundColor: '#fff',\r | |
687 | * border: '1px solid black'\r | |
688 | * },\r | |
689 | * html: '<h1 style="cursor:move">The title</h1><p>The content</p>',\r | |
690 | * draggable: {\r | |
691 | * delegate: 'h1'\r | |
692 | * }\r | |
693 | * }).show();\r | |
694 | */\r | |
695 | draggable: false,\r | |
696 | \r | |
697 | /**\r | |
698 | * @cfg {Number} flex\r | |
699 | * Flex may be applied to **child items** of a box layout ({@link Ext.layout.container.VBox vbox} or \r | |
700 | * {@link Ext.layout.container.HBox hbox}). Each child item with a flex property will \r | |
701 | * fill space (horizontally in `hbox`, vertically in `vbox`) according to that item's\r | |
702 | * **relative** flex value compared to the sum of all items with a flex value specified. \r | |
703 | * \r | |
704 | * Any child items that have either a `flex` of `0` or `undefined` \r | |
705 | * will not be 'flexed' (the initial size will not be changed).\r | |
706 | */\r | |
707 | \r | |
708 | /**\r | |
709 | * @cfg {Boolean} floating\r | |
710 | * Specify as true to float the Component outside of the document flow using CSS absolute positioning.\r | |
711 | *\r | |
712 | * Components such as {@link Ext.window.Window Window}s and {@link Ext.menu.Menu Menu}s are floating by default.\r | |
713 | *\r | |
714 | * Floating Components that are programmatically {@link Ext.Component#method-render rendered} will register\r | |
715 | * themselves with the global {@link Ext.WindowManager ZIndexManager}\r | |
716 | *\r | |
717 | * ### Floating Components as child items of a Container\r | |
718 | *\r | |
719 | * A floating Component may be used as a child item of a Container. This just allows the floating Component to seek\r | |
720 | * a ZIndexManager by examining the ownerCt chain.\r | |
721 | *\r | |
722 | * When configured as floating, Components acquire, at render time, a {@link Ext.ZIndexManager ZIndexManager} which\r | |
723 | * manages a stack of related floating Components. The ZIndexManager sorts its stack according to\r | |
724 | * an incrementing access counter and the {@link Ext.util.Floating#alwaysOnTop alwaysOnTop} config when the Component's {@link #toFront} method is called.\r | |
725 | *\r | |
726 | * The ZIndexManager is found by traversing up the {@link #ownerCt} chain to find an ancestor which itself is\r | |
727 | * floating. This is so that descendant floating Components of floating _Containers_ (Such as a ComboBox dropdown\r | |
728 | * within a Window) can have its zIndex managed relative to any siblings, but always **above** that floating\r | |
729 | * ancestor Container.\r | |
730 | *\r | |
731 | * If no floating ancestor is found, a floating Component registers itself with the default {@link Ext.WindowManager\r | |
732 | * ZIndexManager}.\r | |
733 | *\r | |
734 | * Floating components _do not participate in the Container's layout_. Because of this, they are not rendered until\r | |
735 | * you explicitly {@link #method-show} them.\r | |
736 | *\r | |
737 | * After rendering, the ownerCt reference is deleted, and the {@link #floatParent} property is set to the found\r | |
738 | * floating ancestor Container. If no floating ancestor Container was found the {@link #floatParent} property will\r | |
739 | * not be set.\r | |
740 | */\r | |
741 | floating: false,\r | |
742 | \r | |
743 | /**\r | |
744 | * @cfg {Boolean} [formBind=false]\r | |
745 | * When inside FormPanel, any component configured with `formBind: true` will\r | |
746 | * be enabled/disabled depending on the validity state of the form.\r | |
747 | * See {@link Ext.form.Panel} for more information and example.\r | |
748 | */\r | |
749 | \r | |
750 | /**\r | |
751 | * @cfg {Boolean} frame\r | |
752 | * Specify as `true` to have the Component inject framing elements within the Component at render time to provide a\r | |
753 | * graphical rounded frame around the Component content.\r | |
754 | *\r | |
755 | * This is only necessary when running on outdated, or non standard-compliant browsers such as Microsoft's Internet\r | |
756 | * Explorer prior to version 9 which do not support rounded corners natively.\r | |
757 | *\r | |
758 | * The extra space taken up by this framing is available from the read only property {@link #frameSize}.\r | |
759 | */\r | |
760 | \r | |
761 | /**\r | |
762 | * @cfg {Number|String} height\r | |
763 | * The height of this component. A numeric value will be interpreted as the number of\r | |
764 | * pixels; a string value will be treated as a CSS value with units.\r | |
765 | */\r | |
766 | \r | |
767 | /**\r | |
768 | * @cfg {Boolean} hidden\r | |
769 | * `true` to hide the component.\r | |
770 | * @since 2.3.0\r | |
771 | */\r | |
772 | hidden: false,\r | |
773 | \r | |
774 | /**\r | |
775 | * @cfg {String} hideMode\r | |
776 | * A String which specifies how this Component's encapsulating DOM element will be hidden. Values may be:\r | |
777 | *\r | |
778 | * - `'display'` : The Component will be hidden using the `display: none` style.\r | |
779 | * - `'visibility'` : The Component will be hidden using the `visibility: hidden` style.\r | |
780 | * - `'offsets'` : The Component will be hidden by absolutely positioning it out of the visible area of the document.\r | |
781 | * This is useful when a hidden Component must maintain measurable dimensions. Hiding using `display` results in a\r | |
782 | * Component having zero dimensions.\r | |
783 | *\r | |
784 | * @since 1.1.0\r | |
785 | */\r | |
786 | hideMode: 'display',\r | |
787 | \r | |
788 | /**\r | |
789 | * @cfg {String/Object} [html='']\r | |
790 | * An HTML fragment, or a {@link Ext.dom.Helper DomHelper} specification to use as the layout element content.\r | |
791 | * The HTML content is added after the component is rendered, so the document will not contain this HTML at the time\r | |
792 | * the {@link #event-render} event is fired. This content is inserted into the body _before_ any configured {@link #contentEl}\r | |
793 | * is appended.\r | |
794 | *\r | |
795 | * @since 3.4.0\r | |
796 | */\r | |
797 | \r | |
798 | /**\r | |
799 | * @cfg {String} id\r | |
800 | * The **unique** id of this component instance.\r | |
801 | *\r | |
802 | * Use of this config should be considered carefully as this value must be unique across\r | |
803 | * all existing components. Components created with an `id` may be accessed globally\r | |
804 | * using {@link Ext#getCmp Ext.getCmp}.\r | |
805 | *\r | |
806 | * Instead of using assigned ids, consider a {@link #reference} config and a {@link #cfg-controller ViewController}\r | |
807 | * to respond to events and perform processing upon this Component.\r | |
808 | *\r | |
809 | * Alternatively, {@link #itemId} and {@link Ext.ComponentQuery ComponentQuery} can be\r | |
810 | * used to perform selector-based searching for Components analogous to DOM querying.\r | |
811 | * The {@link Ext.container.Container Container} class contains several helpful\r | |
812 | * {@link Ext.container.Container#down shortcut methods} to query its descendant\r | |
813 | * Components by selector.\r | |
814 | *\r | |
815 | * Note that this `id` will also be used as the element id for the containing HTML\r | |
816 | * element that is rendered to the page for this component. This allows you to write\r | |
817 | * id-based CSS rules to style the specific instance of this component uniquely, and\r | |
818 | * also to select sub-elements using this component's `id` as the parent.\r | |
819 | *\r | |
820 | * Defaults to an {@link #getId auto-assigned id}.\r | |
821 | *\r | |
822 | * **Note**: Valid identifiers start with a letter or underscore and are followed by\r | |
823 | * (optional) additional letters, underscores, digits or hyphens.\r | |
824 | *\r | |
825 | * @since 1.1.0\r | |
826 | */\r | |
827 | \r | |
828 | /**\r | |
829 | * @cfg {String} itemId\r | |
830 | * The **unique** id of this component instance within its container. See also the\r | |
831 | * {@link #reference} config.\r | |
832 | *\r | |
833 | * An `itemId` can be used as an alternative way to get a reference to a component when no object reference is\r | |
834 | * available. Instead of using an `{@link #id}` with {@link Ext#getCmp getCmp}, use\r | |
835 | * `itemId` with {@link Ext.container.Container#getComponent getComponent} which will\r | |
836 | * retrieve `itemId`'s or {@link #id}'s. Since `itemId`'s are an index to the container's\r | |
837 | * internal collection, the `itemId` is scoped locally to the container -- avoiding\r | |
838 | * potential conflicts with {@link Ext.ComponentManager} which requires a **unique**\r | |
839 | * `{@link #id}` values.\r | |
840 | *\r | |
841 | * var c = new Ext.panel.Panel({ //\r | |
842 | * {@link Ext.Component#height height}: 300,\r | |
843 | * {@link #renderTo}: document.body,\r | |
844 | * {@link Ext.container.Container#layout layout}: 'auto',\r | |
845 | * {@link Ext.container.Container#cfg-items items}: [\r | |
846 | * {\r | |
847 | * itemId: 'p1',\r | |
848 | * {@link Ext.panel.Panel#title title}: 'Panel 1',\r | |
849 | * {@link Ext.Component#height height}: 150\r | |
850 | * },\r | |
851 | * {\r | |
852 | * itemId: 'p2',\r | |
853 | * {@link Ext.panel.Panel#title title}: 'Panel 2',\r | |
854 | * {@link Ext.Component#height height}: 150\r | |
855 | * }\r | |
856 | * ]\r | |
857 | * })\r | |
858 | * p1 = c.{@link Ext.container.Container#getComponent getComponent}('p1'); // not the same as {@link Ext#getCmp Ext.getCmp()}\r | |
859 | * p2 = p1.{@link #ownerCt}.{@link Ext.container.Container#getComponent getComponent}('p2'); // reference via a sibling\r | |
860 | *\r | |
861 | * Also see {@link #id}, `{@link Ext.container.Container#query}`, `{@link Ext.container.Container#down}` and\r | |
862 | * `{@link Ext.container.Container#child}`.\r | |
863 | *\r | |
864 | * **Note**: Valid identifiers start with a letter or underscore and are followed by\r | |
865 | * (optional) additional letters, underscores, digits or hyphens.\r | |
866 | *\r | |
867 | * **Note**: to access the container of an item see {@link #ownerCt}.\r | |
868 | *\r | |
869 | * @since 3.4.0\r | |
870 | */\r | |
871 | \r | |
872 | /**\r | |
873 | * @cfg {Ext.ComponentLoader/Object} loader\r | |
874 | * A configuration object or an instance of a {@link Ext.ComponentLoader} to load remote content\r | |
875 | * for this Component.\r | |
876 | *\r | |
877 | * Ext.create('Ext.Component', {\r | |
878 | * loader: {\r | |
879 | * url: 'content.html',\r | |
880 | * autoLoad: true\r | |
881 | * },\r | |
882 | * renderTo: Ext.getBody()\r | |
883 | * });\r | |
884 | */\r | |
885 | \r | |
886 | /**\r | |
887 | * @cfg {Number/String} margin\r | |
888 | * Specifies the margin for this component. The margin can be a single numeric value to apply to all sides or it can\r | |
889 | * be a CSS style specification for each style, for example: '10 5 3 10' (top, right, bottom, left).\r | |
890 | */\r | |
891 | \r | |
892 | /**\r | |
893 | * @cfg {String} [maskElement=null]\r | |
894 | * Related to the {@link #cfg-childEls} configuration which specifies named properties which correspond to component sub-elements.\r | |
895 | *\r | |
896 | * The name of the element property in this component to mask when masked by a LoadMask.\r | |
897 | *\r | |
898 | * Defaults to `null` to indicate that Components cannot by default contain a LoadMask, and that any LoadMask should be rendered into the document body.\r | |
899 | *\r | |
900 | * For example, Panels use `"el"` to indicate that the whole panel should be masked. This could be configured to be\r | |
901 | * `"body"` so that only the body is masked and toolbars and the header are still mouse-accessible.\r | |
902 | */\r | |
903 | maskElement: null,\r | |
904 | \r | |
905 | /**\r | |
906 | * @cfg {String} [overCls='']\r | |
907 | * An optional extra CSS class that will be added to this component's Element when the mouse moves over the Element,\r | |
908 | * and removed when the mouse moves out. This can be useful for adding customized 'active' or 'hover' styles to the\r | |
909 | * component or any of its children using standard CSS rules.\r | |
910 | *\r | |
911 | * @since 2.3.0\r | |
912 | */\r | |
913 | \r | |
914 | /**\r | |
915 | * @cfg {String} overflowX\r | |
916 | * Possible values are:\r | |
917 | *\r | |
918 | * - `'auto'` to enable automatic horizontal scrollbar (Style overflow-x: 'auto').\r | |
919 | * - `'scroll'` to always enable horizontal scrollbar (Style overflow-x: 'scroll').\r | |
920 | *\r | |
921 | * The default is overflow-x: 'hidden'. This should not be combined with {@link #autoScroll}.\r | |
922 | * @deprecated 5.1.0 Use {@link #scrollable} instead\r | |
923 | */\r | |
924 | \r | |
925 | /**\r | |
926 | * @cfg {String} overflowY\r | |
927 | * Possible values are:\r | |
928 | *\r | |
929 | * - `'auto'` to enable automatic vertical scrollbar (Style overflow-y: 'auto').\r | |
930 | * - `'scroll'` to always enable vertical scrollbar (Style overflow-y: 'scroll').\r | |
931 | *\r | |
932 | * The default is overflow-y: 'hidden'. This should not be combined with {@link #autoScroll}.\r | |
933 | * @deprecated 5.1.0 Use {@link #scrollable} instead\r | |
934 | */\r | |
935 | \r | |
936 | /**\r | |
937 | * @cfg {Number/String} padding\r | |
938 | * Specifies the padding for this component. The padding can be a single numeric value to apply to all sides or it\r | |
939 | * can be a CSS style specification for each style, for example: '10 5 3 10' (top, right, bottom, left).\r | |
940 | */\r | |
941 | \r | |
942 | /**\r | |
943 | * @cfg {Ext.plugin.Abstract[]/Ext.plugin.Abstract/Object[]/Object/Ext.enums.Plugin[]/Ext.enums.Plugin} plugins\r | |
944 | * An array of plugins to be added to this component. Can also be just a single plugin instead of array.\r | |
945 | *\r | |
946 | * Plugins provide custom functionality for a component. The only requirement for\r | |
947 | * a valid plugin is that it contain an `init` method that accepts a reference of type Ext.Component. When a component\r | |
948 | * is created, if any plugins are available, the component will call the init method on each plugin, passing a\r | |
949 | * reference to itself. Each plugin can then call methods or respond to events on the component as needed to provide\r | |
950 | * its functionality.\r | |
951 | *\r | |
952 | * Plugins can be added to component by either directly referencing the plugin instance:\r | |
953 | *\r | |
954 | * plugins: [Ext.create('Ext.grid.plugin.CellEditing', {clicksToEdit: 1})],\r | |
955 | *\r | |
956 | * By using config object with ptype:\r | |
957 | *\r | |
958 | * plugins: {ptype: 'cellediting', clicksToEdit: 1},\r | |
959 | *\r | |
960 | * Or with just a ptype:\r | |
961 | *\r | |
962 | * plugins: ['cellediting', 'gridviewdragdrop'],\r | |
963 | *\r | |
964 | * See {@link Ext.enums.Plugin} for list of all ptypes.\r | |
965 | *\r | |
966 | * @since 2.3.0\r | |
967 | */\r | |
968 | \r | |
969 | /**\r | |
970 | * @cfg {"north"/"south"/"east"/"west"/"center"} [region=undefined]\r | |
971 | * Defines the region inside {@link Ext.layout.container.Border border layout}.\r | |
972 | *\r | |
973 | * Possible values:\r | |
974 | *\r | |
975 | * - north - Positions component at top.\r | |
976 | * - south - Positions component at bottom.\r | |
977 | * - east - Positions component at right.\r | |
978 | * - west - Positions component at left.\r | |
979 | * - center - Positions component at the remaining space.\r | |
980 | * There **must** be a component with `region: "center"` in every border layout.\r | |
981 | */\r | |
982 | \r | |
983 | /**\r | |
984 | * @cfg {Object} renderData\r | |
985 | *\r | |
986 | * The data used by {@link #renderTpl} in addition to the following property values of the component:\r | |
987 | *\r | |
988 | * - id\r | |
989 | * - ui\r | |
990 | * - uiCls\r | |
991 | * - baseCls\r | |
992 | * - componentCls\r | |
993 | * - frame\r | |
994 | *\r | |
995 | * See {@link #renderSelectors} and {@link #cfg-childEls} for usage examples.\r | |
996 | */\r | |
997 | \r | |
998 | /**\r | |
999 | * @cfg {Object} renderSelectors\r | |
1000 | * An object containing properties specifying CSS selectors which identify child elements\r | |
1001 | * created by the render process.\r | |
1002 | *\r | |
1003 | * After the Component's internal structure is rendered according to the {@link #renderTpl}, this object is iterated through,\r | |
1004 | * and the found Elements are added as properties to the Component using the `renderSelector` property name.\r | |
1005 | *\r | |
1006 | * For example, a Component which renders a title and description into its element:\r | |
1007 | *\r | |
1008 | * Ext.create('Ext.Component', {\r | |
1009 | * renderTo: Ext.getBody(),\r | |
1010 | * renderTpl: [\r | |
1011 | * '<h1 class="title">{title}</h1>',\r | |
1012 | * '<p>{desc}</p>'\r | |
1013 | * ],\r | |
1014 | * renderData: {\r | |
1015 | * title: "Error",\r | |
1016 | * desc: "Something went wrong"\r | |
1017 | * },\r | |
1018 | * renderSelectors: {\r | |
1019 | * titleEl: 'h1.title',\r | |
1020 | * descEl: 'p'\r | |
1021 | * },\r | |
1022 | * listeners: {\r | |
1023 | * afterrender: function(cmp){\r | |
1024 | * // After rendering the component will have a titleEl and descEl properties\r | |
1025 | * cmp.titleEl.setStyle({color: "red"});\r | |
1026 | * }\r | |
1027 | * }\r | |
1028 | * });\r | |
1029 | *\r | |
1030 | * The use of `renderSelectors` is deprecated (for performance reasons). The above\r | |
1031 | * code should be refactored into something like this:\r | |
1032 | *\r | |
1033 | * Ext.create('Ext.Component', {\r | |
1034 | * renderTo: Ext.getBody(),\r | |
1035 | * renderTpl: [\r | |
1036 | * '<h1 class="title" id="{id}-titleEl" data-ref="titleEl">{title}</h1>',\r | |
1037 | * '<p id="{id}-descEl" data-ref="descEl">{desc}</p>'\r | |
1038 | * ],\r | |
1039 | * renderData: {\r | |
1040 | * title: "Error",\r | |
1041 | * desc: "Something went wrong"\r | |
1042 | * },\r | |
1043 | * childEls: [\r | |
1044 | * 'titleEl',\r | |
1045 | * 'descEl'\r | |
1046 | * ]\r | |
1047 | * });\r | |
1048 | *\r | |
1049 | * To use `childEls` yet retain the use of selectors (which remains as expensive as\r | |
1050 | * `renderSelectors`):\r | |
1051 | *\r | |
1052 | * Ext.create('Ext.Component', {\r | |
1053 | * renderTo: Ext.getBody(),\r | |
1054 | * renderTpl: [\r | |
1055 | * '<h1 class="title">{title}</h1>',\r | |
1056 | * '<p>{desc}</p>'\r | |
1057 | * ],\r | |
1058 | * renderData: {\r | |
1059 | * title: "Error",\r | |
1060 | * desc: "Something went wrong"\r | |
1061 | * },\r | |
1062 | * childEls: {\r | |
1063 | * titleEl: { selectNode: 'h1.title' },\r | |
1064 | * descEl: { selectNode: 'p' }\r | |
1065 | * }\r | |
1066 | * });\r | |
1067 | *\r | |
1068 | * @deprecated 5.0 Use {@link #cfg-childEls} instead.\r | |
1069 | */\r | |
1070 | \r | |
1071 | /**\r | |
1072 | * @cfg {String/HTMLElement/Ext.dom.Element} renderTo\r | |
1073 | * Specify the `id` of the element, a DOM element or an existing Element that this component will be rendered into.\r | |
1074 | *\r | |
1075 | * **Notes:**\r | |
1076 | *\r | |
1077 | * Do *not* use this option if the Component is to be a child item of a {@link Ext.container.Container Container}.\r | |
1078 | * It is the responsibility of the {@link Ext.container.Container Container}'s\r | |
1079 | * {@link Ext.container.Container#layout layout manager} to render and manage its child items.\r | |
1080 | *\r | |
1081 | * When using this config, a call to `render()` is not required.\r | |
1082 | *\r | |
1083 | * See also: {@link #method-render}.\r | |
1084 | *\r | |
1085 | * @since 2.3.0\r | |
1086 | */\r | |
1087 | \r | |
1088 | /**\r | |
1089 | * @cfg {Ext.XTemplate/String/String[]} renderTpl\r | |
1090 | * An {@link Ext.XTemplate XTemplate} used to create the internal structure inside this Component's encapsulating\r | |
1091 | * {@link #getEl Element}.\r | |
1092 | *\r | |
1093 | * You do not normally need to specify this. For the base classes {@link Ext.Component} and\r | |
1094 | * {@link Ext.container.Container}, this defaults to **`null`** which means that they will be initially rendered\r | |
1095 | * with no internal structure; they render their {@link #getEl Element} empty. The more specialized\r | |
1096 | * classes with complex DOM structures provide their own template definitions.\r | |
1097 | *\r | |
1098 | * This is intended to allow the developer to create application-specific utility Components with customized\r | |
1099 | * internal structure.\r | |
1100 | *\r | |
1101 | * Upon rendering, any created child elements may be automatically imported into object properties using the\r | |
1102 | * {@link #renderSelectors} and {@link #cfg-childEls} options.\r | |
1103 | * @protected\r | |
1104 | */\r | |
1105 | renderTpl: [\r | |
1106 | '<tpl if="renderScroller">',\r | |
1107 | '<div class="{scrollerCls}" style="{%this.renderPadding(out, values)%}">',\r | |
1108 | '</tpl>',\r | |
1109 | '{%this.renderContent(out,values)%}',\r | |
1110 | '<tpl if="renderScroller"></div></tpl>'\r | |
1111 | ],\r | |
1112 | \r | |
1113 | /**\r | |
1114 | * @cfg {Boolean/Object} resizable\r | |
1115 | * Specify as `true` to apply a {@link Ext.resizer.Resizer Resizer} to this Component after rendering.\r | |
1116 | *\r | |
1117 | * May also be specified as a config object to be passed to the constructor of {@link Ext.resizer.Resizer Resizer}\r | |
1118 | * to override any defaults. By default the Component passes its minimum and maximum size, and uses\r | |
1119 | * `{@link Ext.resizer.Resizer#dynamic}: false`\r | |
1120 | */\r | |
1121 | \r | |
1122 | /**\r | |
1123 | * @cfg {String} resizeHandles\r | |
1124 | * A valid {@link Ext.resizer.Resizer} handles config string. Only applies when resizable = true.\r | |
1125 | */\r | |
1126 | resizeHandles: 'all',\r | |
1127 | \r | |
1128 | /**\r | |
1129 | * @cfg {Boolean/Number} [shrinkWrap=2]\r | |
1130 | *\r | |
1131 | * The possible values for shrinkWrap are:\r | |
1132 | *\r | |
1133 | * - 0 (or `false`): Neither width nor height depend on content.\r | |
1134 | * - 1: Width depends on content (shrink wraps), but height does not.\r | |
1135 | * - 2: Height depends on content (shrink wraps), but width does not.\r | |
1136 | * - 3 (or `true`): Both width and height depend on content (shrink wrap).\r | |
1137 | *\r | |
1138 | * In CSS terms, shrink-wrap width is analogous to an inline-block element as opposed\r | |
1139 | * to a block-level element.\r | |
1140 | * \r | |
1141 | * @localdoc ##Non-Panel Components\r | |
1142 | * \r | |
1143 | * The shrinkWrap config is a class-level config and should be used when defining a \r | |
1144 | * subclass.\r | |
1145 | * It is not intended to be set as a config on instances of a given component.\r | |
1146 | * \r | |
1147 | * For non-Panel components, shrinkWrap is a descriptive config only. It should be \r | |
1148 | * set when defining your own custom class including the DOM elements used to \r | |
1149 | * construct the component. The shrinkWrap property does not itself apply styling on \r | |
1150 | * the component elements. Rather, it should describe the CSS styling you've applied \r | |
1151 | * to your custom component (_refer to the numeric matrix above_).\r | |
1152 | * \r | |
1153 | * When a component is owned by a container the layout of that container will inspect \r | |
1154 | * the component's shrinkWrap property during layout. The layout then uses the \r | |
1155 | * content-wrapping policy described by shrinkWrap to correctly size and position the \r | |
1156 | * container's child items.\r | |
1157 | */\r | |
1158 | shrinkWrap: 2,\r | |
1159 | \r | |
1160 | /**\r | |
1161 | * @cfg stateEvents\r | |
1162 | * @inheritdoc Ext.state.Stateful#cfg-stateEvents\r | |
1163 | * @localdoc By default the following stateEvents are added:\r | |
1164 | * \r | |
1165 | * - {@link #event-resize}\r | |
1166 | */\r | |
1167 | \r | |
1168 | /**\r | |
1169 | * @cfg {String/Object} style\r | |
1170 | * A custom style specification to be applied to this component's Element. Should be a valid argument to\r | |
1171 | * {@link Ext.dom.Element#applyStyles}.\r | |
1172 | *\r | |
1173 | * new Ext.panel.Panel({\r | |
1174 | * title: 'Some Title',\r | |
1175 | * renderTo: Ext.getBody(),\r | |
1176 | * width: 400, height: 300,\r | |
1177 | * layout: 'form',\r | |
1178 | * items: [{\r | |
1179 | * xtype: 'textarea',\r | |
1180 | * style: {\r | |
1181 | * width: '95%',\r | |
1182 | * marginBottom: '10px'\r | |
1183 | * }\r | |
1184 | * },\r | |
1185 | * new Ext.button.Button({\r | |
1186 | * text: 'Send',\r | |
1187 | * minWidth: '100',\r | |
1188 | * style: {\r | |
1189 | * marginBottom: '10px'\r | |
1190 | * }\r | |
1191 | * })\r | |
1192 | * ]\r | |
1193 | * });\r | |
1194 | *\r | |
1195 | * @since 1.1.0\r | |
1196 | */\r | |
1197 | \r | |
1198 | /**\r | |
1199 | * @cfg {Boolean} toFrontOnShow\r | |
1200 | * True to automatically call {@link #toFront} when the {@link #method-show} method is called on an already visible,\r | |
1201 | * floating component.\r | |
1202 | */\r | |
1203 | toFrontOnShow: true,\r | |
1204 | \r | |
1205 | /**\r | |
1206 | * @cfg {Ext.XTemplate/Ext.Template/String/String[]} tpl\r | |
1207 | * An {@link Ext.Template}, {@link Ext.XTemplate} or an array of strings to form an Ext.XTemplate. Used in\r | |
1208 | * conjunction with the `{@link #data}` and `{@link #tplWriteMode}` configurations.\r | |
1209 | *\r | |
1210 | * @since 3.4.0\r | |
1211 | */\r | |
1212 | \r | |
1213 | /**\r | |
1214 | * @property {Boolean} [synthetic=false]\r | |
1215 | * This property is `true` if the component was created internally by the framework\r | |
1216 | * and is not explicitly user-defined. This is set for such things as `Splitter`\r | |
1217 | * instances managed by `border` and `box` layouts.\r | |
1218 | * @private\r | |
1219 | */\r | |
1220 | synthetic: false,\r | |
1221 | \r | |
1222 | /**\r | |
1223 | * @cfg {String} tplWriteMode\r | |
1224 | * The Ext.(X)Template method to use when updating the content area of the Component.\r | |
1225 | * See `{@link Ext.XTemplate#overwrite}` for information on default mode.\r | |
1226 | *\r | |
1227 | * @since 3.4.0\r | |
1228 | */\r | |
1229 | tplWriteMode: 'overwrite',\r | |
1230 | \r | |
1231 | /**\r | |
1232 | * @cfg {String} ui\r | |
1233 | * A UI style for a component.\r | |
1234 | */\r | |
1235 | ui: 'default',\r | |
1236 | \r | |
1237 | /**\r | |
1238 | * @cfg {String[]} uiCls\r | |
1239 | * An array of of `classNames` which are currently applied to this component.\r | |
1240 | * @private\r | |
1241 | */\r | |
1242 | uiCls: [],\r | |
1243 | \r | |
1244 | /**\r | |
1245 | * @cfg {String/String[]} userCls\r | |
1246 | * One or more CSS classes to add to the component's primary element. This config\r | |
1247 | * is intended solely for use by the component instantiator (the "user"), not by\r | |
1248 | * derived classes.\r | |
1249 | *\r | |
1250 | * For example:\r | |
1251 | *\r | |
1252 | * items: [{\r | |
1253 | * xtype: 'button',\r | |
1254 | * userCls: 'my-button'\r | |
1255 | * ...\r | |
1256 | * }]\r | |
1257 | * @accessor\r | |
1258 | */\r | |
1259 | userCls: null,\r | |
1260 | \r | |
1261 | /**\r | |
1262 | * @cfg {Number} [weight]\r | |
1263 | * A value to control how Components are laid out in a {@link Ext.layout.container.Border Border} layout or as docked items.\r | |
1264 | *\r | |
1265 | * In a Border layout, this can control how the regions (not the center) region lay out if the west or east take full height\r | |
1266 | * or if the north or south region take full width. Also look at the {@link Ext.layout.container.Border#regionWeights} on the Border layout. An example to show how you can\r | |
1267 | * take control of this is:\r | |
1268 | *\r | |
1269 | * Ext.create('Ext.container.Viewport', {\r | |
1270 | * layout : 'border',\r | |
1271 | * defaultType : 'panel',\r | |
1272 | * items : [\r | |
1273 | * {\r | |
1274 | * region : 'north',\r | |
1275 | * title : 'North',\r | |
1276 | * height : 100\r | |
1277 | * },\r | |
1278 | * {\r | |
1279 | * region : 'south',\r | |
1280 | * title : 'South',\r | |
1281 | * height : 100,\r | |
1282 | * weight : -25\r | |
1283 | * },\r | |
1284 | * {\r | |
1285 | * region : 'west',\r | |
1286 | * title : 'West',\r | |
1287 | * width : 200,\r | |
1288 | * weight : 15\r | |
1289 | * },\r | |
1290 | * {\r | |
1291 | * region : 'east',\r | |
1292 | * title : 'East',\r | |
1293 | * width : 200\r | |
1294 | * },\r | |
1295 | * {\r | |
1296 | * region : 'center',\r | |
1297 | * title : 'center'\r | |
1298 | * }\r | |
1299 | * ]\r | |
1300 | * });\r | |
1301 | *\r | |
1302 | * If docked items, the weight will order how the items are laid out. Here is an example to put a {@link Ext.toolbar.Toolbar} above\r | |
1303 | * a {@link Ext.panel.Panel}'s header:\r | |
1304 | *\r | |
1305 | * Ext.create('Ext.panel.Panel', {\r | |
1306 | * renderTo : document.body,\r | |
1307 | * width : 300,\r | |
1308 | * height : 300,\r | |
1309 | * title : 'Panel',\r | |
1310 | * html : 'Panel Body',\r | |
1311 | * dockedItems : [\r | |
1312 | * {\r | |
1313 | * xtype : 'toolbar',\r | |
1314 | * items : [\r | |
1315 | * {\r | |
1316 | * text : 'Save'\r | |
1317 | * }\r | |
1318 | * ]\r | |
1319 | * },\r | |
1320 | * {\r | |
1321 | * xtype : 'toolbar',\r | |
1322 | * weight : -10,\r | |
1323 | * items : [\r | |
1324 | * {\r | |
1325 | * text : 'Remove'\r | |
1326 | * }\r | |
1327 | * ]\r | |
1328 | * }\r | |
1329 | * ]\r | |
1330 | * });\r | |
1331 | */\r | |
1332 | weight: null,\r | |
1333 | \r | |
1334 | /**\r | |
1335 | * @cfg {Number|String} width\r | |
1336 | * The width of this component. A numeric value will be interpreted as the number of\r | |
1337 | * pixels; a string value will be treated as a CSS value with units.\r | |
1338 | */\r | |
1339 | \r | |
1340 | /**\r | |
1341 | * @cfg {Ext.enums.Widget} xtype\r | |
1342 | * **Note:** Only applies to {@link Ext.Component} derived classes when used as \r | |
1343 | * a config in {@link Ext#define Ext.define}.\r | |
1344 | * \r | |
1345 | * This property provides a shorter alternative to creating objects than using a full\r | |
1346 | * class name. Using `xtype` is the most common way to define component instances,\r | |
1347 | * especially in a container. For example, the items in a form containing text fields\r | |
1348 | * could be created explicitly like so:\r | |
1349 | *\r | |
1350 | * items: [\r | |
1351 | * Ext.create('Ext.form.field.Text', {\r | |
1352 | * fieldLabel: 'Foo'\r | |
1353 | * }),\r | |
1354 | * Ext.create('Ext.form.field.Text', {\r | |
1355 | * fieldLabel: 'Bar'\r | |
1356 | * }),\r | |
1357 | * Ext.create('Ext.form.field.Number', {\r | |
1358 | * fieldLabel: 'Num'\r | |
1359 | * })\r | |
1360 | * ]\r | |
1361 | *\r | |
1362 | * But by using `xtype`, the above becomes:\r | |
1363 | *\r | |
1364 | * items: [\r | |
1365 | * {\r | |
1366 | * xtype: 'textfield',\r | |
1367 | * fieldLabel: 'Foo'\r | |
1368 | * },\r | |
1369 | * {\r | |
1370 | * xtype: 'textfield',\r | |
1371 | * fieldLabel: 'Bar'\r | |
1372 | * },\r | |
1373 | * {\r | |
1374 | * xtype: 'numberfield',\r | |
1375 | * fieldLabel: 'Num'\r | |
1376 | * }\r | |
1377 | * ]\r | |
1378 | *\r | |
1379 | * When the `xtype` is common to many items, {@link Ext.container.Container#defaultType}\r | |
1380 | * is another way to specify the `xtype` for all items that don't have an explicit `xtype`:\r | |
1381 | *\r | |
1382 | * defaultType: 'textfield',\r | |
1383 | * items: [\r | |
1384 | * { fieldLabel: 'Foo' },\r | |
1385 | * { fieldLabel: 'Bar' },\r | |
1386 | * { fieldLabel: 'Num', xtype: 'numberfield' }\r | |
1387 | * ]\r | |
1388 | *\r | |
1389 | * Each member of the `items` array is now just a "configuration object". These objects\r | |
1390 | * are used to create and configure component instances. A configuration object can be\r | |
1391 | * manually used to instantiate a component using {@link Ext#widget}:\r | |
1392 | *\r | |
1393 | * var text1 = Ext.create('Ext.form.field.Text', {\r | |
1394 | * fieldLabel: 'Foo'\r | |
1395 | * });\r | |
1396 | *\r | |
1397 | * // or alternatively:\r | |
1398 | *\r | |
1399 | * var text1 = Ext.widget({\r | |
1400 | * xtype: 'textfield',\r | |
1401 | * fieldLabel: 'Foo'\r | |
1402 | * });\r | |
1403 | *\r | |
1404 | * This conversion of configuration objects into instantiated components is done when\r | |
1405 | * a container is created as part of its {Ext.container.AbstractContainer#initComponent}\r | |
1406 | * process. As part of the same process, the `items` array is converted from its raw\r | |
1407 | * array form into a {@link Ext.util.MixedCollection} instance.\r | |
1408 | *\r | |
1409 | * You can define your own `xtype` on a custom {@link Ext.Component component} by specifying\r | |
1410 | * the `xtype` property in {@link Ext#define}. For example:\r | |
1411 | *\r | |
1412 | * Ext.define('MyApp.PressMeButton', {\r | |
1413 | * extend: 'Ext.button.Button',\r | |
1414 | * xtype: 'pressmebutton',\r | |
1415 | * text: 'Press Me'\r | |
1416 | * });\r | |
1417 | *\r | |
1418 | * Care should be taken when naming an `xtype` in a custom component because there is\r | |
1419 | * a single, shared scope for all xtypes. Third part components should consider using\r | |
1420 | * a prefix to avoid collisions.\r | |
1421 | *\r | |
1422 | * Ext.define('Foo.form.CoolButton', {\r | |
1423 | * extend: 'Ext.button.Button',\r | |
1424 | * xtype: 'ux-coolbutton',\r | |
1425 | * text: 'Cool!'\r | |
1426 | * });\r | |
1427 | *\r | |
1428 | * See {@link Ext.enums.Widget} for list of all available xtypes.\r | |
1429 | *\r | |
1430 | * @since 2.3.0\r | |
1431 | */\r | |
1432 | \r | |
1433 | // ***********************************************************************************\r | |
1434 | // End Config\r | |
1435 | // ***********************************************************************************\r | |
1436 | // </editor-fold>\r | |
1437 | \r | |
1438 | // <editor-fold desc="Properties">\r | |
1439 | // ***********************************************************************************\r | |
1440 | // Begin Properties\r | |
1441 | // ***********************************************************************************\r | |
1442 | \r | |
1443 | /**\r | |
1444 | * @private\r | |
1445 | */\r | |
1446 | allowDomMove: true,\r | |
1447 | \r | |
1448 | /**\r | |
1449 | * @property {Boolean} autoGenId\r | |
1450 | * `true` indicates an `id` was auto-generated rather than provided by configuration.\r | |
1451 | * @private\r | |
1452 | */\r | |
1453 | autoGenId: false,\r | |
1454 | \r | |
1455 | /**\r | |
1456 | * @private\r | |
1457 | */\r | |
1458 | borderBoxCls: Ext.baseCSSPrefix + 'border-box',\r | |
1459 | \r | |
1460 | /**\r | |
1461 | * @property {Number} componentLayoutCounter\r | |
1462 | * @private\r | |
1463 | * The number of component layout calls made on this object.\r | |
1464 | */\r | |
1465 | componentLayoutCounter: 0,\r | |
1466 | \r | |
1467 | /**\r | |
1468 | * @property {String} [contentPaddingProperty='padding']\r | |
1469 | * The name of the padding property that is used by the layout to manage\r | |
1470 | * padding. See {@link Ext.layout.container.Auto#managePadding managePadding}\r | |
1471 | */ \r | |
1472 | contentPaddingProperty: 'padding',\r | |
1473 | \r | |
1474 | /**\r | |
1475 | * @private\r | |
1476 | */\r | |
1477 | deferLayouts: false,\r | |
1478 | \r | |
1479 | /**\r | |
1480 | * @property {Ext.Container} floatParent\r | |
1481 | * **Only present for {@link #cfg-floating} Components which were inserted as child items of Containers.**\r | |
1482 | *\r | |
1483 | * There are other similar relationships such as the {@link Ext.button.Button button} which activates a {@link Ext.button.Button#cfg-menu menu}, or the\r | |
1484 | * {@link Ext.menu.Item menu item} which activated a {@link Ext.menu.Item#cfg-menu submenu}, or the\r | |
1485 | * {@link Ext.grid.column.Column column header} which activated the column menu.\r | |
1486 | *\r | |
1487 | * These differences are abstracted away by the {@link #up} method.\r | |
1488 | *\r | |
1489 | * Floating Components that are programmatically {@link Ext.Component#method-render rendered} will not have a `floatParent`\r | |
1490 | * property.\r | |
1491 | *\r | |
1492 | * See {@link #cfg-floating} and {@link #zIndexManager}\r | |
1493 | * @readonly\r | |
1494 | */\r | |
1495 | \r | |
1496 | /**\r | |
1497 | * @property {Object} frameSize\r | |
1498 | * @readonly\r | |
1499 | * Indicates the width of any framing elements which were added within the encapsulating\r | |
1500 | * element to provide graphical, rounded borders. See the {@link #frame} config. This\r | |
1501 | * property is `null` if the component is not framed.\r | |
1502 | *\r | |
1503 | * This is an object containing the frame width in pixels for all four sides of the\r | |
1504 | * Component containing the following properties:\r | |
1505 | *\r | |
1506 | * @property {Number} [frameSize.top=0] The width of the top framing element in pixels.\r | |
1507 | * @property {Number} [frameSize.right=0] The width of the right framing element in pixels.\r | |
1508 | * @property {Number} [frameSize.bottom=0] The width of the bottom framing element in pixels.\r | |
1509 | * @property {Number} [frameSize.left=0] The width of the left framing element in pixels.\r | |
1510 | * @property {Number} [frameSize.width=0] The total width of the left and right framing elements in pixels.\r | |
1511 | * @property {Number} [frameSize.height=0] The total height of the top and right bottom elements in pixels.\r | |
1512 | */\r | |
1513 | frameSize: null,\r | |
1514 | \r | |
1515 | /**\r | |
1516 | * @private\r | |
1517 | */\r | |
1518 | horizontalPosProp: 'left',\r | |
1519 | \r | |
1520 | /**\r | |
1521 | * @property {Boolean} isComponent\r | |
1522 | * `true` in this class to identify an object as an instantiated Component, or subclass thereof.\r | |
1523 | */\r | |
1524 | isComponent: true,\r | |
1525 | \r | |
1526 | /**\r | |
1527 | * @property {Boolean} [_isLayoutRoot=false]\r | |
1528 | * Setting this property to `true` causes the {@link #isLayoutRoot} method to return\r | |
1529 | * `true` and stop the search for the top-most component for a layout.\r | |
1530 | * @protected\r | |
1531 | */\r | |
1532 | _isLayoutRoot: false,\r | |
1533 | \r | |
1534 | /**\r | |
1535 | * @private\r | |
1536 | */\r | |
1537 | layoutSuspendCount: 0,\r | |
1538 | \r | |
1539 | /**\r | |
1540 | * @cfg {Boolean}\r | |
1541 | * Components that achieve their internal layout results using solely CSS with no JS\r | |
1542 | * intervention must set this to true. This allows the component to opt out of the\r | |
1543 | * layout run when used inside certain container layouts such as {@link \r | |
1544 | * Ext.layout.container.Form Form} and {@link Ext.layout.container.Auto Auto}\r | |
1545 | * resulting in a performance gain. The following components currently use liquid\r | |
1546 | * layout (`liquidLayout: true`):\r | |
1547 | * \r | |
1548 | * - All Form Fields (subclasses of {@link Ext.form.field.Base})\r | |
1549 | * - {@link Ext.button.Button}\r | |
1550 | * \r | |
1551 | * It is important to keep in mind that components using liquidLayout do not fire\r | |
1552 | * the following events:\r | |
1553 | * \r | |
1554 | * - {@link #event-resize}\r | |
1555 | * - {@link #event-boxready}\r | |
1556 | * \r | |
1557 | * In addition liquidLayout components do not call the following template methods:\r | |
1558 | * \r | |
1559 | * - {@link #afterComponentLayout}\r | |
1560 | * - {@link #onBoxReady}\r | |
1561 | * - {@link #onResize}\r | |
1562 | * \r | |
1563 | * Any component that needs to fire these events or to have these methods called during\r | |
1564 | * its life cycle needs to set `liquidLayout` to `false`. The following example\r | |
1565 | * demonstrates how to enable the resize event for a\r | |
1566 | * {@link Ext.form.field.TextArea TextArea Field}:\r | |
1567 | * \r | |
1568 | * @example\r | |
1569 | * var win = Ext.create({\r | |
1570 | * xtype: 'window',\r | |
1571 | * title: 'Resize This Window!',\r | |
1572 | * height: 100,\r | |
1573 | * width: 200,\r | |
1574 | * layout: 'anchor',\r | |
1575 | * items: [{\r | |
1576 | * xtype: 'textarea',\r | |
1577 | * anchor: '0 0',\r | |
1578 | * liquidLayout: false // allows the textarea to fire "resize"\r | |
1579 | * }]\r | |
1580 | * }),\r | |
1581 | * textfield = win.items.getAt(0);\r | |
1582 | *\r | |
1583 | * win.show();\r | |
1584 | *\r | |
1585 | * textfield.on('resize', function(textfield, width, height) {\r | |
1586 | * Ext.Msg.alert('Text Field Resized', 'width: ' + width + ', height: ' + height);\r | |
1587 | * });\r | |
1588 | * \r | |
1589 | * Use caution when setting `liquidLayout` to `false` as it carries a performance penalty\r | |
1590 | * since it means the layout system must perform expensive DOM reads to determine the\r | |
1591 | * Component's size.\r | |
1592 | */\r | |
1593 | liquidLayout: false,\r | |
1594 | \r | |
1595 | /**\r | |
1596 | * @property {Boolean} maskOnDisable\r | |
1597 | * This is an internal flag that you use when creating custom components. By default this is set to `true` which means\r | |
1598 | * that every component gets a mask when it's disabled. Components like FieldContainer, FieldSet, Field, Button, Tab\r | |
1599 | * override this property to `false` since they want to implement custom disable logic.\r | |
1600 | */\r | |
1601 | maskOnDisable: true,\r | |
1602 | \r | |
1603 | /**\r | |
1604 | * @private\r | |
1605 | */\r | |
1606 | offsetsCls: Ext.baseCSSPrefix + 'hidden-offsets',\r | |
1607 | \r | |
1608 | /**\r | |
1609 | * @property {Ext.Container} ownerCt\r | |
1610 | * This Component's owner {@link Ext.container.Container Container} (is set automatically\r | |
1611 | * when this Component is added to a Container).\r | |
1612 | *\r | |
1613 | * *Important.* This is not a universal upwards navigation pointer. It indicates the Container which owns and manages\r | |
1614 | * this Component if any. There are other similar relationships such as the {@link Ext.button.Button button} which activates a {@link Ext.button.Button#cfg-menu menu}, or the\r | |
1615 | * {@link Ext.menu.Item menu item} which activated a {@link Ext.menu.Item#cfg-menu submenu}, or the\r | |
1616 | * {@link Ext.grid.column.Column column header} which activated the column menu.\r | |
1617 | *\r | |
1618 | * These differences are abstracted away by the {@link #up} method.\r | |
1619 | *\r | |
1620 | * **Note**: to access items within the Container see {@link #itemId}.\r | |
1621 | * @readonly\r | |
1622 | * @since 2.3.0\r | |
1623 | */\r | |
1624 | \r | |
1625 | /**\r | |
1626 | * @property {Boolean} rendered\r | |
1627 | * Indicates whether or not the component has been rendered.\r | |
1628 | * @readonly\r | |
1629 | * @since 1.1.0\r | |
1630 | */\r | |
1631 | rendered: false,\r | |
1632 | \r | |
1633 | /**\r | |
1634 | * @private\r | |
1635 | */\r | |
1636 | rootCls: Ext.baseCSSPrefix + 'body',\r | |
1637 | \r | |
1638 | /**\r | |
1639 | * @private\r | |
1640 | */\r | |
1641 | scrollerCls: Ext.baseCSSPrefix + 'scroll-scroller',\r | |
1642 | scrollerSelector: '.' + Ext.baseCSSPrefix + 'scroll-scroller',\r | |
1643 | \r | |
1644 | /**\r | |
1645 | * @property {Object} scrollFlags\r | |
1646 | * An object property which provides unified information as to which dimensions are\r | |
1647 | * scrollable based upon the {@link #scrollable} settings (And for *views* of trees and\r | |
1648 | * grids, the owning panel's {@link Ext.panel.Table#scroll scroll} setting).\r | |
1649 | *\r | |
1650 | * Note that if you set overflow styles using the {@link #style} config or\r | |
1651 | * {@link Ext.panel.Panel#bodyStyle bodyStyle} config, this object does not include\r | |
1652 | * that information. Use {@link #scrollable} if you need to access these flags.\r | |
1653 | *\r | |
1654 | * This object has the following properties:\r | |
1655 | * @property {Boolean} scrollFlags.x `true` if this Component is scrollable\r | |
1656 | * horizontally - style setting may be `'auto'` or `'scroll'`.\r | |
1657 | * @property {Boolean} scrollFlags.y `true` if this Component is scrollable\r | |
1658 | * vertically - style setting may be `'auto'` or `'scroll'`.\r | |
1659 | * @property {Boolean} scrollFlags.both `true` if this Component is scrollable both\r | |
1660 | * horizontally and vertically.\r | |
1661 | * @property {String} scrollFlags.overflowX The `overflow-x` style setting, `'auto'`\r | |
1662 | * or `'scroll'` or `''`.\r | |
1663 | * @property {String} scrollFlags.overflowY The `overflow-y` style setting, `'auto'`\r | |
1664 | * or `'scroll'` or `''`.\r | |
1665 | * @readonly\r | |
1666 | * @private\r | |
1667 | */\r | |
1668 | _scrollFlags: {\r | |
1669 | auto: {\r | |
1670 | // x:auto, y:auto\r | |
1671 | auto: {\r | |
1672 | overflowX: 'auto',\r | |
1673 | overflowY: 'auto',\r | |
1674 | x: true,\r | |
1675 | y: true,\r | |
1676 | both: true\r | |
1677 | },\r | |
1678 | // x:auto, y:false\r | |
1679 | 'false': {\r | |
1680 | overflowX: 'auto',\r | |
1681 | overflowY: 'hidden',\r | |
1682 | x: true,\r | |
1683 | y: false,\r | |
1684 | both: false\r | |
1685 | },\r | |
1686 | // x:auto, y:scroll\r | |
1687 | scroll: {\r | |
1688 | overflowX: 'auto',\r | |
1689 | overflowY: 'scroll',\r | |
1690 | x: true,\r | |
1691 | y: true,\r | |
1692 | both: true\r | |
1693 | }\r | |
1694 | },\r | |
1695 | 'false': {\r | |
1696 | // x:false, y:auto\r | |
1697 | auto: {\r | |
1698 | overflowX: 'hidden',\r | |
1699 | overflowY: 'auto',\r | |
1700 | x: false,\r | |
1701 | y: true,\r | |
1702 | both: false\r | |
1703 | },\r | |
1704 | // x:false, y:false\r | |
1705 | 'false': {\r | |
1706 | overflowX: 'hidden',\r | |
1707 | overflowY: 'hidden',\r | |
1708 | x: false,\r | |
1709 | y: false,\r | |
1710 | both: false\r | |
1711 | },\r | |
1712 | // x:false, y:scroll\r | |
1713 | scroll: {\r | |
1714 | overflowX: 'hidden',\r | |
1715 | overflowY: 'scroll',\r | |
1716 | x: false,\r | |
1717 | y: true,\r | |
1718 | both: false\r | |
1719 | }\r | |
1720 | },\r | |
1721 | scroll: {\r | |
1722 | // x:scroll, y:auto\r | |
1723 | auto: {\r | |
1724 | overflowX: 'scroll',\r | |
1725 | overflowY: 'auto',\r | |
1726 | x: true,\r | |
1727 | y: true,\r | |
1728 | both: true\r | |
1729 | },\r | |
1730 | // x:scroll, y:false\r | |
1731 | 'false': {\r | |
1732 | overflowX: 'scroll',\r | |
1733 | overflowY: 'hidden',\r | |
1734 | x: true,\r | |
1735 | y: false,\r | |
1736 | both: false\r | |
1737 | },\r | |
1738 | // x:scroll, y:scroll\r | |
1739 | scroll: {\r | |
1740 | overflowX: 'scroll',\r | |
1741 | overflowY: 'scroll',\r | |
1742 | x: true,\r | |
1743 | y: true,\r | |
1744 | both: true\r | |
1745 | }\r | |
1746 | },\r | |
1747 | none: {\r | |
1748 | overflowX: '',\r | |
1749 | overflowY: '',\r | |
1750 | x: false,\r | |
1751 | y: false,\r | |
1752 | both: false\r | |
1753 | }\r | |
1754 | },\r | |
1755 | \r | |
1756 | _scrollableCfg: {\r | |
1757 | x: {\r | |
1758 | x: true,\r | |
1759 | y: false\r | |
1760 | },\r | |
1761 | y: {\r | |
1762 | x: false,\r | |
1763 | y: true\r | |
1764 | },\r | |
1765 | horizontal: {\r | |
1766 | x: true,\r | |
1767 | y: false\r | |
1768 | },\r | |
1769 | vertical: {\r | |
1770 | x: false,\r | |
1771 | y: true\r | |
1772 | },\r | |
1773 | both: {\r | |
1774 | x: true,\r | |
1775 | y: true\r | |
1776 | },\r | |
1777 | 'true': {\r | |
1778 | x: true,\r | |
1779 | y: true\r | |
1780 | }\r | |
1781 | },\r | |
1782 | \r | |
1783 | validIdRe: Ext.validIdRe,\r | |
1784 | \r | |
1785 | // ***********************************************************************************\r | |
1786 | // End Properties\r | |
1787 | // ***********************************************************************************\r | |
1788 | // </editor-fold>\r | |
1789 | \r | |
1790 | // <editor-fold desc="Events">\r | |
1791 | // ***********************************************************************************\r | |
1792 | // Begin Events\r | |
1793 | // ***********************************************************************************\r | |
1794 | \r | |
1795 | /**\r | |
1796 | * @event afterlayoutanimation\r | |
1797 | * This event first after a component's layout has been updated by a layout that\r | |
1798 | * included animation (e.g., a {@link Ext.panel.Panel panel} in an\r | |
1799 | * {@link Ext.layout.container.Accordion accordion} layout).\r | |
1800 | * @param {Ext.Component} this\r | |
1801 | * @since 6.0.0\r | |
1802 | */\r | |
1803 | \r | |
1804 | /**\r | |
1805 | * @event beforeactivate\r | |
1806 | * Fires before a Component has been visually activated. Returning `false` from an event listener can prevent\r | |
1807 | * the activate from occurring.\r | |
1808 | *\r | |
1809 | * **Note** This event is only fired if this Component is a child of a {@link Ext.container.Container}\r | |
1810 | * that uses {@link Ext.layout.container.Card} as it's layout.\r | |
1811 | * @param {Ext.Component} this\r | |
1812 | */\r | |
1813 | \r | |
1814 | /**\r | |
1815 | * @event activate\r | |
1816 | * Fires after a Component has been visually activated.\r | |
1817 | *\r | |
1818 | * **Note** This event is only fired if this Component is a child of a {@link Ext.container.Container}\r | |
1819 | * that uses {@link Ext.layout.container.Card} as it's layout or this Component is a floating Component.\r | |
1820 | * @param {Ext.Component} this\r | |
1821 | */\r | |
1822 | \r | |
1823 | /**\r | |
1824 | * @event beforedeactivate\r | |
1825 | * Fires before a Component has been visually deactivated. Returning `false` from an event listener can\r | |
1826 | * prevent the deactivate from occurring.\r | |
1827 | *\r | |
1828 | * **Note** This event is only fired if this Component is a child of a {@link Ext.container.Container}\r | |
1829 | * that uses {@link Ext.layout.container.Card} as it's layout.\r | |
1830 | * @param {Ext.Component} this\r | |
1831 | */\r | |
1832 | \r | |
1833 | /**\r | |
1834 | * @event deactivate\r | |
1835 | * Fires after a Component has been visually deactivated.\r | |
1836 | *\r | |
1837 | * **Note** This event is only fired if this Component is a child of a {@link Ext.container.Container}\r | |
1838 | * that uses {@link Ext.layout.container.Card} as it's layout or this Component is a floating Component.\r | |
1839 | * @param {Ext.Component} this\r | |
1840 | */\r | |
1841 | \r | |
1842 | /**\r | |
1843 | * @event added\r | |
1844 | * Fires after a Component had been added to a Container.\r | |
1845 | * @param {Ext.Component} this\r | |
1846 | * @param {Ext.container.Container} container Parent Container\r | |
1847 | * @param {Number} pos position of Component\r | |
1848 | * @since 3.4.0\r | |
1849 | */\r | |
1850 | \r | |
1851 | /**\r | |
1852 | * @event disable\r | |
1853 | * Fires after the component is disabled.\r | |
1854 | * @param {Ext.Component} this\r | |
1855 | * @since 1.1.0\r | |
1856 | */\r | |
1857 | \r | |
1858 | /**\r | |
1859 | * @event enable\r | |
1860 | * Fires after the component is enabled.\r | |
1861 | * @param {Ext.Component} this\r | |
1862 | * @since 1.1.0\r | |
1863 | */\r | |
1864 | \r | |
1865 | /**\r | |
1866 | * @event beforeshow\r | |
1867 | * Fires before the component is shown when calling the {@link Ext.Component#method-show show} method. Return `false` from an event\r | |
1868 | * handler to stop the show.\r | |
1869 | * @param {Ext.Component} this\r | |
1870 | * @since 1.1.0\r | |
1871 | */\r | |
1872 | \r | |
1873 | /**\r | |
1874 | * @event show\r | |
1875 | * Fires after the component is shown when calling the {@link Ext.Component#method-show show} method.\r | |
1876 | * @param {Ext.Component} this\r | |
1877 | * @since 1.1.0\r | |
1878 | */\r | |
1879 | \r | |
1880 | /**\r | |
1881 | * @event beforehide\r | |
1882 | * Fires before the component is hidden when calling the {@link Ext.Component#method-hide hide} method. Return `false` from an event\r | |
1883 | * handler to stop the hide.\r | |
1884 | * @param {Ext.Component} this\r | |
1885 | * @since 1.1.0\r | |
1886 | */\r | |
1887 | \r | |
1888 | /**\r | |
1889 | * @event hide\r | |
1890 | * Fires after the component is hidden. Fires after the component is hidden when calling the {@link Ext.Component#method-hide hide}\r | |
1891 | * method.\r | |
1892 | * @param {Ext.Component} this\r | |
1893 | * @since 1.1.0\r | |
1894 | */\r | |
1895 | \r | |
1896 | /**\r | |
1897 | * @event removed\r | |
1898 | * Fires when a component is removed from an Ext.container.Container\r | |
1899 | * @param {Ext.Component} this\r | |
1900 | * @param {Ext.container.Container} ownerCt Container which holds the component\r | |
1901 | * @since 3.4.0\r | |
1902 | */\r | |
1903 | \r | |
1904 | /**\r | |
1905 | * @event beforerender\r | |
1906 | * Fires before the component is {@link #rendered}. Return `false` from an event handler to stop the\r | |
1907 | * {@link #method-render}.\r | |
1908 | * @param {Ext.Component} this\r | |
1909 | * @since 1.1.0\r | |
1910 | */\r | |
1911 | \r | |
1912 | /**\r | |
1913 | * @event render\r | |
1914 | * Fires after the component markup is {@link #rendered}.\r | |
1915 | * @param {Ext.Component} this\r | |
1916 | * @since 1.1.0\r | |
1917 | */\r | |
1918 | \r | |
1919 | /**\r | |
1920 | * @event afterrender\r | |
1921 | * Fires after the component rendering is finished.\r | |
1922 | *\r | |
1923 | * The `afterrender` event is fired after this Component has been {@link #rendered}, been post-processed by any\r | |
1924 | * `afterRender` method defined for the Component.\r | |
1925 | * @param {Ext.Component} this\r | |
1926 | * @since 3.4.0\r | |
1927 | */\r | |
1928 | \r | |
1929 | /**\r | |
1930 | * @event boxready\r | |
1931 | * Fires *one time* - after the component has been laid out for the first time at its initial size.\r | |
1932 | *\r | |
1933 | * This event does not fire on components that use {@link #liquidLayout}, such as\r | |
1934 | * {@link Ext.button.Button Buttons} and {@link Ext.form.field.Base Form Fields}.\r | |
1935 | * @param {Ext.Component} this\r | |
1936 | * @param {Number} width The initial width.\r | |
1937 | * @param {Number} height The initial height.\r | |
1938 | */\r | |
1939 | \r | |
1940 | /**\r | |
1941 | * @event beforedestroy\r | |
1942 | * Fires before the component is {@link #method-destroy}ed. Return `false` from an event handler to stop the\r | |
1943 | * {@link #method-destroy}.\r | |
1944 | * @param {Ext.Component} this\r | |
1945 | * @since 1.1.0\r | |
1946 | */\r | |
1947 | \r | |
1948 | /**\r | |
1949 | * @event destroy\r | |
1950 | * Fires after the component is {@link #method-destroy}ed.\r | |
1951 | * @param {Ext.Component} this\r | |
1952 | * @since 1.1.0\r | |
1953 | */\r | |
1954 | \r | |
1955 | /**\r | |
1956 | * @event resize\r | |
1957 | * Fires after the component is resized. Note that this does *not* fire when the component is first laid out at its initial\r | |
1958 | * size. To hook that point in the life cycle, use the {@link #boxready} event.\r | |
1959 | * \r | |
1960 | * This event does not fire on components that use {@link #liquidLayout}, such as\r | |
1961 | * {@link Ext.button.Button Buttons} and {@link Ext.form.field.Base Form Fields}.\r | |
1962 | * @param {Ext.Component} this\r | |
1963 | * @param {Number} width The new width that was set.\r | |
1964 | * @param {Number} height The new height that was set.\r | |
1965 | * @param {Number} oldWidth The previous width.\r | |
1966 | * @param {Number} oldHeight The previous height.\r | |
1967 | */\r | |
1968 | \r | |
1969 | /**\r | |
1970 | * @event move\r | |
1971 | * Fires after the component is moved.\r | |
1972 | * @param {Ext.Component} this\r | |
1973 | * @param {Number} x The new x position.\r | |
1974 | * @param {Number} y The new y position.\r | |
1975 | */\r | |
1976 | \r | |
1977 | // ***********************************************************************************\r | |
1978 | // End Events\r | |
1979 | // ***********************************************************************************\r | |
1980 | // </editor-fold>\r | |
1981 | \r | |
1982 | /**\r | |
1983 | * Creates new Component.\r | |
1984 | * @param {Ext.dom.Element/String/Object} config The configuration options may be specified as either:\r | |
1985 | *\r | |
1986 | * - **an element** : it is set as the internal element and its id used as the component id\r | |
1987 | * - **a string** : it is assumed to be the id of an existing element and is used as the component id\r | |
1988 | * - **anything else** : it is assumed to be a standard config object and is applied to the component\r | |
1989 | */\r | |
1990 | constructor: function(config) {\r | |
1991 | var me = this,\r | |
1992 | i, len, xhooks, controller, autoScroll, overflowX, overflowY, scrollable;\r | |
1993 | \r | |
1994 | config = config || {};\r | |
1995 | if (config.initialConfig) {\r | |
1996 | \r | |
1997 | // Being initialized from an Ext.Action instance...\r | |
1998 | if (config.isAction) {\r | |
1999 | me.baseAction = config;\r | |
2000 | }\r | |
2001 | config = config.initialConfig;\r | |
2002 | // component cloning / action set up\r | |
2003 | }\r | |
2004 | else if (config.tagName || config.dom || Ext.isString(config)) {\r | |
2005 | // element object\r | |
2006 | config = {\r | |
2007 | applyTo: config,\r | |
2008 | id: config.id || config\r | |
2009 | };\r | |
2010 | }\r | |
2011 | \r | |
2012 | // Make initialConfig available early so that config getters may access it\r | |
2013 | /**\r | |
2014 | * @property {Object} initialConfig\r | |
2015 | * @readonly\r | |
2016 | * The config object passed to the constructor during Component creation.\r | |
2017 | */\r | |
2018 | me.initialConfig = config;\r | |
2019 | \r | |
2020 | // Ensure that we have an id early so that config getters may access it\r | |
2021 | me.getId();\r | |
2022 | me.protoEl = new Ext.util.ProtoElement();\r | |
2023 | //<debug>\r | |
2024 | me.$calledInitConfig = true;\r | |
2025 | //</debug>\r | |
2026 | me.initConfig(config);\r | |
2027 | //<debug>\r | |
2028 | delete me.$calledInitConfig;\r | |
2029 | //</debug>\r | |
2030 | \r | |
2031 | if (me.scrollable == null) {\r | |
2032 | autoScroll = me.autoScroll;\r | |
2033 | \r | |
2034 | if (autoScroll) {\r | |
2035 | scrollable = !!autoScroll;\r | |
2036 | } else {\r | |
2037 | overflowX = me.overflowX;\r | |
2038 | overflowY = me.overflowY;\r | |
2039 | \r | |
2040 | if (overflowX || overflowY) {\r | |
2041 | scrollable = {\r | |
2042 | x: (overflowX && overflowX !== 'hidden') ? overflowX : false,\r | |
2043 | y: (overflowY && overflowY !== 'hidden') ? overflowY : false\r | |
2044 | };\r | |
2045 | }\r | |
2046 | }\r | |
2047 | \r | |
2048 | if (scrollable) {\r | |
2049 | me.setScrollable(scrollable);\r | |
2050 | }\r | |
2051 | }\r | |
2052 | \r | |
2053 | xhooks = me.xhooks;\r | |
2054 | if (xhooks) {\r | |
2055 | delete me.xhooks;\r | |
2056 | Ext.override(me, xhooks);\r | |
2057 | }\r | |
2058 | \r | |
2059 | me.mixins.elementCt.constructor.call(me);\r | |
2060 | \r | |
2061 | //<debug>\r | |
2062 | if (!me.validIdRe.test(me.id)) {\r | |
2063 | Ext.raise('Invalid component "id": "' + me.id + '"');\r | |
2064 | }\r | |
2065 | if (!me.validIdRe.test(me.itemId)) {\r | |
2066 | Ext.raise('Invalid component "itemId": "' + me.itemId + '"');\r | |
2067 | }\r | |
2068 | //</debug>\r | |
2069 | \r | |
2070 | me.setupProtoEl();\r | |
2071 | \r | |
2072 | // initComponent, beforeRender, or event handlers may have set the style or `cls` property since the `protoEl` was set up\r | |
2073 | // so we must apply styles and classes here too.\r | |
2074 | if (me.cls) {\r | |
2075 | me.initialCls = me.cls;\r | |
2076 | me.protoEl.addCls(me.cls);\r | |
2077 | }\r | |
2078 | if (me.style) {\r | |
2079 | me.initialStyle = me.style;\r | |
2080 | me.protoEl.setStyle(me.style);\r | |
2081 | }\r | |
2082 | \r | |
2083 | me.renderData = me.renderData || {};\r | |
2084 | \r | |
2085 | me.initComponent();\r | |
2086 | \r | |
2087 | // initComponent gets a chance to change the id property before registering\r | |
2088 | if (!me.preventRegister) {\r | |
2089 | Ext.ComponentManager.register(me);\r | |
2090 | }\r | |
2091 | \r | |
2092 | me.mixins.state.constructor.call(me);\r | |
2093 | me.addStateEvents('resize');\r | |
2094 | \r | |
2095 | controller = me.getController();\r | |
2096 | if (controller) {\r | |
2097 | controller.init(me);\r | |
2098 | }\r | |
2099 | \r | |
2100 | // Move this into Observable?\r | |
2101 | if (me.plugins) {\r | |
2102 | for (i = 0, len = me.plugins.length; i < len; i++) {\r | |
2103 | me.plugins[i] = me.initPlugin(me.plugins[i]);\r | |
2104 | }\r | |
2105 | }\r | |
2106 | \r | |
2107 | me.loader = me.getLoader();\r | |
2108 | \r | |
2109 | if (me.disabled) {\r | |
2110 | me.disabled = false;\r | |
2111 | me.disable(true);\r | |
2112 | }\r | |
2113 | \r | |
2114 | if (me.renderTo) {\r | |
2115 | me.render(me.renderTo);\r | |
2116 | // EXTJSIV-1935 - should be a way to do afterShow or something, but that\r | |
2117 | // won't work. Likewise, rendering hidden and then showing (w/autoShow) has\r | |
2118 | // implications to afterRender so we cannot do that.\r | |
2119 | }\r | |
2120 | \r | |
2121 | // Auto show only works unilaterally on *uncontained* Components.\r | |
2122 | // If contained, then it is the Container's responsibility to do the showing at next layout time.\r | |
2123 | if (me.autoShow && !me.$initParent) {\r | |
2124 | me.show();\r | |
2125 | }\r | |
2126 | \r | |
2127 | //<debug>\r | |
2128 | if (Ext.isDefined(me.disabledClass)) {\r | |
2129 | if (Ext.isDefined(Ext.global.console)) {\r | |
2130 | Ext.global.console.warn('Ext.Component: disabledClass has been deprecated. Please use disabledCls.');\r | |
2131 | }\r | |
2132 | me.disabledCls = me.disabledClass;\r | |
2133 | delete me.disabledClass;\r | |
2134 | }\r | |
2135 | //</debug>\r | |
2136 | \r | |
2137 | // If we were configured from an instance of Ext.Action, (or configured with a baseAction option),\r | |
2138 | // register this Component as one of its items\r | |
2139 | if (me.baseAction){\r | |
2140 | me.baseAction.addComponent(me);\r | |
2141 | }\r | |
2142 | },\r | |
2143 | \r | |
2144 | beforeInitConfig: function() {\r | |
2145 | //<debug>\r | |
2146 | if (!this.$calledInitConfig) {\r | |
2147 | Ext.raise('initConfig should not be called by subclasses, it will be called by Ext.Component');\r | |
2148 | }\r | |
2149 | //</debug>\r | |
2150 | this.mixins.observable.constructor.call(this);\r | |
2151 | },\r | |
2152 | \r | |
2153 | // <editor-fold desc="Component Methods">\r | |
2154 | // ***********************************************************************************\r | |
2155 | // Begin Component Methods\r | |
2156 | // ***********************************************************************************\r | |
2157 | \r | |
2158 | /**\r | |
2159 | * Adds a CSS class to the top level element representing this component.\r | |
2160 | * @param {String/String[]} cls The CSS class name to add.\r | |
2161 | * @return {Ext.Component} Returns the Component to allow method chaining.\r | |
2162 | */\r | |
2163 | addCls: function(cls) {\r | |
2164 | var me = this,\r | |
2165 | el = me.rendered ? me.el : me.protoEl;\r | |
2166 | \r | |
2167 | el.addCls.apply(el, arguments);\r | |
2168 | return me;\r | |
2169 | },\r | |
2170 | \r | |
2171 | /**\r | |
2172 | * Adds a `cls` to the `uiCls` array, which will also call {@link #addUIClsToElement} and adds to all elements of this\r | |
2173 | * component.\r | |
2174 | * @param {String/String[]} classes A string or an array of strings to add to the `uiCls`.\r | |
2175 | * @param {Boolean} [skip] `true` to skip adding it to the class and do it later (via the return).\r | |
2176 | */\r | |
2177 | addClsWithUI: function(classes, skip) {\r | |
2178 | var me = this,\r | |
2179 | clsArray = [],\r | |
2180 | i = 0,\r | |
2181 | uiCls = me.uiCls = Ext.Array.clone(me.uiCls),\r | |
2182 | activeUI = me.activeUI,\r | |
2183 | length,\r | |
2184 | cls;\r | |
2185 | \r | |
2186 | if (typeof classes === "string") {\r | |
2187 | classes = (classes.indexOf(' ') < 0) ? [classes] : Ext.String.splitWords(classes);\r | |
2188 | }\r | |
2189 | \r | |
2190 | length = classes.length;\r | |
2191 | \r | |
2192 | for (; i < length; i++) {\r | |
2193 | cls = classes[i];\r | |
2194 | \r | |
2195 | if (cls && !me.hasUICls(cls)) {\r | |
2196 | uiCls.push(cls);\r | |
2197 | \r | |
2198 | // We can skip this bit if there isn't an activeUI because we'll be called again from setUI\r | |
2199 | if (activeUI) {\r | |
2200 | clsArray = clsArray.concat(me.addUIClsToElement(cls));\r | |
2201 | }\r | |
2202 | }\r | |
2203 | }\r | |
2204 | \r | |
2205 | if (skip !== true && activeUI) {\r | |
2206 | me.addCls(clsArray);\r | |
2207 | }\r | |
2208 | \r | |
2209 | return clsArray;\r | |
2210 | },\r | |
2211 | \r | |
2212 | /**\r | |
2213 | * Called by the layout system after the Component has been laid out.\r | |
2214 | *\r | |
2215 | * This method is not called on components that use {@link #liquidLayout}, such as\r | |
2216 | * {@link Ext.button.Button Buttons} and {@link Ext.form.field.Base Form Fields}.\r | |
2217 | *\r | |
2218 | * @param {Number} width The width that was set\r | |
2219 | * @param {Number} height The height that was set\r | |
2220 | * @param {Number/undefined} oldWidth The old width, or `undefined` if this was the initial layout.\r | |
2221 | * @param {Number/undefined} oldHeight The old height, or `undefined` if this was the initial layout.\r | |
2222 | *\r | |
2223 | * @template\r | |
2224 | * @protected\r | |
2225 | */\r | |
2226 | afterComponentLayout: function(width, height, oldWidth, oldHeight) {\r | |
2227 | var me = this,\r | |
2228 | scroller;\r | |
2229 | \r | |
2230 | if (++me.componentLayoutCounter === 1) {\r | |
2231 | \r | |
2232 | // Update the scroller very early in first layout so that it has the overflow element\r | |
2233 | // before any 'boxready', onResize, or 'resize' code gets to run.\r | |
2234 | scroller = me.scrollable; // initConfig has already run by now\r | |
2235 | if (scroller) {\r | |
2236 | if (me.touchScroll && scroller.isTouchScroller) {\r | |
2237 | scroller.setInnerElement(me.getScrollerEl());\r | |
2238 | }\r | |
2239 | \r | |
2240 | scroller.setElement(me.getOverflowEl());\r | |
2241 | \r | |
2242 | // IE browsers don't restore scroll position if the component was scrolled and\r | |
2243 | // then hidden and shown again, so we must do it manually.\r | |
2244 | // See EXTJS-16233.\r | |
2245 | if (Ext.isIE) {\r | |
2246 | Ext.on('show', me.onGlobalShow, me);\r | |
2247 | }\r | |
2248 | }\r | |
2249 | me.afterFirstLayout(width, height);\r | |
2250 | }\r | |
2251 | \r | |
2252 | if (width !== oldWidth || height !== oldHeight) {\r | |
2253 | me.onResize(width, height, oldWidth, oldHeight);\r | |
2254 | }\r | |
2255 | \r | |
2256 | if (me.floating) {\r | |
2257 | me.onAfterFloatLayout();\r | |
2258 | }\r | |
2259 | },\r | |
2260 | \r | |
2261 | /**\r | |
2262 | * @private\r | |
2263 | * Adds a plugin. May be called at any time in the component's life cycle.\r | |
2264 | */\r | |
2265 | addPlugin: function(plugin) {\r | |
2266 | var me = this;\r | |
2267 | \r | |
2268 | plugin = me.constructPlugin(plugin);\r | |
2269 | if (me.plugins) {\r | |
2270 | me.plugins.push(plugin);\r | |
2271 | } else {\r | |
2272 | me.plugins = [ plugin ];\r | |
2273 | }\r | |
2274 | if (me.pluginsInitialized) {\r | |
2275 | me.initPlugin(plugin);\r | |
2276 | }\r | |
2277 | return plugin;\r | |
2278 | },\r | |
2279 | \r | |
2280 | /**\r | |
2281 | * Save a property to the given state object if it is not its default or configured\r | |
2282 | * value.\r | |
2283 | *\r | |
2284 | * @param {Object} state The state object.\r | |
2285 | * @param {String} propName The name of the property on this object to save.\r | |
2286 | * @param {String} [value] The value of the state property (defaults to `this[propName]`).\r | |
2287 | * @return {Object} The state object or a new object if state was `null` and the property\r | |
2288 | * was saved.\r | |
2289 | * @protected\r | |
2290 | */\r | |
2291 | addPropertyToState: function (state, propName, value) {\r | |
2292 | var me = this,\r | |
2293 | len = arguments.length;\r | |
2294 | \r | |
2295 | // If the property is inherited, it is a default and we don't want to save it to\r | |
2296 | // the state, however if we explicitly specify a value, always save it\r | |
2297 | if (len === 3 || me.hasOwnProperty(propName)) {\r | |
2298 | if (len < 3) {\r | |
2299 | value = me[propName];\r | |
2300 | }\r | |
2301 | \r | |
2302 | // If the property has the same value as was initially configured, again, we\r | |
2303 | // don't want to save it.\r | |
2304 | if (value !== me.initialConfig[propName]) {\r | |
2305 | (state || (state = {}))[propName] = value;\r | |
2306 | }\r | |
2307 | }\r | |
2308 | \r | |
2309 | return state;\r | |
2310 | },\r | |
2311 | \r | |
2312 | /**\r | |
2313 | * Method which adds a specified UI + `uiCls` to the components element. Can be overridden\r | |
2314 | * to add the UI to more than just the component's element.\r | |
2315 | * @param {String} uiCls The UI class to add to the element.\r | |
2316 | * @protected\r | |
2317 | */\r | |
2318 | addUIClsToElement: function (uiCls) {\r | |
2319 | var me = this,\r | |
2320 | baseClsUI = me.baseCls + '-' + me.ui + '-' + uiCls,\r | |
2321 | result = [ Ext.baseCSSPrefix + uiCls, me.baseCls + '-' + uiCls, baseClsUI ],\r | |
2322 | childEls, childElName, el, suffix;\r | |
2323 | \r | |
2324 | if (me.rendered && me.frame && !Ext.supports.CSS3BorderRadius) {\r | |
2325 | // Loop through each frame element, and if they are defined add the ui:\r | |
2326 | baseClsUI += '-';\r | |
2327 | childEls = me.getChildEls();\r | |
2328 | \r | |
2329 | for (childElName in childEls) {\r | |
2330 | suffix = childEls[childElName].frame;\r | |
2331 | if (suffix && suffix !== true) {\r | |
2332 | el = me[childElName];\r | |
2333 | if (el) {\r | |
2334 | el.addCls(baseClsUI + suffix);\r | |
2335 | }\r | |
2336 | }\r | |
2337 | }\r | |
2338 | }\r | |
2339 | \r | |
2340 | return result;\r | |
2341 | },\r | |
2342 | \r | |
2343 | /**\r | |
2344 | * Method which removes a specified UI + `uiCls` from the components element. The `cls`\r | |
2345 | * which is added to the element will be: `this.baseCls + '-' + ui + uiCls`.\r | |
2346 | * @param {String} uiCls The UI class to remove from the element.\r | |
2347 | * @protected\r | |
2348 | */\r | |
2349 | removeUIClsFromElement: function(uiCls) {\r | |
2350 | var me = this,\r | |
2351 | baseClsUI = me.baseCls + '-' + me.ui + '-' + uiCls,\r | |
2352 | result = [ Ext.baseCSSPrefix + uiCls, me.baseCls + '-' + uiCls, baseClsUI ],\r | |
2353 | childEls, childElName, el, suffix;\r | |
2354 | \r | |
2355 | if (me.rendered && me.frame && !Ext.supports.CSS3BorderRadius) {\r | |
2356 | // Loop through each frame element, and if they are defined remove the ui:\r | |
2357 | baseClsUI += '-';\r | |
2358 | childEls = me.getChildEls();\r | |
2359 | \r | |
2360 | for (childElName in childEls) {\r | |
2361 | suffix = childEls[childElName].frame;\r | |
2362 | if (suffix && suffix !== true) {\r | |
2363 | el = me[childElName];\r | |
2364 | if (el) {\r | |
2365 | el.removeCls(baseClsUI + suffix);\r | |
2366 | }\r | |
2367 | }\r | |
2368 | }\r | |
2369 | }\r | |
2370 | \r | |
2371 | return result;\r | |
2372 | },\r | |
2373 | \r | |
2374 | /**\r | |
2375 | * @private\r | |
2376 | */\r | |
2377 | adjustPosition: function(x, y) {\r | |
2378 | var me = this,\r | |
2379 | floatParentBox;\r | |
2380 | \r | |
2381 | // Floating Components being positioned in their ownerCt have to be made absolute.\r | |
2382 | if (me.isContainedFloater()) {\r | |
2383 | floatParentBox = me.floatParent.getTargetEl().getViewRegion();\r | |
2384 | x += floatParentBox.left;\r | |
2385 | y += floatParentBox.top;\r | |
2386 | }\r | |
2387 | \r | |
2388 | return {\r | |
2389 | x: x,\r | |
2390 | y: y\r | |
2391 | };\r | |
2392 | },\r | |
2393 | \r | |
2394 | /**\r | |
2395 | * Invoked after the Component has been hidden.\r | |
2396 | *\r | |
2397 | * Gets passed the same `callback` and `scope` parameters that #onHide received.\r | |
2398 | *\r | |
2399 | * @param {Function} [callback]\r | |
2400 | * @param {Object} [scope]\r | |
2401 | *\r | |
2402 | * @template\r | |
2403 | * @protected\r | |
2404 | */\r | |
2405 | afterHide: function(cb, scope) {\r | |
2406 | var me = this,\r | |
2407 | container = me.focusableContainer;\r | |
2408 | \r | |
2409 | me.hiddenByLayout = null;\r | |
2410 | \r | |
2411 | // Only lay out if there is an owning layout which might be affected by the hide\r | |
2412 | if (this.ownerLayout) {\r | |
2413 | this.updateLayout({ isRoot: false });\r | |
2414 | }\r | |
2415 | \r | |
2416 | Ext.callback(cb, scope || me);\r | |
2417 | \r | |
2418 | me.fireHierarchyEvent('hide');\r | |
2419 | me.fireEvent('hide', me);\r | |
2420 | \r | |
2421 | if (container) {\r | |
2422 | container.onFocusableChildHide(me);\r | |
2423 | }\r | |
2424 | },\r | |
2425 | \r | |
2426 | /**\r | |
2427 | * Template method called after a Component has been positioned.\r | |
2428 | *\r | |
2429 | * @param {Number} x\r | |
2430 | * @param {Number} y\r | |
2431 | *\r | |
2432 | * @template\r | |
2433 | * @protected\r | |
2434 | */\r | |
2435 | afterSetPosition: function(x, y) {\r | |
2436 | var me = this;\r | |
2437 | me.onPosition(x, y);\r | |
2438 | if (me.hasListeners.move) {\r | |
2439 | me.fireEvent('move', me, x, y);\r | |
2440 | }\r | |
2441 | },\r | |
2442 | \r | |
2443 | /**\r | |
2444 | * Invoked after the Component is shown (after #onShow is called).\r | |
2445 | *\r | |
2446 | * Gets passed the same parameters as #show.\r | |
2447 | *\r | |
2448 | * @param {String/Ext.dom.Element} [animateTarget]\r | |
2449 | * @param {Function} [callback]\r | |
2450 | * @param {Object} [scope]\r | |
2451 | *\r | |
2452 | * @template\r | |
2453 | * @protected\r | |
2454 | */\r | |
2455 | afterShow: function(animateTarget, cb, scope) {\r | |
2456 | var me = this,\r | |
2457 | myEl = me.el,\r | |
2458 | fromBox,\r | |
2459 | toBox,\r | |
2460 | ghostPanel;\r | |
2461 | \r | |
2462 | // Default to configured animate target if none passed\r | |
2463 | animateTarget = me.getAnimateTarget(animateTarget);\r | |
2464 | \r | |
2465 | // Need to be able to ghost the Component\r | |
2466 | if (!me.ghost) {\r | |
2467 | animateTarget = null;\r | |
2468 | }\r | |
2469 | // If we're animating, kick of an animation of the ghost from the target to the *Element* current box\r | |
2470 | if (animateTarget) {\r | |
2471 | toBox = {\r | |
2472 | x: myEl.getX(),\r | |
2473 | y: myEl.getY(),\r | |
2474 | width: myEl.dom.offsetWidth,\r | |
2475 | height: myEl.dom.offsetHeight\r | |
2476 | };\r | |
2477 | fromBox = {\r | |
2478 | x: animateTarget.getX(),\r | |
2479 | y: animateTarget.getY(),\r | |
2480 | width: animateTarget.dom.offsetWidth,\r | |
2481 | height: animateTarget.dom.offsetHeight\r | |
2482 | };\r | |
2483 | myEl.addCls(me.offsetsCls);\r | |
2484 | ghostPanel = me.ghost();\r | |
2485 | ghostPanel.el.stopAnimation();\r | |
2486 | \r | |
2487 | // Shunting it offscreen immediately, *before* the Animation class grabs it ensure no flicker.\r | |
2488 | ghostPanel.setX(-10000);\r | |
2489 | \r | |
2490 | me.ghostBox = toBox;\r | |
2491 | ghostPanel.el.animate({\r | |
2492 | from: fromBox,\r | |
2493 | to: toBox,\r | |
2494 | listeners: {\r | |
2495 | afteranimate: function() {\r | |
2496 | delete ghostPanel.componentLayout.lastComponentSize;\r | |
2497 | me.unghost();\r | |
2498 | delete me.ghostBox;\r | |
2499 | myEl.removeCls(me.offsetsCls);\r | |
2500 | me.onShowComplete(cb, scope);\r | |
2501 | }\r | |
2502 | }\r | |
2503 | });\r | |
2504 | }\r | |
2505 | else {\r | |
2506 | me.onShowComplete(cb, scope);\r | |
2507 | }\r | |
2508 | me.fireHierarchyEvent('show');\r | |
2509 | },\r | |
2510 | \r | |
2511 | animate: function(animObj) {\r | |
2512 | var me = this,\r | |
2513 | hasToWidth,\r | |
2514 | hasToHeight,\r | |
2515 | toHeight,\r | |
2516 | toWidth,\r | |
2517 | to,\r | |
2518 | clearWidth,\r | |
2519 | clearHeight,\r | |
2520 | curWidth, w, curHeight, h, isExpanding,\r | |
2521 | wasConstrained,\r | |
2522 | wasConstrainedHeader,\r | |
2523 | passedCallback,\r | |
2524 | oldOverflow;\r | |
2525 | \r | |
2526 | animObj = animObj || {};\r | |
2527 | to = animObj.to || {};\r | |
2528 | \r | |
2529 | if (Ext.fx.Manager.hasFxBlock(me.id)) {\r | |
2530 | return me;\r | |
2531 | }\r | |
2532 | \r | |
2533 | hasToWidth = Ext.isDefined(to.width);\r | |
2534 | if (hasToWidth) {\r | |
2535 | toWidth = Ext.Number.constrain(to.width, me.minWidth, me.maxWidth);\r | |
2536 | }\r | |
2537 | \r | |
2538 | hasToHeight = Ext.isDefined(to.height);\r | |
2539 | if (hasToHeight) {\r | |
2540 | toHeight = Ext.Number.constrain(to.height, me.minHeight, me.maxHeight);\r | |
2541 | }\r | |
2542 | \r | |
2543 | // Special processing for animating Component dimensions.\r | |
2544 | if (!animObj.dynamic && (hasToWidth || hasToHeight)) {\r | |
2545 | curWidth = (animObj.from ? animObj.from.width : undefined) || me.getWidth();\r | |
2546 | w = curWidth;\r | |
2547 | curHeight = (animObj.from ? animObj.from.height : undefined) || me.getHeight();\r | |
2548 | h = curHeight;\r | |
2549 | isExpanding = false;\r | |
2550 | \r | |
2551 | if (hasToHeight && toHeight > curHeight) {\r | |
2552 | h = toHeight;\r | |
2553 | isExpanding = true;\r | |
2554 | }\r | |
2555 | if (hasToWidth && toWidth > curWidth) {\r | |
2556 | w = toWidth;\r | |
2557 | isExpanding = true;\r | |
2558 | }\r | |
2559 | \r | |
2560 | // During animated sizing, overflow has to be hidden to clip expanded content\r | |
2561 | if (hasToHeight || hasToWidth) {\r | |
2562 | oldOverflow = me.el.getStyle('overflow');\r | |
2563 | if (oldOverflow !== 'hidden') {\r | |
2564 | me.el.setStyle('overflow', 'hidden');\r | |
2565 | }\r | |
2566 | }\r | |
2567 | \r | |
2568 | // If any dimensions are being increased, we must resize the internal structure\r | |
2569 | // of the Component, but then clip it by sizing its encapsulating element back to original dimensions.\r | |
2570 | // The animation will then progressively reveal the larger content.\r | |
2571 | if (isExpanding) {\r | |
2572 | clearWidth = !Ext.isNumber(me.width);\r | |
2573 | clearHeight = !Ext.isNumber(me.height);\r | |
2574 | \r | |
2575 | // Lay out this component at the new, larger size to get the internals correctly laid out.\r | |
2576 | // Then size the encapsulating **Element** back down to size.\r | |
2577 | // We will then just animate the element to reveal the correctly laid out content.\r | |
2578 | me.setSize(w, h);\r | |
2579 | me.el.setSize(curWidth, curHeight);\r | |
2580 | \r | |
2581 | if (clearWidth) {\r | |
2582 | delete me.width;\r | |
2583 | }\r | |
2584 | if (clearHeight) {\r | |
2585 | delete me.height;\r | |
2586 | }\r | |
2587 | }\r | |
2588 | if (hasToWidth) {\r | |
2589 | to.width = toWidth;\r | |
2590 | }\r | |
2591 | \r | |
2592 | if (hasToHeight) {\r | |
2593 | to.height = toHeight;\r | |
2594 | }\r | |
2595 | }\r | |
2596 | \r | |
2597 | // No constraining during the animate - the "to" size has already been calculated with respect to all settings.\r | |
2598 | // Arrange to reinstate any constraining after the animation has completed\r | |
2599 | wasConstrained = me.constrain;\r | |
2600 | wasConstrainedHeader = me.constrainHeader;\r | |
2601 | if (wasConstrained || wasConstrainedHeader) {\r | |
2602 | me.constrain = me.constrainHeader = false;\r | |
2603 | passedCallback = animObj.callback;\r | |
2604 | animObj.callback = function() {\r | |
2605 | me.constrain = wasConstrained;\r | |
2606 | me.constrainHeader = wasConstrainedHeader;\r | |
2607 | // Call the original callback if any\r | |
2608 | if (passedCallback) {\r | |
2609 | passedCallback.call(animObj.scope||me, arguments);\r | |
2610 | }\r | |
2611 | if (oldOverflow !== 'hidden') {\r | |
2612 | me.el.setStyle('overflow', oldOverflow);\r | |
2613 | }\r | |
2614 | };\r | |
2615 | }\r | |
2616 | return me.mixins.animate.animate.apply(me, arguments);\r | |
2617 | },\r | |
2618 | \r | |
2619 | applyScrollable: function(scrollable, oldScrollable) {\r | |
2620 | var me = this,\r | |
2621 | rendered = me.rendered,\r | |
2622 | scrollableCfg,\r | |
2623 | innerEl;\r | |
2624 | \r | |
2625 | if (scrollable) {\r | |
2626 | if (scrollable === true || typeof scrollable === 'string') {\r | |
2627 | scrollableCfg = me._scrollableCfg[scrollable];\r | |
2628 | \r | |
2629 | //<debug>\r | |
2630 | if (!scrollableCfg) {\r | |
2631 | Ext.raise("'" + scrollable + "' is not a valid value for 'scrollable'");\r | |
2632 | }\r | |
2633 | //</debug>\r | |
2634 | \r | |
2635 | scrollable = scrollableCfg;\r | |
2636 | }\r | |
2637 | \r | |
2638 | if (oldScrollable) {\r | |
2639 | oldScrollable.setConfig(scrollable);\r | |
2640 | scrollable = oldScrollable;\r | |
2641 | } else {\r | |
2642 | scrollable = Ext.Object.chain(scrollable); // don't mutate the user's config\r | |
2643 | \r | |
2644 | if (rendered) {\r | |
2645 | // we create the scroller without an element by default (because the\r | |
2646 | // element is not available at configuration time) and then assign\r | |
2647 | // the element in onBoxReady. If we got here it means the scroller\r | |
2648 | // is being configured after render, so we need to make sure the\r | |
2649 | // element is in its config object\r | |
2650 | scrollable.element = me.getOverflowEl();\r | |
2651 | innerEl = me.getScrollerEl();\r | |
2652 | if (innerEl) {\r | |
2653 | scrollable.innerElement = innerEl;\r | |
2654 | }\r | |
2655 | }\r | |
2656 | \r | |
2657 | // scroller gets refreshed by Component#onResize,\r | |
2658 | // so there is no need to initialize a SizeMonitor\r | |
2659 | scrollable.autoRefresh = false;\r | |
2660 | \r | |
2661 | if (Ext.supports.touchScroll === 1) {\r | |
2662 | // running in a browser that uses the touch scroller to control naturally\r | |
2663 | // overflowing elements.\r | |
2664 | scrollable.translatable = {\r | |
2665 | translationMethod: 'scrollparent'\r | |
2666 | };\r | |
2667 | // We'll have native scrollbars, so no indicators are needed\r | |
2668 | scrollable.indicators = false;\r | |
2669 | }\r | |
2670 | scrollable = Ext.scroll.Scroller.create(scrollable);\r | |
2671 | scrollable.component = me;\r | |
2672 | }\r | |
2673 | } else if (oldScrollable) {\r | |
2674 | oldScrollable.setConfig({\r | |
2675 | x: false,\r | |
2676 | y: false\r | |
2677 | });\r | |
2678 | oldScrollable.destroy();\r | |
2679 | scrollable = null;\r | |
2680 | }\r | |
2681 | \r | |
2682 | if (me.rendered && !me.destroying && !me.destroyed) {\r | |
2683 | if (scrollable) {\r | |
2684 | me.getOverflowStyle(); // refresh the scrollFlags\r | |
2685 | } else {\r | |
2686 | me.scrollFlags = me._scrollFlags.none;\r | |
2687 | }\r | |
2688 | me.updateLayout();\r | |
2689 | }\r | |
2690 | \r | |
2691 | return scrollable;\r | |
2692 | },\r | |
2693 | \r | |
2694 | /**\r | |
2695 | * Occurs before `componentLayout` is run. Returning `false` from this method will prevent the `componentLayout` from\r | |
2696 | * being executed.\r | |
2697 | *\r | |
2698 | * @param {Number} adjWidth The box-adjusted width that was set.\r | |
2699 | * @param {Number} adjHeight The box-adjusted height that was set.\r | |
2700 | *\r | |
2701 | * @template\r | |
2702 | * @protected\r | |
2703 | */\r | |
2704 | beforeComponentLayout: function() {\r | |
2705 | return true;\r | |
2706 | },\r | |
2707 | \r | |
2708 | /**\r | |
2709 | * Invoked before the Component is destroyed.\r | |
2710 | *\r | |
2711 | * @method\r | |
2712 | * @template\r | |
2713 | * @protected\r | |
2714 | */\r | |
2715 | beforeDestroy : Ext.emptyFn,\r | |
2716 | \r | |
2717 | /**\r | |
2718 | * Occurs before componentLayout is run. In previous releases, this method could\r | |
2719 | * return `false` to prevent its layout but that is not supported in Ext JS 4.1 or\r | |
2720 | * higher. This method is simply a notification of the impending layout to give the\r | |
2721 | * component a chance to adjust the DOM. Ideally, DOM reads should be avoided at this\r | |
2722 | * time to reduce expensive document reflows.\r | |
2723 | *\r | |
2724 | * @template\r | |
2725 | * @protected\r | |
2726 | */\r | |
2727 | beforeLayout: function(){\r | |
2728 | if (this.floating) {\r | |
2729 | this.onBeforeFloatLayout();\r | |
2730 | }\r | |
2731 | },\r | |
2732 | \r | |
2733 | /**\r | |
2734 | * @private\r | |
2735 | * Template method called before a Component is positioned.\r | |
2736 | *\r | |
2737 | * Ensures that the position is adjusted so that the Component is constrained if so configured.\r | |
2738 | */\r | |
2739 | beforeSetPosition: function (x, y, animate) {\r | |
2740 | var me = this,\r | |
2741 | pos = null,\r | |
2742 | x0, hasX, hasY, adj;\r | |
2743 | \r | |
2744 | // Decode members of x if x is an array or an object.\r | |
2745 | // If it is numeric (including zero), we need do nothing.\r | |
2746 | if (x) {\r | |
2747 | // Position in first argument as an array of [x, y]\r | |
2748 | if (Ext.isNumber(x0 = x[0])) {\r | |
2749 | animate = y;\r | |
2750 | y = x[1];\r | |
2751 | x = x0;\r | |
2752 | }\r | |
2753 | // Position in first argument as object w/ x & y properties\r | |
2754 | else if ((x0 = x.x) !== undefined) {\r | |
2755 | animate = y;\r | |
2756 | y = x.y;\r | |
2757 | x = x0;\r | |
2758 | }\r | |
2759 | }\r | |
2760 | \r | |
2761 | if (me.constrain || me.constrainHeader) {\r | |
2762 | pos = me.calculateConstrainedPosition(null, [x, y], true);\r | |
2763 | if (pos) {\r | |
2764 | x = pos[0];\r | |
2765 | y = pos[1];\r | |
2766 | }\r | |
2767 | }\r | |
2768 | \r | |
2769 | hasX = (x !== undefined);\r | |
2770 | hasY = (y !== undefined);\r | |
2771 | \r | |
2772 | if (hasX || hasY) {\r | |
2773 | // The component's position is the position it was told to be at.\r | |
2774 | // If it is contained, adjustPosition will add the floatParent's offsets.\r | |
2775 | me.x = x;\r | |
2776 | me.y = y;\r | |
2777 | \r | |
2778 | adj = me.adjustPosition(x, y);\r | |
2779 | // Set up the return info and store the position in this object\r | |
2780 | pos = {\r | |
2781 | x : adj.x,\r | |
2782 | y : adj.y,\r | |
2783 | anim: animate,\r | |
2784 | hasX: hasX,\r | |
2785 | hasY: hasY\r | |
2786 | };\r | |
2787 | }\r | |
2788 | \r | |
2789 | return pos;\r | |
2790 | },\r | |
2791 | \r | |
2792 | /**\r | |
2793 | * Invoked before the Component is shown.\r | |
2794 | *\r | |
2795 | * @method\r | |
2796 | * @template\r | |
2797 | * @protected\r | |
2798 | */\r | |
2799 | beforeShow: Ext.emptyFn,\r | |
2800 | \r | |
2801 | /**\r | |
2802 | * Bubbles up the component/container hierarchy, calling the specified function with each component. The scope\r | |
2803 | * (*this*) of function call will be the scope provided or the current component. The arguments to the function will\r | |
2804 | * be the args provided or the current component. If the function returns false at any point, the bubble is stopped.\r | |
2805 | *\r | |
2806 | * @param {Function} fn The function to call\r | |
2807 | * @param {Object} [scope] The scope of the function. Defaults to current node.\r | |
2808 | * @param {Array} [args] The args to call the function with. Defaults to passing the current component.\r | |
2809 | * @return {Ext.Component} this\r | |
2810 | */\r | |
2811 | bubble: function(fn, scope, args) {\r | |
2812 | var p = this;\r | |
2813 | while (p) {\r | |
2814 | if (fn.apply(scope || p, args || [p]) === false) {\r | |
2815 | break;\r | |
2816 | }\r | |
2817 | p = p.getBubbleTarget();\r | |
2818 | }\r | |
2819 | return this;\r | |
2820 | },\r | |
2821 | \r | |
2822 | clearListeners: function() {\r | |
2823 | var me = this;\r | |
2824 | me.mixins.observable.clearListeners.call(me);\r | |
2825 | me.mixins.componentDelegation.clearDelegatedListeners.call(me);\r | |
2826 | },\r | |
2827 | \r | |
2828 | /**\r | |
2829 | * Clone the current component using the original config values passed into this instance by default.\r | |
2830 | * @param {Object} overrides A new config containing any properties to override in the cloned version.\r | |
2831 | * An id property can be passed on this object, otherwise one will be generated to avoid duplicates.\r | |
2832 | * @return {Ext.Component} clone The cloned copy of this component\r | |
2833 | */\r | |
2834 | cloneConfig: function(overrides) {\r | |
2835 | overrides = overrides || {};\r | |
2836 | var id = overrides.id || Ext.id(),\r | |
2837 | cfg = Ext.applyIf(overrides, this.initialConfig),\r | |
2838 | self;\r | |
2839 | \r | |
2840 | cfg.id = id;\r | |
2841 | \r | |
2842 | self = Ext.getClass(this);\r | |
2843 | \r | |
2844 | // prevent dup id\r | |
2845 | return new self(cfg);\r | |
2846 | },\r | |
2847 | \r | |
2848 | /**\r | |
2849 | * Destroys the Component. This method must not be overridden.\r | |
2850 | * To add extra functionality to destruction time in a subclass, implement the\r | |
2851 | * template method {@link #beforeDestroy} or {@link #onDestroy}. And do not forget to\r | |
2852 | * `callParent()` in your implementation.\r | |
2853 | * @since 1.1.0\r | |
2854 | */\r | |
2855 | destroy: function() {\r | |
2856 | var me = this,\r | |
2857 | selectors = me.renderSelectors,\r | |
2858 | viewModel = me.getConfig('viewModel', true),\r | |
2859 | session = me.getConfig('session', true),\r | |
2860 | selector, ownerCt, el;\r | |
2861 | \r | |
2862 | if (!me.hasListeners.beforedestroy || me.fireEvent('beforedestroy', me) !== false) {\r | |
2863 | // isDestroying added for compat reasons\r | |
2864 | me.isDestroying = me.destroying = true;\r | |
2865 | \r | |
2866 | ownerCt = me.floatParent || me.ownerCt;\r | |
2867 | if (me.floating) {\r | |
2868 | delete me.floatParent;\r | |
2869 | // A zIndexManager is stamped into a *floating* Component when it is added to a Container.\r | |
2870 | // If it has no zIndexManager at render time, it is assigned to the global Ext.WindowManager instance.\r | |
2871 | if (me.zIndexManager) {\r | |
2872 | me.zIndexManager.unregister(me);\r | |
2873 | me.zIndexManager = null;\r | |
2874 | }\r | |
2875 | }\r | |
2876 | \r | |
2877 | me.removeBindings();\r | |
2878 | \r | |
2879 | // beforeDestroy destroys children, ensure they go before the viewModel/session/controller\r | |
2880 | me.beforeDestroy();\r | |
2881 | \r | |
2882 | me.destroyBindable();\r | |
2883 | \r | |
2884 | if (ownerCt && ownerCt.remove) {\r | |
2885 | ownerCt.remove(me, false);\r | |
2886 | }\r | |
2887 | \r | |
2888 | me.stopAnimation();\r | |
2889 | me.onDestroy();\r | |
2890 | \r | |
2891 | // Attempt to destroy all plugins\r | |
2892 | Ext.destroy(me.plugins);\r | |
2893 | \r | |
2894 | if (me.rendered) {\r | |
2895 | Ext.Component.cancelLayout(me, true);\r | |
2896 | }\r | |
2897 | \r | |
2898 | me.componentLayout = null;\r | |
2899 | if (me.hasListeners.destroy) {\r | |
2900 | me.fireEvent('destroy', me);\r | |
2901 | }\r | |
2902 | if (!me.preventRegister) {\r | |
2903 | Ext.ComponentManager.unregister(me);\r | |
2904 | }\r | |
2905 | \r | |
2906 | me.mixins.state.destroy.call(me);\r | |
2907 | \r | |
2908 | if (me.floating) {\r | |
2909 | me.onFloatDestroy();\r | |
2910 | }\r | |
2911 | \r | |
2912 | me.clearListeners();\r | |
2913 | \r | |
2914 | // make sure we clean up the element references after removing all events\r | |
2915 | if (me.rendered) {\r | |
2916 | if (!me.preserveElOnDestroy) {\r | |
2917 | me.el.destroy();\r | |
2918 | }\r | |
2919 | me.el.component = null;\r | |
2920 | me.mixins.elementCt.destroy.call(me); // removes childEls\r | |
2921 | if (selectors) {\r | |
2922 | for (selector in selectors) {\r | |
2923 | if (selectors.hasOwnProperty(selector)) {\r | |
2924 | el = me[selector];\r | |
2925 | if (el) { // in case any other code may have already removed it\r | |
2926 | delete me[selector];\r | |
2927 | el.destroy();\r | |
2928 | }\r | |
2929 | }\r | |
2930 | }\r | |
2931 | }\r | |
2932 | \r | |
2933 | me.data = me.el = me.frameBody = me.rendered = me.afterRenderEvents = null;\r | |
2934 | me.tpl = me.renderTpl = me.renderData = null;\r | |
2935 | me.focusableContainer = me.container = me.scrollable = null;\r | |
2936 | }\r | |
2937 | \r | |
2938 | // isDestroying added for compat reasons\r | |
2939 | me.isDestroying = me.destroying = false;\r | |
2940 | me.callParent();\r | |
2941 | }\r | |
2942 | },\r | |
2943 | \r | |
2944 | /**\r | |
2945 | * Disable the component.\r | |
2946 | * @param {Boolean} [silent=false] Passing `true` will suppress the `disable` event from being fired.\r | |
2947 | * @since 1.1.0\r | |
2948 | */\r | |
2949 | disable: function(silent, /* private */fromParent) {\r | |
2950 | var me = this,\r | |
2951 | container = me.focusableContainer,\r | |
2952 | inherited = me.getInherited();\r | |
2953 | \r | |
2954 | if (!fromParent) {\r | |
2955 | inherited.disabled = true;\r | |
2956 | me.savedDisabled = true;\r | |
2957 | }\r | |
2958 | \r | |
2959 | if (me.maskOnDisable) {\r | |
2960 | inherited.disableMask = true;\r | |
2961 | }\r | |
2962 | \r | |
2963 | if (!me.disabled) {\r | |
2964 | if (container) {\r | |
2965 | container.beforeFocusableChildDisable(me);\r | |
2966 | }\r | |
2967 | \r | |
2968 | me.addCls(me.disabledCls);\r | |
2969 | \r | |
2970 | if (me.rendered) {\r | |
2971 | me.onDisable();\r | |
2972 | }\r | |
2973 | else {\r | |
2974 | me.disableOnRender = true;\r | |
2975 | }\r | |
2976 | \r | |
2977 | me.disabled = true;\r | |
2978 | \r | |
2979 | if (silent !== true) {\r | |
2980 | me.fireEvent('disable', me);\r | |
2981 | }\r | |
2982 | \r | |
2983 | if (container) {\r | |
2984 | container.onFocusableChildDisable(me);\r | |
2985 | }\r | |
2986 | }\r | |
2987 | \r | |
2988 | return me;\r | |
2989 | },\r | |
2990 | \r | |
2991 | doFireEvent: function(eventName, args, bubbles) {\r | |
2992 | var me = this,\r | |
2993 | ret = me.mixins.observable.doFireEvent.call(me, eventName, args, bubbles);\r | |
2994 | \r | |
2995 | if (ret !== false) {\r | |
2996 | ret = me.mixins.componentDelegation.doFireDelegatedEvent.call(me, eventName, args);\r | |
2997 | }\r | |
2998 | \r | |
2999 | return ret;\r | |
3000 | },\r | |
3001 | \r | |
3002 | /**\r | |
3003 | * Enable the component\r | |
3004 | * @param {Boolean} [silent=false] Passing `true` will suppress the `enable` event from being fired.\r | |
3005 | * @since 1.1.0\r | |
3006 | */\r | |
3007 | enable: function(silent, /* private */fromParent) {\r | |
3008 | var me = this,\r | |
3009 | container = me.focusableContainer,\r | |
3010 | inherited = me.getInherited();\r | |
3011 | \r | |
3012 | if (!fromParent) {\r | |
3013 | delete me.getInherited().disabled;\r | |
3014 | me.savedDisabled = false;\r | |
3015 | }\r | |
3016 | \r | |
3017 | if (me.maskOnDisable) {\r | |
3018 | delete inherited.disableMask;\r | |
3019 | }\r | |
3020 | \r | |
3021 | if (me.disabled) {\r | |
3022 | // A parent is asking us to enable, but if we were disabled directly, keep\r | |
3023 | // our current state\r | |
3024 | if (!(fromParent && inherited.hasOwnProperty('disabled'))) {\r | |
3025 | if (container) {\r | |
3026 | container.beforeFocusableChildEnable(me);\r | |
3027 | }\r | |
3028 | \r | |
3029 | me.disableOnRender = false;\r | |
3030 | me.removeCls(me.disabledCls);\r | |
3031 | \r | |
3032 | if (me.rendered) {\r | |
3033 | me.onEnable();\r | |
3034 | }\r | |
3035 | \r | |
3036 | me.disabled = false;\r | |
3037 | \r | |
3038 | if (silent !== true) {\r | |
3039 | me.fireEvent('enable', me);\r | |
3040 | }\r | |
3041 | \r | |
3042 | if (container) {\r | |
3043 | container.onFocusableChildEnable(me);\r | |
3044 | }\r | |
3045 | }\r | |
3046 | }\r | |
3047 | \r | |
3048 | return me;\r | |
3049 | },\r | |
3050 | \r | |
3051 | /**\r | |
3052 | * Find a container above this component at any level by a custom function. If the passed function returns true, the\r | |
3053 | * container will be returned.\r | |
3054 | *\r | |
3055 | * See also the {@link Ext.Component#up up} method.\r | |
3056 | *\r | |
3057 | * @param {Function} fn The custom function to call with the arguments (container, this component).\r | |
3058 | * @return {Ext.container.Container} The first Container for which the custom function returns true\r | |
3059 | */\r | |
3060 | findParentBy: function(fn) {\r | |
3061 | var p;\r | |
3062 | \r | |
3063 | // Iterate up the owner chain until we don't have one, or we find an ancestor which matches using the selector function.\r | |
3064 | for (p = this.getRefOwner(); p && !fn(p, this); p = p.getRefOwner()) {\r | |
3065 | // do nothing\r | |
3066 | }\r | |
3067 | return p || null;\r | |
3068 | },\r | |
3069 | \r | |
3070 | /**\r | |
3071 | * Find a container above this component at any level by xtype or class\r | |
3072 | *\r | |
3073 | * See also the {@link Ext.Component#up up} method.\r | |
3074 | *\r | |
3075 | * @param {String/Ext.Class} xtype The xtype string for a component, or the class of the component directly\r | |
3076 | * @return {Ext.container.Container} The first Container which matches the given xtype or class\r | |
3077 | */\r | |
3078 | findParentByType: function(xtype) {\r | |
3079 | return Ext.isFunction(xtype) ?\r | |
3080 | this.findParentBy(function(p) {\r | |
3081 | return p.constructor === xtype;\r | |
3082 | })\r | |
3083 | :\r | |
3084 | this.up(xtype);\r | |
3085 | },\r | |
3086 | \r | |
3087 | /**\r | |
3088 | * Retrieves plugin from this component's collection by its `ptype`.\r | |
3089 | * \r | |
3090 | * var grid = Ext.create('Ext.grid.Panel', {\r | |
3091 | * store: {\r | |
3092 | * fields: ['name'],\r | |
3093 | * data: [{\r | |
3094 | * name: 'Scott Pilgrim'\r | |
3095 | * }]\r | |
3096 | * },\r | |
3097 | * columns: [{\r | |
3098 | * header: 'Name',\r | |
3099 | * dataIndex: 'name',\r | |
3100 | * editor: 'textfield',\r | |
3101 | * flex: 1\r | |
3102 | * }],\r | |
3103 | * selType: 'cellmodel',\r | |
3104 | * plugins: {\r | |
3105 | * ptype: 'cellediting',\r | |
3106 | * clicksToEdit: 1,\r | |
3107 | * pluginId: 'myplugin'\r | |
3108 | * },\r | |
3109 | * height: 200,\r | |
3110 | * width: 400,\r | |
3111 | * renderTo: Ext.getBody()\r | |
3112 | * });\r | |
3113 | * \r | |
3114 | * grid.findPlugin('cellediting'); // the cellediting plugin\r | |
3115 | * \r | |
3116 | * **Note:** See also {@link #getPlugin}\r | |
3117 | * \r | |
3118 | * @param {String} ptype The Plugin's `ptype` as specified by the class's \r | |
3119 | * {@link Ext.Class#cfg-alias alias} configuration.\r | |
3120 | * @return {Ext.plugin.Abstract} plugin instance or `undefined` if not found\r | |
3121 | */\r | |
3122 | findPlugin: function(ptype) {\r | |
3123 | var i,\r | |
3124 | plugins = this.plugins,\r | |
3125 | ln = plugins && plugins.length;\r | |
3126 | for (i = 0; i < ln; i++) {\r | |
3127 | if (plugins[i].ptype === ptype) {\r | |
3128 | return plugins[i];\r | |
3129 | }\r | |
3130 | }\r | |
3131 | },\r | |
3132 | \r | |
3133 | getAnimateTarget: function(target){\r | |
3134 | target = target || this.animateTarget;\r | |
3135 | if (target) {\r | |
3136 | target = target.isComponent ? target.getEl() : Ext.get(target);\r | |
3137 | }\r | |
3138 | return target || null;\r | |
3139 | },\r | |
3140 | \r | |
3141 | /**\r | |
3142 | * @protected\r | |
3143 | * Implements an upward event bubbling policy. By default a Component bubbles events up to its {@link #getRefOwner reference owner}.\r | |
3144 | *\r | |
3145 | * Component subclasses may implement a different bubbling strategy by overriding this method.\r | |
3146 | */\r | |
3147 | getBubbleTarget: function() {\r | |
3148 | return this.getRefOwner();\r | |
3149 | },\r | |
3150 | \r | |
3151 | getComponentLayout: function() {\r | |
3152 | var me = this;\r | |
3153 | \r | |
3154 | if (!me.componentLayout || !me.componentLayout.isLayout) {\r | |
3155 | me.setComponentLayout(Ext.layout.Layout.create(me.componentLayout, 'autocomponent'));\r | |
3156 | }\r | |
3157 | return me.componentLayout;\r | |
3158 | },\r | |
3159 | \r | |
3160 | /**\r | |
3161 | * Retrieves the top level element representing this component.\r | |
3162 | * @return {Ext.dom.Element}\r | |
3163 | * @since 1.1.0\r | |
3164 | */\r | |
3165 | getEl: function() {\r | |
3166 | return this.el;\r | |
3167 | },\r | |
3168 | \r | |
3169 | /**\r | |
3170 | * Gets the current height of the component's underlying element.\r | |
3171 | * @return {Number}\r | |
3172 | */\r | |
3173 | getHeight: function() {\r | |
3174 | return this.el.getHeight();\r | |
3175 | },\r | |
3176 | \r | |
3177 | /**\r | |
3178 | * Called by `getInherited` to initialize the inheritedState the first time it is\r | |
3179 | * requested.\r | |
3180 | * @protected\r | |
3181 | */\r | |
3182 | initInheritedState: function (inheritedState) {\r | |
3183 | var me = this,\r | |
3184 | layout = me.componentLayout;\r | |
3185 | \r | |
3186 | if (me.hidden) {\r | |
3187 | inheritedState.hidden = true;\r | |
3188 | }\r | |
3189 | if (me.collapseImmune) {\r | |
3190 | inheritedState.collapseImmune = true;\r | |
3191 | }\r | |
3192 | if (me.modelValidation !== undefined) {\r | |
3193 | inheritedState.modelValidation = me.modelValidation;\r | |
3194 | }\r | |
3195 | \r | |
3196 | if (me.savedDisabled) {\r | |
3197 | inheritedState.disabled = true;\r | |
3198 | }\r | |
3199 | \r | |
3200 | me.mixins.bindable.initInheritedState.call(me, inheritedState);\r | |
3201 | \r | |
3202 | if (layout && layout.initInheritedState) {\r | |
3203 | layout.initInheritedState(inheritedState);\r | |
3204 | }\r | |
3205 | },\r | |
3206 | \r | |
3207 | /**\r | |
3208 | * Retrieves the `id` of this component. Will auto-generate an `id` if one has not already been set.\r | |
3209 | * @return {String}\r | |
3210 | */\r | |
3211 | getId: function() {\r | |
3212 | var me = this,\r | |
3213 | xtype;\r | |
3214 | \r | |
3215 | // If we have no id, attempt to gather it from our configuration.\r | |
3216 | // Autogenerate it if none was configured.\r | |
3217 | if (!(me.id || (me.id = me.initialConfig.id))) {\r | |
3218 | xtype = me.getXType();\r | |
3219 | if (xtype) {\r | |
3220 | xtype = xtype.replace(Ext.Component.INVALID_ID_CHARS_Re, '-');\r | |
3221 | } else {\r | |
3222 | xtype = Ext.name.toLowerCase() + '-comp';\r | |
3223 | }\r | |
3224 | me.id = xtype + '-' + me.getAutoId();\r | |
3225 | }\r | |
3226 | return me.id;\r | |
3227 | },\r | |
3228 | \r | |
3229 | /**\r | |
3230 | * Returns the value of {@link #itemId} assigned to this component, or when that\r | |
3231 | * is not set, returns the value of {@link #id}.\r | |
3232 | * @return {String}\r | |
3233 | */\r | |
3234 | getItemId: function() {\r | |
3235 | return this.itemId || this.id;\r | |
3236 | },\r | |
3237 | \r | |
3238 | /**\r | |
3239 | * Gets the {@link Ext.ComponentLoader} for this Component.\r | |
3240 | * @return {Ext.ComponentLoader} The loader instance, null if it doesn't exist.\r | |
3241 | */\r | |
3242 | getLoader: function(){\r | |
3243 | var me = this,\r | |
3244 | loader = me.loader;\r | |
3245 | \r | |
3246 | if (loader) {\r | |
3247 | if (!loader.isLoader) {\r | |
3248 | me.loader = new Ext.ComponentLoader(Ext.apply({\r | |
3249 | target: me\r | |
3250 | }, loader));\r | |
3251 | } else {\r | |
3252 | loader.setTarget(me);\r | |
3253 | }\r | |
3254 | return me.loader;\r | |
3255 | \r | |
3256 | }\r | |
3257 | return null;\r | |
3258 | },\r | |
3259 | \r | |
3260 | /**\r | |
3261 | * @protected\r | |
3262 | * Returns the element which is masked by the {@link #mask} method, or into which the {@link #setLoading LoadMask} is rendered into.\r | |
3263 | *\r | |
3264 | * The default implementation uses the {@link #maskElement} configuration to access the Component's child element by name. By default, {@link #maskElement}\r | |
3265 | * is `null` which means that `null` is returned from this method indicating that the mask needs to be rendered into the document because\r | |
3266 | * component structure should not be contaminated by mask elements.\r | |
3267 | *\r | |
3268 | * Some subclasses may override this method if they have knowledge about external structures where a mask could usefully be rendered.\r | |
3269 | *\r | |
3270 | * For example a {@link Ext.view.Table GridView} will request that its owning {@link Ext.panel.Table GridPanel} be masked. The\r | |
3271 | * GridPanel will have its own implementation of `getMaskTarget` which will return the element dictated by its own {@link #maskElement}\r | |
3272 | * Panels use `"el"` as their {@link #maskElement} by default, but that could be overridden to be `"body"` to leave toolbars and the header\r | |
3273 | * mouse-accessible.\r | |
3274 | * \r | |
3275 | */\r | |
3276 | getMaskTarget: function() {\r | |
3277 | return this.maskElement ? this[this.maskElement] : null;\r | |
3278 | },\r | |
3279 | \r | |
3280 | /**\r | |
3281 | * Retrieves a plugin from this component's collection by its `pluginId`.\r | |
3282 | * \r | |
3283 | * var grid = Ext.create('Ext.grid.Panel', {\r | |
3284 | * store: {\r | |
3285 | * fields: ['name'],\r | |
3286 | * data: [{\r | |
3287 | * name: 'Scott Pilgrim'\r | |
3288 | * }]\r | |
3289 | * },\r | |
3290 | * columns: [{\r | |
3291 | * header: 'Name',\r | |
3292 | * dataIndex: 'name',\r | |
3293 | * editor: 'textfield',\r | |
3294 | * flex: 1\r | |
3295 | * }],\r | |
3296 | * selType: 'cellmodel',\r | |
3297 | * plugins: {\r | |
3298 | * ptype: 'cellediting',\r | |
3299 | * clicksToEdit: 1,\r | |
3300 | * pluginId: 'myplugin'\r | |
3301 | * },\r | |
3302 | * height: 200,\r | |
3303 | * width: 400,\r | |
3304 | * renderTo: Ext.getBody()\r | |
3305 | * });\r | |
3306 | * \r | |
3307 | * grid.getPlugin('myplugin'); // the cellediting plugin\r | |
3308 | * \r | |
3309 | * **Note:** See also {@link #findPlugin}\r | |
3310 | * \r | |
3311 | * @param {String} pluginId The `pluginId` set on the plugin config object\r | |
3312 | * @return {Ext.plugin.Abstract} plugin instance or `null` if not found\r | |
3313 | */\r | |
3314 | getPlugin: function(pluginId) {\r | |
3315 | var i,\r | |
3316 | plugins = this.plugins,\r | |
3317 | ln = plugins && plugins.length;\r | |
3318 | \r | |
3319 | for (i = 0; i < ln; i++) {\r | |
3320 | if (plugins[i].pluginId === pluginId) {\r | |
3321 | return plugins[i];\r | |
3322 | }\r | |
3323 | }\r | |
3324 | return null;\r | |
3325 | },\r | |
3326 | \r | |
3327 | /**\r | |
3328 | * Gets the current XY position of the component's underlying element.\r | |
3329 | * @param {Boolean} [local=false] If true the element's left and top are returned instead of page XY.\r | |
3330 | * @return {Number[]} The XY position of the element (e.g., [100, 200])\r | |
3331 | */\r | |
3332 | getPosition: function(local) {\r | |
3333 | var me = this,\r | |
3334 | xy,\r | |
3335 | isContainedFloater = me.isContainedFloater(),\r | |
3336 | floatParentBox;\r | |
3337 | \r | |
3338 | // Local position for non-floaters means element's local position\r | |
3339 | if ((local === true) && !isContainedFloater) {\r | |
3340 | return [me.getLocalX(), me.getLocalY()];\r | |
3341 | }\r | |
3342 | \r | |
3343 | xy = me.getXY();\r | |
3344 | \r | |
3345 | // Local position for floaters means position relative to the container's target element\r | |
3346 | if ((local === true) && isContainedFloater) {\r | |
3347 | floatParentBox = me.floatParent.getTargetEl().getViewRegion();\r | |
3348 | xy[0] -= floatParentBox.left;\r | |
3349 | xy[1] -= floatParentBox.top;\r | |
3350 | }\r | |
3351 | return xy;\r | |
3352 | },\r | |
3353 | \r | |
3354 | /**\r | |
3355 | * Returns the "x" scroll position for this component. Only applicable for\r | |
3356 | * {@link #scrollable} components\r | |
3357 | * @return {Number}\r | |
3358 | */\r | |
3359 | getScrollX: function() {\r | |
3360 | var scroller = this.getScrollable();\r | |
3361 | return scroller ? scroller.getPosition().x : 0;\r | |
3362 | },\r | |
3363 | \r | |
3364 | /**\r | |
3365 | * Returns the "y" scroll position for this component. Only applicable for\r | |
3366 | * {@link #scrollable} components\r | |
3367 | * @return {Number}\r | |
3368 | */\r | |
3369 | getScrollY: function() {\r | |
3370 | var scroller = this.getScrollable();\r | |
3371 | return scroller ? scroller.getPosition().y : 0;\r | |
3372 | },\r | |
3373 | \r | |
3374 | /**\r | |
3375 | * Gets the current size of the component's underlying element.\r | |
3376 | * @param {Boolean} [contentSize] true to get the width/size minus borders and padding\r | |
3377 | * @return {Object} An object containing the element's size:\r | |
3378 | * @return {Number} return.width\r | |
3379 | * @return {Number} return.height\r | |
3380 | */\r | |
3381 | getSize: function(contentSize) {\r | |
3382 | return this.el.getSize(contentSize);\r | |
3383 | },\r | |
3384 | \r | |
3385 | /**\r | |
3386 | * Returns an object that describes how this component's width and height are managed.\r | |
3387 | * All of these objects are shared and should not be modified.\r | |
3388 | *\r | |
3389 | * @return {Object} The size model for this component.\r | |
3390 | * @return {Ext.layout.SizeModel} return.width The {@link Ext.layout.SizeModel size model}\r | |
3391 | * for the width.\r | |
3392 | * @return {Ext.layout.SizeModel} return.height The {@link Ext.layout.SizeModel size model}\r | |
3393 | * for the height.\r | |
3394 | * @protected\r | |
3395 | */\r | |
3396 | getSizeModel: function (ownerCtSizeModel) {\r | |
3397 | var me = this,\r | |
3398 | models = Ext.layout.SizeModel,\r | |
3399 | ownerContext = me.componentLayout.ownerContext,\r | |
3400 | width = me.width,\r | |
3401 | height = me.height,\r | |
3402 | typeofWidth, typeofHeight,\r | |
3403 | hasPixelWidth, hasPixelHeight,\r | |
3404 | heightModel, ownerLayout, policy, shrinkWrap, topLevel, widthModel,\r | |
3405 | \r | |
3406 | // floating === a floating Component, floated === a border layout's slideout view of a region.\r | |
3407 | isFloating = me.floating || me.floated;\r | |
3408 | \r | |
3409 | if (ownerContext) {\r | |
3410 | // If we are in the middle of a running layout, always report the current,\r | |
3411 | // dynamic size model rather than recompute it. This is not (only) a time\r | |
3412 | // saving thing, but a correctness thing since we cannot get the right answer\r | |
3413 | // otherwise.\r | |
3414 | widthModel = ownerContext.widthModel;\r | |
3415 | heightModel = ownerContext.heightModel;\r | |
3416 | }\r | |
3417 | \r | |
3418 | if (!widthModel || !heightModel) {\r | |
3419 | hasPixelWidth = ((typeofWidth = typeof width) === 'number');\r | |
3420 | hasPixelHeight = ((typeofHeight = typeof height) === 'number');\r | |
3421 | topLevel = isFloating || !(ownerLayout = me.ownerLayout);\r | |
3422 | \r | |
3423 | // Floating or no owner layout, e.g. rendered using renderTo\r | |
3424 | if (topLevel) {\r | |
3425 | policy = Ext.layout.Layout.prototype.autoSizePolicy;\r | |
3426 | shrinkWrap = isFloating ? 3 : me.shrinkWrap;\r | |
3427 | \r | |
3428 | if (hasPixelWidth) {\r | |
3429 | widthModel = models.configured;\r | |
3430 | }\r | |
3431 | \r | |
3432 | if (hasPixelHeight) {\r | |
3433 | heightModel = models.configured;\r | |
3434 | }\r | |
3435 | } else {\r | |
3436 | policy = ownerLayout.getItemSizePolicy(me, ownerCtSizeModel);\r | |
3437 | shrinkWrap = ownerLayout.isItemShrinkWrap(me);\r | |
3438 | }\r | |
3439 | \r | |
3440 | if (ownerContext) {\r | |
3441 | ownerContext.ownerSizePolicy = policy;\r | |
3442 | }\r | |
3443 | \r | |
3444 | shrinkWrap = (shrinkWrap === true) ? 3 : (shrinkWrap || 0); // false->0, true->3\r | |
3445 | \r | |
3446 | // Now that we have shrinkWrap as a 0-3 value, we need to turn off shrinkWrap\r | |
3447 | // bits for any dimension that has a configured size not in pixels. These must\r | |
3448 | // be read from the DOM.\r | |
3449 | //\r | |
3450 | if (topLevel && shrinkWrap) {\r | |
3451 | if (width && typeofWidth === 'string') {\r | |
3452 | shrinkWrap &= 2; // percentage, "30em" or whatever - not width shrinkWrap\r | |
3453 | }\r | |
3454 | if (height && typeofHeight === 'string') {\r | |
3455 | shrinkWrap &= 1; // percentage, "30em" or whatever - not height shrinkWrap\r | |
3456 | }\r | |
3457 | }\r | |
3458 | \r | |
3459 | if (shrinkWrap !== 3) {\r | |
3460 | if (!ownerCtSizeModel) {\r | |
3461 | ownerCtSizeModel = me.ownerCt && me.ownerCt.getSizeModel();\r | |
3462 | }\r | |
3463 | \r | |
3464 | if (ownerCtSizeModel) {\r | |
3465 | shrinkWrap |= (ownerCtSizeModel.width.shrinkWrap ? 1 : 0) | (ownerCtSizeModel.height.shrinkWrap ? 2 : 0);\r | |
3466 | }\r | |
3467 | }\r | |
3468 | \r | |
3469 | if (!widthModel) {\r | |
3470 | if (!policy.setsWidth) {\r | |
3471 | if (hasPixelWidth) {\r | |
3472 | widthModel = models.configured;\r | |
3473 | } else {\r | |
3474 | widthModel = (shrinkWrap & 1) ? models.shrinkWrap : models.natural;\r | |
3475 | }\r | |
3476 | } else if (policy.readsWidth) {\r | |
3477 | if (hasPixelWidth) {\r | |
3478 | widthModel = models.calculatedFromConfigured;\r | |
3479 | } else {\r | |
3480 | widthModel = (shrinkWrap & 1) ? models.calculatedFromShrinkWrap :\r | |
3481 | models.calculatedFromNatural;\r | |
3482 | }\r | |
3483 | } else {\r | |
3484 | widthModel = models.calculated;\r | |
3485 | }\r | |
3486 | }\r | |
3487 | \r | |
3488 | if (!heightModel) {\r | |
3489 | if (!policy.setsHeight) {\r | |
3490 | if (hasPixelHeight) {\r | |
3491 | heightModel = models.configured;\r | |
3492 | } else {\r | |
3493 | heightModel = (shrinkWrap & 2) ? models.shrinkWrap : models.natural;\r | |
3494 | }\r | |
3495 | } else if (policy.readsHeight) {\r | |
3496 | if (hasPixelHeight) {\r | |
3497 | heightModel = models.calculatedFromConfigured;\r | |
3498 | } else {\r | |
3499 | heightModel = (shrinkWrap & 2) ? models.calculatedFromShrinkWrap :\r | |
3500 | models.calculatedFromNatural;\r | |
3501 | }\r | |
3502 | } else {\r | |
3503 | heightModel = models.calculated;\r | |
3504 | }\r | |
3505 | }\r | |
3506 | }\r | |
3507 | \r | |
3508 | // We return one of the cached objects with the proper "width" and "height" as the\r | |
3509 | // sizeModels we have determined.\r | |
3510 | return widthModel.pairsByHeightOrdinal[heightModel.ordinal];\r | |
3511 | },\r | |
3512 | \r | |
3513 | /**\r | |
3514 | * The supplied default state gathering method for the Component class.\r | |
3515 | *\r | |
3516 | * This method returns dimension settings such as `flex`, `anchor`, `width` and `height` along with `collapsed`\r | |
3517 | * state.\r | |
3518 | *\r | |
3519 | * Subclasses which implement more complex state should call the superclass's implementation, and apply their state\r | |
3520 | * to the result if this basic state is to be saved.\r | |
3521 | *\r | |
3522 | * Note that Component state will only be saved if the Component has a {@link #stateId} and there as a StateProvider\r | |
3523 | * configured for the document.\r | |
3524 | *\r | |
3525 | * @return {Object}\r | |
3526 | */\r | |
3527 | getState: function() {\r | |
3528 | var me = this,\r | |
3529 | state = null,\r | |
3530 | sizeModel = me.getSizeModel();\r | |
3531 | \r | |
3532 | if (sizeModel.width.configured) {\r | |
3533 | state = me.addPropertyToState(state, 'width');\r | |
3534 | }\r | |
3535 | if (sizeModel.height.configured) {\r | |
3536 | state = me.addPropertyToState(state, 'height');\r | |
3537 | }\r | |
3538 | \r | |
3539 | return state;\r | |
3540 | },\r | |
3541 | \r | |
3542 | getUserCls: function () {\r | |
3543 | return this.userCls;\r | |
3544 | },\r | |
3545 | \r | |
3546 | setUserCls: function (cls) {\r | |
3547 | var me = this,\r | |
3548 | was = me.userCls;\r | |
3549 | \r | |
3550 | if (cls !== was) {\r | |
3551 | me.userCls = cls;\r | |
3552 | \r | |
3553 | if (me.rendered) {\r | |
3554 | me.el.replaceCls(was, cls);\r | |
3555 | }\r | |
3556 | }\r | |
3557 | \r | |
3558 | return was;\r | |
3559 | },\r | |
3560 | \r | |
3561 | /**\r | |
3562 | * Gets the current width of the component's underlying element.\r | |
3563 | * @return {Number}\r | |
3564 | */\r | |
3565 | getWidth: function() {\r | |
3566 | return this.el.getWidth();\r | |
3567 | },\r | |
3568 | \r | |
3569 | /**\r | |
3570 | * Gets the xtype for this component as registered with {@link Ext.ComponentManager}. For a list of all available\r | |
3571 | * xtypes, see the {@link Ext.Component} header. Example usage:\r | |
3572 | *\r | |
3573 | * var t = new Ext.form.field.Text();\r | |
3574 | * alert(t.getXType()); // alerts 'textfield'\r | |
3575 | *\r | |
3576 | * @return {String} The xtype\r | |
3577 | */\r | |
3578 | getXType: function() {\r | |
3579 | return this.self.xtype;\r | |
3580 | },\r | |
3581 | \r | |
3582 | /**\r | |
3583 | * Returns this Component's xtype hierarchy as a slash-delimited string. For a list of all available xtypes, see the\r | |
3584 | * {@link Ext.Component} header.\r | |
3585 | *\r | |
3586 | * **If using your own subclasses, be aware that a Component must register its own xtype to participate in\r | |
3587 | * determination of inherited xtypes.**\r | |
3588 | *\r | |
3589 | * Example usage:\r | |
3590 | *\r | |
3591 | * @example\r | |
3592 | * var t = new Ext.form.field.Text();\r | |
3593 | * alert(t.getXTypes()); // alerts 'component/field/textfield'\r | |
3594 | *\r | |
3595 | * @return {String} The xtype hierarchy string\r | |
3596 | *\r | |
3597 | * @since 2.3.0\r | |
3598 | */\r | |
3599 | getXTypes: function() {\r | |
3600 | var self = this.self,\r | |
3601 | xtypes, parentPrototype, parentXtypes;\r | |
3602 | \r | |
3603 | if (!self.xtypes) {\r | |
3604 | xtypes = [];\r | |
3605 | parentPrototype = this;\r | |
3606 | \r | |
3607 | while (parentPrototype) {\r | |
3608 | parentXtypes = parentPrototype.xtypes;\r | |
3609 | \r | |
3610 | if (parentXtypes !== undefined) {\r | |
3611 | xtypes.unshift.apply(xtypes, parentXtypes);\r | |
3612 | }\r | |
3613 | \r | |
3614 | parentPrototype = parentPrototype.superclass;\r | |
3615 | }\r | |
3616 | \r | |
3617 | self.xtypeChain = xtypes;\r | |
3618 | self.xtypes = xtypes.join('/');\r | |
3619 | }\r | |
3620 | \r | |
3621 | return self.xtypes;\r | |
3622 | },\r | |
3623 | \r | |
3624 | /**\r | |
3625 | * Checks if the specified CSS class exists on this element's DOM node.\r | |
3626 | * @param {String} className The CSS class to check for.\r | |
3627 | * @return {Boolean} `true` if the class exists, else `false`.\r | |
3628 | * @method\r | |
3629 | */\r | |
3630 | hasCls: function (cls) {\r | |
3631 | var el = this.rendered ? this.el : this.protoEl;\r | |
3632 | return el.hasCls.apply(el, arguments);\r | |
3633 | },\r | |
3634 | \r | |
3635 | /**\r | |
3636 | * Checks if there is currently a specified `uiCls`.\r | |
3637 | * @param {String} cls The `cls` to check.\r | |
3638 | */\r | |
3639 | hasUICls: function(cls) {\r | |
3640 | var me = this,\r | |
3641 | uiCls = me.uiCls || [];\r | |
3642 | \r | |
3643 | return Ext.Array.contains(uiCls, cls);\r | |
3644 | },\r | |
3645 | \r | |
3646 | /**\r | |
3647 | * Hides this Component, setting it to invisible using the configured {@link #hideMode}.\r | |
3648 | * @param {String/Ext.dom.Element/Ext.Component} [animateTarget=null] **only valid for {@link #cfg-floating} Components\r | |
3649 | * such as {@link Ext.window.Window Window}s or {@link Ext.tip.ToolTip ToolTip}s, or regular Components which have\r | |
3650 | * been configured with `floating: true`.**. The target to which the Component should animate while hiding.\r | |
3651 | * @param {Function} [callback] A callback function to call after the Component is hidden.\r | |
3652 | * @param {Object} [scope] The scope (`this` reference) in which the callback is executed.\r | |
3653 | * Defaults to this Component.\r | |
3654 | * @return {Ext.Component} this\r | |
3655 | */\r | |
3656 | hide: function(animateTarget, cb, scope) {\r | |
3657 | var me = this;\r | |
3658 | \r | |
3659 | if (me.pendingShow) {\r | |
3660 | // If this is a hierarchically hidden floating component with a pending show\r | |
3661 | // hide() simply cancels the pending show.\r | |
3662 | me.pendingShow = false;\r | |
3663 | }\r | |
3664 | \r | |
3665 | if (!(me.rendered && !me.isVisible())) {\r | |
3666 | if (!me.hasListeners.beforehide || me.fireEvent('beforehide', me) !== false || me.hierarchicallyHidden) {\r | |
3667 | me.getInherited().hidden = me.hidden = true;\r | |
3668 | \r | |
3669 | // Order of events is important here. Hierarchy event kicks off\r | |
3670 | // ZIndexManager's collection sorting and floater activation;\r | |
3671 | // The hidden flag must be set so that ZIndexManager takes it out of its stack.\r | |
3672 | me.fireHierarchyEvent('beforehide');\r | |
3673 | \r | |
3674 | if (me.rendered) {\r | |
3675 | me.onHide.apply(me, arguments);\r | |
3676 | }\r | |
3677 | }\r | |
3678 | }\r | |
3679 | return me;\r | |
3680 | },\r | |
3681 | \r | |
3682 | /**\r | |
3683 | * The initComponent template method is an important initialization step for a Component. It is intended to be\r | |
3684 | * implemented by each subclass of Ext.Component to provide any needed constructor logic. The\r | |
3685 | * initComponent method of the class being created is called first, with each initComponent method\r | |
3686 | * up the hierarchy to Ext.Component being called thereafter. This makes it easy to implement and,\r | |
3687 | * if needed, override the constructor logic of the Component at any step in the hierarchy.\r | |
3688 | *\r | |
3689 | * The initComponent method **must** contain a call to {@link Ext.Base#callParent callParent} in order\r | |
3690 | * to ensure that the parent class' initComponent method is also called.\r | |
3691 | *\r | |
3692 | * All config options passed to the constructor are applied to `this` before initComponent is called,\r | |
3693 | * so you can simply access them with `this.someOption`.\r | |
3694 | *\r | |
3695 | * The following example demonstrates using a dynamic string for the text of a button at the time of\r | |
3696 | * instantiation of the class.\r | |
3697 | *\r | |
3698 | * Ext.define('DynamicButtonText', {\r | |
3699 | * extend: 'Ext.button.Button',\r | |
3700 | *\r | |
3701 | * initComponent: function() {\r | |
3702 | * this.text = new Date();\r | |
3703 | * this.renderTo = Ext.getBody();\r | |
3704 | * this.callParent();\r | |
3705 | * }\r | |
3706 | * });\r | |
3707 | *\r | |
3708 | * Ext.onReady(function() {\r | |
3709 | * Ext.create('DynamicButtonText');\r | |
3710 | * });\r | |
3711 | *\r | |
3712 | * @template\r | |
3713 | * @protected\r | |
3714 | * @since 1.1.0\r | |
3715 | */\r | |
3716 | initComponent: function () {\r | |
3717 | var me = this,\r | |
3718 | width = me.width,\r | |
3719 | height = me.height;\r | |
3720 | \r | |
3721 | // If plugins have been added by a subclass's initComponent before calling up to here (or any components\r | |
3722 | // that don't have a table view), the processed flag will not have been set, and we must process them again.\r | |
3723 | // We could just call getPlugins here however most components don't have them so prevent the extra function call.\r | |
3724 | if (me.plugins && !me.plugins.processed) {\r | |
3725 | me.plugins = me.constructPlugins();\r | |
3726 | }\r | |
3727 | me.pluginsInitialized = true;\r | |
3728 | \r | |
3729 | // this will properly (ignore or) constrain the configured width/height to their\r | |
3730 | // min/max values for consistency.\r | |
3731 | if (width != null || height != null) {\r | |
3732 | me.setSize(width, height);\r | |
3733 | }\r | |
3734 | \r | |
3735 | if (me.listeners) {\r | |
3736 | me.on(me.listeners);\r | |
3737 | me.listeners = null; //change the value to remove any on prototype\r | |
3738 | }\r | |
3739 | \r | |
3740 | if (me.focusable) {\r | |
3741 | me.initFocusable();\r | |
3742 | }\r | |
3743 | },\r | |
3744 | \r | |
3745 | /**\r | |
3746 | * Initialize any events on this component\r | |
3747 | * @protected\r | |
3748 | */\r | |
3749 | initEvents: function() {\r | |
3750 | var me = this,\r | |
3751 | afterRenderEvents = me.afterRenderEvents,\r | |
3752 | afterRenderEvent, el, property, index, len;\r | |
3753 | \r | |
3754 | if (afterRenderEvents) {\r | |
3755 | for (property in afterRenderEvents) {\r | |
3756 | el = me[property];\r | |
3757 | \r | |
3758 | if (el && el.on) {\r | |
3759 | afterRenderEvent = afterRenderEvents[property];\r | |
3760 | \r | |
3761 | for (index = 0, len = afterRenderEvent.length ; index < len ; ++index) {\r | |
3762 | me.mon(el, afterRenderEvent[index]);\r | |
3763 | }\r | |
3764 | }\r | |
3765 | }\r | |
3766 | }\r | |
3767 | \r | |
3768 | if (me.focusable) {\r | |
3769 | me.initFocusableEvents();\r | |
3770 | }\r | |
3771 | },\r | |
3772 | \r | |
3773 | /**\r | |
3774 | * Tests whether this Component matches a {@link Ext.ComponentQuery ComponentQuery}\r | |
3775 | * selector string.\r | |
3776 | * @param {String} selector The selector string to test against.\r | |
3777 | * @return {Boolean} `true` if this Component matches the selector.\r | |
3778 | */\r | |
3779 | is: function(selector) {\r | |
3780 | return Ext.ComponentQuery.is(this, selector);\r | |
3781 | },\r | |
3782 | \r | |
3783 | /**\r | |
3784 | * Determines whether this component is the descendant of a passed component.\r | |
3785 | * @param {Ext.Component} ancestor A Component which may contain this Component.\r | |
3786 | * @return {Boolean} `true` if the component is the descendant of the passed component, otherwise `false`.\r | |
3787 | */\r | |
3788 | isDescendantOf: function(ancestor) {\r | |
3789 | var p;\r | |
3790 | \r | |
3791 | // Iterate up the owner chain until we don't have one, or we find the ancestor.\r | |
3792 | for (p = this.getRefOwner(); p && p !== ancestor; p = p.getRefOwner()) {\r | |
3793 | // do nothing\r | |
3794 | }\r | |
3795 | return p || null;\r | |
3796 | },\r | |
3797 | \r | |
3798 | /**\r | |
3799 | * Determines whether **this Component** is an ancestor of the passed Component.\r | |
3800 | * This will return `true` if the passed Component is anywhere within the subtree\r | |
3801 | * beneath this Component.\r | |
3802 | * @param {Ext.Component} possibleDescendant The Component to test for presence\r | |
3803 | * within this Component's subtree.\r | |
3804 | */\r | |
3805 | isAncestor: function(possibleDescendant) {\r | |
3806 | while (possibleDescendant) {\r | |
3807 | if (possibleDescendant.getRefOwner() === this) {\r | |
3808 | return true;\r | |
3809 | }\r | |
3810 | possibleDescendant = possibleDescendant.getRefOwner();\r | |
3811 | }\r | |
3812 | },\r | |
3813 | \r | |
3814 | /**\r | |
3815 | * Method to determine whether this Component is currently disabled.\r | |
3816 | * @return {Boolean} the disabled state of this Component.\r | |
3817 | */\r | |
3818 | isDisabled: function() {\r | |
3819 | return this.disabled;\r | |
3820 | },\r | |
3821 | \r | |
3822 | /**\r | |
3823 | * Method to determine whether this Component is draggable.\r | |
3824 | * @return {Boolean} the draggable state of this component.\r | |
3825 | */\r | |
3826 | isDraggable: function() {\r | |
3827 | return !!this.draggable;\r | |
3828 | },\r | |
3829 | \r | |
3830 | /**\r | |
3831 | * Method to determine whether this Component is droppable.\r | |
3832 | * @return {Boolean} the droppable state of this component.\r | |
3833 | */\r | |
3834 | isDroppable: function() {\r | |
3835 | return !!this.droppable;\r | |
3836 | },\r | |
3837 | \r | |
3838 | /**\r | |
3839 | * Method to determine whether this Component is floating.\r | |
3840 | * @return {Boolean} the floating state of this component.\r | |
3841 | */\r | |
3842 | isFloating: function() {\r | |
3843 | return this.floating;\r | |
3844 | },\r | |
3845 | \r | |
3846 | /**\r | |
3847 | * Method to determine whether this Component is currently set to hidden.\r | |
3848 | * @return {Boolean} the hidden state of this Component.\r | |
3849 | */\r | |
3850 | isHidden: function() {\r | |
3851 | return this.hidden;\r | |
3852 | },\r | |
3853 | \r | |
3854 | isHierarchicallyHidden: function() {\r | |
3855 | var child = this,\r | |
3856 | hidden = false,\r | |
3857 | parent, parentInheritedState;\r | |
3858 | \r | |
3859 | // It is possible for some components to be immune to collapse meaning the immune\r | |
3860 | // component remains visible when its direct parent is collapsed, e.g. panel header.\r | |
3861 | // Because of this, we must walk up the component hierarchy to determine the true\r | |
3862 | // visible state of the component.\r | |
3863 | for (; (parent = child.ownerCt || child.floatParent); child = parent) {\r | |
3864 | parentInheritedState = parent.getInherited();\r | |
3865 | if (parentInheritedState.hidden) {\r | |
3866 | hidden = true;\r | |
3867 | break;\r | |
3868 | }\r | |
3869 | if (child.getInherited().collapseImmune) {\r | |
3870 | // The child or one of its ancestors is immune to collapse.\r | |
3871 | if (parent.collapsed && !child.collapseImmune) {\r | |
3872 | // If the child's direct parent is collapsed, and the child\r | |
3873 | // itself does not have collapse immunity we know that\r | |
3874 | // the child is not visible.\r | |
3875 | hidden = true;\r | |
3876 | break;\r | |
3877 | }\r | |
3878 | } else {\r | |
3879 | // We have ascended the tree to a point where collapse immunity\r | |
3880 | // is not in play. This means if any ancestor above this point\r | |
3881 | // is collapsed, then the component is not visible.\r | |
3882 | hidden = !!parentInheritedState.collapsed;\r | |
3883 | break;\r | |
3884 | }\r | |
3885 | }\r | |
3886 | \r | |
3887 | return hidden;\r | |
3888 | },\r | |
3889 | \r | |
3890 | /**\r | |
3891 | * Checks if this component will be contained by the passed component as part of its\r | |
3892 | * layout run. If `true`, then the layout on `this` can be skipped because it will be\r | |
3893 | * encompassed when the layout for `comp` runs. Typical cases where this may be be `false`\r | |
3894 | * is when asking about floaters nested in containers.\r | |
3895 | * @param {Ext.Component} comp The potential owner.\r | |
3896 | * @return {Boolean} `true` if this component is a layout child of `comp`.\r | |
3897 | *\r | |
3898 | * @private\r | |
3899 | */\r | |
3900 | isLayoutChild: function(ownerCandidate) {\r | |
3901 | return !this.floating && !!this.up(ownerCandidate);\r | |
3902 | },\r | |
3903 | \r | |
3904 | /**\r | |
3905 | * Determines whether this Component is the root of a layout. This returns `true` if\r | |
3906 | * this component can run its layout without assistance from or impact on its owner.\r | |
3907 | * If this component cannot run its layout given these restrictions, `false` is returned\r | |
3908 | * and its owner will be considered as the next candidate for the layout root.\r | |
3909 | *\r | |
3910 | * Setting the {@link #_isLayoutRoot} property to `true` causes this method to always\r | |
3911 | * return `true`. This may be useful when updating a layout of a Container which shrink\r | |
3912 | * wraps content, and you know that it will not change size, and so can safely be the\r | |
3913 | * topmost participant in the layout run.\r | |
3914 | * @protected\r | |
3915 | */\r | |
3916 | isLayoutRoot: function() {\r | |
3917 | var me = this,\r | |
3918 | ownerLayout = me.ownerLayout;\r | |
3919 | \r | |
3920 | // Return true if we have been explicitly flagged as the layout root, or if we are floating.\r | |
3921 | // Sometimes floating Components get an ownerCt ref injected into them which is *not* a true ownerCt, merely\r | |
3922 | // an upward link for reference purposes. For example a grid column menu is linked to the\r | |
3923 | // owning header via an ownerCt reference.\r | |
3924 | if (!ownerLayout || me._isLayoutRoot || me.floating) {\r | |
3925 | return true;\r | |
3926 | }\r | |
3927 | \r | |
3928 | return ownerLayout.isItemLayoutRoot(me);\r | |
3929 | },\r | |
3930 | \r | |
3931 | /**\r | |
3932 | * Returns `true` if layout is suspended for this component. This can come from direct\r | |
3933 | * suspension of this component's layout activity ({@link Ext.Container#suspendLayout}) or if one\r | |
3934 | * of this component's containers is suspended.\r | |
3935 | *\r | |
3936 | * @return {Boolean} `true` layout of this component is suspended.\r | |
3937 | */\r | |
3938 | isLayoutSuspended: function () {\r | |
3939 | var comp = this,\r | |
3940 | ownerLayout;\r | |
3941 | \r | |
3942 | while (comp) {\r | |
3943 | if (comp.layoutSuspendCount || comp.suspendLayout) {\r | |
3944 | return true;\r | |
3945 | }\r | |
3946 | \r | |
3947 | ownerLayout = comp.ownerLayout;\r | |
3948 | if (!ownerLayout) {\r | |
3949 | break;\r | |
3950 | }\r | |
3951 | \r | |
3952 | // TODO - what about suspending a Layout instance?\r | |
3953 | \r | |
3954 | // this works better than ownerCt since ownerLayout means "is managed by" in\r | |
3955 | // the proper sense... some floating components have ownerCt but won't have an\r | |
3956 | // ownerLayout\r | |
3957 | comp = ownerLayout.owner;\r | |
3958 | }\r | |
3959 | \r | |
3960 | return false;\r | |
3961 | },\r | |
3962 | \r | |
3963 | /**\r | |
3964 | * Returns `true` if this component is visible.\r | |
3965 | *\r | |
3966 | * @param {Boolean} [deep=false] Pass `true` to interrogate the visibility status of all parent Containers to\r | |
3967 | * determine whether this Component is truly visible to the user.\r | |
3968 | *\r | |
3969 | * Generally, to determine whether a Component is hidden, the no argument form is needed. For example when creating\r | |
3970 | * dynamically laid out UIs in a hidden Container before showing them.\r | |
3971 | *\r | |
3972 | * @return {Boolean} `true` if this component is visible, `false` otherwise.\r | |
3973 | *\r | |
3974 | * @since 1.1.0\r | |
3975 | */\r | |
3976 | isVisible: function(deep) {\r | |
3977 | var me = this,\r | |
3978 | hidden;\r | |
3979 | \r | |
3980 | if (me.hidden || !me.rendered || me.destroyed) {\r | |
3981 | hidden = true;\r | |
3982 | } else if (deep) {\r | |
3983 | hidden = me.isHierarchicallyHidden();\r | |
3984 | }\r | |
3985 | \r | |
3986 | return !hidden;\r | |
3987 | },\r | |
3988 | \r | |
3989 | /**\r | |
3990 | * Tests whether or not this Component is of a specific xtype. This can test whether this Component is descended\r | |
3991 | * from the xtype (default) or whether it is directly of the xtype specified (`shallow = true`).\r | |
3992 | *\r | |
3993 | * **If using your own subclasses, be aware that a Component must register its own xtype to participate in\r | |
3994 | * determination of inherited xtypes.**\r | |
3995 | *\r | |
3996 | * For a list of all available xtypes, see the {@link Ext.Component} header.\r | |
3997 | *\r | |
3998 | * Example usage:\r | |
3999 | *\r | |
4000 | * @example\r | |
4001 | * var t = new Ext.form.field.Text();\r | |
4002 | * var isText = t.isXType('textfield'); // true\r | |
4003 | * var isBoxSubclass = t.isXType('field'); // true, descended from Ext.form.field.Base\r | |
4004 | * var isBoxInstance = t.isXType('field', true); // false, not a direct Ext.form.field.Base instance\r | |
4005 | *\r | |
4006 | * @param {String} xtype The xtype to check for this Component\r | |
4007 | * @param {Boolean} [shallow=false] `true` to check whether this Component is directly of the specified xtype, `false` to\r | |
4008 | * check whether this Component is descended from the xtype.\r | |
4009 | * @return {Boolean} `true` if this component descends from the specified xtype, `false` otherwise.\r | |
4010 | *\r | |
4011 | * @since 2.3.0\r | |
4012 | */\r | |
4013 | isXType: function(xtype, shallow) {\r | |
4014 | return shallow ? (Ext.Array.indexOf(this.xtypes, xtype) !== -1) :\r | |
4015 | !!this.xtypesMap[xtype];\r | |
4016 | },\r | |
4017 | \r | |
4018 | /**\r | |
4019 | * Returns masked state for this Component.\r | |
4020 | *\r | |
4021 | * @param {Boolean} [deep=false] True to look up this Component's parent masked state.\r | |
4022 | *\r | |
4023 | * @return {Boolean} True if masked, false otherwise.\r | |
4024 | */\r | |
4025 | isMasked: function(deep) {\r | |
4026 | var me = this;\r | |
4027 | \r | |
4028 | return !!(me.masked || (me.loadMask && me.loadMask.isVisible()) ||\r | |
4029 | (deep && me.getInherited().masked));\r | |
4030 | },\r | |
4031 | \r | |
4032 | /**\r | |
4033 | * Set masked state for this Component.\r | |
4034 | *\r | |
4035 | * @param {Boolean} isMasked True if masked, false otherwise.\r | |
4036 | * @private\r | |
4037 | */\r | |
4038 | setMasked: function(isMasked) {\r | |
4039 | var me = this,\r | |
4040 | container = me.focusableContainer;\r | |
4041 | \r | |
4042 | if (isMasked) {\r | |
4043 | me.masked = true;\r | |
4044 | me.getInherited().masked = isMasked;\r | |
4045 | } else {\r | |
4046 | me.masked = false;\r | |
4047 | delete me.getInherited().masked;\r | |
4048 | }\r | |
4049 | \r | |
4050 | if (container) {\r | |
4051 | container.onFocusableChildMasked(me, isMasked);\r | |
4052 | }\r | |
4053 | \r | |
4054 | return me;\r | |
4055 | },\r | |
4056 | \r | |
4057 | /**\r | |
4058 | * Masks this component with a semi-opaque layer and makes the contents unavailable to clicks.\r | |
4059 | *\r | |
4060 | * See {@link #unmask}.\r | |
4061 | *\r | |
4062 | * @param {String} [msg] A message to show in the center of the mask layer.\r | |
4063 | * @param {String} [msgCls] A CSS class name to use on the message element in the center of the layer.\r | |
4064 | */\r | |
4065 | mask: function (msg, msgCls, elHeight) {\r | |
4066 | var box = this.lastBox,\r | |
4067 | // getMaskTarget may be overridden in subclasses/\r | |
4068 | // null means that a LoadMask has to be rendered to document.body\r | |
4069 | // Element masking falls back to masking the local el\r | |
4070 | target = this.getMaskTarget() || this.el;\r | |
4071 | \r | |
4072 | // Pass it the height of our element if we know it.\r | |
4073 | if (box) {\r | |
4074 | elHeight = box.height;\r | |
4075 | }\r | |
4076 | target.mask(msg, msgCls, elHeight);\r | |
4077 | \r | |
4078 | this.setMasked(true);\r | |
4079 | },\r | |
4080 | \r | |
4081 | /**\r | |
4082 | * Returns the next node in the Component tree in tree traversal order.\r | |
4083 | *\r | |
4084 | * Note that this is not limited to siblings, and if invoked upon a node with no matching siblings, will walk the\r | |
4085 | * tree to attempt to find a match. Contrast with {@link #nextSibling}.\r | |
4086 | * @param {String} [selector] A {@link Ext.ComponentQuery ComponentQuery} selector to filter the following nodes.\r | |
4087 | * @return {Ext.Component} The next node (or the next node which matches the selector).\r | |
4088 | * Returns `null` if there is no matching node.\r | |
4089 | */\r | |
4090 | nextNode: function(selector, /* private */ includeSelf) {\r | |
4091 | var node = this,\r | |
4092 | ownerCt = node.ownerCt,\r | |
4093 | result,\r | |
4094 | it, len, i, sib;\r | |
4095 | \r | |
4096 | // If asked to include self, test me\r | |
4097 | if (includeSelf && node.is(selector)) {\r | |
4098 | return node;\r | |
4099 | }\r | |
4100 | \r | |
4101 | if (ownerCt) {\r | |
4102 | for (it = ownerCt.items.items, i = Ext.Array.indexOf(it, node) + 1, len = it.length; i < len; i++) {\r | |
4103 | sib = it[i];\r | |
4104 | if (sib.is(selector)) {\r | |
4105 | return sib;\r | |
4106 | }\r | |
4107 | if (sib.down) {\r | |
4108 | result = sib.down(selector);\r | |
4109 | if (result) {\r | |
4110 | return result;\r | |
4111 | }\r | |
4112 | }\r | |
4113 | }\r | |
4114 | return ownerCt.nextNode(selector);\r | |
4115 | }\r | |
4116 | return null;\r | |
4117 | },\r | |
4118 | \r | |
4119 | /**\r | |
4120 | * Returns the next sibling of this Component.\r | |
4121 | *\r | |
4122 | * Optionally selects the next sibling which matches the passed {@link Ext.ComponentQuery ComponentQuery} selector.\r | |
4123 | *\r | |
4124 | * May also be referred to as **`next()`**\r | |
4125 | *\r | |
4126 | * Note that this is limited to siblings, and if no siblings of the item match, `null` is returned. Contrast with\r | |
4127 | * {@link #nextNode}\r | |
4128 | * @param {String} [selector] A {@link Ext.ComponentQuery ComponentQuery} selector to filter the following items.\r | |
4129 | * @return {Ext.Component} The next sibling (or the next sibling which matches the selector).\r | |
4130 | * Returns `null` if there is no matching sibling.\r | |
4131 | */\r | |
4132 | nextSibling: function(selector) {\r | |
4133 | var o = this.ownerCt, it, last, idx, c;\r | |
4134 | if (o) {\r | |
4135 | it = o.items;\r | |
4136 | idx = it.indexOf(this) + 1;\r | |
4137 | if (idx) {\r | |
4138 | if (selector) {\r | |
4139 | for (last = it.getCount(); idx < last; idx++) {\r | |
4140 | if ((c = it.getAt(idx)).is(selector)) {\r | |
4141 | return c;\r | |
4142 | }\r | |
4143 | }\r | |
4144 | } else {\r | |
4145 | if (idx < it.getCount()) {\r | |
4146 | return it.getAt(idx);\r | |
4147 | }\r | |
4148 | }\r | |
4149 | }\r | |
4150 | }\r | |
4151 | return null;\r | |
4152 | },\r | |
4153 | \r | |
4154 | /**\r | |
4155 | * Method to manage awareness of when components are added to their\r | |
4156 | * respective Container, firing an #added event. References are\r | |
4157 | * established at add time rather than at render time.\r | |
4158 | *\r | |
4159 | * Allows addition of behavior when a Component is added to a\r | |
4160 | * Container. At this stage, the Component is in the parent\r | |
4161 | * Container's collection of child items. After calling the\r | |
4162 | * superclass's `onAdded`, the `ownerCt` reference will be present,\r | |
4163 | * and if configured with a ref, the `refOwner` will be set.\r | |
4164 | *\r | |
4165 | * @param {Ext.container.Container} container Container which holds the component.\r | |
4166 | * @param {Number} pos Position at which the component was added.\r | |
4167 | * @param {Boolean} instanced `false` if this component was instanced by the parent\r | |
4168 | * container. `true` if the instance already existed when it was passed to the container.\r | |
4169 | *\r | |
4170 | * @template\r | |
4171 | * @protected\r | |
4172 | * @since 3.4.0\r | |
4173 | */\r | |
4174 | onAdded: function (container, pos, instanced) {\r | |
4175 | var me = this;\r | |
4176 | \r | |
4177 | me.ownerCt = container;\r | |
4178 | \r | |
4179 | me.onInheritedAdd(me, instanced);\r | |
4180 | \r | |
4181 | if (me.hasListeners && me.hasListeners.added) {\r | |
4182 | me.fireEvent('added', me, container, pos);\r | |
4183 | }\r | |
4184 | \r | |
4185 | if (Ext.GlobalEvents.hasListeners.added) {\r | |
4186 | me.fireHierarchyEvent('added');\r | |
4187 | }\r | |
4188 | },\r | |
4189 | \r | |
4190 | /**\r | |
4191 | * Method to manage awareness of when components are removed from their\r | |
4192 | * respective Container, firing a #removed event. References are properly\r | |
4193 | * cleaned up after removing a component from its owning container.\r | |
4194 | *\r | |
4195 | * Allows addition of behavior when a Component is removed from\r | |
4196 | * its parent Container. At this stage, the Component has been\r | |
4197 | * removed from its parent Container's collection of child items,\r | |
4198 | * but has not been destroyed (It will be destroyed if the parent\r | |
4199 | * Container's `autoDestroy` is `true`, or if the remove call was\r | |
4200 | * passed a truthy second parameter). After calling the\r | |
4201 | * superclass's `onRemoved`, the `ownerCt` and the `refOwner` will not\r | |
4202 | * be present.\r | |
4203 | * @param {Boolean} destroying Will be passed as `true` if the Container performing the remove operation will delete this\r | |
4204 | * Component upon remove.\r | |
4205 | *\r | |
4206 | * @template\r | |
4207 | * @protected\r | |
4208 | * @since 3.4.0\r | |
4209 | */\r | |
4210 | onRemoved: function(destroying) {\r | |
4211 | var me = this,\r | |
4212 | refHolder;\r | |
4213 | \r | |
4214 | if (Ext.GlobalEvents.hasListeners.removed) {\r | |
4215 | me.fireHierarchyEvent('removed');\r | |
4216 | }\r | |
4217 | \r | |
4218 | if (me.hasListeners.removed) {\r | |
4219 | me.fireEvent('removed', me, me.ownerCt);\r | |
4220 | }\r | |
4221 | \r | |
4222 | if (!destroying) {\r | |
4223 | me.removeBindings();\r | |
4224 | }\r | |
4225 | \r | |
4226 | me.onInheritedRemove(destroying);\r | |
4227 | \r | |
4228 | me.ownerCt = me.ownerLayout = null;\r | |
4229 | },\r | |
4230 | \r | |
4231 | /**\r | |
4232 | * Invoked when this component has first achieved size. Occurs after the\r | |
4233 | * {@link #componentLayout} has completed its initial run.\r | |
4234 | *\r | |
4235 | * This method is not called on components that use {@link #liquidLayout}, such as\r | |
4236 | * {@link Ext.button.Button Buttons} and {@link Ext.form.field.Base Form Fields}.\r | |
4237 | * \r | |
4238 | * **Note:** If the Component has a {@link Ext.Component#controller ViewController} \r | |
4239 | * and the controller has a {@link Ext.app.ViewController#boxReady boxReady} method \r | |
4240 | * it will be called passing the Component as the single param.\r | |
4241 | *\r | |
4242 | * @param {Number} width The width of this component\r | |
4243 | * @param {Number} height The height of this component\r | |
4244 | *\r | |
4245 | * @template\r | |
4246 | * @protected\r | |
4247 | */\r | |
4248 | onBoxReady: function(width, height) {\r | |
4249 | var me = this,\r | |
4250 | label;\r | |
4251 | \r | |
4252 | // We have to do this lookup onBoxReady instead of afterRender\r | |
4253 | // to ensure that the components that could be referenced in\r | |
4254 | // me.ariaLabelledBy or me.ariaDescribedBy are already rendered\r | |
4255 | if (me.ariaLabelledBy || me.ariaDescribedBy) {\r | |
4256 | if (me.ariaLabelledBy) {\r | |
4257 | label = me.getAriaLabelEl(me.ariaLabelledBy);\r | |
4258 | \r | |
4259 | if (label) {\r | |
4260 | me.ariaEl.dom.setAttribute('aria-labelledby', label);\r | |
4261 | }\r | |
4262 | }\r | |
4263 | \r | |
4264 | if (me.ariaDescribedBy) {\r | |
4265 | label = me.getAriaLabelEl(me.ariaDescribedBy);\r | |
4266 | \r | |
4267 | if (label) {\r | |
4268 | me.ariaEl.dom.setAttribute('aria-describedby', label);\r | |
4269 | }\r | |
4270 | }\r | |
4271 | }\r | |
4272 | \r | |
4273 | if (me.resizable) {\r | |
4274 | me.initResizable(me.resizable);\r | |
4275 | }\r | |
4276 | \r | |
4277 | // Draggability must be initialized after resizability\r | |
4278 | // Because if we have to be wrapped, the resizer wrapper must be dragged as a pseudo-Component\r | |
4279 | if (me.draggable) {\r | |
4280 | me.initDraggable();\r | |
4281 | }\r | |
4282 | \r | |
4283 | if (me.hasListeners.boxready) {\r | |
4284 | me.fireEvent('boxready', me, width, height);\r | |
4285 | }\r | |
4286 | },\r | |
4287 | \r | |
4288 | /**\r | |
4289 | * Allows addition of behavior to the destroy operation.\r | |
4290 | * After calling the superclass's onDestroy, the Component will be destroyed.\r | |
4291 | *\r | |
4292 | * @template\r | |
4293 | * @protected\r | |
4294 | */\r | |
4295 | onDestroy: function() {\r | |
4296 | var me = this,\r | |
4297 | container = me.focusableContainer;\r | |
4298 | \r | |
4299 | // Ensure that any ancillary components are destroyed.\r | |
4300 | if (me.rendered) {\r | |
4301 | Ext.destroy(\r | |
4302 | me.dd,\r | |
4303 | me.resizer,\r | |
4304 | me.proxy,\r | |
4305 | me.proxyWrap,\r | |
4306 | me.resizerComponent,\r | |
4307 | me.scrollable,\r | |
4308 | me.contentEl\r | |
4309 | );\r | |
4310 | }\r | |
4311 | \r | |
4312 | if (container) {\r | |
4313 | container.onFocusableChildDestroy(me);\r | |
4314 | }\r | |
4315 | \r | |
4316 | if (me.focusable) {\r | |
4317 | me.destroyFocusable();\r | |
4318 | }\r | |
4319 | \r | |
4320 | // Destroying the floatingItems ZIndexManager will also destroy descendant floating Components\r | |
4321 | Ext.destroy(\r | |
4322 | me.componentLayout,\r | |
4323 | me.loadMask,\r | |
4324 | me.floatingDescendants\r | |
4325 | );\r | |
4326 | },\r | |
4327 | \r | |
4328 | /**\r | |
4329 | * Allows addition of behavior to the disable operation.\r | |
4330 | * After calling the superclass's `onDisable`, the Component will be disabled.\r | |
4331 | *\r | |
4332 | * @template\r | |
4333 | * @protected\r | |
4334 | */\r | |
4335 | onDisable: function () {\r | |
4336 | var me = this,\r | |
4337 | dom, nodeName;\r | |
4338 | \r | |
4339 | if (me.focusable) {\r | |
4340 | me.disableFocusable();\r | |
4341 | }\r | |
4342 | \r | |
4343 | if (!me.ariaStaticRoles[me.ariaRole]) {\r | |
4344 | me.ariaEl.dom.setAttribute('aria-disabled', true);\r | |
4345 | }\r | |
4346 | \r | |
4347 | // Only mask if we're set to & nobody above us will do so\r | |
4348 | if (me.maskOnDisable && !me.getInheritedConfig('disableMask', true)) {\r | |
4349 | dom = me.el.dom;\r | |
4350 | nodeName = dom.nodeName;\r | |
4351 | \r | |
4352 | if (me.disabledRe.test(nodeName)) {\r | |
4353 | dom.disabled = true;\r | |
4354 | }\r | |
4355 | \r | |
4356 | if (!me.nonMaskableRe.test(nodeName)) {\r | |
4357 | me.mask();\r | |
4358 | }\r | |
4359 | }\r | |
4360 | },\r | |
4361 | \r | |
4362 | /**\r | |
4363 | * Allows addition of behavior to the enable operation.\r | |
4364 | * After calling the superclass's `onEnable`, the Component will be enabled.\r | |
4365 | *\r | |
4366 | * @template\r | |
4367 | * @protected\r | |
4368 | */\r | |
4369 | onEnable: function () {\r | |
4370 | var me = this,\r | |
4371 | dom, nodeName;\r | |
4372 | \r | |
4373 | if (me.focusable) {\r | |
4374 | me.enableFocusable();\r | |
4375 | }\r | |
4376 | \r | |
4377 | if (!me.ariaStaticRoles[me.ariaRole]) {\r | |
4378 | me.ariaEl.dom.setAttribute('aria-disabled', false);\r | |
4379 | }\r | |
4380 | \r | |
4381 | if (me.maskOnDisable && me.getInherited().hasOwnProperty('masked')) {\r | |
4382 | dom = me.el.dom;\r | |
4383 | nodeName = dom.nodeName;\r | |
4384 | \r | |
4385 | if (me.disabledRe.test(nodeName)) {\r | |
4386 | dom.disabled = false;\r | |
4387 | }\r | |
4388 | \r | |
4389 | if (!me.nonMaskableRe.test(nodeName)) {\r | |
4390 | me.unmask();\r | |
4391 | }\r | |
4392 | }\r | |
4393 | },\r | |
4394 | \r | |
4395 | onGlobalShow: function (c) {\r | |
4396 | if (this.up(c)) {\r | |
4397 | this.getScrollable().restoreState();\r | |
4398 | }\r | |
4399 | },\r | |
4400 | \r | |
4401 | /**\r | |
4402 | * Allows addition of behavior to the hide operation. After\r | |
4403 | * calling the superclass's onHide, the Component will be hidden.\r | |
4404 | *\r | |
4405 | * Gets passed the same parameters as #hide.\r | |
4406 | *\r | |
4407 | * @param {String/Ext.dom.Element/Ext.Component} [animateTarget]\r | |
4408 | * @param {Function} [callback]\r | |
4409 | * @param {Object} [scope]\r | |
4410 | *\r | |
4411 | * @template\r | |
4412 | * @protected\r | |
4413 | */\r | |
4414 | onHide: function(animateTarget, cb, scope) {\r | |
4415 | var me = this,\r | |
4416 | ghostPanel, fromSize, toBox;\r | |
4417 | \r | |
4418 | if (!me.ariaStaticRoles[me.ariaRole]) {\r | |
4419 | me.ariaEl.dom.setAttribute('aria-hidden', true);\r | |
4420 | }\r | |
4421 | \r | |
4422 | // Part of the Focusable mixin API.\r | |
4423 | // If we have focus now, move focus back to whatever had it before.\r | |
4424 | me.revertFocus();\r | |
4425 | \r | |
4426 | // Default to configured animate target if none passed\r | |
4427 | animateTarget = me.getAnimateTarget(animateTarget);\r | |
4428 | \r | |
4429 | // Need to be able to ghost the Component\r | |
4430 | if (!me.ghost) {\r | |
4431 | animateTarget = null;\r | |
4432 | }\r | |
4433 | // If we're animating, kick off an animation of the ghost down to the target\r | |
4434 | if (animateTarget) {\r | |
4435 | toBox = {\r | |
4436 | x: animateTarget.getX(),\r | |
4437 | y: animateTarget.getY(),\r | |
4438 | width: animateTarget.dom.offsetWidth,\r | |
4439 | height: animateTarget.dom.offsetHeight\r | |
4440 | };\r | |
4441 | ghostPanel = me.ghost();\r | |
4442 | ghostPanel.el.stopAnimation();\r | |
4443 | fromSize = me.getSize();\r | |
4444 | ghostPanel.el.animate({\r | |
4445 | to: toBox,\r | |
4446 | listeners: {\r | |
4447 | afteranimate: function() {\r | |
4448 | delete ghostPanel.componentLayout.lastComponentSize;\r | |
4449 | ghostPanel.el.hide();\r | |
4450 | ghostPanel.setHiddenState(true);\r | |
4451 | ghostPanel.el.setSize(fromSize);\r | |
4452 | me.afterHide(cb, scope);\r | |
4453 | }\r | |
4454 | }\r | |
4455 | });\r | |
4456 | }\r | |
4457 | me.el.hide();\r | |
4458 | if (!animateTarget) {\r | |
4459 | me.afterHide(cb, scope);\r | |
4460 | }\r | |
4461 | },\r | |
4462 | \r | |
4463 | /**\r | |
4464 | * @method\r | |
4465 | * Called after the component is moved, this method is empty by default but can be implemented by any\r | |
4466 | * subclass that needs to perform custom logic after a move occurs.\r | |
4467 | *\r | |
4468 | * @param {Number} x The new x position.\r | |
4469 | * @param {Number} y The new y position.\r | |
4470 | *\r | |
4471 | * @template\r | |
4472 | * @protected\r | |
4473 | */\r | |
4474 | onPosition: Ext.emptyFn,\r | |
4475 | \r | |
4476 | /**\r | |
4477 | * Called when the component is resized.\r | |
4478 | *\r | |
4479 | * This method is not called on components that use {@link #liquidLayout}, such as\r | |
4480 | * {@link Ext.button.Button Buttons} and {@link Ext.form.field.Base Form Fields}.\r | |
4481 | *\r | |
4482 | * @method\r | |
4483 | * @template\r | |
4484 | * @protected\r | |
4485 | */\r | |
4486 | onResize: function(width, height, oldWidth, oldHeight) {\r | |
4487 | var me = this;\r | |
4488 | \r | |
4489 | // constrain is a config on Floating\r | |
4490 | if (me.floating && me.constrain) {\r | |
4491 | me.doConstrain();\r | |
4492 | }\r | |
4493 | \r | |
4494 | me.refreshScroll();\r | |
4495 | \r | |
4496 | if (me.hasListeners.resize) {\r | |
4497 | me.fireEvent('resize', me, width, height, oldWidth, oldHeight);\r | |
4498 | }\r | |
4499 | },\r | |
4500 | \r | |
4501 | /**\r | |
4502 | * Invoked when a scroll is initiated on this component via its {@link #scrollable scroller}.\r | |
4503 | * @method onScrollStart\r | |
4504 | * @param {Number} x The current x position\r | |
4505 | * @param {Number} y The current y position\r | |
4506 | * @template\r | |
4507 | * @protected\r | |
4508 | */\r | |
4509 | \r | |
4510 | /**\r | |
4511 | * Invoked when this component is scrolled via its {@link #scrollable scroller}.\r | |
4512 | * @method onScrollMove\r | |
4513 | * @param {Number} x The current x position\r | |
4514 | * @param {Number} y The current y position\r | |
4515 | * @template\r | |
4516 | * @protected\r | |
4517 | */\r | |
4518 | \r | |
4519 | /**\r | |
4520 | * Invoked when a scroll operation is completed via this component's {@link #scrollable scroller}.\r | |
4521 | * @method onScrollEnd\r | |
4522 | * @param {Number} x The current x position\r | |
4523 | * @param {Number} y The current y position\r | |
4524 | * @template\r | |
4525 | * @protected\r | |
4526 | */\r | |
4527 | \r | |
4528 | /**\r | |
4529 | * Allows addition of behavior to the show operation. After\r | |
4530 | * calling the superclass's onShow, the Component will be visible.\r | |
4531 | *\r | |
4532 | * Override in subclasses where more complex behaviour is needed.\r | |
4533 | *\r | |
4534 | * Gets passed the same parameters as #show.\r | |
4535 | *\r | |
4536 | * @param {String/Ext.dom.Element} [animateTarget]\r | |
4537 | * @param {Function} [callback]\r | |
4538 | * @param {Object} [scope]\r | |
4539 | *\r | |
4540 | * @template\r | |
4541 | * @protected\r | |
4542 | */\r | |
4543 | onShow: function() {\r | |
4544 | var me = this;\r | |
4545 | \r | |
4546 | if (!me.ariaStaticRoles[me.ariaRole]) {\r | |
4547 | me.ariaEl.dom.setAttribute('aria-hidden', false);\r | |
4548 | }\r | |
4549 | \r | |
4550 | me.el.show();\r | |
4551 | \r | |
4552 | me.updateLayout({ isRoot: false });\r | |
4553 | \r | |
4554 | // Constraining/containing element may have changed size while this Component was hidden\r | |
4555 | if (me.floating) {\r | |
4556 | if (me.maximized) {\r | |
4557 | me.fitContainer();\r | |
4558 | }\r | |
4559 | else if (me.constrain) {\r | |
4560 | me.doConstrain();\r | |
4561 | }\r | |
4562 | }\r | |
4563 | },\r | |
4564 | \r | |
4565 | /**\r | |
4566 | * Invoked after the #afterShow method is complete.\r | |
4567 | *\r | |
4568 | * Gets passed the same `callback` and `scope` parameters that #afterShow received.\r | |
4569 | *\r | |
4570 | * @param {Function} [callback]\r | |
4571 | * @param {Object} [scope]\r | |
4572 | *\r | |
4573 | * @template\r | |
4574 | * @protected\r | |
4575 | */\r | |
4576 | onShowComplete: function(cb, scope) {\r | |
4577 | var me = this,\r | |
4578 | container = me.focusableContainer;\r | |
4579 | \r | |
4580 | if (me.floating) {\r | |
4581 | me.onFloatShow();\r | |
4582 | }\r | |
4583 | \r | |
4584 | Ext.callback(cb, scope || me);\r | |
4585 | me.fireEvent('show', me);\r | |
4586 | \r | |
4587 | if (container) {\r | |
4588 | container.onFocusableChildShow(me);\r | |
4589 | }\r | |
4590 | \r | |
4591 | delete me.hiddenByLayout;\r | |
4592 | },\r | |
4593 | \r | |
4594 | onShowVeto: Ext.emptyFn,\r | |
4595 | \r | |
4596 | /**\r | |
4597 | * Returns the previous node in the Component tree in tree traversal order.\r | |
4598 | *\r | |
4599 | * Note that this is not limited to siblings, and if invoked upon a node with no matching siblings, will walk the\r | |
4600 | * tree in reverse order to attempt to find a match. Contrast with {@link #previousSibling}.\r | |
4601 | * @param {String} [selector] A {@link Ext.ComponentQuery ComponentQuery} selector to filter the preceding nodes.\r | |
4602 | * @return {Ext.Component} The previous node (or the previous node which matches the selector).\r | |
4603 | * Returns `null` if there is no matching node.\r | |
4604 | */\r | |
4605 | previousNode: function(selector, /* private */ includeSelf) {\r | |
4606 | var node = this,\r | |
4607 | ownerCt = node.ownerCt,\r | |
4608 | result,\r | |
4609 | it, i, sib;\r | |
4610 | \r | |
4611 | // If asked to include self, test me\r | |
4612 | if (includeSelf && node.is(selector)) {\r | |
4613 | return node;\r | |
4614 | }\r | |
4615 | \r | |
4616 | if (ownerCt) {\r | |
4617 | for (it = ownerCt.items.items, i = Ext.Array.indexOf(it, node) - 1; i > -1; i--) {\r | |
4618 | sib = it[i];\r | |
4619 | if (sib.query) {\r | |
4620 | result = sib.query(selector);\r | |
4621 | result = result[result.length - 1];\r | |
4622 | if (result) {\r | |
4623 | return result;\r | |
4624 | }\r | |
4625 | }\r | |
4626 | if (sib.is(selector)) {\r | |
4627 | return sib;\r | |
4628 | }\r | |
4629 | }\r | |
4630 | return ownerCt.previousNode(selector, true);\r | |
4631 | }\r | |
4632 | return null;\r | |
4633 | },\r | |
4634 | \r | |
4635 | /**\r | |
4636 | * Returns the previous sibling of this Component.\r | |
4637 | *\r | |
4638 | * Optionally selects the previous sibling which matches the passed {@link Ext.ComponentQuery ComponentQuery}\r | |
4639 | * selector.\r | |
4640 | *\r | |
4641 | * May also be referred to as **`prev()`**\r | |
4642 | *\r | |
4643 | * Note that this is limited to siblings, and if no siblings of the item match, `null` is returned. Contrast with\r | |
4644 | * {@link #previousNode}\r | |
4645 | * @param {String} [selector] A {@link Ext.ComponentQuery ComponentQuery} selector to filter the preceding items.\r | |
4646 | * @return {Ext.Component} The previous sibling (or the previous sibling which matches the selector).\r | |
4647 | * Returns `null` if there is no matching sibling.\r | |
4648 | */\r | |
4649 | previousSibling: function(selector) {\r | |
4650 | var o = this.ownerCt, it, idx, c;\r | |
4651 | if (o) {\r | |
4652 | it = o.items;\r | |
4653 | idx = it.indexOf(this);\r | |
4654 | if (idx !== -1) {\r | |
4655 | if (selector) {\r | |
4656 | for (--idx; idx >= 0; idx--) {\r | |
4657 | if ((c = it.getAt(idx)).is(selector)) {\r | |
4658 | return c;\r | |
4659 | }\r | |
4660 | }\r | |
4661 | } else {\r | |
4662 | if (idx) {\r | |
4663 | return it.getAt(--idx);\r | |
4664 | }\r | |
4665 | }\r | |
4666 | }\r | |
4667 | }\r | |
4668 | return null;\r | |
4669 | },\r | |
4670 | \r | |
4671 | /**\r | |
4672 | * Called by Component#doAutoRender\r | |
4673 | *\r | |
4674 | * Register a Container configured `floating: true` with this Component's {@link Ext.ZIndexManager ZIndexManager}.\r | |
4675 | *\r | |
4676 | * Components added in this way will not participate in any layout, but will be rendered\r | |
4677 | * upon first show in the way that {@link Ext.window.Window Window}s are.\r | |
4678 | */\r | |
4679 | registerFloatingItem: function(cmp) {\r | |
4680 | var me = this;\r | |
4681 | if (!me.floatingDescendants) {\r | |
4682 | me.floatingDescendants = new Ext.ZIndexManager(me);\r | |
4683 | }\r | |
4684 | me.floatingDescendants.register(cmp);\r | |
4685 | },\r | |
4686 | \r | |
4687 | /**\r | |
4688 | * Removes a CSS class from the top level element representing this component.\r | |
4689 | * @param {String/String[]} cls The CSS class name to remove.\r | |
4690 | * @return {Ext.Component} Returns the Component to allow method chaining.\r | |
4691 | */\r | |
4692 | removeCls: function(cls) {\r | |
4693 | var me = this,\r | |
4694 | el = me.rendered ? me.el : me.protoEl;\r | |
4695 | \r | |
4696 | el.removeCls.apply(el, arguments);\r | |
4697 | return me;\r | |
4698 | },\r | |
4699 | \r | |
4700 | /**\r | |
4701 | * Removes a `cls` to the `uiCls` array, which will also call {@link #removeUIClsFromElement} and removes it from all\r | |
4702 | * elements of this component.\r | |
4703 | * @param {String/String[]} cls A string or an array of strings to remove to the `uiCls`.\r | |
4704 | */\r | |
4705 | removeClsWithUI: function(classes, skip) {\r | |
4706 | var me = this,\r | |
4707 | clsArray = [],\r | |
4708 | i = 0,\r | |
4709 | extArray = Ext.Array,\r | |
4710 | remove = extArray.remove,\r | |
4711 | uiCls = me.uiCls = extArray.clone(me.uiCls),\r | |
4712 | activeUI = me.activeUI,\r | |
4713 | length, cls;\r | |
4714 | \r | |
4715 | if (typeof classes === "string") {\r | |
4716 | classes = (classes.indexOf(' ') < 0) ? [classes] : Ext.String.splitWords(classes);\r | |
4717 | }\r | |
4718 | \r | |
4719 | length = classes.length;\r | |
4720 | \r | |
4721 | for (i = 0; i < length; i++) {\r | |
4722 | cls = classes[i];\r | |
4723 | \r | |
4724 | if (cls && me.hasUICls(cls)) {\r | |
4725 | remove(uiCls, cls);\r | |
4726 | \r | |
4727 | //If there's no activeUI then there's nothing to remove\r | |
4728 | if (activeUI) {\r | |
4729 | clsArray = clsArray.concat(me.removeUIClsFromElement(cls));\r | |
4730 | }\r | |
4731 | }\r | |
4732 | }\r | |
4733 | \r | |
4734 | if (skip !== true && activeUI) {\r | |
4735 | me.removeCls(clsArray);\r | |
4736 | }\r | |
4737 | \r | |
4738 | return clsArray;\r | |
4739 | },\r | |
4740 | \r | |
4741 | resumeLayouts: function (flushOptions) {\r | |
4742 | var me = this;\r | |
4743 | if (!me.rendered) {\r | |
4744 | return;\r | |
4745 | }\r | |
4746 | //<debug>\r | |
4747 | if (!me.layoutSuspendCount) {\r | |
4748 | Ext.log.warn('Mismatched call to resumeLayouts - layouts are currently not suspended.');\r | |
4749 | }\r | |
4750 | //</debug>\r | |
4751 | if (me.layoutSuspendCount && !--me.layoutSuspendCount) {\r | |
4752 | me.suspendLayout = false;\r | |
4753 | if (flushOptions && !me.isLayoutSuspended()) {\r | |
4754 | me.updateLayout(flushOptions);\r | |
4755 | }\r | |
4756 | }\r | |
4757 | },\r | |
4758 | \r | |
4759 | /**\r | |
4760 | * Scrolls this Component by the passed delta values, optionally animating.\r | |
4761 | *\r | |
4762 | * All of the following are equivalent:\r | |
4763 | *\r | |
4764 | * comp.scrollBy(10, 10, true);\r | |
4765 | * comp.scrollBy([10, 10], true);\r | |
4766 | * comp.scrollBy({ x: 10, y: 10 }, true);\r | |
4767 | *\r | |
4768 | * @param {Number/Number[]/Object} deltaX Either the x delta, an Array specifying x and y deltas or\r | |
4769 | * an object with "x" and "y" properties.\r | |
4770 | * @param {Number/Boolean/Object} deltaY Either the y delta, or an animate flag or config object.\r | |
4771 | * @param {Boolean/Object} animate Animate flag/config object if the delta values were passed separately.\r | |
4772 | */\r | |
4773 | scrollBy: function(deltaX, deltaY, animate) {\r | |
4774 | var scroller = this.getScrollable();\r | |
4775 | \r | |
4776 | if (scroller) {\r | |
4777 | scroller.scrollBy(deltaX, deltaY, animate);\r | |
4778 | }\r | |
4779 | },\r | |
4780 | \r | |
4781 | /**\r | |
4782 | * Scrolls this component to the specified `x` and `y` coordinates. Only applicable\r | |
4783 | * for {@link #scrollable} components.\r | |
4784 | * @param {Number} x\r | |
4785 | * @param {Number} y\r | |
4786 | * @param {Boolean/Object} [animate] true for the default animation or a standard Element\r | |
4787 | * animation config object\r | |
4788 | */\r | |
4789 | scrollTo: function(x, y, animate) {\r | |
4790 | var scroller = this.getScrollable();\r | |
4791 | \r | |
4792 | if (scroller) {\r | |
4793 | scroller.scrollTo(x, y, animate);\r | |
4794 | }\r | |
4795 | },\r | |
4796 | \r | |
4797 | /**\r | |
4798 | * Sets the overflow on the content element of the component.\r | |
4799 | * @param {Boolean} scroll True to allow the Component to auto scroll.\r | |
4800 | * @return {Ext.Component} this\r | |
4801 | * @deprecated 5.0.0 Use {@link #setScrollable} instead\r | |
4802 | */\r | |
4803 | setAutoScroll: function(scroll) {\r | |
4804 | this.setScrollable(!!scroll);\r | |
4805 | return this;\r | |
4806 | },\r | |
4807 | \r | |
4808 | /**\r | |
4809 | *\r | |
4810 | * @param {String/Number} border The border, see {@link #border}. If a falsey value is passed\r | |
4811 | * the border will be removed.\r | |
4812 | */\r | |
4813 | setBorder: function(border, /* private */ targetEl) {\r | |
4814 | var me = this,\r | |
4815 | initial = !!targetEl;\r | |
4816 | \r | |
4817 | if (me.rendered || initial) {\r | |
4818 | if (!initial) {\r | |
4819 | targetEl = me.el;\r | |
4820 | }\r | |
4821 | \r | |
4822 | if (!border) {\r | |
4823 | border = 0;\r | |
4824 | } else if (border === true) {\r | |
4825 | border = '1px';\r | |
4826 | } else {\r | |
4827 | border = this.unitizeBox(border);\r | |
4828 | }\r | |
4829 | targetEl.setStyle('border-width', border);\r | |
4830 | if (!initial) {\r | |
4831 | me.updateLayout();\r | |
4832 | }\r | |
4833 | }\r | |
4834 | me.border = border;\r | |
4835 | },\r | |
4836 | \r | |
4837 | /**\r | |
4838 | * Sets the dock position of this component in its parent panel. Note that this only has effect if this item is part\r | |
4839 | * of the `dockedItems` collection of a parent that has a DockLayout (note that any Panel has a DockLayout by default)\r | |
4840 | * @param {Object} dock The dock position.\r | |
4841 | * @return {Ext.Component} this\r | |
4842 | */\r | |
4843 | setDock: function(dock) {\r | |
4844 | var me = this,\r | |
4845 | ownerCt = me.ownerCt;\r | |
4846 | \r | |
4847 | if (dock !== me.dock) {\r | |
4848 | if (ownerCt && ownerCt.moveDocked) {\r | |
4849 | ownerCt.moveDocked(me, dock);\r | |
4850 | } else {\r | |
4851 | me.dock = dock;\r | |
4852 | }\r | |
4853 | }\r | |
4854 | \r | |
4855 | return me;\r | |
4856 | },\r | |
4857 | \r | |
4858 | /**\r | |
4859 | * Enable or disable the component.\r | |
4860 | * @param {Boolean} disabled `true` to disable.\r | |
4861 | */\r | |
4862 | setDisabled: function(disabled) {\r | |
4863 | return this[disabled ? 'disable': 'enable']();\r | |
4864 | },\r | |
4865 | \r | |
4866 | /**\r | |
4867 | * Sets the flex property of this component. Only applicable when this component is\r | |
4868 | * an item of a box layout\r | |
4869 | * @private\r | |
4870 | * @param {Number} flex\r | |
4871 | */\r | |
4872 | setFlex: function(flex) {\r | |
4873 | this.flex = flex;\r | |
4874 | },\r | |
4875 | \r | |
4876 | /**\r | |
4877 | * Sets the height of the component. This method fires the {@link #resize} event.\r | |
4878 | *\r | |
4879 | * @param {Number} height The new height to set. This may be one of:\r | |
4880 | *\r | |
4881 | * - A Number specifying the new height in pixels.\r | |
4882 | * - A String used to set the CSS height style.\r | |
4883 | * - `undefined` to leave the height unchanged.\r | |
4884 | * - `null` to clear the height.\r | |
4885 | *\r | |
4886 | * @return {Ext.Component} this\r | |
4887 | */\r | |
4888 | setHeight: function(height) {\r | |
4889 | return this.setSize(undefined, height);\r | |
4890 | },\r | |
4891 | \r | |
4892 | /**\r | |
4893 | * This method allows you to show or hide a LoadMask on top of this component.\r | |
4894 | *\r | |
4895 | * The mask will be rendered into the element returned by {@link #getMaskTarget} which for most Components is the Component's\r | |
4896 | * element. See {@link #getMaskTarget} and {@link #maskElement}.\r | |
4897 | *\r | |
4898 | * Most Components will return `null` indicating that their LoadMask cannot reside inside their element, but must\r | |
4899 | * be rendered into the document body.\r | |
4900 | *\r | |
4901 | * {@link Ext.view.Table Grid Views} however will direct a LoadMask to be rendered into the owning {@link Ext.panel.Table GridPanel}.\r | |
4902 | *\r | |
4903 | * @param {Boolean/Object/String} load True to show the default LoadMask, a config object that will be passed to the\r | |
4904 | * LoadMask constructor, or a message String to show. False to hide the current LoadMask.\r | |
4905 | * @return {Ext.LoadMask} The LoadMask instance that has just been shown.\r | |
4906 | */\r | |
4907 | setLoading: function(load, /*deprecated */ targetEl) {\r | |
4908 | var me = this,\r | |
4909 | config = {\r | |
4910 | target: me\r | |
4911 | };\r | |
4912 | \r | |
4913 | if (me.rendered) {\r | |
4914 | // Shows mask for anything but false.\r | |
4915 | if (load !== false) {\r | |
4916 | if (Ext.isString(load)) {\r | |
4917 | config.msg = load;\r | |
4918 | } else {\r | |
4919 | Ext.apply(config, load);\r | |
4920 | }\r | |
4921 | // We do not already have a LoadMask: create one\r | |
4922 | if (!me.loadMask || !me.loadMask.isLoadMask) {\r | |
4923 | // Deprecated second parameter.\r | |
4924 | // maskElement config replaces this\r | |
4925 | if (targetEl && config.useTargetEl == null) {\r | |
4926 | config.useTargetEl = true;\r | |
4927 | }\r | |
4928 | me.loadMask = new Ext.LoadMask(config);\r | |
4929 | }\r | |
4930 | // Change any settings according to load config\r | |
4931 | else {\r | |
4932 | Ext.apply(me.loadMask, config);\r | |
4933 | }\r | |
4934 | // If already visible, just update display with passed configs.\r | |
4935 | if (me.loadMask.isVisible()) {\r | |
4936 | me.loadMask.syncMaskState();\r | |
4937 | }\r | |
4938 | // Otherwise show with new configs\r | |
4939 | else {\r | |
4940 | me.loadMask.show();\r | |
4941 | }\r | |
4942 | }\r | |
4943 | // load == falsy: Hide the mask if it exists\r | |
4944 | else {\r | |
4945 | if (me.loadMask && me.loadMask.isLoadMask) {\r | |
4946 | me.loadMask.hide();\r | |
4947 | }\r | |
4948 | }\r | |
4949 | }\r | |
4950 | return me.loadMask;\r | |
4951 | },\r | |
4952 | \r | |
4953 | /**\r | |
4954 | * Sets the margin on the target element.\r | |
4955 | * @param {Number/String} margin The margin to set. See the {@link #margin} config.\r | |
4956 | */\r | |
4957 | setMargin: function(margin, /* private */ preventLayout) {\r | |
4958 | var me = this;\r | |
4959 | \r | |
4960 | if (me.rendered) {\r | |
4961 | if (!margin && margin !== 0) {\r | |
4962 | margin = '';\r | |
4963 | } else {\r | |
4964 | if (margin === true) {\r | |
4965 | margin = 5;\r | |
4966 | }\r | |
4967 | margin = this.unitizeBox(margin);\r | |
4968 | }\r | |
4969 | me.margin = margin;\r | |
4970 | // See: EXTJS-13359\r | |
4971 | me.margin$ = null;\r | |
4972 | me.getEl().setStyle('margin', margin);\r | |
4973 | if (!preventLayout) {\r | |
4974 | // Changing the margins can impact the position of this (and possibly) \r | |
4975 | // other subsequent components in the layout.\r | |
4976 | me.updateLayout(me._notAsLayoutRoot);\r | |
4977 | }\r | |
4978 | } else {\r | |
4979 | me.margin = margin;\r | |
4980 | }\r | |
4981 | },\r | |
4982 | \r | |
4983 | /**\r | |
4984 | * Sets the overflow x/y on the content element of the component. The x/y overflow\r | |
4985 | * values can be any valid CSS overflow (e.g., 'auto' or 'scroll'). By default, the\r | |
4986 | * value is 'hidden'. Passing `undefined` will preserve the current value.\r | |
4987 | *\r | |
4988 | * @param {String} overflowX The overflow-x value.\r | |
4989 | * @param {String} overflowY The overflow-y value.\r | |
4990 | * @return {Ext.Component} this\r | |
4991 | * @deprecated 5.0.0 Use {@link #setScrollable} instead\r | |
4992 | */\r | |
4993 | setOverflowXY: function(overflowX, overflowY) {\r | |
4994 | this.setScrollable({\r | |
4995 | x: (overflowX && overflowX !== 'hidden') ? overflowX : false,\r | |
4996 | y: (overflowY && overflowY !== 'hidden') ? overflowY : false\r | |
4997 | });\r | |
4998 | \r | |
4999 | return this;\r | |
5000 | },\r | |
5001 | \r | |
5002 | /**\r | |
5003 | * Sets the page XY position of the component. To set the left and top instead, use {@link #setPosition}.\r | |
5004 | * This method fires the {@link #event-move} event.\r | |
5005 | * @param {Number/Number[]} x The new x position or an array of `[x,y]`.\r | |
5006 | * @param {Number} [y] The new y position.\r | |
5007 | * @param {Boolean/Object} [animate] True to animate the Component into its new position. You may also pass an\r | |
5008 | * animation configuration.\r | |
5009 | * @return {Ext.Component} this\r | |
5010 | */\r | |
5011 | setPagePosition: function(x, y, animate) {\r | |
5012 | var me = this,\r | |
5013 | p,\r | |
5014 | floatParentBox;\r | |
5015 | \r | |
5016 | if (Ext.isArray(x)) {\r | |
5017 | y = x[1];\r | |
5018 | x = x[0];\r | |
5019 | }\r | |
5020 | me.pageX = x;\r | |
5021 | me.pageY = y;\r | |
5022 | \r | |
5023 | if (me.floating) {\r | |
5024 | \r | |
5025 | // Floating Components which are registered with a Container have to have their x and y properties made relative\r | |
5026 | if (me.isContainedFloater()) {\r | |
5027 | floatParentBox = me.floatParent.getTargetEl().getViewRegion();\r | |
5028 | if (Ext.isNumber(x) && Ext.isNumber(floatParentBox.left)) {\r | |
5029 | x -= floatParentBox.left;\r | |
5030 | }\r | |
5031 | if (Ext.isNumber(y) && Ext.isNumber(floatParentBox.top)) {\r | |
5032 | y -= floatParentBox.top;\r | |
5033 | }\r | |
5034 | } else {\r | |
5035 | p = me.el.translateXY(x, y);\r | |
5036 | x = p.x;\r | |
5037 | y = p.y;\r | |
5038 | }\r | |
5039 | \r | |
5040 | me.setPosition(x, y, animate);\r | |
5041 | } else {\r | |
5042 | p = me.el.translateXY(x, y);\r | |
5043 | me.setPosition(p.x, p.y, animate);\r | |
5044 | }\r | |
5045 | \r | |
5046 | return me;\r | |
5047 | },\r | |
5048 | \r | |
5049 | /**\r | |
5050 | * @member Ext.Component\r | |
5051 | * Sets the left and top of the component. To set the page XY position instead, use {@link Ext.Component#setPagePosition setPagePosition}. This\r | |
5052 | * method fires the {@link #event-move} event.\r | |
5053 | * @param {Number/Number[]/Object} x The new left, an array of `[x,y]`, or animation config object containing `x` and `y` properties.\r | |
5054 | * @param {Number} [y] The new top.\r | |
5055 | * @param {Boolean/Object} [animate] If `true`, the Component is _animated_ into its new position. You may also pass an\r | |
5056 | * animation configuration.\r | |
5057 | * @return {Ext.Component} this\r | |
5058 | */\r | |
5059 | setPosition: function(x, y, animate) {\r | |
5060 | var me = this,\r | |
5061 | pos = me.beforeSetPosition.apply(me, arguments);\r | |
5062 | \r | |
5063 | if (pos && me.rendered) {\r | |
5064 | x = pos.x;\r | |
5065 | y = pos.y;\r | |
5066 | \r | |
5067 | if (animate) {\r | |
5068 | // Proceed only if the new position is different from the current\r | |
5069 | // one. We only do these DOM reads in the animate case as we don't\r | |
5070 | // want to incur the penalty of read/write on every call to setPosition\r | |
5071 | if (x !== me.getLocalX() || y !== me.getLocalY()) {\r | |
5072 | me.stopAnimation();\r | |
5073 | me.animate(Ext.apply({\r | |
5074 | duration: 1000,\r | |
5075 | listeners: {\r | |
5076 | afteranimate: Ext.Function.bind(me.afterSetPosition, me, [x, y])\r | |
5077 | },\r | |
5078 | to: {\r | |
5079 | // Use local coordinates for a component\r | |
5080 | // We don't need to normalize this for RTL, the anim.target.Component\r | |
5081 | // calls setPosition, which will normalize the x value to right when\r | |
5082 | // it's necessary\r | |
5083 | left: x,\r | |
5084 | top: y\r | |
5085 | }\r | |
5086 | }, animate));\r | |
5087 | }\r | |
5088 | } else {\r | |
5089 | me.setLocalXY(x, y);\r | |
5090 | me.afterSetPosition(x, y);\r | |
5091 | }\r | |
5092 | }\r | |
5093 | return me;\r | |
5094 | },\r | |
5095 | \r | |
5096 | /**\r | |
5097 | * Sets the "x" scroll position for this component. Only applicable for\r | |
5098 | * {@link #scrollable} components\r | |
5099 | * @param {Number} x\r | |
5100 | * @param {Boolean/Object} [animate] true for the default animation or a standard Element\r | |
5101 | * animation config object\r | |
5102 | */\r | |
5103 | setScrollX: function(x, animate) {\r | |
5104 | var scroller = this.getScrollable();\r | |
5105 | \r | |
5106 | if (scroller) {\r | |
5107 | scroller.scrollTo(x, null, animate);\r | |
5108 | }\r | |
5109 | },\r | |
5110 | \r | |
5111 | /**\r | |
5112 | * Sets the "y" scroll position for this component. Only applicable for\r | |
5113 | * {@link #scrollable} components\r | |
5114 | * @param {Number} y\r | |
5115 | * @param {Boolean/Object} [animate] true for the default animation or a standard Element\r | |
5116 | * animation config object\r | |
5117 | */\r | |
5118 | setScrollY: function(y, animate) {\r | |
5119 | var scroller = this.getScrollable();\r | |
5120 | \r | |
5121 | if (scroller) {\r | |
5122 | scroller.scrollTo(null, y, animate);\r | |
5123 | }\r | |
5124 | },\r | |
5125 | \r | |
5126 | /**\r | |
5127 | * Sets the width and height of this Component. This method fires the {@link #resize} event. This method can accept\r | |
5128 | * either width and height as separate arguments, or you can pass a size object like `{width:10, height:20}`.\r | |
5129 | *\r | |
5130 | * @param {Number/String/Object} width The new width to set. This may be one of:\r | |
5131 | *\r | |
5132 | * - A Number specifying the new width in pixels.\r | |
5133 | * - A String used to set the CSS width style.\r | |
5134 | * - A size object in the format `{width: widthValue, height: heightValue}`.\r | |
5135 | * - `undefined` to leave the width unchanged.\r | |
5136 | *\r | |
5137 | * @param {Number/String} height The new height to set (not required if a size object is passed as the first arg).\r | |
5138 | * This may be one of:\r | |
5139 | *\r | |
5140 | * - A Number specifying the new height in pixels.\r | |
5141 | * - A String used to set the CSS height style. Animation may **not** be used.\r | |
5142 | * - `undefined` to leave the height unchanged.\r | |
5143 | *\r | |
5144 | * @return {Ext.Component} this\r | |
5145 | */\r | |
5146 | setSize: function(width, height) {\r | |
5147 | var me = this,\r | |
5148 | oldWidth = me.width,\r | |
5149 | oldHeight = me.height,\r | |
5150 | widthIsString, heightIsString;\r | |
5151 | \r | |
5152 | // support for standard size objects\r | |
5153 | if (width && typeof width === 'object') {\r | |
5154 | height = width.height;\r | |
5155 | width = width.width;\r | |
5156 | }\r | |
5157 | \r | |
5158 | // Constrain within configured maximum\r | |
5159 | if (typeof width === 'number') {\r | |
5160 | me.width = Ext.Number.constrain(width, me.minWidth, me.maxWidth);\r | |
5161 | } else if (width === null) {\r | |
5162 | delete me.width;\r | |
5163 | } else if(typeof width === 'string') {\r | |
5164 | // handle width specified as a string css style\r | |
5165 | widthIsString = true;\r | |
5166 | me.width = width;\r | |
5167 | }\r | |
5168 | \r | |
5169 | if (typeof height === 'number') {\r | |
5170 | me.height = Ext.Number.constrain(height, me.minHeight, me.maxHeight);\r | |
5171 | } else if (height === null) {\r | |
5172 | delete me.height;\r | |
5173 | } else if(typeof height === 'string') {\r | |
5174 | // handle width specified as a string css style\r | |
5175 | heightIsString = true;\r | |
5176 | me.height = height;\r | |
5177 | }\r | |
5178 | \r | |
5179 | // If not rendered, all we need to is set the properties.\r | |
5180 | // The initial layout will set the size\r | |
5181 | if (me.rendered && me.isVisible()) {\r | |
5182 | if (oldWidth !== me.width || oldHeight !== me.height) {\r | |
5183 | if (me.liquidLayout || widthIsString || heightIsString) {\r | |
5184 | // if we have a liquid layout we must setSize now, since the following\r | |
5185 | // updateLayout call will not set our size in the dom if we successfully\r | |
5186 | // opt out of the layout run\r | |
5187 | me.el.setSize(me.width, me.height);\r | |
5188 | }\r | |
5189 | \r | |
5190 | // If we are changing size, then we are not the root.\r | |
5191 | me.updateLayout(me._notAsLayoutRoot);\r | |
5192 | }\r | |
5193 | }\r | |
5194 | \r | |
5195 | return me;\r | |
5196 | },\r | |
5197 | \r | |
5198 | /**\r | |
5199 | * Sets the style for this Component's primary element.\r | |
5200 | * \r | |
5201 | * Styles should be a valid DOM element style property. \r | |
5202 | * [Valid style property names](http://www.w3schools.com/jsref/dom_obj_style.asp) \r | |
5203 | * (_along with the supported CSS version for each_)\r | |
5204 | * \r | |
5205 | * var name = Ext.create({\r | |
5206 | * xtype: 'component',\r | |
5207 | * renderTo: Ext.getBody(),\r | |
5208 | * html: 'Phineas Flynn'\r | |
5209 | * });\r | |
5210 | * \r | |
5211 | * // two-param syntax\r | |
5212 | * name.setStyle('color', 'white');\r | |
5213 | * \r | |
5214 | * // single-param syntax\r | |
5215 | * name.setStyle({\r | |
5216 | * fontWeight: 'bold',\r | |
5217 | * backgroundColor: 'gray',\r | |
5218 | * padding: '10px'\r | |
5219 | * });\r | |
5220 | * \r | |
5221 | * @param {String/Object} property The style property to be set, or an object of\r | |
5222 | * multiple styles.\r | |
5223 | * @param {String} [value] The value to apply to the given property, or null if an\r | |
5224 | * object was passed.\r | |
5225 | * @return {Ext.Component} this\r | |
5226 | */\r | |
5227 | setStyle: function (prop, value) {\r | |
5228 | var el = this.el || this.protoEl;\r | |
5229 | el.setStyle(prop, value);\r | |
5230 | return this;\r | |
5231 | },\r | |
5232 | \r | |
5233 | /**\r | |
5234 | * Sets the UI for the component. This will remove any existing UIs on the component. It will also loop through any\r | |
5235 | * `uiCls` set on the component and rename them so they include the new UI.\r | |
5236 | * @param {String} ui The new UI for the component.\r | |
5237 | */\r | |
5238 | setUI: function(ui) {\r | |
5239 | var me = this,\r | |
5240 | uiCls = me.uiCls,\r | |
5241 | activeUI = me.activeUI,\r | |
5242 | classes;\r | |
5243 | \r | |
5244 | if (ui === activeUI) {\r | |
5245 | // The ui hasn't changed\r | |
5246 | return;\r | |
5247 | }\r | |
5248 | \r | |
5249 | // activeUI will only be set if setUI has been called before. If it hasn't there's no need to remove anything\r | |
5250 | if (activeUI) {\r | |
5251 | classes = me.removeClsWithUI(uiCls, true);\r | |
5252 | \r | |
5253 | if (classes.length) {\r | |
5254 | me.removeCls(classes);\r | |
5255 | }\r | |
5256 | \r | |
5257 | // Remove the UI from the element\r | |
5258 | me.removeUIFromElement();\r | |
5259 | }\r | |
5260 | else {\r | |
5261 | // We need uiCls to be empty otherwise our call to addClsWithUI won't do anything\r | |
5262 | me.uiCls = [];\r | |
5263 | }\r | |
5264 | \r | |
5265 | // Set the UI\r | |
5266 | me.ui = ui;\r | |
5267 | \r | |
5268 | // After the first call to setUI the values ui and activeUI should track each other but initially we need some\r | |
5269 | // way to tell whether the ui has really been set.\r | |
5270 | me.activeUI = ui;\r | |
5271 | \r | |
5272 | // Add the new UI to the element\r | |
5273 | me.addUIToElement();\r | |
5274 | \r | |
5275 | classes = me.addClsWithUI(uiCls, true);\r | |
5276 | \r | |
5277 | if (classes.length) {\r | |
5278 | me.addCls(classes);\r | |
5279 | }\r | |
5280 | \r | |
5281 | // Changing the ui can lead to significant changes to a component's appearance, so the layout needs to be\r | |
5282 | // updated. Internally most calls to setUI are pre-render. Buttons are a notable exception as setScale changes\r | |
5283 | // the ui and often requires the layout to be updated.\r | |
5284 | if (me.rendered) {\r | |
5285 | me.updateLayout();\r | |
5286 | }\r | |
5287 | },\r | |
5288 | \r | |
5289 | /**\r | |
5290 | * Convenience function to hide or show this component by Boolean.\r | |
5291 | * @param {Boolean} visible `true` to show, `false` to hide.\r | |
5292 | * @return {Ext.Component} this\r | |
5293 | * @since 1.1.0\r | |
5294 | */\r | |
5295 | setVisible: function(visible) {\r | |
5296 | return this[visible ? 'show': 'hide']();\r | |
5297 | },\r | |
5298 | \r | |
5299 | /**\r | |
5300 | * Sets the hidden state of this component. This is basically the same as\r | |
5301 | * `{@link #setVisible}` but the boolean parameter has the opposite meaning.\r | |
5302 | * @param {Boolean} hidden\r | |
5303 | * @return {Ext.Component}\r | |
5304 | */\r | |
5305 | setHidden: function(hidden) {\r | |
5306 | return this.setVisible(!hidden);\r | |
5307 | },\r | |
5308 | \r | |
5309 | /**\r | |
5310 | * Sets the width of the component. This method fires the {@link #resize} event.\r | |
5311 | *\r | |
5312 | * @param {Number} width The new width to set. This may be one of:\r | |
5313 | *\r | |
5314 | * - A Number specifying the new width in pixels.\r | |
5315 | * - A String used to set the CSS width style.\r | |
5316 | * - `undefined` to leave the width unchanged.\r | |
5317 | * - `null` to clear the width.\r | |
5318 | *\r | |
5319 | * @return {Ext.Component} this\r | |
5320 | */\r | |
5321 | setWidth: function(width) {\r | |
5322 | return this.setSize(width);\r | |
5323 | },\r | |
5324 | \r | |
5325 | /**\r | |
5326 | * Shows this Component, rendering it first if {@link #autoRender} or {@link #cfg-floating} are `true`.\r | |
5327 | *\r | |
5328 | * After being shown, a {@link #cfg-floating} Component (such as a {@link Ext.window.Window}), is activated it and\r | |
5329 | * brought to the front of its {@link #zIndexManager z-index stack}.\r | |
5330 | *\r | |
5331 | * @param {String/Ext.dom.Element} [animateTarget=null] **only valid for {@link #cfg-floating} Components such as {@link\r | |
5332 | * Ext.window.Window Window}s or {@link Ext.tip.ToolTip ToolTip}s, or regular Components which have been configured\r | |
5333 | * with `floating: true`.** The target from which the Component should animate from while opening.\r | |
5334 | * @param {Function} [callback] A callback function to call after the Component is displayed.\r | |
5335 | * Only necessary if animation was specified.\r | |
5336 | * @param {Object} [scope] The scope (`this` reference) in which the callback is executed.\r | |
5337 | * Defaults to this Component.\r | |
5338 | * @return {Ext.Component} this\r | |
5339 | */\r | |
5340 | show: function(animateTarget, cb, scope) {\r | |
5341 | var me = this,\r | |
5342 | rendered = me.rendered;\r | |
5343 | \r | |
5344 | if (me.hierarchicallyHidden || (me.floating && !rendered && me.isHierarchicallyHidden())) {\r | |
5345 | // If this is a hierarchically hidden floating component, we need to stash\r | |
5346 | // the arguments to this call so that the call can be deferred until the next\r | |
5347 | // time syncHidden() is called.\r | |
5348 | if (!rendered) {\r | |
5349 | // If the component has not yet been rendered it requires special treatment.\r | |
5350 | // Normally, for rendered components we can just set the pendingShow property\r | |
5351 | // and syncHidden() listens to events in the hierarchyEventSource and calls\r | |
5352 | // show() when this component becomes hierarchically visible. However,\r | |
5353 | // if the component has not yet been rendered the hierarchy event listeners\r | |
5354 | // have not yet been attached (since Floating is initialized during the\r | |
5355 | // render phase. This means we have to initialize the hierarchy event\r | |
5356 | // listeners right now to ensure that the component will show itself when\r | |
5357 | // it becomes hierarchically visible.\r | |
5358 | me.initHierarchyEvents();\r | |
5359 | }\r | |
5360 | // defer the show call until next syncHidden(), but ignore animateTarget.\r | |
5361 | if (arguments.length > 1) {\r | |
5362 | arguments[0] = null; // jshint ignore:line\r | |
5363 | me.pendingShow = arguments;\r | |
5364 | } else {\r | |
5365 | me.pendingShow = true;\r | |
5366 | }\r | |
5367 | } else if (rendered && me.isVisible()) {\r | |
5368 | if (me.floating) {\r | |
5369 | me.onFloatShow();\r | |
5370 | }\r | |
5371 | } else {\r | |
5372 | if (me.fireEvent('beforeshow', me) !== false) {\r | |
5373 | me.hidden = false;\r | |
5374 | delete this.getInherited().hidden;\r | |
5375 | // Render on first show if there is an autoRender config, or if this\r | |
5376 | // is a floater (Window, Menu, BoundList etc).\r | |
5377 | \r | |
5378 | // We suspend layouts here because floaters/autoRenders\r | |
5379 | // will layout when onShow is called. If the render succeeded,\r | |
5380 | // the layout will be trigger inside onShow, so we don't flush\r | |
5381 | // in the first block. If, for some reason we couldn't render, then\r | |
5382 | // we resume layouts and force a flush because we don't know if something\r | |
5383 | // will force it.\r | |
5384 | Ext.suspendLayouts();\r | |
5385 | if (!rendered && (me.autoRender || me.floating)) {\r | |
5386 | me.doAutoRender();\r | |
5387 | rendered = me.rendered;\r | |
5388 | }\r | |
5389 | \r | |
5390 | if (rendered) {\r | |
5391 | me.beforeShow();\r | |
5392 | Ext.resumeLayouts();\r | |
5393 | me.onShow.apply(me, arguments);\r | |
5394 | me.afterShow.apply(me, arguments);\r | |
5395 | } else {\r | |
5396 | Ext.resumeLayouts(true);\r | |
5397 | }\r | |
5398 | } else {\r | |
5399 | me.onShowVeto();\r | |
5400 | }\r | |
5401 | }\r | |
5402 | return me;\r | |
5403 | },\r | |
5404 | \r | |
5405 | /**\r | |
5406 | * Displays component at specific xy position.\r | |
5407 | * A floating component (like a menu) is positioned relative to its ownerCt if any.\r | |
5408 | * Useful for popping up a context menu:\r | |
5409 | *\r | |
5410 | * listeners: {\r | |
5411 | * itemcontextmenu: function(view, record, item, index, event, options) {\r | |
5412 | * Ext.create('Ext.menu.Menu', {\r | |
5413 | * width: 100,\r | |
5414 | * height: 100,\r | |
5415 | * margin: '0 0 10 0',\r | |
5416 | * items: [{\r | |
5417 | * text: 'regular item 1'\r | |
5418 | * },{\r | |
5419 | * text: 'regular item 2'\r | |
5420 | * },{\r | |
5421 | * text: 'regular item 3'\r | |
5422 | * }]\r | |
5423 | * }).showAt(event.getXY());\r | |
5424 | * }\r | |
5425 | * }\r | |
5426 | *\r | |
5427 | * @param {Number/Number[]} x The new x position or array of `[x,y]`.\r | |
5428 | * @param {Number} [y] The new y position\r | |
5429 | * @param {Boolean/Object} [animate] True to animate the Component into its new position. You may also pass an\r | |
5430 | * animation configuration.\r | |
5431 | * @return {Ext.Component} this\r | |
5432 | */\r | |
5433 | showAt: function(x, y, animate) {\r | |
5434 | var me = this;\r | |
5435 | \r | |
5436 | // Not rendered, then animating to a position is meaningless,\r | |
5437 | // just set the x,y position and allow show's processing to work.\r | |
5438 | if (!me.rendered && (me.autoRender || me.floating)) {\r | |
5439 | me.x = x;\r | |
5440 | me.y = y;\r | |
5441 | return me.show();\r | |
5442 | }\r | |
5443 | if (me.floating) {\r | |
5444 | me.setPosition(x, y, animate);\r | |
5445 | } else {\r | |
5446 | me.setPagePosition(x, y, animate);\r | |
5447 | }\r | |
5448 | return me.show();\r | |
5449 | },\r | |
5450 | \r | |
5451 | /**\r | |
5452 | * Shows this component by the specified {@link Ext.Component Component} or {@link Ext.dom.Element Element}.\r | |
5453 | * Used when this component is {@link #cfg-floating}.\r | |
5454 | * @param {Ext.Component/Ext.dom.Element} component The {@link Ext.Component} or {@link Ext.dom.Element} to show the component by.\r | |
5455 | * @param {String} [position] Alignment position as used by {@link Ext.util.Positionable#getAlignToXY}.\r | |
5456 | * Defaults to `{@link #defaultAlign}`. See {@link #alignTo} for possible values.\r | |
5457 | * @param {Number[]} [offsets] Alignment offsets as used by {@link Ext.util.Positionable#getAlignToXY}. See {@link #alignTo} for possible values.\r | |
5458 | * @return {Ext.Component} this\r | |
5459 | */\r | |
5460 | showBy: function(cmp, pos, off) {\r | |
5461 | var me = this;\r | |
5462 | \r | |
5463 | //<debug>\r | |
5464 | if (!me.floating) {\r | |
5465 | Ext.log.warn('Using showBy on a non-floating component');\r | |
5466 | }\r | |
5467 | //</debug>\r | |
5468 | \r | |
5469 | if (me.floating && cmp) {\r | |
5470 | me.alignTarget = cmp;\r | |
5471 | \r | |
5472 | if (pos) {\r | |
5473 | me.defaultAlign = pos;\r | |
5474 | }\r | |
5475 | \r | |
5476 | if (off) {\r | |
5477 | me.alignOffset = off;\r | |
5478 | }\r | |
5479 | \r | |
5480 | me.show();\r | |
5481 | \r | |
5482 | // Could have been vetoed.\r | |
5483 | if (!me.hidden) {\r | |
5484 | me.alignTo(cmp, pos || me.defaultAlign, off || me.alignOffset);\r | |
5485 | }\r | |
5486 | }\r | |
5487 | \r | |
5488 | return me;\r | |
5489 | },\r | |
5490 | \r | |
5491 | suspendLayouts: function () {\r | |
5492 | var me = this;\r | |
5493 | if (!me.rendered) {\r | |
5494 | return;\r | |
5495 | }\r | |
5496 | if (++me.layoutSuspendCount === 1) {\r | |
5497 | me.suspendLayout = true;\r | |
5498 | }\r | |
5499 | },\r | |
5500 | \r | |
5501 | unitizeBox: function(box) {\r | |
5502 | return Ext.Element.unitizeBox(box); \r | |
5503 | },\r | |
5504 | \r | |
5505 | /**\r | |
5506 | * Removes the mask applied by {@link #mask}\r | |
5507 | */\r | |
5508 | unmask: function() {\r | |
5509 | (this.getMaskTarget() || this.el).unmask();\r | |
5510 | \r | |
5511 | this.setMasked(false);\r | |
5512 | },\r | |
5513 | \r | |
5514 | unregisterFloatingItem: function(cmp) {\r | |
5515 | var me = this;\r | |
5516 | if (me.floatingDescendants) {\r | |
5517 | me.floatingDescendants.unregister(cmp);\r | |
5518 | }\r | |
5519 | },\r | |
5520 | \r | |
5521 | /**\r | |
5522 | * Navigates up the ownership hierarchy searching for an ancestor Container which matches any passed selector or component.\r | |
5523 | *\r | |
5524 | * *Important.* There is not a universal upwards navigation pointer. There are several upwards relationships\r | |
5525 | * such as the {@link Ext.button.Button button} which activates a {@link Ext.button.Button#cfg-menu menu}, or the\r | |
5526 | * {@link Ext.menu.Item menu item} which activated a {@link Ext.menu.Item#cfg-menu submenu}, or the\r | |
5527 | * {@link Ext.grid.column.Column column header} which activated the column menu.\r | |
5528 | *\r | |
5529 | * These differences are abstracted away by this method.\r | |
5530 | *\r | |
5531 | * Example:\r | |
5532 | *\r | |
5533 | * var owningTabPanel = grid.up('tabpanel');\r | |
5534 | *\r | |
5535 | * @param {String/Ext.Component} [selector] The selector component or actual component to test. If not passed the immediate owner/activator is returned.\r | |
5536 | * @param {String/Number/Ext.Component} [limit] This may be a selector upon which to stop the upward scan, or a limit of the number of steps, or Component reference to stop on.\r | |
5537 | * @return {Ext.container.Container} The matching ancestor Container (or `undefined` if no match was found).\r | |
5538 | */\r | |
5539 | up: function (selector, limit) {\r | |
5540 | var result = this.getRefOwner(),\r | |
5541 | limitSelector = typeof limit === 'string',\r | |
5542 | limitCount = typeof limit === 'number',\r | |
5543 | limitComponent = limit && limit.isComponent,\r | |
5544 | steps = 0;\r | |
5545 | \r | |
5546 | if (selector) {\r | |
5547 | for (; result; result = result.getRefOwner()) {\r | |
5548 | steps++;\r | |
5549 | if (selector.isComponent) {\r | |
5550 | if (result === selector) {\r | |
5551 | return result;\r | |
5552 | }\r | |
5553 | } else {\r | |
5554 | if (Ext.ComponentQuery.is(result, selector)) {\r | |
5555 | return result;\r | |
5556 | }\r | |
5557 | }\r | |
5558 | \r | |
5559 | // Stop when we hit the limit selector\r | |
5560 | if (limitSelector && result.is(limit)) {\r | |
5561 | return;\r | |
5562 | }\r | |
5563 | if (limitCount && steps === limit) {\r | |
5564 | return;\r | |
5565 | }\r | |
5566 | if (limitComponent && result === limit) {\r | |
5567 | return;\r | |
5568 | }\r | |
5569 | }\r | |
5570 | }\r | |
5571 | return result;\r | |
5572 | },\r | |
5573 | \r | |
5574 | /**\r | |
5575 | * Update the content area of a component.\r | |
5576 | * @param {String/Object} htmlOrData If this component has been configured with a\r | |
5577 | * template via the tpl config then it will use this argument as data to populate the\r | |
5578 | * template. If this component was not configured with a template, the components\r | |
5579 | * content area will be updated via Ext.Element update.\r | |
5580 | * @param {Boolean} [loadScripts=false] Only legitimate when using the `html`\r | |
5581 | * configuration. Causes embedded script tags to be executed. Inline source will be executed\r | |
5582 | * with this Component as the scope (`this` reference).\r | |
5583 | * @param {Function} [callback] Only legitimate when using the `html` configuration.\r | |
5584 | * Callback to execute when scripts have finished loading.\r | |
5585 | * @param {Object} [scriptScope=`this`] The scope (`this` reference) in which to\r | |
5586 | * execute *inline* script elements content. Scripts with a `src` attribute cannot\r | |
5587 | * be executed with this scope.\r | |
5588 | *\r | |
5589 | * @since 3.4.0\r | |
5590 | */\r | |
5591 | update: function(htmlOrData, loadScripts, callback, scriptScope) {\r | |
5592 | var me = this,\r | |
5593 | isData = (me.tpl && !Ext.isString(htmlOrData)),\r | |
5594 | scroller = me.getScrollable(),\r | |
5595 | container = me.focusableContainer,\r | |
5596 | sizeModel, doLayout, el;\r | |
5597 | \r | |
5598 | \r | |
5599 | if (isData) {\r | |
5600 | me.data = (htmlOrData && htmlOrData.isEntity) ? htmlOrData.getData(true) : htmlOrData;\r | |
5601 | } else {\r | |
5602 | me.html = Ext.isObject(htmlOrData) ? Ext.DomHelper.markup(htmlOrData) : htmlOrData;\r | |
5603 | }\r | |
5604 | \r | |
5605 | if (me.rendered) {\r | |
5606 | sizeModel = me.getSizeModel();\r | |
5607 | doLayout = sizeModel.width.shrinkWrap || sizeModel.height.shrinkWrap;\r | |
5608 | \r | |
5609 | if (me.isContainer) {\r | |
5610 | el = me.layout.getRenderTarget();\r | |
5611 | \r | |
5612 | // If we are a non-empty container being updated with raw content we have to lay out\r | |
5613 | doLayout = doLayout || me.items.items.length > 0;\r | |
5614 | } else {\r | |
5615 | el = me.touchScroll ? me.getScrollerEl() : me.getTargetEl();\r | |
5616 | }\r | |
5617 | if (isData) {\r | |
5618 | me.tpl[me.tplWriteMode](el, me.data || {});\r | |
5619 | } else {\r | |
5620 | el.setHtml(me.html, loadScripts, callback, scriptScope || me);\r | |
5621 | }\r | |
5622 | \r | |
5623 | if (doLayout) {\r | |
5624 | me.updateLayout();\r | |
5625 | }\r | |
5626 | if (scroller) {\r | |
5627 | scroller.refresh(true);\r | |
5628 | }\r | |
5629 | \r | |
5630 | if (container) {\r | |
5631 | container.onFocusableChildUpdate(me);\r | |
5632 | }\r | |
5633 | }\r | |
5634 | },\r | |
5635 | \r | |
5636 | setHtml: function (html, loadScripts, scriptScope) {\r | |
5637 | this.update(html, loadScripts, null, scriptScope);\r | |
5638 | },\r | |
5639 | \r | |
5640 | applyData: function (data) {\r | |
5641 | // Don't return data here, update will set this.data\r | |
5642 | this.update(data);\r | |
5643 | },\r | |
5644 | \r | |
5645 | /**\r | |
5646 | * Sets the current box measurements of the component's underlying element.\r | |
5647 | * @param {Object} box An object in the format {x, y, width, height}\r | |
5648 | * @return {Ext.Component} this\r | |
5649 | */\r | |
5650 | updateBox: function(box){\r | |
5651 | this.setSize(box.width, box.height);\r | |
5652 | this.setPagePosition(box.x, box.y);\r | |
5653 | return this;\r | |
5654 | },\r | |
5655 | \r | |
5656 | _asLayoutRoot: { isRoot: true },\r | |
5657 | _notAsLayoutRoot: { isRoot: false },\r | |
5658 | \r | |
5659 | /**\r | |
5660 | * Updates this component's layout. If this update affects this components {@link #ownerCt},\r | |
5661 | * that component's `updateLayout` method will be called to perform the layout instead.\r | |
5662 | * Otherwise, just this component (and its child items) will layout.\r | |
5663 | *\r | |
5664 | * @param {Object} [options] An object with layout options.\r | |
5665 | * @param {Boolean} options.defer `true` if this layout should be deferred.\r | |
5666 | * @param {Boolean} options.isRoot `true` if this layout should be the root of the layout.\r | |
5667 | */\r | |
5668 | updateLayout: function (options) {\r | |
5669 | var me = this,\r | |
5670 | defer,\r | |
5671 | lastBox = me.lastBox,\r | |
5672 | isRoot = options && options.isRoot;\r | |
5673 | \r | |
5674 | if (lastBox) {\r | |
5675 | // remember that this component's last layout result is invalid and must be\r | |
5676 | // recalculated\r | |
5677 | lastBox.invalid = true;\r | |
5678 | }\r | |
5679 | \r | |
5680 | if (!me.rendered || me.layoutSuspendCount || me.suspendLayout) {\r | |
5681 | return;\r | |
5682 | }\r | |
5683 | \r | |
5684 | if (me.hidden) {\r | |
5685 | Ext.Component.cancelLayout(me);\r | |
5686 | } else if (typeof isRoot !== 'boolean') {\r | |
5687 | isRoot = me.isLayoutRoot();\r | |
5688 | }\r | |
5689 | \r | |
5690 | // if we aren't the root, see if our ownerLayout will handle it...\r | |
5691 | if (isRoot || !me.ownerLayout || !me.ownerLayout.onContentChange(me)) {\r | |
5692 | // either we are the root or our ownerLayout doesn't care\r | |
5693 | if (!me.isLayoutSuspended()) {\r | |
5694 | // we aren't suspended (knew that), but neither is any of our ownerCt's...\r | |
5695 | defer = (options && options.hasOwnProperty('defer')) ? options.defer : me.deferLayouts;\r | |
5696 | Ext.Component.updateLayout(me, defer);\r | |
5697 | }\r | |
5698 | }\r | |
5699 | },\r | |
5700 | \r | |
5701 | updateMaxHeight: function(maxHeight, oldMaxHeight) {\r | |
5702 | this.changeConstraint(maxHeight, oldMaxHeight, 'min', 'max-height', 'height');\r | |
5703 | },\r | |
5704 | \r | |
5705 | updateMaxWidth: function(maxWidth, oldMaxWidth) {\r | |
5706 | this.changeConstraint(maxWidth, oldMaxWidth, 'min', 'max-width', 'width');\r | |
5707 | },\r | |
5708 | \r | |
5709 | updateMinHeight: function(minHeight, oldMinHeight) {\r | |
5710 | this.changeConstraint(minHeight, oldMinHeight, 'max', 'min-height', 'height');\r | |
5711 | },\r | |
5712 | \r | |
5713 | updateMinWidth: function(minWidth, oldMinWidth) {\r | |
5714 | this.changeConstraint(minWidth, oldMinWidth, 'max', 'min-width', 'width');\r | |
5715 | },\r | |
5716 | \r | |
5717 | // ***********************************************************************************\r | |
5718 | // End Component methods\r | |
5719 | // ***********************************************************************************\r | |
5720 | // </editor-fold>\r | |
5721 | \r | |
5722 | // <editor-fold desc="Positionable Methods">\r | |
5723 | // ***********************************************************************************\r | |
5724 | // Begin Positionable methods\r | |
5725 | // ***********************************************************************************\r | |
5726 | getAnchorToXY: function(el, anchor, local, mySize) {\r | |
5727 | return el.getAnchorXY(anchor, local, mySize);\r | |
5728 | },\r | |
5729 | \r | |
5730 | getBorderPadding: function() {\r | |
5731 | return this.el.getBorderPadding();\r | |
5732 | },\r | |
5733 | \r | |
5734 | getLocalX: function() {\r | |
5735 | return this.el.getLocalX();\r | |
5736 | },\r | |
5737 | \r | |
5738 | getLocalXY: function() {\r | |
5739 | return this.el.getLocalXY();\r | |
5740 | },\r | |
5741 | \r | |
5742 | getLocalY: function() {\r | |
5743 | return this.el.getLocalY();\r | |
5744 | },\r | |
5745 | \r | |
5746 | getX: function() {\r | |
5747 | return this.el.getX();\r | |
5748 | },\r | |
5749 | \r | |
5750 | getXY: function() {\r | |
5751 | return this.el.getXY();\r | |
5752 | },\r | |
5753 | \r | |
5754 | getY: function() {\r | |
5755 | return this.el.getY();\r | |
5756 | },\r | |
5757 | \r | |
5758 | setLocalX: function(x) {\r | |
5759 | this.el.setLocalX(x);\r | |
5760 | },\r | |
5761 | \r | |
5762 | setLocalXY: function(x, y) {\r | |
5763 | this.el.setLocalXY(x, y);\r | |
5764 | },\r | |
5765 | \r | |
5766 | setLocalY: function(y) {\r | |
5767 | this.el.setLocalY(y);\r | |
5768 | },\r | |
5769 | \r | |
5770 | setX: function(x, animate) {\r | |
5771 | this.el.setX(x, animate);\r | |
5772 | },\r | |
5773 | \r | |
5774 | setXY: function(xy, animate) {\r | |
5775 | this.el.setXY(xy, animate);\r | |
5776 | },\r | |
5777 | \r | |
5778 | setY: function(y, animate) {\r | |
5779 | this.el.setY(y, animate);\r | |
5780 | },\r | |
5781 | \r | |
5782 | // ***********************************************************************************\r | |
5783 | // End Positionable methods\r | |
5784 | // ***********************************************************************************\r | |
5785 | // </editor-fold>\r | |
5786 | \r | |
5787 | privates: {\r | |
5788 | addOverCls: function() {\r | |
5789 | var me = this;\r | |
5790 | if (!me.disabled) {\r | |
5791 | me.el.addCls(me.overCls);\r | |
5792 | }\r | |
5793 | },\r | |
5794 | \r | |
5795 | /**\r | |
5796 | * Method which adds a specified UI to the components element.\r | |
5797 | * @private\r | |
5798 | */\r | |
5799 | addUIToElement: function() {\r | |
5800 | var me = this,\r | |
5801 | baseClsUI = me.baseCls + '-' + me.ui,\r | |
5802 | childEls, childElName, el, suffix;\r | |
5803 | \r | |
5804 | me.addCls(baseClsUI);\r | |
5805 | \r | |
5806 | if (me.rendered && me.frame && !Ext.supports.CSS3BorderRadius) {\r | |
5807 | // Loop through each frame element, and if they are defined add the ui:\r | |
5808 | baseClsUI += '-';\r | |
5809 | childEls = me.getChildEls();\r | |
5810 | \r | |
5811 | for (childElName in childEls) {\r | |
5812 | suffix = childEls[childElName].frame;\r | |
5813 | if (suffix && suffix !== true) {\r | |
5814 | el = me[childElName];\r | |
5815 | if (el) {\r | |
5816 | el.addCls(baseClsUI + suffix);\r | |
5817 | }\r | |
5818 | }\r | |
5819 | }\r | |
5820 | }\r | |
5821 | },\r | |
5822 | \r | |
5823 | /**\r | |
5824 | * @private\r | |
5825 | */\r | |
5826 | changeConstraint: function(newValue, oldValue, constrainMethod, styleName, sizeName) {\r | |
5827 | var me = this,\r | |
5828 | size = me[sizeName];\r | |
5829 | \r | |
5830 | if (newValue != null && typeof size === 'number') {\r | |
5831 | me[sizeName] = Math[constrainMethod](size, newValue);\r | |
5832 | }\r | |
5833 | \r | |
5834 | if (me.liquidLayout) {\r | |
5835 | // components that use liquidLayout need their size constraints set in the dom\r | |
5836 | if (newValue != null) {\r | |
5837 | me.setStyle(styleName, newValue + 'px');\r | |
5838 | } else if (oldValue) {\r | |
5839 | me.setStyle(styleName, '');\r | |
5840 | }\r | |
5841 | }\r | |
5842 | \r | |
5843 | if (me.rendered) {\r | |
5844 | me.updateLayout();\r | |
5845 | }\r | |
5846 | },\r | |
5847 | \r | |
5848 | /**\r | |
5849 | * @param {String/Object} ptype string or config object containing a ptype property.\r | |
5850 | *\r | |
5851 | * Constructs a plugin according to the passed config object/ptype string.\r | |
5852 | *\r | |
5853 | * Ensures that the constructed plugin always has a `cmp` reference back to this component.\r | |
5854 | * The setting up of this is done in PluginManager. The PluginManager ensures that a reference to this\r | |
5855 | * component is passed to the constructor. It also ensures that the plugin's `setCmp` method (if any) is called.\r | |
5856 | * @private\r | |
5857 | */\r | |
5858 | constructPlugin: function(plugin) {\r | |
5859 | var me = this;\r | |
5860 | \r | |
5861 | // ptype only, pass as the defultType\r | |
5862 | if (typeof plugin === 'string') {\r | |
5863 | plugin = Ext.PluginManager.create({}, plugin, me);\r | |
5864 | }\r | |
5865 | // Object (either config with ptype or an instantiated plugin)\r | |
5866 | else {\r | |
5867 | plugin = Ext.PluginManager.create(plugin, null, me);\r | |
5868 | }\r | |
5869 | return plugin;\r | |
5870 | },\r | |
5871 | \r | |
5872 | /**\r | |
5873 | * Returns an array of fully constructed plugin instances. This converts any configs into their\r | |
5874 | * appropriate instances.\r | |
5875 | *\r | |
5876 | * It does not mutate the plugins array. It creates a new array.\r | |
5877 | * @private\r | |
5878 | */\r | |
5879 | constructPlugins: function() {\r | |
5880 | var me = this,\r | |
5881 | plugins = me.plugins,\r | |
5882 | result, i, len;\r | |
5883 | \r | |
5884 | if (plugins) {\r | |
5885 | result = [];\r | |
5886 | \r | |
5887 | // The processed flag indicates that the plugins have been constructed. This is usually done\r | |
5888 | // at construction time, so if at initComponent time, there is a non-zero array of plugins which\r | |
5889 | // does NOT have the processed flag, it needs to be processed again.\r | |
5890 | result.processed = true;\r | |
5891 | if (!Ext.isArray(plugins)) {\r | |
5892 | plugins = [ plugins ];\r | |
5893 | }\r | |
5894 | for (i = 0, len = plugins.length; i < len; i++) {\r | |
5895 | // this just returns already-constructed plugin instances...\r | |
5896 | result[i] = me.constructPlugin(plugins[i]);\r | |
5897 | }\r | |
5898 | }\r | |
5899 | \r | |
5900 | me.pluginsInitialized = true;\r | |
5901 | return result;\r | |
5902 | },\r | |
5903 | \r | |
5904 | detachFromBody: function() {\r | |
5905 | // Currently this is called by column.Widget to store components\r | |
5906 | // in the pool when they are not needed in the grid.\r | |
5907 | // \r | |
5908 | // Also see reattachToBody\r | |
5909 | Ext.getDetachedBody().appendChild(this.el);\r | |
5910 | Ext.Component.cancelLayout(this);\r | |
5911 | this.isDetached = true;\r | |
5912 | },\r | |
5913 | \r | |
5914 | doAddListener: function(ename, fn, scope, options, order, caller, manager) {\r | |
5915 | var me = this,\r | |
5916 | listeners, option, eventOptions, elementName, element, delegate;\r | |
5917 | \r | |
5918 | if (Ext.isObject(fn) || (options && options.element)) {\r | |
5919 | if (options.element) {\r | |
5920 | elementName = options.element;\r | |
5921 | listeners = {};\r | |
5922 | listeners[ename] = fn;\r | |
5923 | if (scope) {\r | |
5924 | listeners.scope = scope;\r | |
5925 | }\r | |
5926 | \r | |
5927 | eventOptions = me.$elementEventOptions;\r | |
5928 | for (option in options) {\r | |
5929 | if (eventOptions[option]) {\r | |
5930 | listeners[option] = options[option];\r | |
5931 | }\r | |
5932 | }\r | |
5933 | } else {\r | |
5934 | listeners = fn;\r | |
5935 | elementName = ename;\r | |
5936 | }\r | |
5937 | \r | |
5938 | element = me[elementName];\r | |
5939 | \r | |
5940 | if (element && element.isObservable) { // can be any kind of observable, not just element\r | |
5941 | me.mon(element, listeners);\r | |
5942 | } else {\r | |
5943 | me.afterRenderEvents = me.afterRenderEvents || {};\r | |
5944 | if (!me.afterRenderEvents[elementName]) {\r | |
5945 | me.afterRenderEvents[elementName] = [];\r | |
5946 | }\r | |
5947 | me.afterRenderEvents[elementName].push(listeners);\r | |
5948 | }\r | |
5949 | return;\r | |
5950 | }\r | |
5951 | \r | |
5952 | if (options) {\r | |
5953 | delegate = options.delegate;\r | |
5954 | if (delegate) {\r | |
5955 | me.mixins.componentDelegation.addDelegatedListener.call(me, ename, fn, scope, options, order, caller, manager);\r | |
5956 | return;\r | |
5957 | }\r | |
5958 | }\r | |
5959 | \r | |
5960 | me.mixins.observable.doAddListener.call(me, ename, fn, scope, options, order, caller, manager);\r | |
5961 | },\r | |
5962 | \r | |
5963 | doRemoveListener: function(eventName, fn, scope) {\r | |
5964 | var me = this;\r | |
5965 | me.mixins.observable.doRemoveListener.call(me, eventName, fn, scope);\r | |
5966 | me.mixins.componentDelegation.removeDelegatedListener.call(me, eventName, fn, scope);\r | |
5967 | },\r | |
5968 | \r | |
5969 | /**\r | |
5970 | * This method fires an event on `Ext.GlobalEvents` allowing interested parties to know\r | |
5971 | * of certain critical events for this component. This is done globally because the\r | |
5972 | * (few) listeners can immediately receive the event rather than bubbling the event\r | |
5973 | * only to reach the top and have no listeners.\r | |
5974 | *\r | |
5975 | * The main usage for these events is to do with floating components. For example, the\r | |
5976 | * load mask is a floating component. The component it is masking may be inside several\r | |
5977 | * containers. As such, they need to know when component is hidden, either directly, or\r | |
5978 | * via a parent container being hidden. To do this they subscribe to these events and\r | |
5979 | * filter out the appropriate container.\r | |
5980 | *\r | |
5981 | * This functionality is contained in Component (as opposed to Container) because a\r | |
5982 | * Component can be the ownerCt for a floating component (loadmask), and the loadmask\r | |
5983 | * needs to know when its owner is shown/hidden so that its hidden state can be\r | |
5984 | * synchronized.\r | |
5985 | *\r | |
5986 | * @param {String} eventName The event name.\r | |
5987 | * @since 4.2.0\r | |
5988 | * @private\r | |
5989 | */\r | |
5990 | fireHierarchyEvent: function (eventName) {\r | |
5991 | var globalEvents = Ext.GlobalEvents;\r | |
5992 | \r | |
5993 | if (globalEvents.hasListeners[eventName]) {\r | |
5994 | globalEvents.fireEvent(eventName, this);\r | |
5995 | }\r | |
5996 | },\r | |
5997 | \r | |
5998 | getActionEl: function() {\r | |
5999 | return this.el;\r | |
6000 | },\r | |
6001 | \r | |
6002 | /**\r | |
6003 | * @private\r | |
6004 | */\r | |
6005 | getAutoId: function() {\r | |
6006 | this.autoGenId = true;\r | |
6007 | return ++Ext.Component.AUTO_ID;\r | |
6008 | },\r | |
6009 | \r | |
6010 | /**\r | |
6011 | * @private\r | |
6012 | */\r | |
6013 | getContentTarget: function() {\r | |
6014 | return this.el;\r | |
6015 | },\r | |
6016 | \r | |
6017 | getDragEl: function() {\r | |
6018 | return this.el;\r | |
6019 | },\r | |
6020 | \r | |
6021 | /**\r | |
6022 | * Get an el for overflowing, defaults to the target el\r | |
6023 | * @private\r | |
6024 | */\r | |
6025 | getOverflowEl: function(){\r | |
6026 | return this.getTargetEl();\r | |
6027 | },\r | |
6028 | \r | |
6029 | /**\r | |
6030 | * @private\r | |
6031 | * Returns the CSS style object which will set the Component's scroll styles.\r | |
6032 | * This must be applied to the {@link #getTargetEl target element}.\r | |
6033 | */\r | |
6034 | getOverflowStyle: function() {\r | |
6035 | var me = this,\r | |
6036 | scroller = me.getScrollable(),\r | |
6037 | flags = me._scrollFlags,\r | |
6038 | x, y, scrollFlags;\r | |
6039 | \r | |
6040 | if (scroller) {\r | |
6041 | x = scroller.getX();\r | |
6042 | if (x === true) {\r | |
6043 | x = 'auto';\r | |
6044 | }\r | |
6045 | y = scroller.getY();\r | |
6046 | if (y === true) {\r | |
6047 | y = 'auto';\r | |
6048 | }\r | |
6049 | scrollFlags = flags[x][y];\r | |
6050 | } else {\r | |
6051 | scrollFlags = flags.none;\r | |
6052 | }\r | |
6053 | \r | |
6054 | me.scrollFlags = scrollFlags;\r | |
6055 | \r | |
6056 | return {\r | |
6057 | overflowX: scrollFlags.overflowX,\r | |
6058 | overflowY: scrollFlags.overflowY\r | |
6059 | };\r | |
6060 | },\r | |
6061 | \r | |
6062 | /**\r | |
6063 | * Returns an array of current fully constructed plugin instances.\r | |
6064 | * @private\r | |
6065 | */\r | |
6066 | getPlugins : function() {\r | |
6067 | var plugins = this.plugins;\r | |
6068 | \r | |
6069 | plugins = (plugins && plugins.processed) ? plugins : this.constructPlugins();\r | |
6070 | return plugins || null;\r | |
6071 | },\r | |
6072 | \r | |
6073 | getProxy: function() {\r | |
6074 | var me = this,\r | |
6075 | target;\r | |
6076 | \r | |
6077 | if (!me.proxy) {\r | |
6078 | target = Ext.getBody();\r | |
6079 | me.proxy = me.el.createProxy(Ext.baseCSSPrefix + 'proxy-el', target, true);\r | |
6080 | }\r | |
6081 | return me.proxy;\r | |
6082 | },\r | |
6083 | \r | |
6084 | getScrollerEl: function() {\r | |
6085 | var me = this;\r | |
6086 | \r | |
6087 | return me.scrollerEl || (me.scrollerEl =\r | |
6088 | me.componentLayout.getScrollerEl() || me.getOverflowEl().child(me.scrollerSelector));\r | |
6089 | },\r | |
6090 | \r | |
6091 | /**\r | |
6092 | * This is used to determine where to insert the 'html', 'contentEl' and 'items' in this component.\r | |
6093 | * @private\r | |
6094 | */\r | |
6095 | getTargetEl: function() {\r | |
6096 | return this.frameBody || this.el;\r | |
6097 | },\r | |
6098 | \r | |
6099 | /**\r | |
6100 | * @private\r | |
6101 | * Needed for when widget is rendered into a grid cell. The class to add to the cell element.\r | |
6102 | */\r | |
6103 | getTdCls: function() {\r | |
6104 | return Ext.baseCSSPrefix + this.getTdType() + '-' + this.ui + '-cell';\r | |
6105 | },\r | |
6106 | \r | |
6107 | /**\r | |
6108 | * @private\r | |
6109 | * Partner method to {@link #getTdCls}.\r | |
6110 | *\r | |
6111 | * Returns the base type for the component. Defaults to return `this.xtype`, but\r | |
6112 | * All derived classes of {@link Ext.form.field.Text TextField} can return the type 'textfield',\r | |
6113 | * and all derived classes of {@link Ext.button.Button Button} can return the type 'button'\r | |
6114 | */\r | |
6115 | getTdType: function() {\r | |
6116 | return this.xtype;\r | |
6117 | },\r | |
6118 | \r | |
6119 | /**\r | |
6120 | * @private\r | |
6121 | */\r | |
6122 | getTpl: function(name) {\r | |
6123 | return Ext.XTemplate.getTpl(this, name);\r | |
6124 | },\r | |
6125 | \r | |
6126 | initCls: function() {\r | |
6127 | var me = this,\r | |
6128 | cls = [me.baseCls],\r | |
6129 | targetCls = me.getComponentLayout().targetCls;\r | |
6130 | \r | |
6131 | if (targetCls) {\r | |
6132 | cls.push(targetCls);\r | |
6133 | }\r | |
6134 | \r | |
6135 | //<deprecated since=0.99>\r | |
6136 | if (Ext.isDefined(me.cmpCls)) {\r | |
6137 | if (Ext.isDefined(Ext.global.console)) {\r | |
6138 | Ext.global.console.warn('Ext.Component: cmpCls has been deprecated. Please use componentCls.');\r | |
6139 | }\r | |
6140 | me.componentCls = me.cmpCls;\r | |
6141 | delete me.cmpCls;\r | |
6142 | }\r | |
6143 | //</deprecated>\r | |
6144 | \r | |
6145 | if (me.componentCls) {\r | |
6146 | cls.push(me.componentCls);\r | |
6147 | } else {\r | |
6148 | me.componentCls = me.baseCls;\r | |
6149 | }\r | |
6150 | \r | |
6151 | return cls;\r | |
6152 | },\r | |
6153 | \r | |
6154 | initDraggable: function() {\r | |
6155 | var me = this,\r | |
6156 | \r | |
6157 | // If we are resizable, and the resizer had to wrap this Component's el (e.g. an Img)\r | |
6158 | // Then we have to create a pseudo-Component out of the resizer to drag that,\r | |
6159 | // otherwise, we just drag this Component\r | |
6160 | dragTarget = (me.resizer && me.resizer.el !== me.el) ? me.resizerComponent = new Ext.Component({\r | |
6161 | el: me.resizer.el,\r | |
6162 | rendered: true,\r | |
6163 | container: me.container\r | |
6164 | }) : me,\r | |
6165 | ddConfig = Ext.applyIf({\r | |
6166 | el: dragTarget.getDragEl(),\r | |
6167 | constrainTo: (me.constrain||me.draggable.constrain) ? (me.constrainTo || (me.floatParent ? me.floatParent.getTargetEl() : me.container)) : undefined\r | |
6168 | }, me.draggable);\r | |
6169 | \r | |
6170 | // Add extra configs if Component is specified to be constrained\r | |
6171 | if (me.constrain || me.constrainDelegate) {\r | |
6172 | ddConfig.constrain = me.constrain;\r | |
6173 | ddConfig.constrainDelegate = me.constrainDelegate;\r | |
6174 | }\r | |
6175 | \r | |
6176 | me.dd = new Ext.util.ComponentDragger(dragTarget, ddConfig);\r | |
6177 | },\r | |
6178 | \r | |
6179 | /**\r | |
6180 | * Initializes padding by applying it to the target element, or if the layout manages\r | |
6181 | * padding ensures that the padding on the target element is "0".\r | |
6182 | * @private\r | |
6183 | */\r | |
6184 | initPadding: function(targetEl) {\r | |
6185 | var me = this,\r | |
6186 | padding = me.padding;\r | |
6187 | \r | |
6188 | if (padding != null) {\r | |
6189 | if (me.touchScroll || (me.layout && me.layout.managePadding && me.contentPaddingProperty === 'padding')) {\r | |
6190 | // If the container layout manages padding, or if a touch scroller is in\r | |
6191 | // use, the padding will be applied to an inner layout element, or the\r | |
6192 | // touch scroller element. This is done as a workaround for the browser bug\r | |
6193 | // where right and/or bottom padding is lost when the element has overflow.\r | |
6194 | // The assumed intent is for the configured padding to override any padding\r | |
6195 | // that is applied to the target element via style sheet rules. It is\r | |
6196 | // therefore necessary to set the target element's padding to "0".\r | |
6197 | targetEl.setStyle('padding', 0);\r | |
6198 | } else {\r | |
6199 | // Convert the padding, margin and border properties from a space separated string\r | |
6200 | // into a proper style string\r | |
6201 | targetEl.setStyle('padding', this.unitizeBox((padding === true) ? 5 : padding));\r | |
6202 | }\r | |
6203 | }\r | |
6204 | },\r | |
6205 | \r | |
6206 | /**\r | |
6207 | * @private\r | |
6208 | */\r | |
6209 | initPlugin: function(plugin) {\r | |
6210 | plugin.init(this);\r | |
6211 | \r | |
6212 | return plugin;\r | |
6213 | },\r | |
6214 | \r | |
6215 | initResizable: function(resizable) {\r | |
6216 | var me = this;\r | |
6217 | \r | |
6218 | resizable = Ext.apply({\r | |
6219 | target: me,\r | |
6220 | dynamic: false,\r | |
6221 | constrainTo: (me.constrain||(resizable && resizable.constrain)) ? (me.constrainTo || (me.floatParent ? me.floatParent.getTargetEl() : me.container)) : undefined,\r | |
6222 | handles: me.resizeHandles\r | |
6223 | }, resizable);\r | |
6224 | resizable.target = me;\r | |
6225 | me.resizer = new Ext.resizer.Resizer(resizable);\r | |
6226 | },\r | |
6227 | \r | |
6228 | /**\r | |
6229 | * Applies padding, margin, border, top, left, height, and width configs to the\r | |
6230 | * appropriate elements.\r | |
6231 | * @private\r | |
6232 | */\r | |
6233 | initStyles: function(targetEl) {\r | |
6234 | var me = this,\r | |
6235 | margin = me.margin,\r | |
6236 | border = me.border,\r | |
6237 | cls = me.cls,\r | |
6238 | style = me.style,\r | |
6239 | x = me.x,\r | |
6240 | y = me.y,\r | |
6241 | liquidLayout = me.liquidLayout,\r | |
6242 | width, height;\r | |
6243 | \r | |
6244 | me.initPadding(targetEl);\r | |
6245 | \r | |
6246 | if (margin != null) {\r | |
6247 | targetEl.setStyle('margin', this.unitizeBox((margin === true) ? 5 : margin));\r | |
6248 | }\r | |
6249 | \r | |
6250 | if (border != null) {\r | |
6251 | me.setBorder(border, targetEl);\r | |
6252 | }\r | |
6253 | \r | |
6254 | // initComponent, beforeRender, or event handlers may have set the style or cls property since the protoEl was set up\r | |
6255 | // so we must apply styles and classes here too.\r | |
6256 | if (cls && cls !== me.initialCls) {\r | |
6257 | targetEl.addCls(cls);\r | |
6258 | me.cls = me.initialCls = null;\r | |
6259 | }\r | |
6260 | if (style && style !== me.initialStyle) {\r | |
6261 | targetEl.setStyle(style);\r | |
6262 | me.style = me.initialStyle = null;\r | |
6263 | }\r | |
6264 | \r | |
6265 | if (x != null) {\r | |
6266 | targetEl.setStyle(me.horizontalPosProp, (typeof x === 'number') ? (x + 'px') : x);\r | |
6267 | }\r | |
6268 | if (y != null) {\r | |
6269 | targetEl.setStyle('top', (typeof y === 'number') ? (y + 'px') : y);\r | |
6270 | }\r | |
6271 | \r | |
6272 | if (!me.ownerCt || me.floating) {\r | |
6273 | if (Ext.scopeCss) {\r | |
6274 | targetEl.addCls(me.rootCls);\r | |
6275 | }\r | |
6276 | targetEl.addCls(me.borderBoxCls);\r | |
6277 | }\r | |
6278 | \r | |
6279 | // Framed components need their width/height to apply to the frame, which is\r | |
6280 | // best handled in layout at present. The exception to this rule is component\r | |
6281 | // that use liquidLayout and so cannot rely on the layout to set their size.\r | |
6282 | if (liquidLayout || !me.getFrameInfo()) {\r | |
6283 | width = me.width;\r | |
6284 | height = me.height;\r | |
6285 | \r | |
6286 | // If we're using the content box model, we also cannot assign numeric initial sizes since we do not know the border widths to subtract\r | |
6287 | if (width != null) {\r | |
6288 | if (typeof width === 'number') {\r | |
6289 | targetEl.setStyle('width', width + 'px');\r | |
6290 | } else {\r | |
6291 | targetEl.setStyle('width', width);\r | |
6292 | }\r | |
6293 | }\r | |
6294 | if (height != null) {\r | |
6295 | if (typeof height === 'number') {\r | |
6296 | targetEl.setStyle('height', height + 'px');\r | |
6297 | } else {\r | |
6298 | targetEl.setStyle('height', height);\r | |
6299 | }\r | |
6300 | }\r | |
6301 | }\r | |
6302 | },\r | |
6303 | \r | |
6304 | // Utility method to determine if a Component is floating, and has an owning Container whose coordinate system\r | |
6305 | // it must be positioned in when using setPosition.\r | |
6306 | isContainedFloater: function() {\r | |
6307 | return (this.floating && this.floatParent);\r | |
6308 | },\r | |
6309 | \r | |
6310 | isDescendant: function(ancestor) {\r | |
6311 | if (ancestor.isContainer) {\r | |
6312 | for (var c = this.ownerCt; c; c = c.ownerCt) {\r | |
6313 | if (c === ancestor) {\r | |
6314 | return true;\r | |
6315 | }\r | |
6316 | }\r | |
6317 | }\r | |
6318 | return false;\r | |
6319 | },\r | |
6320 | \r | |
6321 | /**\r | |
6322 | * @private\r | |
6323 | * Returns `true` if the passed element is within the container tree of this component.\r | |
6324 | *\r | |
6325 | * For example if a menu's submenu contains an {@link Ext.form.field.Date}, that top level\r | |
6326 | * menu owns the elements of the date picker. Using this method, you can tell if an event took place\r | |
6327 | * within a certain component tree.\r | |
6328 | */\r | |
6329 | owns: function(element) {\r | |
6330 | var result = false,\r | |
6331 | cmp;\r | |
6332 | \r | |
6333 | if (element.isEvent) {\r | |
6334 | element = element.target;\r | |
6335 | } else if (element.isElement) {\r | |
6336 | element = element.dom;\r | |
6337 | }\r | |
6338 | \r | |
6339 | cmp = Ext.Component.fromElement(element);\r | |
6340 | \r | |
6341 | if (cmp) {\r | |
6342 | result = (cmp === this) || (!!cmp.up(this));\r | |
6343 | }\r | |
6344 | \r | |
6345 | return result;\r | |
6346 | },\r | |
6347 | \r | |
6348 | parseBox: function(box) {\r | |
6349 | return Ext.Element.parseBox(box);\r | |
6350 | },\r | |
6351 | \r | |
6352 | reattachToBody: function() {\r | |
6353 | // Also see detachFromBody\r | |
6354 | this.isDetached = false;\r | |
6355 | },\r | |
6356 | \r | |
6357 | /**\r | |
6358 | * @private\r | |
6359 | * Implementation which updates the scroll range of a touch scroller.\r | |
6360 | * Subclasses may change implementation.\r | |
6361 | */\r | |
6362 | refreshScroll: function() {\r | |
6363 | var scroller = this.getScrollable();\r | |
6364 | \r | |
6365 | if (scroller) {\r | |
6366 | scroller.refresh();\r | |
6367 | }\r | |
6368 | },\r | |
6369 | \r | |
6370 | removeManagedListenerItem: function(isClear, managedListener, item, ename, fn, scope){\r | |
6371 | var me = this,\r | |
6372 | element = managedListener.options ? managedListener.options.element : null;\r | |
6373 | \r | |
6374 | if (element) {\r | |
6375 | element = me[element];\r | |
6376 | if (element && element.un) {\r | |
6377 | if (isClear || (managedListener.item === item && managedListener.ename === ename && (!fn || managedListener.fn === fn) && (!scope || managedListener.scope === scope))) {\r | |
6378 | element.un(managedListener.ename, managedListener.fn, managedListener.scope);\r | |
6379 | if (!isClear) {\r | |
6380 | Ext.Array.remove(me.managedListeners, managedListener);\r | |
6381 | }\r | |
6382 | }\r | |
6383 | }\r | |
6384 | } else {\r | |
6385 | return me.mixins.observable.removeManagedListenerItem.apply(me, arguments);\r | |
6386 | }\r | |
6387 | },\r | |
6388 | \r | |
6389 | removeOverCls: function() {\r | |
6390 | this.el.removeCls(this.overCls);\r | |
6391 | },\r | |
6392 | \r | |
6393 | removePlugin: function(plugin) {\r | |
6394 | Ext.Array.remove(this.plugins, plugin);\r | |
6395 | plugin.destroy();\r | |
6396 | },\r | |
6397 | \r | |
6398 | /**\r | |
6399 | * Method which removes a specified UI from the components element.\r | |
6400 | * @private\r | |
6401 | */\r | |
6402 | removeUIFromElement: function() {\r | |
6403 | var me = this,\r | |
6404 | baseClsUI = me.baseCls + '-' + me.ui,\r | |
6405 | childEls, childElName, el, suffix;\r | |
6406 | \r | |
6407 | me.removeCls(baseClsUI);\r | |
6408 | \r | |
6409 | if (me.rendered && me.frame && !Ext.supports.CSS3BorderRadius) {\r | |
6410 | // Loop through each frame element, and if they are defined remove the ui:\r | |
6411 | baseClsUI += '-';\r | |
6412 | childEls = me.getChildEls();\r | |
6413 | \r | |
6414 | for (childElName in childEls) {\r | |
6415 | suffix = childEls[childElName].frame;\r | |
6416 | if (suffix && suffix !== true) {\r | |
6417 | el = me[childElName];\r | |
6418 | if (el) {\r | |
6419 | el.removeCls(baseClsUI + suffix);\r | |
6420 | }\r | |
6421 | }\r | |
6422 | }\r | |
6423 | }\r | |
6424 | },\r | |
6425 | \r | |
6426 | /**\r | |
6427 | * @private\r | |
6428 | */\r | |
6429 | setComponentLayout: function(layout) {\r | |
6430 | var currentLayout = this.componentLayout;\r | |
6431 | if (currentLayout && currentLayout.isLayout && currentLayout !== layout) {\r | |
6432 | currentLayout.setOwner(null);\r | |
6433 | }\r | |
6434 | this.componentLayout = layout;\r | |
6435 | layout.setOwner(this);\r | |
6436 | },\r | |
6437 | \r | |
6438 | setHiddenState: function (hidden) {\r | |
6439 | var me = this,\r | |
6440 | inheritedState = me.getInherited(),\r | |
6441 | zIndexManager = me.zIndexManager;\r | |
6442 | \r | |
6443 | me.hidden = hidden;\r | |
6444 | \r | |
6445 | if (hidden) {\r | |
6446 | inheritedState.hidden = true;\r | |
6447 | } else {\r | |
6448 | delete inheritedState.hidden;\r | |
6449 | }\r | |
6450 | \r | |
6451 | // Ensure any ZIndexManager knowns about visibility state change to keep its filtering correct\r | |
6452 | if (zIndexManager) {\r | |
6453 | zIndexManager.onComponentShowHide(me);\r | |
6454 | }\r | |
6455 | },\r | |
6456 | \r | |
6457 | setupProtoEl: function() {\r | |
6458 | var cls = this.initCls();\r | |
6459 | \r | |
6460 | this.protoEl.addCls(cls);\r | |
6461 | },\r | |
6462 | \r | |
6463 | wrapPrimaryEl: function (dom) {\r | |
6464 | var me = this,\r | |
6465 | el = me.el;\r | |
6466 | \r | |
6467 | if (!el || !el.isElement) { // allow subclass override to instantiate the element\r | |
6468 | me.el = Ext.get(dom);\r | |
6469 | }\r | |
6470 | \r | |
6471 | if (me.floating) {\r | |
6472 | this.mixins.floating.constructor.call(this);\r | |
6473 | }\r | |
6474 | }\r | |
6475 | }, // private\r | |
6476 | \r | |
6477 | deprecated: {\r | |
6478 | 5: {\r | |
6479 | methods: {\r | |
6480 | /**\r | |
6481 | * @method addClass\r | |
6482 | * @inheritdoc Ext.Component#addCls\r | |
6483 | * @deprecated 4.1 Use {@link #addCls} instead.\r | |
6484 | * @since 2.3.0\r | |
6485 | */\r | |
6486 | addClass: 'addCls',\r | |
6487 | \r | |
6488 | /**\r | |
6489 | * This method needs to be called whenever you change something on this component that\r | |
6490 | * requires the Component's layout to be recalculated.\r | |
6491 | * @return {Ext.Component} this\r | |
6492 | * @deprecated 4.1 Use {@link #updateLayout} instead.\r | |
6493 | */\r | |
6494 | doComponentLayout: function() {\r | |
6495 | this.updateLayout();\r | |
6496 | return this;\r | |
6497 | },\r | |
6498 | \r | |
6499 | /**\r | |
6500 | * @method removeClass\r | |
6501 | * @inheritdoc Ext.Component#removeCls\r | |
6502 | * @deprecated 4.1 Use {@link #addCls} instead.\r | |
6503 | * @since 2.3.0\r | |
6504 | */\r | |
6505 | removeClass: 'removeCls',\r | |
6506 | \r | |
6507 | /**\r | |
6508 | * @method forceComponentLayout\r | |
6509 | * @inheritdoc Ext.Component#updateLayout\r | |
6510 | * @deprecated 4.1 Use {@link #updateLayout} instead.\r | |
6511 | */\r | |
6512 | forceComponentLayout: 'updateLayout',\r | |
6513 | \r | |
6514 | /**\r | |
6515 | * @method setDocked\r | |
6516 | * @inheritdoc Ext.Component#setDock\r | |
6517 | * @deprecated 5.0 Use {@link #setDock} instead.\r | |
6518 | */\r | |
6519 | setDocked: 'setDock'\r | |
6520 | }\r | |
6521 | }\r | |
6522 | }\r | |
6523 | }, function(Component) {\r | |
6524 | var prototype = Component.prototype;\r | |
6525 | \r | |
6526 | // event options for listeners that use the "element" event options must also include\r | |
6527 | // event options from Ext.Element\r | |
6528 | (prototype.$elementEventOptions =\r | |
6529 | Ext.Object.chain(Ext.Element.prototype.$eventOptions)).element = 1;\r | |
6530 | \r | |
6531 | (prototype.$eventOptions = Ext.Object.chain(prototype.$eventOptions)).delegate = 1;\r | |
6532 | \r | |
6533 | Component.createAlias({\r | |
6534 | on: 'addListener',\r | |
6535 | prev: 'previousSibling',\r | |
6536 | next: 'nextSibling'\r | |
6537 | });\r | |
6538 | \r | |
6539 | /**\r | |
6540 | * @method\r | |
6541 | * @inheritdoc Ext.Component#static-resumeLayouts\r | |
6542 | * @member Ext\r | |
6543 | */\r | |
6544 | Ext.resumeLayouts = function (flush) {\r | |
6545 | Component.resumeLayouts(flush);\r | |
6546 | };\r | |
6547 | \r | |
6548 | /**\r | |
6549 | * @method\r | |
6550 | * @inheritdoc Ext.Component#static-suspendLayouts\r | |
6551 | * @member Ext\r | |
6552 | */\r | |
6553 | Ext.suspendLayouts = function () {\r | |
6554 | Component.suspendLayouts();\r | |
6555 | };\r | |
6556 | \r | |
6557 | /**\r | |
6558 | * Utility wrapper that suspends layouts of all components for the duration of a given\r | |
6559 | * function.\r | |
6560 | * @param {Function} fn The function to execute.\r | |
6561 | * @param {Object} [scope] The scope (`this` reference) in which the specified function\r | |
6562 | * is executed.\r | |
6563 | * @member Ext\r | |
6564 | */\r | |
6565 | Ext.batchLayouts = function(fn, scope) {\r | |
6566 | Component.suspendLayouts();\r | |
6567 | // Invoke the function\r | |
6568 | fn.call(scope);\r | |
6569 | Component.resumeLayouts(true);\r | |
6570 | };\r | |
6571 | \r | |
6572 | /**\r | |
6573 | * Sets the default font-family to use for components that support a `glyph` config.\r | |
6574 | * @param {String} fontFamily The name of the font-family\r | |
6575 | * @member Ext\r | |
6576 | */\r | |
6577 | Ext.setGlyphFontFamily = function (fontFamily) {\r | |
6578 | Ext._glyphFontFamily = fontFamily;\r | |
6579 | };\r | |
6580 | \r | |
6581 | // These are legacy names which are now subsumed by Ext.GlobalEvents\r | |
6582 | Component.hierarchyEventSource = prototype.hierarchyEventSource =\r | |
6583 | Ext.GlobalEvents;\r | |
6584 | \r | |
6585 | // High Contrast mode in Windows disables background images and usually\r | |
6586 | // causes much pain by this. We feature detect it early and add this class\r | |
6587 | // to allow potential workarounds.\r | |
6588 | Ext.onReady(function() {\r | |
6589 | if (Ext.supports.HighContrastMode) {\r | |
6590 | Ext.getBody().addCls(Component.ariaHighContrastModeCls);\r | |
6591 | }\r | |
6592 | });\r | |
6593 | \r | |
6594 | //<debug>\r | |
6595 | var metaTags = document.getElementsByTagName('head')[0].getElementsByTagName('meta'),\r | |
6596 | len = metaTags.length,\r | |
6597 | i, hasViewport;\r | |
6598 | \r | |
6599 | for (i = 0; i < len; i++) {\r | |
6600 | if (metaTags[i].name === 'viewport') {\r | |
6601 | hasViewport = true;\r | |
6602 | }\r | |
6603 | }\r | |
6604 | \r | |
6605 | if (!hasViewport) {\r | |
6606 | Ext.log.warn('Ext JS requires a viewport meta tag in order to function correctly on mobile devices. Please add the following tag to the <head> of your html page: \n <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">');\r | |
6607 | }\r | |
6608 | //</debug>\r | |
6609 | });\r | |
6610 | \r | |
6611 | \r | |
6612 | \r | |
6613 | /* TODO\r | |
6614 | *\r | |
6615 | * ## Child Sessions\r | |
6616 | *\r | |
6617 | * By default, sessions created in child components are called "child sessions".\r | |
6618 | * All data and edits are copied from the parent session in to the child session.\r | |
6619 | * These changes can be written back to the parent session much like a session\r | |
6620 | * can save its data to a server.\r | |
6621 | *\r | |
6622 | * Ext.create({\r | |
6623 | * xtype: 'window',\r | |
6624 | * modal: true,\r | |
6625 | *\r | |
6626 | * // Creates a new session for this Window but that session is linked\r | |
6627 | * // to a parent session (probably from the application's Viewport).\r | |
6628 | * //\r | |
6629 | * session: true,\r | |
6630 | *\r | |
6631 | * items: [{\r | |
6632 | * ...\r | |
6633 | * },{\r | |
6634 | * xtype: 'button',\r | |
6635 | * text: 'OK',\r | |
6636 | * listeners: {\r | |
6637 | * click: function () {\r | |
6638 | * // Get the Session this component has inherited (from\r | |
6639 | * // the Window) and save it back to the parent session.\r | |
6640 | * //\r | |
6641 | * this.lookupSession().save();\r | |
6642 | * }\r | |
6643 | * }\r | |
6644 | * }]\r | |
6645 | * });\r | |
6646 | *\r | |
6647 | * ### Isolated Sessions\r | |
6648 | *\r | |
6649 | * This connection of a child session to its parent session is determined by the\r | |
6650 | * `{@link Ext.data.Session#isolated isolated}` config. If `isolated` is\r | |
6651 | * set to `true` then this session will not copy anything from a higher level\r | |
6652 | * session and will instead do its own communication with the server.\r | |
6653 | *\r | |
6654 | * Ext.create({\r | |
6655 | * xtype: 'window',\r | |
6656 | * modal: true,\r | |
6657 | *\r | |
6658 | * // Creates a new session for this Window that is isolated from any\r | |
6659 | * // other sessions. All data for this session will be fetched from\r | |
6660 | * // the server and ultimately saved back to the server.\r | |
6661 | * //\r | |
6662 | * session: {\r | |
6663 | * isolated: true\r | |
6664 | * },\r | |
6665 | *\r | |
6666 | * items: [{\r | |
6667 | * ...\r | |
6668 | * },{\r | |
6669 | * xtype: 'button',\r | |
6670 | * text: 'OK',\r | |
6671 | * listeners: {\r | |
6672 | * click: function () {\r | |
6673 | * // Get the Session this component has inherited (from\r | |
6674 | * // the Window) and save it back to the server.\r | |
6675 | * //\r | |
6676 | * this.lookupSession().save();\r | |
6677 | * }\r | |
6678 | * }\r | |
6679 | * }]\r | |
6680 | * });\r | |
6681 | */\r |