-
-
Notifications
You must be signed in to change notification settings - Fork 3
/
swap.js
45 lines (45 loc) · 2.11 KB
/
swap.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
var Swap = (() => {
"use strict";
var loaders = {}, unloaders = {};
register_links();
new MutationObserver(dom_changes).observe(document.querySelector("html"), { childList: true, subtree: true });
window.addEventListener("popstate", () => update(location.href, "[swap-history-restore]", false, "body"));
window.addEventListener("DOMContentLoaded", dom_load);
function update(href, target, pushstate, fallback = null) {
fetch(href, { headers: new Headers({"swap-target": target}) }).then(r => r.text()).then(html => {
var tmp = document.createElement('html');
tmp.innerHTML = html;
(document.querySelector(target) ?? document.querySelector(fallback)).outerHTML = (tmp.querySelector(target) ?? tmp.querySelector(fallback)).outerHTML;
if (pushstate)
history.pushState({}, "", href);
register_links();
});
}
function register_links() {
for (const elt of document.querySelectorAll('*[swap-target]'))
elt.onclick = e => {
update(elt.getAttribute('href'), elt.getAttribute('swap-target'), elt.getAttribute('swap-history'));
e.preventDefault();
}
}
function dom_changes(mutations) {
for (var selector in unloaders)
for (var m of mutations)
for (var n of m.removedNodes)
if (n.matches && n.querySelector && (n.matches(selector) || n.querySelector(selector))) {
unloaders[selector]();
delete unloaders[selector];
}
for (var selector in loaders)
for (var m of mutations)
for (var n of m.addedNodes)
if (n.matches && n.querySelector && (n.matches(selector) || n.querySelector(selector)))
unloaders[selector] = loaders[selector]();
}
function dom_load() {
for (var selector in loaders)
if (document.querySelector(selector))
unloaders[selector] = loaders[selector]();
}
return {loaders: loaders};
})();