]>
Commit | Line | Data |
---|---|---|
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 | |
6 | Ext.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 |