]> git.proxmox.com Git - extjs.git/blame - extjs/packages/core/src/dom/Fly.js
add extjs 6.0.1 sources
[extjs.git] / extjs / packages / core / src / dom / Fly.js
CommitLineData
6527f429
DM
1/**\r
2 * A flyweight Ext.dom.Element that can be dynamically attached to a DOM node.\r
3 * In general this class should not be instantiated directly. Use {@link Ext#fly}\r
4 * to create and retrieve Fly instances.\r
5 */\r
6Ext.define('Ext.dom.Fly', {\r
7 extend: 'Ext.dom.Element',\r
8 alternateClassName: 'Ext.dom.Element.Fly',\r
9\r
10 // This adds the ability to wrap DOCUMENT_FRAGMENT_NODE\r
11 // Document Fragments cannot have event listeners and therefore do not\r
12 // need the caching mechanism provided by Ext.get.\r
13 // However the many Element APIs are useful such as Traversal, child appending/removing.\r
14 validNodeTypes: {\r
15 1: 1, // ELEMENT_NODE\r
16 9: 1, // DOCUMENT_NODE\r
17 11: 1 // DOCUMENT_FRAGMENT_NODE\r
18 },\r
19\r
20 /**\r
21 * @property {Boolean} isFly\r
22 * This is `true` to identify Element flyweights\r
23 */\r
24 isFly: true,\r
25\r
26 constructor: function(dom) {\r
27 this.dom = dom;\r
28\r
29 // set an "el" property that references "this". This allows\r
30 // Ext.util.Positionable methods to operate on this.el.dom since it\r
31 // gets mixed into both Element and Component\r
32 this.el = this;\r
33 },\r
34\r
35 attach: function (dom) {\r
36 var me = this;\r
37\r
38 if (!dom) {\r
39 return me.detach();\r
40 }\r
41 me.dom = dom;\r
42\r
43 // If the element is not being managed by an Ext.Element instance,\r
44 // we have to assume that the classList/classMap in the data object are out of sync with reality.\r
45 if (!Ext.cache[dom.id]) {\r
46 me.getData().isSynchronized = false;\r
47 }\r
48\r
49 return me;\r
50 },\r
51\r
52 detach: function() {\r
53 this.dom = null;\r
54 },\r
55\r
56 addListener:\r
57 //<debug>\r
58 function() {\r
59 Ext.raise(\r
60 "Cannot use addListener() on Ext.dom.Fly instances. " +\r
61 "Please use Ext.get() to retrieve an Ext.dom.Element instance instead."\r
62 );\r
63 } ||\r
64 //</debug>\r
65 null,\r
66\r
67 removeListener: \r
68 //<debug>\r
69 function() {\r
70 Ext.raise(\r
71 "Cannot use removeListener() on Ext.dom.Fly instances. " +\r
72 "Please use Ext.get() to retrieve an Ext.dom.Element instance instead."\r
73 );\r
74 } ||\r
75 //</debug>\r
76 null\r
77}, function(Fly) {\r
78 var flyweights = {};\r
79\r
80 /**\r
81 * @member Ext\r
82 * @property {Object} cache\r
83 * Stores `Fly` instances keyed by their assigned or generated name.\r
84 * @readonly\r
85 * @private\r
86 * @since 5.0.0\r
87 */\r
88 Fly.cache = flyweights;\r
89\r
90 /**\r
91 * @member Ext\r
92 * @method fly\r
93 * Gets the globally shared flyweight Element, with the passed node as the active\r
94 * element. Do not store a reference to this element - the dom node can be overwritten\r
95 * by other code. {@link Ext#fly} is alias for {@link Ext.dom.Element#fly}.\r
96 *\r
97 * Use this to make one-time references to DOM elements which are not going to be\r
98 * accessed again either by application code, or by Ext's classes. If accessing an\r
99 * element which will be processed regularly, then {@link Ext#get Ext.get} will be\r
100 * more appropriate to take advantage of the caching provided by the\r
101 * {@link Ext.dom.Element} class.\r
102 * \r
103 * If this method is called with and id or element that has already been cached by\r
104 * a previous call to Ext.get() it will return the cached Element instead of the\r
105 * flyweight instance.\r
106 *\r
107 * @param {String/HTMLElement} dom The DOM node or `id`.\r
108 * @param {String} [named] Allows for creation of named reusable flyweights to prevent \r
109 * conflicts (e.g. internally Ext uses "_global").\r
110 * @return {Ext.dom.Element} The shared Element object (or `null` if no matching\r
111 * element was found).\r
112 */\r
113 Ext.fly = function(dom, named) {\r
114 var fly = null,\r
115 fn = Ext.fly,\r
116 nodeType, data;\r
117\r
118 // name the flyweight after the calling method name if possible.\r
119 named = named || (fn.caller && fn.caller.$name) || '_global';\r
120\r
121 dom = Ext.getDom(dom);\r
122\r
123 if (dom) {\r
124 nodeType = dom.nodeType;\r
125 // check if we have a valid node type or if the el is a window object before\r
126 // proceeding. This allows elements, document fragments, and document/window\r
127 // objects (even those inside iframes) to be wrapped.\r
128 // Note: a window object can be detected by comparing it's window property to\r
129 // itself, but we must use == for the comparison because === will return false\r
130 // in IE8 even though the 2 window objects are the same\r
131 if (Fly.prototype.validNodeTypes[nodeType] || (!nodeType && (dom.window == dom))) {\r
132 fly = Ext.cache[dom.id];\r
133\r
134 // If there's no Element cached, or the element cached is for another DOM node, return a Fly\r
135 if (!fly || fly.dom !== dom) {\r
136 fly = flyweights[named] || (flyweights[named] = new Fly());\r
137 fly.dom = dom;\r
138 data = fly.getData(true);\r
139 if (data) {\r
140 data.isSynchronized = false;\r
141 }\r
142 }\r
143 }\r
144 }\r
145 return fly;\r
146 };\r
147});\r