Skip to content

Commit a32f21b

Browse files
committed
Merge pull request #241 from Polymer/master
8/15 master -> stable
2 parents 12fb68a + 38ce9b4 commit a32f21b

29 files changed

+423
-300
lines changed

gruntfile.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ module.exports = function(grunt) {
3838
"declaration/events.js",
3939
"declaration/properties.js",
4040
"declaration/attributes.js",
41+
"declaration/prototype.js",
4142
"declaration/polymer-element.js",
4243
"deprecated.js"
4344
].map(function(n) {
@@ -140,7 +141,10 @@ module.exports = function(grunt) {
140141
'../CustomElements',
141142
'../PointerEvents',
142143
'../PointerGestures',
143-
'../mdv'
144+
'../polymer-expressions',
145+
'../observe-js',
146+
'../NodeBind',
147+
'../TemplateInstances'
144148
]
145149
},
146150
dest: 'build.log',

polymer.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ var modules = [
3131
"declaration/events.js",
3232
"declaration/properties.js",
3333
"declaration/attributes.js",
34+
"declaration/prototype.js",
3435
"declaration/polymer-element.js",
3536
"deprecated.js"
3637
].map(function(n) {
@@ -50,10 +51,10 @@ var script = document.querySelector('script[src*="' + thisFile + '"]');
5051
var src = script.attributes.src.value;
5152
var basePath = src.slice(0, src.indexOf(thisFile));
5253

53-
if (!window.Loader) {
54+
if (!window.PolymerLoader) {
5455
var path = basePath + 'tools/loader/loader.js';
5556
document.write('<script src="' + path + '"></script>');
5657
}
57-
document.write('<script>Loader.load("' + scopeName + '")</script>');
58+
document.write('<script>PolymerLoader.load("' + scopeName + '")</script>');
5859

5960
})();

src/declaration/polymer-element.js

Lines changed: 73 additions & 168 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,11 @@
77

88
// imports
99

10-
var extend = Polymer.extend;
10+
var extend = scope.extend;
1111
var apis = scope.api.declaration;
1212

1313
// imperative implementation: Polymer()
1414

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-
2515
// specify an 'own' prototype for tag `name`
2616
function element(name, prototype) {
2717
//console.log('registering [' + name + ']');
@@ -31,71 +21,9 @@
3121
notifyPrototype(name);
3222
}
3323

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-
9024
// declarative implementation: <polymer-element>
9125

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), {
9927
createdCallback: function() {
10028
// fetch the element name
10129
this.name = this.getAttribute('name');
@@ -108,48 +36,22 @@
10836
if (!getRegisteredPrototype(name)) {
10937
// then wait for a prototype
11038
waitPrototype[name] = this;
111-
// TODO(sjmiles): 'noscript' gambit is mutually exclusive
112-
// with 'async' gambit below
113-
//
11439
// if explicitly marked as 'noscript'
11540
if (this.hasAttribute('noscript')) {
116-
// go async to allow children to parse
117-
setTimeout(function() {
118-
// register with the default prototype
119-
element(name, null);
120-
}, 0);
121-
}
122-
// TODO(sjmiles): 'async' gambit is deemed too dangerous
123-
// because it changes the timing of noscript elements
124-
// in import from 'timeout 0' to 'HTMLImportsReady'
125-
/*
126-
// if we are not explicitly async...
127-
if (!this.hasAttribute('async')) {
128-
// then we expect the script to be registered
129-
// by end of microtask(-ish) and can otherwise
130-
// consider this element to have no script
131-
//
132-
// TODO(sjmiles):
133-
// we have to wait for end-of-microtask because
134-
// native CE upgrades polymer-element (any custom
135-
// element, really) *before* it's children are
136-
// parsed, and it's common for the script to
137-
// exist as a child of the polymer-element
138-
//
139-
// additionally, there is a massive asynchrony
140-
// between parsing HTML in imports and executing
141-
// script that foils the end of microtask gambit
142-
// Waiting on HTMLImportsLoaded signal solves
143-
// both timing problems for imports loaded
144-
// at startup under the import polyfill
145-
whenImportsLoaded(function() {
146-
if (!getRegisteredPrototype(name)) {
147-
console.warn('giving up waiting for script for [' + name + ']');
148-
element(name, null);
149-
}
150-
});
41+
// TODO(sorvell): CustomElements polyfill awareness:
42+
// noscript elements should upgrade in logical order
43+
// script injection ensures this under native custom elements;
44+
// under imports + ce polyfill, scripts run before upgrades
45+
// dependencies should be ready at upgrade time so register
46+
// prototype at this time.
47+
if (window.CustomElements && !CustomElements.useNative) {
48+
element(name);
49+
} else {
50+
var script = document.createElement('script');
51+
script.textContent = 'Polymer(\'' + name + '\');';
52+
this.appendChild(script);
53+
}
15154
}
152-
*/
15355
return;
15456
}
15557
// fetch our extendee name
@@ -162,7 +64,7 @@
16264
return;
16365
}
16466
}
165-
// TODO(sjmiles): HTMLImports polyfill awareness
67+
// TODO(sjmiles): HTMLImports polyfill awareness:
16668
// elements in the main document are likely to parse
16769
// in advance of elements in imports because the
16870
// polyfill parser is simulated
@@ -177,7 +79,6 @@
17779
}
17880
},
17981
register: function(name, extendee) {
180-
//console.log('register', name, extendee);
18182
// build prototype combining extendee, Polymer base, and named api
18283
this.prototype = this.generateCustomPrototype(name, extendee);
18384
// backref
@@ -188,7 +89,6 @@
18889
// Potentially remove when spec bug is addressed.
18990
// https://www.w3.org/Bugs/Public/show_bug.cgi?id=21407
19091
this.addResolvePathApi();
191-
ensurePrototypeTraversal(this.prototype);
19292
// declarative features
19393
this.desugar();
19494
// under ShadowDOMPolyfill, transforms to approximate missing CSS features
@@ -219,57 +119,6 @@
219119
// cache the list of custom prototype names for faster reflection
220120
this.cacheProperties();
221121
},
222-
// prototype marshaling
223-
// build prototype combining extendee, Polymer base, and named api
224-
generateCustomPrototype: function (name, extnds) {
225-
// basal prototype
226-
var prototype = this.generateBasePrototype(extnds);
227-
// mixin registered custom api
228-
return this.addNamedApi(prototype, name);
229-
},
230-
// build prototype combining extendee, Polymer base, and named api
231-
generateBasePrototype: function(extnds) {
232-
// create a prototype based on tag-name extension
233-
var prototype = generatePrototype(extnds);
234-
// insert base api in inheritance chain (if needed)
235-
return this.ensureBaseApi(prototype);
236-
},
237-
// install Polymer instance api into prototype chain, as needed
238-
ensureBaseApi: function(prototype) {
239-
if (!prototype.PolymerBase) {
240-
Object.keys(scope.api.instance).forEach(function(n) {
241-
extend(prototype, scope.api.instance[n]);
242-
});
243-
prototype = Object.create(prototype);
244-
}
245-
// inherit publishing meta-data
246-
this.inheritAttributesObjects(prototype);
247-
// inherit event delegates
248-
this.inheritDelegates(prototype);
249-
// return buffed-up prototype
250-
return prototype;
251-
},
252-
// mix api registered to 'name' into 'prototype'
253-
addNamedApi: function(prototype, name) {
254-
// combine custom api into prototype
255-
return extend(prototype, getRegisteredPrototype(name));
256-
},
257-
// make a fresh object that inherits from a prototype object
258-
inheritObject: function(prototype, name) {
259-
// copy inherited properties onto a new object
260-
prototype[name] = extend({}, Object.getPrototypeOf(prototype)[name]);
261-
},
262-
// register 'prototype' to custom element 'name', store constructor
263-
registerPrototype: function(name) {
264-
// register the custom type
265-
this.ctor = document.register(name, {
266-
prototype: this.prototype
267-
});
268-
// constructor shenanigans
269-
this.prototype.constructor = this.ctor;
270-
// register the prototype with HTMLElement for name lookup
271-
HTMLElement.register(name, this.prototype);
272-
},
273122
// if a named constructor is requested in element, map a reference
274123
// to the constructor to the given symbol
275124
publishConstructor: function() {
@@ -280,6 +129,8 @@
280129
}
281130
});
282131

132+
// semi-pluggable APIs
133+
// TODO(sjmiles): should be fully pluggable
283134
Object.keys(apis).forEach(function(n) {
284135
extend(prototype, apis[n]);
285136
});
@@ -288,7 +139,61 @@
288139

289140
document.register('polymer-element', {prototype: prototype});
290141

291-
// namespace shenanigans so we can expose our scope on the registration function
142+
// utility and bookkeeping
143+
144+
// maps tag names to prototypes
145+
var prototypesByName = {};
146+
147+
function getRegisteredPrototype(name) {
148+
return prototypesByName[name];
149+
}
150+
151+
// elements waiting for prototype, by name
152+
var waitPrototype = {};
153+
154+
function notifyPrototype(name) {
155+
if (waitPrototype[name]) {
156+
waitPrototype[name].registerWhenReady();
157+
delete waitPrototype[name];
158+
}
159+
}
160+
161+
// elements waiting for super, by name
162+
var waitSuper = {};
163+
164+
function notifySuper(name) {
165+
registered[name] = true;
166+
var waiting = waitSuper[name];
167+
if (waiting) {
168+
waiting.forEach(function(w) {
169+
w.registerWhenReady();
170+
});
171+
delete waitSuper[name];
172+
}
173+
}
174+
175+
// track document.register'ed tag names
176+
177+
var registered = {};
178+
179+
function isRegistered(name) {
180+
return registered[name];
181+
}
182+
183+
function whenImportsLoaded(doThis) {
184+
if (window.HTMLImports && !HTMLImports.readyTime) {
185+
addEventListener('HTMLImportsLoaded', doThis);
186+
} else {
187+
doThis();
188+
}
189+
}
190+
191+
// exports
192+
193+
scope.getRegisteredPrototype = getRegisteredPrototype;
194+
195+
// namespace shenanigans so we can expose our scope on the registration
196+
// function
292197

293198
// TODO(sjmiles): find a way to do this that is less terrible
294199
// copy window.Polymer properties onto `element()`

0 commit comments

Comments
 (0)