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

Commit fad19b9

Browse files
committed
Merge pull request #14 from Polymer/master
6/17 master -> stable
2 parents 57961c0 + 7960a89 commit fad19b9

26 files changed

+465
-95
lines changed

.gitmodules

-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
[submodule "buildbot"]
2-
path = buildbot
3-
url = https://github.com/Polymer/buildbot.git
41
[submodule "tools"]
52
path = tools
63
url = https://github.com/Polymer/tools.git

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ For HTML imports use the `import` relation on a standard `<link>` tag, for examp
1818

1919
Include the `html-imports.js` or `html-imports.min.js` (minified) file in your project.
2020

21-
<script src="HTMLImports/html-imports.js"></script>
21+
<script src="HTMLImports/html-imports.js"></script>
2222

2323
`html-imports.js` is the debug loader and uses `document.write` to load additional modules.
2424
Use the minified version (`html-imports.min.js`) if you need to load the file dynamically.

buildbot

-1
This file was deleted.

html-imports.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
var thisFile = 'html-imports.js';
1010
var scopeName = 'HTMLImports';
1111
var modules = [
12-
'src/HTMLImports.js'
12+
'src/Parser.js',
13+
'src/HTMLImports.js',
14+
'src/boot.js'
1315
];
1416

1517
// export

src/HTMLImports.js

+117-85
Original file line numberDiff line numberDiff line change
@@ -10,82 +10,141 @@ if (!scope) {
1010
scope = window.HTMLImports = {flags:{}};
1111
}
1212

13+
// imports
14+
15+
var xhr = scope.xhr;
16+
17+
// importer
18+
1319
var IMPORT_LINK_TYPE = 'import';
20+
var STYLE_LINK_TYPE = 'stylesheet';
1421

15-
// highlander object represents a primary document (the argument to 'parse')
22+
// highlander object represents a primary document (the argument to 'load')
1623
// at the root of a tree of documents
1724

25+
// for any document, importer:
26+
// - loads any linked documents (with deduping), modifies paths and feeds them back into importer
27+
// - loads text of external script tags
28+
// - loads text of external style tags inside of <element>, modifies paths
29+
30+
// when importer 'modifies paths' in a document, this includes
31+
// - href/src/action in node attributes
32+
// - paths in inline stylesheets
33+
// - all content inside templates
34+
35+
// linked style sheets in an import have their own path fixed up when their containing import modifies paths
36+
// linked style sheets in an <element> are loaded, and the content gets path fixups
37+
// inline style sheets get path fixups when their containing import modifies paths
38+
1839
var importer = {
1940
documents: {},
2041
cache: {},
2142
preloadSelectors: [
2243
'link[rel=' + IMPORT_LINK_TYPE + ']',
23-
'script[src]',
24-
'link[rel=stylesheet]'
44+
'element link[rel=' + STYLE_LINK_TYPE + ']',
45+
'template',
46+
'script[src]'
2547
].join(','),
26-
load: function(inDocument, inNext) {
48+
loader: function(inNext) {
2749
// construct a loader instance
2850
loader = new Loader(importer.loaded, inNext);
2951
// alias the loader cache (for debugging)
3052
loader.cache = importer.cache;
53+
return loader;
54+
},
55+
load: function(inDocument, inNext) {
56+
// construct a loader instance
57+
loader = importer.loader(inNext);
3158
// add nodes from document into loader queue
3259
importer.preload(inDocument);
3360
},
3461
preload: function(inDocument) {
3562
// all preloadable nodes in inDocument
3663
var nodes = inDocument.querySelectorAll(importer.preloadSelectors);
37-
// only load imports from the main document
64+
// from the main document, only load imports
3865
// TODO(sjmiles): do this by altering the selector list instead
66+
nodes = this.filterMainDocumentNodes(inDocument, nodes);
67+
// extra link nodes from templates, filter templates out of the nodes list
68+
nodes = this.extractTemplateNodes(nodes);
69+
// add these nodes to loader's queue
70+
loader.addNodes(nodes);
71+
},
72+
filterMainDocumentNodes: function(inDocument, nodes) {
3973
if (inDocument === document) {
4074
nodes = Array.prototype.filter.call(nodes, function(n) {
41-
return isDocumentLink(n);
75+
return !isScript(n);
4276
});
4377
}
44-
// add these nodes to loader's queue
45-
loader.addNodes(nodes);
78+
return nodes;
79+
},
80+
extractTemplateNodes: function(nodes) {
81+
var extra = [];
82+
nodes = Array.prototype.filter.call(nodes, function(n) {
83+
if (n.localName === 'template') {
84+
if (n.content) {
85+
var l$ = n.content.querySelectorAll('link[rel=' + STYLE_LINK_TYPE +
86+
']');
87+
if (l$.length) {
88+
extra = extra.concat(Array.prototype.slice.call(l$, 0));
89+
}
90+
}
91+
return false;
92+
}
93+
return true;
94+
});
95+
if (extra.length) {
96+
nodes = nodes.concat(extra);
97+
}
98+
return nodes;
4699
},
47-
loaded: function(inUrl, inElt, inResource) {
48-
if (isDocumentLink(inElt)) {
49-
var document = importer.documents[inUrl];
100+
loaded: function(url, elt, resource) {
101+
if (isDocumentLink(elt)) {
102+
var document = importer.documents[url];
50103
// if we've never seen a document at this url
51104
if (!document) {
52105
// generate an HTMLDocument from data
53-
document = makeDocument(inResource, inUrl);
106+
document = makeDocument(resource, url);
54107
// resolve resource paths relative to host document
55-
path.resolvePathsInHTML(document);
108+
path.resolvePathsInHTML(document.body);
56109
// cache document
57-
importer.documents[inUrl] = document;
110+
importer.documents[url] = document;
58111
// add nodes from this document to the loader queue
59112
importer.preload(document);
60113
}
114+
// store import record
115+
elt.import = {
116+
href: url,
117+
ownerNode: elt,
118+
content: document
119+
};
61120
// store document resource
62-
inElt.content = inElt.__resource = document;
63-
} else {
64-
inElt.__resource = inResource;
65-
// resolve stylesheet resource paths relative to host document
66-
if (isStylesheetLink(inElt)) {
67-
path.resolvePathsInStylesheet(inElt);
68-
}
121+
elt.content = resource = document;
122+
}
123+
// store generic resource
124+
// TODO(sorvell): fails for nodes inside <template>.content
125+
// see https://code.google.com/p/chromium/issues/detail?id=249381.
126+
elt.__resource = resource;
127+
// css path fixups
128+
if (isStylesheetLink(elt)) {
129+
path.resolvePathsInStylesheet(elt);
69130
}
70131
}
71132
};
72133

73-
function isDocumentLink(inElt) {
74-
return isLinkRel(inElt, IMPORT_LINK_TYPE);
134+
function isDocumentLink(elt) {
135+
return isLinkRel(elt, IMPORT_LINK_TYPE);
75136
}
76137

77-
function isStylesheetLink(inElt) {
78-
return isLinkRel(inElt, 'stylesheet');
138+
function isStylesheetLink(elt) {
139+
return isLinkRel(elt, STYLE_LINK_TYPE);
79140
}
80141

81-
function isLinkRel(inElt, inRel) {
82-
return (inElt.localName === 'link' && inElt.getAttribute('rel') === inRel);
142+
function isLinkRel(elt, rel) {
143+
return elt.localName === 'link' && elt.getAttribute('rel') === rel;
83144
}
84145

85-
function inMainDocument(inElt) {
86-
return inElt.ownerDocument === document ||
87-
// TODO(sjmiles): ShadowDOMPolyfill intrusion
88-
inElt.ownerDocument.impl === document;
146+
function isScript(elt) {
147+
return elt.localName === 'script';
89148
}
90149

91150
function makeDocument(inHTML, inUrl) {
@@ -99,6 +158,10 @@ function makeDocument(inHTML, inUrl) {
99158
doc.head.appendChild(base);
100159
// install html
101160
doc.body.innerHTML = inHTML;
161+
// TODO(sorvell): MDV Polyfill intrusion: boostrap template polyfill
162+
if (window.HTMLTemplateElement && HTMLTemplateElement.bootstrap) {
163+
HTMLTemplateElement.bootstrap(doc);
164+
}
102165
return doc;
103166
}
104167

@@ -151,10 +214,11 @@ Loader.prototype = {
151214
// need fetch (not a dupe)
152215
return false;
153216
},
154-
fetch: function(inUrl, inElt) {
155-
xhr.load(inUrl, function(err, resource) {
156-
this.receive(inUrl, inElt, err, resource);
157-
}.bind(this));
217+
fetch: function(url, elt) {
218+
var receiveXhr = function(err, resource) {
219+
this.receive(url, elt, err, resource);
220+
}.bind(this);
221+
xhr.load(url, receiveXhr);
158222
},
159223
receive: function(inUrl, inElt, inErr, inResource) {
160224
if (!inErr) {
@@ -179,6 +243,10 @@ Loader.prototype = {
179243
}
180244
};
181245

246+
var URL_ATTRS = ['href', 'src', 'action'];
247+
var URL_ATTRS_SELECTOR = '[' + URL_ATTRS.join('],[') + ']';
248+
var URL_TEMPLATE_SEARCH = '{{.*}}';
249+
182250
var path = {
183251
nodeUrl: function(inNode) {
184252
return path.resolveUrl(path.getDocumentUrl(document), path.hrefOrSrc(inNode));
@@ -243,26 +311,18 @@ var path = {
243311
var r = t.join("/");
244312
return r;
245313
},
246-
resolvePathsInHTML: function(inRoot) {
247-
var docUrl = path.documentUrlFromNode(inRoot.body);
248-
// TODO(sorvell): MDV Polyfill Intrusion
249-
if (window.HTMLTemplateElement && HTMLTemplateElement.bootstrap) {
250-
HTMLTemplateElement.bootstrap(inRoot);
251-
}
252-
var node = inRoot.body;
253-
path._resolvePathsInHTML(node, docUrl);
254-
},
255-
_resolvePathsInHTML: function(inRoot, inUrl) {
256-
path.resolveAttributes(inRoot, inUrl);
257-
path.resolveStyleElts(inRoot, inUrl);
258-
// handle templates, if supported
259-
if (window.templateContent) {
260-
var templates = inRoot.querySelectorAll('template');
261-
if (templates) {
262-
forEach(templates, function(t) {
263-
path._resolvePathsInHTML(templateContent(t), inUrl);
264-
});
265-
}
314+
resolvePathsInHTML: function(root, url) {
315+
url = url || path.documentUrlFromNode(root)
316+
path.resolveAttributes(root, url);
317+
path.resolveStyleElts(root, url);
318+
// handle template.content
319+
var templates = root.querySelectorAll('template');
320+
if (templates) {
321+
forEach(templates, function(t) {
322+
if (t.content) {
323+
path.resolvePathsInHTML(t.content, url);
324+
}
325+
});
266326
}
267327
},
268328
resolvePathsInStylesheet: function(inSheet) {
@@ -306,11 +366,7 @@ var path = {
306366
}
307367
};
308368

309-
var URL_ATTRS = ['href', 'src', 'action'];
310-
var URL_ATTRS_SELECTOR = '[' + URL_ATTRS.join('],[') + ']';
311-
var URL_TEMPLATE_SEARCH = '{{.*}}';
312-
313-
var xhr = scope.xhr || {
369+
xhr = xhr || {
314370
async: true,
315371
ok: function(inRequest) {
316372
return (inRequest.status >= 200 && inRequest.status < 300)
@@ -340,30 +396,6 @@ var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach);
340396
scope.xhr = xhr;
341397
scope.importer = importer;
342398
scope.getDocumentUrl = path.getDocumentUrl;
343-
344-
// bootstrap
345-
346-
// IE shim for CustomEvent
347-
if (typeof window.CustomEvent !== 'function') {
348-
window.CustomEvent = function(inType) {
349-
var e = document.createEvent('HTMLEvents');
350-
e.initEvent(inType, true, true);
351-
return e;
352-
};
353-
}
354-
355-
document.addEventListener('DOMContentLoaded', function() {
356-
// preload document resource trees
357-
importer.load(document, function() {
358-
// TODO(sjmiles): ShadowDOM polyfill pollution
359-
var doc = window.ShadowDOMPolyfill ? ShadowDOMPolyfill.wrap(document)
360-
: document;
361-
HTMLImports.readyTime = new Date().getTime();
362-
// send HTMLImportsLoaded when finished
363-
doc.body.dispatchEvent(
364-
new CustomEvent('HTMLImportsLoaded', {bubbles: true})
365-
);
366-
});
367-
});
399+
scope.IMPORT_LINK_TYPE = IMPORT_LINK_TYPE;
368400

369401
})(window.HTMLImports);

0 commit comments

Comments
 (0)