|
7 | 7 |
|
8 | 8 | // imports
|
9 | 9 |
|
10 |
| - var extend = Polymer.extend; |
| 10 | + var extend = scope.extend; |
11 | 11 | var apis = scope.api.declaration;
|
12 | 12 |
|
13 | 13 | // imperative implementation: Polymer()
|
14 | 14 |
|
15 |
| - // maps tag names to prototypes |
16 |
| - var prototypesByName = {}; |
17 |
| - |
18 |
| - function getRegisteredPrototype(name) { |
19 |
| - return prototypesByName[name]; |
20 |
| - } |
21 |
| - |
22 |
| - // elements waiting for prototype, by name |
23 |
| - var waitPrototype = {}; |
24 |
| - |
25 | 15 | // specify an 'own' prototype for tag `name`
|
26 | 16 | function element(name, prototype) {
|
27 | 17 | //console.log('registering [' + name + ']');
|
|
31 | 21 | notifyPrototype(name);
|
32 | 22 | }
|
33 | 23 |
|
34 |
| - function notifyPrototype(name) { |
35 |
| - if (waitPrototype[name]) { |
36 |
| - waitPrototype[name].registerWhenReady(); |
37 |
| - delete waitPrototype[name]; |
38 |
| - } |
39 |
| - } |
40 |
| - |
41 |
| - // elements waiting for super, by name |
42 |
| - var waitSuper = {}; |
43 |
| - |
44 |
| - function notifySuper(name) { |
45 |
| - registered[name] = true; |
46 |
| - var waiting = waitSuper[name]; |
47 |
| - if (waiting) { |
48 |
| - waiting.forEach(function(w) { |
49 |
| - w.registerWhenReady(); |
50 |
| - }); |
51 |
| - delete waitSuper[name]; |
52 |
| - } |
53 |
| - } |
54 |
| - |
55 |
| - // track document.register'ed tag names |
56 |
| - |
57 |
| - var registered = {}; |
58 |
| - |
59 |
| - function isRegistered(name) { |
60 |
| - return registered[name]; |
61 |
| - } |
62 |
| - |
63 |
| - // returns a prototype that chains to <tag> or HTMLElement |
64 |
| - function generatePrototype(tag) { |
65 |
| - return Object.create(HTMLElement.getPrototypeForTag(tag)); |
66 |
| - } |
67 |
| - |
68 |
| - // On platforms that do not support __proto__ (IE10), the prototype chain |
69 |
| - // of a custom element is simulated via installation of __proto__. |
70 |
| - // Although custom elements manages this, we install it here so it's |
71 |
| - // available during desugaring. |
72 |
| - function ensurePrototypeTraversal(prototype) { |
73 |
| - if (!Object.__proto__) { |
74 |
| - var ancestor = Object.getPrototypeOf(prototype); |
75 |
| - prototype.__proto__ = ancestor; |
76 |
| - if (scope.isBase(ancestor)) { |
77 |
| - ancestor.__proto__ = Object.getPrototypeOf(ancestor); |
78 |
| - } |
79 |
| - } |
80 |
| - } |
81 |
| - |
82 |
| - function whenImportsLoaded(doThis) { |
83 |
| - if (window.HTMLImports && !HTMLImports.readyTime) { |
84 |
| - addEventListener('HTMLImportsLoaded', doThis); |
85 |
| - } else { |
86 |
| - doThis(); |
87 |
| - } |
88 |
| - } |
89 |
| - |
90 | 24 | // declarative implementation: <polymer-element>
|
91 | 25 |
|
92 |
| - var prototype = generatePrototype(); |
93 |
| - |
94 |
| - extend(prototype, { |
95 |
| - // TODO(sjmiles): temporary BC |
96 |
| - readyCallback: function() { |
97 |
| - this.createdCallback(); |
98 |
| - }, |
| 26 | + var prototype = extend(Object.create(HTMLElement.prototype), { |
99 | 27 | createdCallback: function() {
|
100 | 28 | // fetch the element name
|
101 | 29 | this.name = this.getAttribute('name');
|
|
113 | 41 | var script = document.createElement('script');
|
114 | 42 | script.textContent = 'Polymer(\'' + name + '\');';
|
115 | 43 | this.appendChild(script);
|
116 |
| - |
117 | 44 | }
|
118 | 45 | return;
|
119 | 46 | }
|
|
127 | 54 | return;
|
128 | 55 | }
|
129 | 56 | }
|
130 |
| - // TODO(sjmiles): HTMLImports polyfill awareness |
| 57 | + // TODO(sjmiles): HTMLImports polyfill awareness: |
131 | 58 | // elements in the main document are likely to parse
|
132 | 59 | // in advance of elements in imports because the
|
133 | 60 | // polyfill parser is simulated
|
|
152 | 79 | // Potentially remove when spec bug is addressed.
|
153 | 80 | // https://www.w3.org/Bugs/Public/show_bug.cgi?id=21407
|
154 | 81 | this.addResolvePathApi();
|
155 |
| - ensurePrototypeTraversal(this.prototype); |
156 | 82 | // declarative features
|
157 | 83 | this.desugar();
|
158 | 84 | // under ShadowDOMPolyfill, transforms to approximate missing CSS features
|
|
183 | 109 | // cache the list of custom prototype names for faster reflection
|
184 | 110 | this.cacheProperties();
|
185 | 111 | },
|
186 |
| - // prototype marshaling |
187 |
| - // build prototype combining extendee, Polymer base, and named api |
188 |
| - generateCustomPrototype: function (name, extnds) { |
189 |
| - // basal prototype |
190 |
| - var prototype = this.generateBasePrototype(extnds); |
191 |
| - // mixin registered custom api |
192 |
| - return this.addNamedApi(prototype, name); |
193 |
| - }, |
194 |
| - // build prototype combining extendee, Polymer base, and named api |
195 |
| - generateBasePrototype: function(extnds) { |
196 |
| - // create a prototype based on tag-name extension |
197 |
| - var prototype = generatePrototype(extnds); |
198 |
| - // insert base api in inheritance chain (if needed) |
199 |
| - return this.ensureBaseApi(prototype); |
200 |
| - }, |
201 |
| - // install Polymer instance api into prototype chain, as needed |
202 |
| - ensureBaseApi: function(prototype) { |
203 |
| - if (!prototype.PolymerBase) { |
204 |
| - Object.keys(scope.api.instance).forEach(function(n) { |
205 |
| - extend(prototype, scope.api.instance[n]); |
206 |
| - }); |
207 |
| - prototype = Object.create(prototype); |
208 |
| - } |
209 |
| - // inherit publishing meta-data |
210 |
| - this.inheritAttributesObjects(prototype); |
211 |
| - // inherit event delegates |
212 |
| - this.inheritDelegates(prototype); |
213 |
| - // return buffed-up prototype |
214 |
| - return prototype; |
215 |
| - }, |
216 |
| - // mix api registered to 'name' into 'prototype' |
217 |
| - addNamedApi: function(prototype, name) { |
218 |
| - // combine custom api into prototype |
219 |
| - return extend(prototype, getRegisteredPrototype(name)); |
220 |
| - }, |
221 |
| - // make a fresh object that inherits from a prototype object |
222 |
| - inheritObject: function(prototype, name) { |
223 |
| - // copy inherited properties onto a new object |
224 |
| - prototype[name] = extend({}, Object.getPrototypeOf(prototype)[name]); |
225 |
| - }, |
226 |
| - // register 'prototype' to custom element 'name', store constructor |
227 |
| - registerPrototype: function(name) { |
228 |
| - // register the custom type |
229 |
| - this.ctor = document.register(name, { |
230 |
| - prototype: this.prototype |
231 |
| - }); |
232 |
| - // constructor shenanigans |
233 |
| - this.prototype.constructor = this.ctor; |
234 |
| - // register the prototype with HTMLElement for name lookup |
235 |
| - HTMLElement.register(name, this.prototype); |
236 |
| - }, |
237 | 112 | // if a named constructor is requested in element, map a reference
|
238 | 113 | // to the constructor to the given symbol
|
239 | 114 | publishConstructor: function() {
|
|
244 | 119 | }
|
245 | 120 | });
|
246 | 121 |
|
| 122 | + // semi-pluggable APIs |
| 123 | + // TODO(sjmiles): should be fully pluggable |
247 | 124 | Object.keys(apis).forEach(function(n) {
|
248 | 125 | extend(prototype, apis[n]);
|
249 | 126 | });
|
|
252 | 129 |
|
253 | 130 | document.register('polymer-element', {prototype: prototype});
|
254 | 131 |
|
255 |
| - // namespace shenanigans so we can expose our scope on the registration function |
| 132 | + // utility and bookkeeping |
| 133 | + |
| 134 | + // maps tag names to prototypes |
| 135 | + var prototypesByName = {}; |
| 136 | + |
| 137 | + function getRegisteredPrototype(name) { |
| 138 | + return prototypesByName[name]; |
| 139 | + } |
| 140 | + |
| 141 | + // elements waiting for prototype, by name |
| 142 | + var waitPrototype = {}; |
| 143 | + |
| 144 | + function notifyPrototype(name) { |
| 145 | + if (waitPrototype[name]) { |
| 146 | + waitPrototype[name].registerWhenReady(); |
| 147 | + delete waitPrototype[name]; |
| 148 | + } |
| 149 | + } |
| 150 | + |
| 151 | + // elements waiting for super, by name |
| 152 | + var waitSuper = {}; |
| 153 | + |
| 154 | + function notifySuper(name) { |
| 155 | + registered[name] = true; |
| 156 | + var waiting = waitSuper[name]; |
| 157 | + if (waiting) { |
| 158 | + waiting.forEach(function(w) { |
| 159 | + w.registerWhenReady(); |
| 160 | + }); |
| 161 | + delete waitSuper[name]; |
| 162 | + } |
| 163 | + } |
| 164 | + |
| 165 | + // track document.register'ed tag names |
| 166 | + |
| 167 | + var registered = {}; |
| 168 | + |
| 169 | + function isRegistered(name) { |
| 170 | + return registered[name]; |
| 171 | + } |
| 172 | + |
| 173 | + function whenImportsLoaded(doThis) { |
| 174 | + if (window.HTMLImports && !HTMLImports.readyTime) { |
| 175 | + addEventListener('HTMLImportsLoaded', doThis); |
| 176 | + } else { |
| 177 | + doThis(); |
| 178 | + } |
| 179 | + } |
| 180 | + |
| 181 | + // exports |
| 182 | + |
| 183 | + scope.getRegisteredPrototype = getRegisteredPrototype; |
| 184 | + |
| 185 | + // namespace shenanigans so we can expose our scope on the registration |
| 186 | + // function |
256 | 187 |
|
257 | 188 | // TODO(sjmiles): find a way to do this that is less terrible
|
258 | 189 | // copy window.Polymer properties onto `element()`
|
|
0 commit comments