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

Commit

Permalink
support dynamic imports; parser made smart enough to go in proper ord…
Browse files Browse the repository at this point in the history
…er; tests pass.
  • Loading branch information
sorvell committed Jan 28, 2014
1 parent ceeb970 commit 5297e25
Show file tree
Hide file tree
Showing 9 changed files with 122 additions and 125 deletions.
44 changes: 18 additions & 26 deletions src/HTMLImports.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
(function(scope) {

var hasNative = ('import' in document.createElement('link'));
var useNative = !scope.flags.imports && hasNative;
var flags = scope.flags;
var useNative = !flags.imports && hasNative;

var IMPORT_LINK_TYPE = 'import';

Expand Down Expand Up @@ -41,10 +42,11 @@ if (!useNative) {

var importer = {
documents: {},
preloadSelectors: [
'link[rel=' + IMPORT_LINK_TYPE + ']',
'script[src]:not([type])',
'script[src][type="text/javascript"]'
documentPreloadSelectors: 'link[rel=' + IMPORT_LINK_TYPE + ']',
importsPreloadSelectors: [
'link[rel=' + IMPORT_LINK_TYPE + ']',
'script[src]:not([type])',
'script[src][type="text/javascript"]'
].join(','),
loadNode: function(node) {
importLoader.addNode(node);
Expand All @@ -56,22 +58,15 @@ if (!useNative) {
},
marshalNodes: function(parent) {
// all preloadable nodes in inDocument
var nodes = parent.querySelectorAll(importer.preloadSelectors);
// from the main document, only load imports
// TODO(sjmiles): do this by altering the selector list instead
return this.filterMainDocumentNodes(parent, nodes);
return parent.querySelectorAll(this.loadSelectorsForNode(parent));
},
filterMainDocumentNodes: function(doc, nodes) {
var doc = parent.ownerDocument || parent;
if (doc === mainDoc) {
nodes = Array.prototype.filter.call(nodes, function(n) {
return !isScript(n);
});
}
return nodes;
loadSelectorsForNode: function(node) {
var doc = node.ownerDocument || node;
return doc === mainDoc ? this.documentPreloadSelectors :
this.importsPreloadSelectors;
},
loaded: function(url, elt, resource) {
//console.log('loaded', url, elt);
flags.load && console.log('loaded', url, elt);
// store generic resource
// TODO(sorvell): fails for nodes inside <template>.content
// see https://code.google.com/p/chromium/issues/detail?id=249381.
Expand All @@ -82,31 +77,27 @@ if (!useNative) {
if (!doc) {
// generate an HTMLDocument from data
doc = makeDocument(resource, url);
doc.__importLink = elt;
// TODO(sorvell): we cannot use MO to detect parsed nodes because
// SD polyfill does not report these as mutations.
importer.loadSubtree(doc);
importer.observe(doc);
// cache document
importer.documents[url] = doc;
}
}
// don't store import record until we're actually loaded
// store document resource
elt.import = elt.content = resource = doc;
elt.import = doc;
}
parser.parseNext();
},
errored: function(url, elt) {
elt.__resource = null;
parser.parseNext();
},
loadedAll: function() {
parser.parseNext();
}
};

var importLoader = new Loader(importer.loaded, importer.errored,
importer.loadedAll);
var importLoader = new Loader(importer.loaded.bind(importer),
importer.loadedAll.bind(importer));

function isDocumentLink(elt) {
return isLinkRel(elt, IMPORT_LINK_TYPE);
Expand Down Expand Up @@ -235,5 +226,6 @@ scope.useNative = useNative;
scope.whenImportsReady = whenImportsReady;
scope.IMPORT_LINK_TYPE = IMPORT_LINK_TYPE;
scope.isImportLoaded = isImportLoaded;
scope.importLoader = importLoader;

})(window.HTMLImports);
19 changes: 8 additions & 11 deletions src/Loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
// imports
var path = scope.path;
var xhr = scope.xhr;
var flags = scope.flags;

var Loader = function(onLoad, onError, onComplete) {
var Loader = function(onLoad, onComplete) {
this.cache = {};
this.onload = onLoad;
this.onerror = onError;
this.oncomplete = onComplete;
this.inflight = 0;
this.pending = {};
Expand Down Expand Up @@ -57,8 +57,8 @@
// don't need fetch
return true;
}
if (cache[url]) {
// complete load using cache data
var resource;
if (this.cache[url]) {
this.onload(url, elt, this.cache[url]);
// finished this transaction
this.tail();
Expand All @@ -71,6 +71,7 @@
return false;
},
fetch: function(url, elt) {
flags.load && console.log('fetch', url, elt);
var receiveXhr = function(err, resource) {
this.receive(url, elt, err, resource);
}.bind(this);
Expand All @@ -90,16 +91,12 @@
*/
},
receive: function(url, elt, err, resource) {
if (!err) {
this.cache[url] = resource;
}
this.cache[url] = resource;
var $p = this.pending[url];
for (var i=0, l=$p.length, p; (i<l) && (p=$p[i]); i++) {
if (!err) {
//if (!err) {
this.onload(url, p, resource);
} else {
this.onerror(url, p);
}
//}
this.tail();
}
this.pending[url] = null;
Expand Down
9 changes: 5 additions & 4 deletions src/Observer.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,16 @@ function addedNodes(nodes) {
for (var i=0, l=nodes.length, n; (i<l) && (n=nodes[i]); i++) {
if (shouldLoadNode(n)) {
importer.loadNode(n);
if (n.children && n.children.length) {
addedNodes(n.children);
}
}
if (n.children && n.children.length) {
addedNodes(n.children);
}
}
}

function shouldLoadNode(node) {
return (node.nodeType !== 3) && matches.call(node, importer.preloadSelectors);
return (node.nodeType === 1) && matches.call(node,
importer.loadSelectorsForNode(node));
}

var observer = new MutationObserver(handler);
Expand Down
Loading

0 comments on commit 5297e25

Please sign in to comment.