forked from mereskin-zz/html-template-polyfill
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhtml-template-polyfill.js
80 lines (68 loc) · 2.48 KB
/
html-template-polyfill.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
(function(){
'use strict'
// If `content` is in HTMLTemplateElement.prototype,
// then polyfill is not required
if(window.HTMLTemplateElement && 'content' in window.HTMLTemplateElement.prototype){ return; }
setTemplateDisplayToNone();
createHTMLTemplateElementPrototype();
createTemplateHostDocument();
polyfillContentProperty();
upgradeExistingElements();
setUpObserver();
function createHTMLTemplateElementPrototype() {
window.HTMLTemplateElement = function(){
throw new TypeError('Illegal constructor');
};
HTMLTemplateElement.prototype = Object.create(HTMLElement.prototype);
};
function setTemplateDisplayToNone(){
var style = document.createElement('style');
style.textContent = 'template { display: none; }';
document.head.appendChild(style);
};
function createTemplateHostDocument() {
// Create inert document to host template's document fragments
HTMLTemplateElement.prototype._templateHostDocument = document.implementation.createHTMLDocument('');
};
function polyfillContentProperty() {
Object.defineProperty(HTMLTemplateElement.prototype, 'content', {
get: function(){
if(!this._contentFragment) {
this._createContentFragment();
};
return this._contentFragment;
}
});
// If HTMLTemplateElement is unknown, then
HTMLTemplateElement.prototype._createContentFragment = function(){
this._contentFragment = this._templateHostDocument.createDocumentFragment();
while(this.firstChild) {
this._contentFragment.appendChild(this.removeChild(this.firstChild));
}
};
};
function applyPolyfill(template){
if(template.htmlTemplatePolyfillApplied) { return; }
template.htmlTemplatePolyfillApplied = true;
// TODO: or mixin?
template.__proto__ = HTMLTemplateElement.prototype;
template._createContentFragment();
};
function upgradeExistingElements() {
Array.prototype.forEach.call(document.querySelectorAll('template'), applyPolyfill);
};
function setUpObserver(){
function childListCallback(mutations){
Array.prototype.forEach.call(mutations, function(mx){
if(mx.addedNodes) {
Array.prototype.forEach.call(mx.addedNodes, function(node) {
if(node.tagName && node.tagName == 'TEMPLATE') {
applyPolyfill(node);
}
});
};
});
};
new MutationObserver(childListCallback).observe(document, { subtree: true, childList: true });
};
})();