@inc2734/unitone-css 1.4.0 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app.css +1 -1
- package/dist/app.js +1 -1
- package/dist/behaviors/dividers.js +1 -1
- package/dist/behaviors/index.js +1 -1
- package/dist/behaviors/stairs.js +1 -1
- package/dist/layout-primitives/cluster/react.js +1 -1
- package/dist/layout-primitives/index.js +1 -1
- package/dist/layout-primitives/marquee/behavior.js +1 -1
- package/dist/layout-primitives/marquee/react.js +1 -1
- package/dist/layout-primitives/responsive-grid/react.js +1 -1
- package/dist/layout-primitives/stack/react.js +1 -1
- package/dist/layout-primitives/switcher/react.js +1 -1
- package/dist/layout-primitives/vertical-writing/behavior.js +1 -1
- package/dist/layout-primitives/vertical-writing/react.js +1 -1
- package/dist/layout-primitives/with-sidebar/react.js +1 -1
- package/dist/library.js +1 -1
- package/package.json +2 -2
- package/src/layout-primitives/marquee/_index.scss +2 -3
- package/src/library.js +498 -425
- package/src/observer-scope.js +53 -0
- package/src/register-layout-initializer.js +35 -3
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Owns the resources and queued work of one layout observer initialization.
|
|
3
|
+
*
|
|
4
|
+
* @param {Element} target Target element.
|
|
5
|
+
* @returns {object} Observer lifetime and cleanup helpers.
|
|
6
|
+
*/
|
|
7
|
+
export const createObserverScope = (target) => {
|
|
8
|
+
const defaultView = target.ownerDocument.defaultView;
|
|
9
|
+
const cleanups = new Set();
|
|
10
|
+
const frames = new Set();
|
|
11
|
+
let disposed = false;
|
|
12
|
+
|
|
13
|
+
return {
|
|
14
|
+
get disposed() {
|
|
15
|
+
return disposed;
|
|
16
|
+
},
|
|
17
|
+
addCleanup(cleanup) {
|
|
18
|
+
if (disposed) {
|
|
19
|
+
cleanup();
|
|
20
|
+
} else {
|
|
21
|
+
cleanups.add(cleanup);
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
requestAnimationFrame(callback) {
|
|
25
|
+
if (disposed) {
|
|
26
|
+
return 0;
|
|
27
|
+
}
|
|
28
|
+
if (!defaultView?.requestAnimationFrame) {
|
|
29
|
+
callback();
|
|
30
|
+
return 0;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const id = defaultView.requestAnimationFrame((time) => {
|
|
34
|
+
frames.delete(id);
|
|
35
|
+
if (!disposed) {
|
|
36
|
+
callback(time);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
frames.add(id);
|
|
40
|
+
return id;
|
|
41
|
+
},
|
|
42
|
+
dispose() {
|
|
43
|
+
if (disposed) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
disposed = true;
|
|
47
|
+
frames.forEach((id) => defaultView.cancelAnimationFrame(id));
|
|
48
|
+
frames.clear();
|
|
49
|
+
cleanups.forEach((cleanup) => cleanup());
|
|
50
|
+
cleanups.clear();
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
};
|
|
@@ -23,7 +23,7 @@ const getRegistry = () => {
|
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
const initializeInitializer = (initializer, root) => {
|
|
26
|
-
if (!initializer.enabled() || root
|
|
26
|
+
if (!root?.isConnected || !initializer.enabled() || root.nodeType !== Node.ELEMENT_NODE) {
|
|
27
27
|
return;
|
|
28
28
|
}
|
|
29
29
|
|
|
@@ -42,8 +42,11 @@ const initializeInitializer = (initializer, root) => {
|
|
|
42
42
|
return;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
initializer.initialize(target);
|
|
45
|
+
const cleanup = initializer.initialize(target);
|
|
46
46
|
initializer.initialized.add(target);
|
|
47
|
+
if ('function' === typeof cleanup) {
|
|
48
|
+
initializer.cleanups.set(target, cleanup);
|
|
49
|
+
}
|
|
47
50
|
});
|
|
48
51
|
};
|
|
49
52
|
|
|
@@ -58,6 +61,27 @@ const initializeNode = (root) => {
|
|
|
58
61
|
});
|
|
59
62
|
};
|
|
60
63
|
|
|
64
|
+
// Inspect detached subtrees without relying on selectors that may have changed before removal.
|
|
65
|
+
const disposeNode = (root) => {
|
|
66
|
+
const registry = getRegistry();
|
|
67
|
+
if (!registry || root?.isConnected || root?.nodeType !== Node.ELEMENT_NODE) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
[root, ...root.querySelectorAll('*')].forEach((target) => {
|
|
72
|
+
registry.initializers.forEach((initializer) => {
|
|
73
|
+
const cleanup = initializer.cleanups?.get(target);
|
|
74
|
+
if (!cleanup || target.isConnected) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
initializer.cleanups.delete(target);
|
|
79
|
+
initializer.initialized.delete(target);
|
|
80
|
+
cleanup();
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
};
|
|
84
|
+
|
|
61
85
|
const flushPendingNodes = () => {
|
|
62
86
|
const registry = getRegistry();
|
|
63
87
|
if (!registry) {
|
|
@@ -82,13 +106,20 @@ const observeDocument = () => {
|
|
|
82
106
|
|
|
83
107
|
registry.observer = new MutationObserver((entries) => {
|
|
84
108
|
entries.forEach((entry) => {
|
|
109
|
+
entry.removedNodes.forEach(disposeNode);
|
|
85
110
|
entry.addedNodes.forEach((addedNode) => {
|
|
86
|
-
if (addedNode?.nodeType === Node.ELEMENT_NODE) {
|
|
111
|
+
if (addedNode?.isConnected && addedNode.nodeType === Node.ELEMENT_NODE) {
|
|
87
112
|
registry.pendingNodes.add(addedNode);
|
|
88
113
|
}
|
|
89
114
|
});
|
|
90
115
|
});
|
|
91
116
|
|
|
117
|
+
registry.pendingNodes.forEach((node) => {
|
|
118
|
+
if (!node.isConnected) {
|
|
119
|
+
registry.pendingNodes.delete(node);
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
|
|
92
123
|
if (!registry.rafId && 0 < registry.pendingNodes.size) {
|
|
93
124
|
registry.rafId = requestAnimationFrame(flushPendingNodes);
|
|
94
125
|
}
|
|
@@ -111,6 +142,7 @@ export const registerLayoutInitializer = ({ key, selector, initialize, enabled =
|
|
|
111
142
|
initialize,
|
|
112
143
|
enabled,
|
|
113
144
|
initialized: new WeakSet(),
|
|
145
|
+
cleanups: new WeakMap(),
|
|
114
146
|
};
|
|
115
147
|
|
|
116
148
|
registry.initializers.set(key, initializer);
|