Skip to content
This repository was archived by the owner on Mar 13, 2018. It is now read-only.

Commit 8d4f5ec

Browse files
author
Steve Orvell
committed
Merge pull request #79 from Polymer/dynamic
Fixes #78
2 parents af95b49 + 40d6b02 commit 8d4f5ec

File tree

7 files changed

+128
-60
lines changed

7 files changed

+128
-60
lines changed

src/HTMLImports.js

+16-8
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,15 @@
88
*/
99
(function(scope) {
1010

11+
// imports
1112
var useNative = scope.useNative;
1213
var flags = scope.flags;
13-
var IMPORT_LINK_TYPE = 'import';
14-
15-
// TODO(sorvell): SD polyfill intrusion
16-
var mainDoc = window.ShadowDOMPolyfill ?
17-
ShadowDOMPolyfill.wrapIfNeeded(document) : document;
14+
var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;
1815

1916
if (!useNative) {
2017

2118
// imports
19+
var rootDocument = scope.rootDocument;
2220
var xhr = scope.xhr;
2321
var Loader = scope.Loader;
2422
var parser = scope.parser;
@@ -30,32 +28,40 @@ if (!useNative) {
3028
// - loads any linked import documents (with deduping)
3129

3230
var importer = {
31+
3332
documents: {},
33+
3434
// nodes to load in the mian document
3535
documentPreloadSelectors: 'link[rel=' + IMPORT_LINK_TYPE + ']',
36+
3637
// nodes to load in imports
3738
importsPreloadSelectors: [
3839
'link[rel=' + IMPORT_LINK_TYPE + ']'
3940
].join(','),
41+
4042
loadNode: function(node) {
4143
importLoader.addNode(node);
4244
},
45+
4346
// load all loadable elements within the parent element
4447
loadSubtree: function(parent) {
4548
var nodes = this.marshalNodes(parent);
4649
// add these nodes to loader's queue
4750
importLoader.addNodes(nodes);
4851
},
52+
4953
marshalNodes: function(parent) {
5054
// all preloadable nodes in inDocument
5155
return parent.querySelectorAll(this.loadSelectorsForNode(parent));
5256
},
57+
5358
// find the proper set of load selectors for a given node
5459
loadSelectorsForNode: function(node) {
5560
var doc = node.ownerDocument || node;
56-
return doc === mainDoc ? this.documentPreloadSelectors :
61+
return doc === rootDocument ? this.documentPreloadSelectors :
5762
this.importsPreloadSelectors;
5863
},
64+
5965
loaded: function(url, elt, resource, err, redirectedUrl) {
6066
flags.load && console.log('loaded', url, elt);
6167
// store generic resource
@@ -84,14 +90,17 @@ if (!useNative) {
8490
}
8591
parser.parseNext();
8692
},
93+
8794
bootDocument: function(doc) {
8895
this.loadSubtree(doc);
8996
this.observe(doc);
9097
parser.parseNext();
9198
},
99+
92100
loadedAll: function() {
93101
parser.parseNext();
94102
}
103+
95104
};
96105

97106
// loader singleton
@@ -159,7 +168,7 @@ if (!useNative) {
159168
};
160169

161170
Object.defineProperty(document, 'baseURI', baseURIDescriptor);
162-
Object.defineProperty(mainDoc, 'baseURI', baseURIDescriptor);
171+
Object.defineProperty(rootDocument, 'baseURI', baseURIDescriptor);
163172
}
164173

165174
// IE shim for CustomEvent
@@ -184,5 +193,4 @@ scope.importer = importer;
184193
scope.IMPORT_LINK_TYPE = IMPORT_LINK_TYPE;
185194
scope.importLoader = importLoader;
186195

187-
188196
})(window.HTMLImports);

src/Loader.js

+13
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
};
2727

2828
Loader.prototype = {
29+
2930
addNodes: function(nodes) {
3031
// number of transactions to complete
3132
this.inflight += nodes.length;
@@ -36,6 +37,7 @@
3637
// anything to do?
3738
this.checkDone();
3839
},
40+
3941
addNode: function(node) {
4042
// number of transactions to complete
4143
this.inflight++;
@@ -44,6 +46,7 @@
4446
// anything to do?
4547
this.checkDone();
4648
},
49+
4750
require: function(elt) {
4851
var url = elt.src || elt.href;
4952
// ensure we have a standard url that can be used
@@ -56,6 +59,7 @@
5659
this.fetch(url, elt);
5760
}
5861
},
62+
5963
dedupe: function(url, elt) {
6064
if (this.pending[url]) {
6165
// add to list of nodes waiting for inUrl
@@ -76,6 +80,7 @@
7680
// need fetch (not a dupe)
7781
return false;
7882
},
83+
7984
fetch: function(url, elt) {
8085
flags.load && console.log('fetch', url, elt);
8186
if (url.match(/^data:/)) {
@@ -111,6 +116,7 @@
111116
*/
112117
}
113118
},
119+
114120
receive: function(url, elt, err, resource, redirectedUrl) {
115121
this.cache[url] = resource;
116122
var $p = this.pending[url];
@@ -122,24 +128,29 @@
122128
}
123129
this.pending[url] = null;
124130
},
131+
125132
tail: function() {
126133
--this.inflight;
127134
this.checkDone();
128135
},
136+
129137
checkDone: function() {
130138
if (!this.inflight) {
131139
this.oncomplete();
132140
}
133141
}
142+
134143
};
135144

136145
xhr = xhr || {
137146
async: true,
147+
138148
ok: function(request) {
139149
return (request.status >= 200 && request.status < 300)
140150
|| (request.status === 304)
141151
|| (request.status === 0);
142152
},
153+
143154
load: function(url, next, nextContext) {
144155
var request = new XMLHttpRequest();
145156
if (scope.flags.debug || scope.flags.bust) {
@@ -164,9 +175,11 @@
164175
request.send();
165176
return request;
166177
},
178+
167179
loadDocument: function(url, next, nextContext) {
168180
this.load(url, next, nextContext).responseType = 'document';
169181
}
182+
170183
};
171184

172185
// exports

src/Observer.js

+24-13
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,14 @@
88
*/
99
(function(scope){
1010

11+
// imports
1112
var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;
12-
var importSelector = 'link[rel=' + IMPORT_LINK_TYPE + ']';
1313
var importer = scope.importer;
1414
var parser = scope.parser;
1515

16+
var importSelector = 'link[rel=' + IMPORT_LINK_TYPE + ']';
17+
18+
1619
// we track mutations for addedNodes, looking for imports
1720
function handler(mutations) {
1821
for (var i=0, l=mutations.length, m; (i<l) && (m=mutations[i]); i++) {
@@ -23,32 +26,40 @@ function handler(mutations) {
2326
}
2427

2528
// find loadable elements and add them to the importer
29+
// IFF the owning document has already parsed, then parsable elements
30+
// need to be marked for dynamic parsing.
2631
function addedNodes(nodes) {
27-
var owner;
28-
for (var i=0, l=nodes.length, n; (i<l) && (n=nodes[i]); i++) {
29-
owner = owner || n.ownerDocument;
30-
if (shouldLoadNode(n)) {
32+
var owner, parsed;
33+
for (var i=0, l=nodes.length, n, loading; (i<l) && (n=nodes[i]); i++) {
34+
if (!owner) {
35+
owner = n.ownerDocument;
36+
parsed = parser.isParsed(owner);
37+
}
38+
// note: the act of loading kicks the parser, so we use parseDynamic's
39+
// 2nd argument to control if this added node needs to kick the parser.
40+
loading = shouldLoadNode(n);
41+
if (loading) {
3142
importer.loadNode(n);
3243
}
44+
if (shouldParseNode(n) && parsed) {
45+
parser.parseDynamic(n, loading);
46+
}
3347
if (n.children && n.children.length) {
3448
addedNodes(n.children);
3549
}
3650
}
37-
// TODO(sorvell): This is not the right approach here. We shouldn't need to
38-
// invalidate parsing when an element is added. Disabling this code
39-
// until a better approach is found.
40-
/*
41-
if (owner) {
42-
parser.invalidateParse(owner);
43-
}
44-
*/
4551
}
4652

4753
function shouldLoadNode(node) {
4854
return (node.nodeType === 1) && matches.call(node,
4955
importer.loadSelectorsForNode(node));
5056
}
5157

58+
function shouldParseNode(node) {
59+
return (node.nodeType === 1) && matches.call(node,
60+
parser.parseSelectorsForNode(node));
61+
}
62+
5263
// x-plat matches
5364
var matches = HTMLElement.prototype.matches ||
5465
HTMLElement.prototype.matchesSelector ||

0 commit comments

Comments
 (0)