-
Notifications
You must be signed in to change notification settings - Fork 0
/
math_element_lifecycle.js
105 lines (94 loc) · 3.07 KB
/
math_element_lifecycle.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
window.MathElementLifecycle = {};
(function (scope) {
'use strict';
var MML = "http://www.w3.org/1998/Math/MathML",
observerConfig = {childList: true, subtree: true},
hooks, observer;
function searchTree(node, visitor) {
if (node.localName == 'math' && node.namespaceURI == MML) {
visitor(node);
return; // don't recurse into <math> element
}
node = node.firstElementChild;
while (node) {
searchTree(node, visitor);
node = node.nextElementSibling;
}
}
function create(node) {
if (!node.__hooked__) {
node.__hooked__ = true;
if (hooks.created) {
hooks.created(node);
}
}
}
function attach(node) {
if (!node.__attached__) {
create(node);
node.__attached__ = true;
if (hooks.attached) {
hooks.attached(node);
}
}
}
function detach(node) {
if (node.__attached__) {
delete node.__attached__;
if (hooks.detached) {
hooks.detached(node);
}
}
}
function observeHandler(mutations) {
mutations.forEach(function (mutation) {
//console.log(mutation);
if (mutation.removedNodes) {
Array.prototype.forEach.call(mutation.removedNodes, function (node) {
searchTree(node, detach);
});
}
if (mutation.addedNodes) {
Array.prototype.forEach.call(mutation.addedNodes, function (node) {
searchTree(node, attach);
});
}
});
}
function createWrapper(obj, methodName) {
var orig = obj[methodName];
obj[methodName] = function () {
var node = orig.apply(this, arguments);
searchTree(node, create);
return node;
}
}
function domReady() {
var body = document.querySelector('body');
// Wrap DOM API
createWrapper(document, 'createElementNS');
createWrapper(Node.prototype, 'cloneNode');
// Call created+attached on existing <math> nodes
searchTree(body, attach);
// Listen for node additions and removals in entire body
observer = new MutationObserver(observeHandler);
observer.observe(body, observerConfig);
}
scope.register = function (_hooks) {
if (!_hooks) {
throw new Error('MathElementLifecycle.register: first argument `hooks` must not be empty');
}
if (hooks) {
throw new Error('MathElementLifecycle.register: already registered');
}
hooks = _hooks;
if (document.readyState == 'complete') {
domReady();
} else if (document.readyState == 'interactive' && !window.attachEvent) {
domReady();
} else {
document.addEventListener('DOMContentLoaded', domReady);
}
};
scope.MML = MML;
})(window.MathElementLifecycle);