This repository has been archived by the owner on Nov 3, 2021. It is now read-only.
/
lazy_loader.js
135 lines (115 loc) · 3.38 KB
/
lazy_loader.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/* exported LazyLoader */
/* globals HtmlImports, Promise */
'use strict';
/**
* This contains a simple LazyLoader implementation
* To use:
*
* LazyLoader.load(
* ['/path/to/file.js', '/path/to/file.css', 'domNode'], callback
* );
*/
var LazyLoader = (function() {
function LazyLoader() {
this._loaded = {};
this._isLoading = {};
}
LazyLoader.prototype = {
_js: function(file, callback) {
var script = document.createElement('script');
script.src = file;
// until bug 916255 lands async is the default so
// we must disable it so scripts load in the order they where
// required.
script.async = false;
script.addEventListener('load', callback);
document.head.appendChild(script);
this._isLoading[file] = script;
},
_css: function(file, callback) {
var style = document.createElement('link');
style.type = 'text/css';
style.rel = 'stylesheet';
style.href = file;
document.head.appendChild(style);
callback();
},
_html: function(domNode, callback) {
// The next few lines are for loading html imports in DEBUG mode
if (domNode.getAttribute('is')) {
this.load(['/shared/js/html_imports.js'], function() {
HtmlImports.populate(callback);
}.bind(this));
return;
}
for (var i = 0; i < domNode.childNodes.length; i++) {
if (domNode.childNodes[i].nodeType == document.COMMENT_NODE) {
domNode.innerHTML = domNode.childNodes[i].nodeValue;
break;
}
}
window.dispatchEvent(new CustomEvent('lazyload', {
detail: domNode
}));
callback();
},
/**
* Retrieves content of JSON file.
*
* @param {String} file Path to JSON file
* @return {Promise} A promise that resolves to the JSON content
* or null in case of invalid path. Rejects if an error occurs.
*/
getJSON: function(file) {
return new Promise(function(resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open('GET', file, true);
xhr.responseType = 'json';
xhr.onerror = function(error) {
reject(error);
};
xhr.onload = function() {
resolve(xhr.response);
};
xhr.send();
});
},
load: function(files, callback) {
if (!Array.isArray(files)) {
files = [files];
}
var loadsRemaining = files.length, self = this;
function perFileCallback(file) {
if (self._isLoading[file]) {
delete self._isLoading[file];
}
self._loaded[file] = true;
if (--loadsRemaining === 0) {
if (callback) {
callback();
}
}
}
for (var i = 0; i < files.length; i++) {
var file = files[i];
if (this._loaded[file.id || file]) {
perFileCallback(file);
} else if (this._isLoading[file]) {
this._isLoading[file].addEventListener(
'load', perFileCallback.bind(null, file));
} else {
var method, idx;
if (typeof file === 'string') {
method = file.match(/\.([^.]+)$/)[1];
idx = file;
} else {
method = 'html';
idx = file.id;
}
this['_' + method](file, perFileCallback.bind(null, idx));
}
}
}
};
return new LazyLoader();
}());