@inc2734/unitone-css 0.94.3 → 0.95.0
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 -0
- package/dist/behaviors/index.js +1 -0
- package/dist/behaviors/stairs.js +1 -0
- package/dist/compatibility/fluid-typography.js +1 -0
- package/dist/compatibility/index.js +1 -0
- package/dist/layout-primitives/both-sides/react.js +1 -0
- package/dist/layout-primitives/center/react.js +1 -0
- package/dist/layout-primitives/cluster/react.js +1 -0
- package/dist/layout-primitives/container/react.js +1 -0
- package/dist/layout-primitives/cover/react.js +1 -0
- package/dist/layout-primitives/decorator/react.js +1 -0
- package/dist/layout-primitives/float/react.js +1 -0
- package/dist/layout-primitives/frame/react.js +1 -0
- package/dist/layout-primitives/gutters/react.js +1 -0
- package/dist/layout-primitives/index.js +1 -0
- package/dist/layout-primitives/layers/react.js +1 -0
- package/dist/layout-primitives/marquee/behavior.js +1 -0
- package/dist/layout-primitives/marquee/react.js +1 -0
- package/dist/layout-primitives/masonry/react.js +1 -0
- package/dist/layout-primitives/reel/react.js +1 -0
- package/dist/layout-primitives/responsive-grid/react.js +1 -0
- package/dist/layout-primitives/stack/react.js +1 -0
- package/dist/layout-primitives/switcher/react.js +1 -0
- package/dist/layout-primitives/text/react.js +1 -0
- package/dist/layout-primitives/texture/react.js +1 -0
- package/dist/layout-primitives/vertical-writing/behavior.js +1 -0
- package/dist/layout-primitives/vertical-writing/react.js +1 -0
- package/dist/layout-primitives/with-sidebar/react.js +1 -0
- package/dist/library.js +1 -1
- package/package.json +24 -19
- package/src/app.js +3 -110
- package/src/app.scss +4 -4
- package/src/behaviors/_index.scss +43 -0
- package/src/{helper → behaviors}/_typography.scss +1 -1
- package/src/behaviors/dividers.js +8 -0
- package/src/behaviors/index.js +2 -0
- package/src/behaviors/stairs.js +8 -0
- package/src/compatibility/fluid-typography.js +18 -0
- package/src/compatibility/index.js +1 -0
- package/src/foundation/_foundation-core.scss +107 -0
- package/src/foundation/_foundation.scss +2 -106
- package/src/foundation/_index.scss +1 -0
- package/src/helper/_helper.scss +2 -42
- package/src/layout-primitives/_index.scss +1 -0
- package/src/layout-primitives/_layout-primitives-core.scss +41 -0
- package/src/layout-primitives/_layout-primitives.scss +2 -42
- package/src/layout-primitives/both-sides/_both-sides-core.scss +31 -0
- package/src/layout-primitives/both-sides/_both-sides.scss +2 -30
- package/src/layout-primitives/both-sides/_index.scss +1 -0
- package/src/layout-primitives/both-sides/react.jsx +1 -0
- package/src/layout-primitives/center/_center-core.scss +22 -0
- package/src/layout-primitives/center/_center.scss +2 -21
- package/src/layout-primitives/center/_index.scss +1 -0
- package/src/layout-primitives/center/react.jsx +1 -0
- package/src/layout-primitives/cluster/_cluster-core.scss +126 -0
- package/src/layout-primitives/cluster/_cluster.scss +2 -125
- package/src/layout-primitives/cluster/_index.scss +1 -0
- package/src/layout-primitives/cluster/react.jsx +3 -0
- package/src/layout-primitives/container/_container-core.scss +18 -0
- package/src/layout-primitives/container/_container.scss +2 -17
- package/src/layout-primitives/container/_index.scss +1 -0
- package/src/layout-primitives/container/react.jsx +1 -0
- package/src/layout-primitives/cover/_cover-core.scss +80 -0
- package/src/layout-primitives/cover/_cover.scss +2 -79
- package/src/layout-primitives/cover/_index.scss +1 -0
- package/src/layout-primitives/cover/react.jsx +1 -0
- package/src/layout-primitives/decorator/_decorator-core.scss +104 -0
- package/src/layout-primitives/decorator/_decorator.scss +2 -103
- package/src/layout-primitives/decorator/_index.scss +1 -0
- package/src/layout-primitives/decorator/react.jsx +1 -0
- package/src/layout-primitives/float/_float-core.scss +29 -0
- package/src/layout-primitives/float/_float.scss +2 -28
- package/src/layout-primitives/float/_index.scss +1 -0
- package/src/layout-primitives/float/react.jsx +1 -0
- package/src/layout-primitives/frame/_frame-core.scss +36 -0
- package/src/layout-primitives/frame/_frame.scss +2 -35
- package/src/layout-primitives/frame/_index.scss +1 -0
- package/src/layout-primitives/frame/react.jsx +1 -0
- package/src/layout-primitives/gutters/_gutters-core.scss +12 -0
- package/src/layout-primitives/gutters/_gutters.scss +2 -11
- package/src/layout-primitives/gutters/_index.scss +1 -0
- package/src/layout-primitives/gutters/react.jsx +1 -0
- package/src/layout-primitives/index.js +2 -20
- package/src/layout-primitives/layers/_index.scss +1 -0
- package/src/layout-primitives/layers/_layers-core.scss +139 -0
- package/src/layout-primitives/layers/_layers.scss +2 -138
- package/src/layout-primitives/layers/react.jsx +1 -0
- package/src/layout-primitives/marquee/_index.scss +1 -0
- package/src/layout-primitives/marquee/_marquee-core.scss +73 -0
- package/src/layout-primitives/marquee/_marquee.scss +2 -72
- package/src/layout-primitives/marquee/behavior.js +8 -0
- package/src/layout-primitives/marquee/react.jsx +3 -0
- package/src/layout-primitives/masonry/_index.scss +1 -0
- package/src/layout-primitives/masonry/_masonry-core.scss +26 -0
- package/src/layout-primitives/masonry/_masonry.scss +2 -25
- package/src/layout-primitives/masonry/react.jsx +1 -0
- package/src/layout-primitives/reel/_index.scss +1 -0
- package/src/layout-primitives/reel/_reel-core.scss +55 -0
- package/src/layout-primitives/reel/_reel.scss +2 -54
- package/src/layout-primitives/reel/react.jsx +1 -0
- package/src/layout-primitives/responsive-grid/_index.scss +1 -0
- package/src/layout-primitives/responsive-grid/_responsive-grid-core.scss +249 -0
- package/src/layout-primitives/responsive-grid/_responsive-grid.scss +2 -248
- package/src/layout-primitives/responsive-grid/react.jsx +4 -0
- package/src/layout-primitives/stack/_index.scss +1 -0
- package/src/layout-primitives/stack/_stack-core.scss +201 -0
- package/src/layout-primitives/stack/_stack.scss +2 -200
- package/src/layout-primitives/stack/react.jsx +3 -0
- package/src/layout-primitives/switcher/_index.scss +1 -0
- package/src/layout-primitives/switcher/_switcher-core.scss +70 -0
- package/src/layout-primitives/switcher/_switcher.scss +2 -69
- package/src/layout-primitives/switcher/react.jsx +3 -0
- package/src/layout-primitives/text/_index.scss +1 -0
- package/src/layout-primitives/text/_text-core.scss +169 -0
- package/src/layout-primitives/text/_text.scss +2 -168
- package/src/layout-primitives/text/react.jsx +1 -0
- package/src/layout-primitives/texture/_index.scss +1 -0
- package/src/layout-primitives/texture/_texture-core.scss +235 -0
- package/src/layout-primitives/texture/_texture.scss +2 -234
- package/src/layout-primitives/texture/react.jsx +1 -0
- package/src/layout-primitives/vertical-writing/_index.scss +1 -0
- package/src/layout-primitives/vertical-writing/_vertical-writing-core.scss +118 -0
- package/src/layout-primitives/vertical-writing/_vertical-writing.scss +2 -117
- package/src/layout-primitives/vertical-writing/behavior.js +8 -0
- package/src/layout-primitives/vertical-writing/react.jsx +3 -0
- package/src/layout-primitives/with-sidebar/_index.scss +1 -0
- package/src/layout-primitives/with-sidebar/_with-sidebar-core.scss +337 -0
- package/src/layout-primitives/with-sidebar/_with-sidebar.scss +2 -336
- package/src/layout-primitives/with-sidebar/react.jsx +3 -0
- package/src/library.js +653 -219
- package/src/register-layout-initializer.js +132 -0
- package/src/settings/_html.scss +1 -1
- package/src/settings/_index.scss +1 -0
- package/src/settings/_root.scss +1 -1
- package/src/settings/_settings-core.scss +3 -0
- package/src/settings/_settings.scss +3 -3
- package/src/variables/_index.scss +1 -0
- package/src/variables/_variables-core.scss +78 -0
- package/src/variables/_variables.scss +2 -77
- package/dist/index.js +0 -1
- package/src/index.js +0 -1
- /package/src/{helper → behaviors}/_align-content.scss +0 -0
- /package/src/{helper → behaviors}/_align-items.scss +0 -0
- /package/src/{helper → behaviors}/_align-self.scss +0 -0
- /package/src/{helper → behaviors}/_align.scss +0 -0
- /package/src/{helper → behaviors}/_auto-phrase.scss +0 -0
- /package/src/{helper → behaviors}/_auto-repeat.scss +0 -0
- /package/src/{helper → behaviors}/_background-clip.scss +0 -0
- /package/src/{helper → behaviors}/_gap.scss +0 -0
- /package/src/{helper → behaviors}/_gutters.scss +0 -0
- /package/src/{helper → behaviors}/_justify-content.scss +0 -0
- /package/src/{helper → behaviors}/_justify-items.scss +0 -0
- /package/src/{helper → behaviors}/_justify-self.scss +0 -0
- /package/src/{helper → behaviors}/_link-decoration.scss +0 -0
- /package/src/{helper → behaviors}/_mix-blend-mode.scss +0 -0
- /package/src/{helper → behaviors}/_negative-gap.scss +0 -0
- /package/src/{helper → behaviors}/_overflow.scss +0 -0
- /package/src/{helper → behaviors}/_padding.scss +0 -0
- /package/src/{helper → behaviors}/_position.scss +0 -0
- /package/src/{helper → behaviors}/_stairs.scss +0 -0
- /package/src/{helper → behaviors}/_text-orientation.scss +0 -0
package/src/library.js
CHANGED
|
@@ -1,11 +1,33 @@
|
|
|
1
1
|
const layoutAttributeName = 'data-unitone-layout';
|
|
2
|
-
|
|
2
|
+
const layoutIntersectionMargin = 200;
|
|
3
|
+
const layoutIntersectionRootMargin = `${layoutIntersectionMargin}px 0px`;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Returns layout tokens from the target element.
|
|
7
|
+
*
|
|
8
|
+
* @param {Element | null | undefined} element Target element.
|
|
9
|
+
* @returns {string[]} Layout tokens.
|
|
10
|
+
*/
|
|
3
11
|
const getLayoutTokens = (element) =>
|
|
4
12
|
(element.getAttribute(layoutAttributeName) ?? '').split(/\s+/).filter(Boolean);
|
|
5
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Returns tokens with the specified values removed.
|
|
16
|
+
*
|
|
17
|
+
* @param {string[]} tokens Source tokens.
|
|
18
|
+
* @param {string[]} removedTokens Tokens to remove.
|
|
19
|
+
* @returns {string[]} Filtered tokens.
|
|
20
|
+
*/
|
|
6
21
|
const withoutLayoutTokens = (tokens, removedTokens) =>
|
|
7
22
|
tokens.filter((value) => !removedTokens.includes(value));
|
|
8
23
|
|
|
24
|
+
/**
|
|
25
|
+
* Updates the layout token attribute on the element.
|
|
26
|
+
*
|
|
27
|
+
* @param {Element} element Target element.
|
|
28
|
+
* @param {string[]} tokens Tokens to set.
|
|
29
|
+
* @returns {void}
|
|
30
|
+
*/
|
|
9
31
|
const setLayoutTokens = (element, tokens) => {
|
|
10
32
|
const nextValue = tokens.filter(Boolean).join(' ');
|
|
11
33
|
if ((element.getAttribute(layoutAttributeName) ?? '') !== nextValue) {
|
|
@@ -13,9 +35,15 @@ const setLayoutTokens = (element, tokens) => {
|
|
|
13
35
|
}
|
|
14
36
|
};
|
|
15
37
|
|
|
38
|
+
/**
|
|
39
|
+
* Observes target resizes and invokes the callback when a relevant change is detected.
|
|
40
|
+
*
|
|
41
|
+
* @param {Element} target Target element.
|
|
42
|
+
* @param {(target: Element, entry?: ResizeObserverEntry) => void} callback Callback to run.
|
|
43
|
+
* @param {{ getValue?: (entry: ResizeObserverEntry) => unknown, delay?: number }} [options]
|
|
44
|
+
* @returns {ResizeObserver} ResizeObserver instance.
|
|
45
|
+
*/
|
|
16
46
|
const createResizeObserver = (target, callback, { getValue, delay = 250 } = {}) => {
|
|
17
|
-
callback(target);
|
|
18
|
-
|
|
19
47
|
let prevValue;
|
|
20
48
|
let isFirstEntry = true;
|
|
21
49
|
|
|
@@ -42,6 +70,14 @@ const createResizeObserver = (target, callback, { getValue, delay = 250 } = {})
|
|
|
42
70
|
return observer;
|
|
43
71
|
};
|
|
44
72
|
|
|
73
|
+
/**
|
|
74
|
+
* Creates a MutationObserver for the target node.
|
|
75
|
+
*
|
|
76
|
+
* @param {Node} target Target node.
|
|
77
|
+
* @param {MutationObserverInit} options Observer options.
|
|
78
|
+
* @param {(entries: MutationRecord[]) => void} callback Callback to run.
|
|
79
|
+
* @returns {MutationObserver} MutationObserver instance.
|
|
80
|
+
*/
|
|
45
81
|
const createMutationObserver = (target, options, callback) => {
|
|
46
82
|
const observer = new MutationObserver((entries) => {
|
|
47
83
|
requestAnimationFrame(() => {
|
|
@@ -58,12 +94,366 @@ const createMutationObserver = (target, options, callback) => {
|
|
|
58
94
|
return observer;
|
|
59
95
|
};
|
|
60
96
|
|
|
97
|
+
/**
|
|
98
|
+
* Creates an IntersectionObserver for the target element.
|
|
99
|
+
*
|
|
100
|
+
* @param {Element} target Target element.
|
|
101
|
+
* @param {(entry: IntersectionObserverEntry) => void} callback Callback to run.
|
|
102
|
+
* @returns {IntersectionObserver} IntersectionObserver instance.
|
|
103
|
+
*/
|
|
104
|
+
const createIntersectionObserver = (target, callback) => {
|
|
105
|
+
const observer = new IntersectionObserver(
|
|
106
|
+
([entry]) => {
|
|
107
|
+
if (entry) {
|
|
108
|
+
callback(entry);
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
{ rootMargin: layoutIntersectionRootMargin },
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
observer.observe(target);
|
|
115
|
+
|
|
116
|
+
return observer;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Returns a scheduler that coalesces re-application work into a single frame.
|
|
121
|
+
*
|
|
122
|
+
* @param {Element} target Target element.
|
|
123
|
+
* @param {(target: Element) => void} callback Callback to run.
|
|
124
|
+
* @returns {() => void} Schedule function.
|
|
125
|
+
*/
|
|
126
|
+
const createScheduledTargetCallback = (target, callback) => {
|
|
127
|
+
let rafId = 0;
|
|
128
|
+
let defaultView;
|
|
129
|
+
|
|
130
|
+
return () => {
|
|
131
|
+
defaultView = target?.ownerDocument?.defaultView;
|
|
132
|
+
if (!defaultView?.requestAnimationFrame) {
|
|
133
|
+
callback(target);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (rafId) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
rafId = defaultView.requestAnimationFrame(() => {
|
|
142
|
+
rafId = 0;
|
|
143
|
+
defaultView = null;
|
|
144
|
+
|
|
145
|
+
if (target?.isConnected) {
|
|
146
|
+
callback(target);
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
};
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Observes resizes on the target and its direct children.
|
|
154
|
+
*
|
|
155
|
+
* @param {Element} target Target element.
|
|
156
|
+
* @param {(target: Element) => void} callback Callback to run.
|
|
157
|
+
* @param {{ getValue?: (entry: ResizeObserverEntry) => unknown, delay?: number, onChildList?: (entries: MutationRecord[]) => void }} [options]
|
|
158
|
+
* @returns {{ resizeObserver: ResizeObserver, mutationObserver: MutationObserver }}
|
|
159
|
+
*/
|
|
160
|
+
const createDirectChildrenResizeObserver = (
|
|
161
|
+
target,
|
|
162
|
+
callback,
|
|
163
|
+
{ getValue, delay = 250, onChildList } = {},
|
|
164
|
+
) => {
|
|
165
|
+
const prevValues = new WeakMap();
|
|
166
|
+
const observedChildren = new Set();
|
|
167
|
+
|
|
168
|
+
const observer = new ResizeObserver(
|
|
169
|
+
debounce((entries) => {
|
|
170
|
+
let shouldApply = false;
|
|
171
|
+
|
|
172
|
+
for (const entry of entries) {
|
|
173
|
+
const currentValue = getValue?.(entry);
|
|
174
|
+
if (!prevValues.has(entry.target)) {
|
|
175
|
+
prevValues.set(entry.target, currentValue);
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (undefined === currentValue || currentValue !== prevValues.get(entry.target)) {
|
|
180
|
+
shouldApply = true;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
prevValues.set(entry.target, currentValue);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (shouldApply) {
|
|
187
|
+
callback(target);
|
|
188
|
+
}
|
|
189
|
+
}, delay),
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
const syncObservedChildren = () => {
|
|
193
|
+
Array.from(observedChildren).forEach((child) => {
|
|
194
|
+
if (child.parentElement !== target) {
|
|
195
|
+
observer.unobserve(child);
|
|
196
|
+
observedChildren.delete(child);
|
|
197
|
+
prevValues.delete(child);
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
Array.from(target?.children ?? []).forEach((child) => {
|
|
202
|
+
if (observedChildren.has(child)) {
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
observer.observe(child);
|
|
207
|
+
observedChildren.add(child);
|
|
208
|
+
});
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
observer.observe(target);
|
|
212
|
+
syncObservedChildren();
|
|
213
|
+
|
|
214
|
+
const mutationObserver = createMutationObserver(target, { childList: true }, (entries) => {
|
|
215
|
+
if (!entries.some((entry) => 'childList' === entry.type)) {
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
syncObservedChildren();
|
|
220
|
+
onChildList?.(entries);
|
|
221
|
+
callback(target);
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
return {
|
|
225
|
+
resizeObserver: observer,
|
|
226
|
+
mutationObserver,
|
|
227
|
+
};
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Observes attribute changes on direct children.
|
|
232
|
+
*
|
|
233
|
+
* @param {Element} target Target element.
|
|
234
|
+
* @param {(target: Element) => void} callback Callback to run.
|
|
235
|
+
* @param {{ attributeFilter: string[], shouldApply: (entry: MutationRecord) => boolean, attributeOldValue?: boolean }} options
|
|
236
|
+
* @returns {{ observer: MutationObserver, syncObservedChildren: () => void }}
|
|
237
|
+
*/
|
|
238
|
+
const createDirectChildrenAttributeObserver = (
|
|
239
|
+
target,
|
|
240
|
+
callback,
|
|
241
|
+
{ attributeFilter, shouldApply, attributeOldValue = true } = {},
|
|
242
|
+
) => {
|
|
243
|
+
const observer = new MutationObserver((entries) => {
|
|
244
|
+
requestAnimationFrame(() => {
|
|
245
|
+
if (!target?.isConnected) {
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
if (
|
|
250
|
+
entries.some(
|
|
251
|
+
(entry) =>
|
|
252
|
+
'attributes' === entry.type &&
|
|
253
|
+
entry.target.parentElement === target &&
|
|
254
|
+
shouldApply(entry),
|
|
255
|
+
)
|
|
256
|
+
) {
|
|
257
|
+
callback(target);
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
const syncObservedChildren = () => {
|
|
263
|
+
observer.disconnect();
|
|
264
|
+
Array.from(target?.children ?? []).forEach((child) => {
|
|
265
|
+
observer.observe(child, {
|
|
266
|
+
attributes: true,
|
|
267
|
+
attributeFilter,
|
|
268
|
+
attributeOldValue,
|
|
269
|
+
});
|
|
270
|
+
});
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
syncObservedChildren();
|
|
274
|
+
|
|
275
|
+
return {
|
|
276
|
+
observer,
|
|
277
|
+
syncObservedChildren,
|
|
278
|
+
};
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Creates a bundled observer setup for layout re-application.
|
|
283
|
+
*
|
|
284
|
+
* @param {Element} target Target element.
|
|
285
|
+
* @param {(target: Element) => void} apply Apply function.
|
|
286
|
+
* @param {{
|
|
287
|
+
* getResizeValue?: (entry: ResizeObserverEntry) => unknown,
|
|
288
|
+
* delay?: number,
|
|
289
|
+
* observeResize?: boolean,
|
|
290
|
+
* observeIntersection?: boolean,
|
|
291
|
+
* observeDirectChildrenResize?: boolean,
|
|
292
|
+
* targetMutation?: { options: MutationObserverInit, shouldApply?: (entries: MutationRecord[]) => boolean },
|
|
293
|
+
* directChildMutation?: { attributeFilter: string[], shouldApply: (entry: MutationRecord) => boolean, attributeOldValue?: boolean }
|
|
294
|
+
* }} [options]
|
|
295
|
+
* @returns {void}
|
|
296
|
+
*/
|
|
297
|
+
const createLayoutObserver = (
|
|
298
|
+
target,
|
|
299
|
+
apply,
|
|
300
|
+
{
|
|
301
|
+
getResizeValue,
|
|
302
|
+
delay = 250,
|
|
303
|
+
observeResize = true,
|
|
304
|
+
observeIntersection = false,
|
|
305
|
+
observeDirectChildrenResize = false,
|
|
306
|
+
targetMutation,
|
|
307
|
+
directChildMutation,
|
|
308
|
+
} = {},
|
|
309
|
+
) => {
|
|
310
|
+
const shouldObserveIntersection =
|
|
311
|
+
observeIntersection && 'undefined' !== typeof IntersectionObserver;
|
|
312
|
+
let isIntersecting = !shouldObserveIntersection || isNearViewport(target);
|
|
313
|
+
let needsApply = shouldObserveIntersection && !isIntersecting;
|
|
314
|
+
|
|
315
|
+
const runApply = (element = target) => {
|
|
316
|
+
if (!element?.isConnected) {
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
if (shouldObserveIntersection && !isIntersecting) {
|
|
321
|
+
needsApply = true;
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
needsApply = false;
|
|
326
|
+
apply(element);
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
const schedule = createScheduledTargetCallback(target, runApply);
|
|
330
|
+
const scheduleApply = () => {
|
|
331
|
+
if (!target?.isConnected) {
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
if (shouldObserveIntersection && !isIntersecting) {
|
|
336
|
+
needsApply = true;
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
needsApply = true;
|
|
341
|
+
schedule();
|
|
342
|
+
};
|
|
343
|
+
|
|
344
|
+
let syncDirectChildAttributes = () => {};
|
|
345
|
+
|
|
346
|
+
const resizeBundle = !observeResize
|
|
347
|
+
? {
|
|
348
|
+
resizeObserver: null,
|
|
349
|
+
mutationObserver: null,
|
|
350
|
+
}
|
|
351
|
+
: observeDirectChildrenResize
|
|
352
|
+
? createDirectChildrenResizeObserver(target, scheduleApply, {
|
|
353
|
+
getValue: getResizeValue,
|
|
354
|
+
delay,
|
|
355
|
+
onChildList: () => {
|
|
356
|
+
syncDirectChildAttributes();
|
|
357
|
+
},
|
|
358
|
+
})
|
|
359
|
+
: {
|
|
360
|
+
resizeObserver: createResizeObserver(target, scheduleApply, {
|
|
361
|
+
getValue: getResizeValue,
|
|
362
|
+
delay,
|
|
363
|
+
}),
|
|
364
|
+
};
|
|
365
|
+
|
|
366
|
+
if (shouldObserveIntersection) {
|
|
367
|
+
createIntersectionObserver(target, (entry) => {
|
|
368
|
+
isIntersecting = entry.isIntersecting;
|
|
369
|
+
if (isIntersecting && needsApply) {
|
|
370
|
+
scheduleApply();
|
|
371
|
+
}
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
if (targetMutation?.options) {
|
|
376
|
+
createMutationObserver(target, targetMutation.options, (entries) => {
|
|
377
|
+
if (targetMutation.shouldApply?.(entries) ?? 0 < entries.length) {
|
|
378
|
+
scheduleApply();
|
|
379
|
+
}
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
const directChildAttributeBundle =
|
|
384
|
+
directChildMutation?.attributeFilter && directChildMutation.shouldApply
|
|
385
|
+
? createDirectChildrenAttributeObserver(target, scheduleApply, {
|
|
386
|
+
attributeFilter: directChildMutation.attributeFilter,
|
|
387
|
+
shouldApply: directChildMutation.shouldApply,
|
|
388
|
+
attributeOldValue: directChildMutation.attributeOldValue,
|
|
389
|
+
})
|
|
390
|
+
: null;
|
|
391
|
+
|
|
392
|
+
if (directChildAttributeBundle) {
|
|
393
|
+
syncDirectChildAttributes = directChildAttributeBundle.syncObservedChildren;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
if (!resizeBundle.mutationObserver && directChildAttributeBundle) {
|
|
397
|
+
createMutationObserver(target, { childList: true }, (entries) => {
|
|
398
|
+
if (!entries.some((entry) => 'childList' === entry.type)) {
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
syncDirectChildAttributes();
|
|
403
|
+
scheduleApply();
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
if (!shouldObserveIntersection || isIntersecting) {
|
|
408
|
+
runApply(target);
|
|
409
|
+
}
|
|
410
|
+
};
|
|
411
|
+
|
|
61
412
|
const getBorderBoxInlineSize = (entry) => entry.borderBoxSize?.[0].inlineSize;
|
|
62
413
|
|
|
63
414
|
const getContentRectWidth = (entry) => parseInt(entry.contentRect?.width);
|
|
64
415
|
|
|
65
416
|
const hasLayoutBox = (element) => !!element?.isConnected && 0 < element.getClientRects().length;
|
|
66
417
|
|
|
418
|
+
const isNearViewport = (element) => {
|
|
419
|
+
if (!hasLayoutBox(element)) {
|
|
420
|
+
return false;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
const defaultView = element?.ownerDocument?.defaultView;
|
|
424
|
+
if (!defaultView) {
|
|
425
|
+
return true;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
const rect = element.getBoundingClientRect();
|
|
429
|
+
const viewportWidth = defaultView.innerWidth;
|
|
430
|
+
const viewportHeight = defaultView.innerHeight;
|
|
431
|
+
|
|
432
|
+
return (
|
|
433
|
+
rect.bottom > -layoutIntersectionMargin &&
|
|
434
|
+
rect.right > 0 &&
|
|
435
|
+
rect.top < viewportHeight + layoutIntersectionMargin &&
|
|
436
|
+
rect.left < viewportWidth
|
|
437
|
+
);
|
|
438
|
+
};
|
|
439
|
+
|
|
440
|
+
/**
|
|
441
|
+
* Returns whether the mutation list contains a matching attributes record.
|
|
442
|
+
*
|
|
443
|
+
* @param {MutationRecord[]} entries Mutation records.
|
|
444
|
+
* @param {(entry: MutationRecord) => boolean} predicate Match predicate.
|
|
445
|
+
* @returns {boolean} Whether a matching attributes mutation exists.
|
|
446
|
+
*/
|
|
447
|
+
const hasAttributeMutation = (entries, predicate) =>
|
|
448
|
+
entries.some((entry) => 'attributes' === entry.type && predicate(entry));
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* Coalesces repeated calls into the final call within the delay window.
|
|
452
|
+
*
|
|
453
|
+
* @param {Function} fn Function to wrap.
|
|
454
|
+
* @param {number} delay Delay in milliseconds.
|
|
455
|
+
* @returns {Function} Debounced function.
|
|
456
|
+
*/
|
|
67
457
|
export function debounce(fn, delay) {
|
|
68
458
|
let timer;
|
|
69
459
|
|
|
@@ -76,6 +466,12 @@ export function debounce(fn, delay) {
|
|
|
76
466
|
};
|
|
77
467
|
}
|
|
78
468
|
|
|
469
|
+
/**
|
|
470
|
+
* Recalculates line wrapping state for divider layouts.
|
|
471
|
+
*
|
|
472
|
+
* @param {Element} target Target element.
|
|
473
|
+
* @returns {void}
|
|
474
|
+
*/
|
|
79
475
|
export const setDividerLinewrap = (target) => {
|
|
80
476
|
const children = Array.from(target?.children ?? []);
|
|
81
477
|
const firstChild = children[0];
|
|
@@ -144,68 +540,83 @@ export const setDividerLinewrap = (target) => {
|
|
|
144
540
|
setLayoutTokens(target, nextTargetLayout);
|
|
145
541
|
};
|
|
146
542
|
|
|
543
|
+
/**
|
|
544
|
+
* Creates the observer bundle for divider layouts.
|
|
545
|
+
*
|
|
546
|
+
* @param {Element} target Target element.
|
|
547
|
+
* @param {{ ignore?: { layout?: string[], className?: string[] } }} [args]
|
|
548
|
+
* @returns {void}
|
|
549
|
+
*/
|
|
147
550
|
export const dividersResizeObserver = (target, args = {}) => {
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
551
|
+
const shouldRecalculateByAttributeMutation = (entry) => {
|
|
552
|
+
if ('data-unitone-layout' === entry.attributeName) {
|
|
553
|
+
const ignoreUnitoneLayouts = [
|
|
554
|
+
...(args?.ignore?.layout ?? []),
|
|
555
|
+
...['divider:initialized', '-bol', '-linewrap', '-stack'],
|
|
556
|
+
];
|
|
557
|
+
|
|
558
|
+
const current = (entry.target.getAttribute(entry.attributeName) ?? '')
|
|
559
|
+
.split(' ')
|
|
560
|
+
.filter((v) => !ignoreUnitoneLayouts.includes(v))
|
|
561
|
+
.join(' ');
|
|
562
|
+
|
|
563
|
+
const old = (entry.oldValue ?? '')
|
|
564
|
+
.split(' ')
|
|
565
|
+
.filter((v) => !ignoreUnitoneLayouts.includes(v))
|
|
566
|
+
.join(' ');
|
|
567
|
+
|
|
568
|
+
return current !== old;
|
|
569
|
+
}
|
|
159
570
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
if ('attributes' === entry.type && 'data-unitone-layout' === entry.attributeName) {
|
|
163
|
-
const ignoreUnitoneLayouts = [
|
|
164
|
-
...(args?.ignore?.layout ?? []),
|
|
165
|
-
...['divider:initialized', '-bol', '-linewrap', '-stack'],
|
|
166
|
-
];
|
|
167
|
-
|
|
168
|
-
const current = (entry.target.getAttribute(entry.attributeName) ?? '')
|
|
169
|
-
.split(' ')
|
|
170
|
-
.filter((v) => !ignoreUnitoneLayouts.includes(v))
|
|
171
|
-
.join(' ');
|
|
172
|
-
|
|
173
|
-
const old = (entry.oldValue ?? '')
|
|
174
|
-
.split(' ')
|
|
175
|
-
.filter((v) => !ignoreUnitoneLayouts.includes(v))
|
|
176
|
-
.join(' ');
|
|
177
|
-
|
|
178
|
-
if (current !== old) {
|
|
179
|
-
setDividerLinewrap(target);
|
|
180
|
-
}
|
|
181
|
-
} else if ('attributes' === entry.type && 'class' === entry.attributeName) {
|
|
182
|
-
const ignoreClassNames = [...(args?.ignore?.className ?? [])];
|
|
571
|
+
if ('class' === entry.attributeName) {
|
|
572
|
+
const ignoreClassNames = [...(args?.ignore?.className ?? [])];
|
|
183
573
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
574
|
+
const current = (entry.target.getAttribute(entry.attributeName) ?? '')
|
|
575
|
+
.split(' ')
|
|
576
|
+
.filter((v) => !ignoreClassNames.includes(v))
|
|
577
|
+
.join(' ');
|
|
188
578
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
579
|
+
const old = (entry.oldValue ?? '')
|
|
580
|
+
.split(' ')
|
|
581
|
+
.filter((v) => !ignoreClassNames.includes(v))
|
|
582
|
+
.join(' ');
|
|
193
583
|
|
|
194
|
-
|
|
195
|
-
setDividerLinewrap(target);
|
|
196
|
-
}
|
|
197
|
-
} else if ('attributes' === entry.type && 'style' === entry.attributeName) {
|
|
198
|
-
setDividerLinewrap(target);
|
|
199
|
-
}
|
|
584
|
+
return current !== old;
|
|
200
585
|
}
|
|
201
|
-
});
|
|
202
586
|
|
|
203
|
-
|
|
204
|
-
resizeObserver: observer,
|
|
205
|
-
mutationObserver: mObserver,
|
|
587
|
+
return 'style' === entry.attributeName;
|
|
206
588
|
};
|
|
589
|
+
|
|
590
|
+
createLayoutObserver(target, setDividerLinewrap, {
|
|
591
|
+
getResizeValue: getBorderBoxInlineSize,
|
|
592
|
+
observeIntersection: true,
|
|
593
|
+
observeDirectChildrenResize: true,
|
|
594
|
+
targetMutation: {
|
|
595
|
+
options: {
|
|
596
|
+
attributes: true,
|
|
597
|
+
attributeFilter: ['style', 'data-unitone-layout', 'class'],
|
|
598
|
+
attributeOldValue: true,
|
|
599
|
+
},
|
|
600
|
+
shouldApply: (entries) =>
|
|
601
|
+
hasAttributeMutation(
|
|
602
|
+
entries,
|
|
603
|
+
(entry) => entry.target === target && shouldRecalculateByAttributeMutation(entry),
|
|
604
|
+
),
|
|
605
|
+
},
|
|
606
|
+
directChildMutation: {
|
|
607
|
+
attributeFilter: ['style', 'data-unitone-layout', 'class'],
|
|
608
|
+
attributeOldValue: true,
|
|
609
|
+
shouldApply: shouldRecalculateByAttributeMutation,
|
|
610
|
+
},
|
|
611
|
+
});
|
|
207
612
|
};
|
|
208
613
|
|
|
614
|
+
/**
|
|
615
|
+
* Recalculates step values for stairs layouts.
|
|
616
|
+
*
|
|
617
|
+
* @param {Element} target Target element.
|
|
618
|
+
* @returns {void}
|
|
619
|
+
*/
|
|
209
620
|
export const setStairsStep = (target) => {
|
|
210
621
|
const children = Array.from(target.children);
|
|
211
622
|
const currentLayoutArray = withoutLayoutTokens(getLayoutTokens(target), ['stairs:initialized']);
|
|
@@ -294,33 +705,79 @@ export const setStairsStep = (target) => {
|
|
|
294
705
|
setLayoutTokens(target, [...currentLayoutArray, 'stairs:initialized']);
|
|
295
706
|
};
|
|
296
707
|
|
|
708
|
+
/**
|
|
709
|
+
* Creates the observer bundle for stairs layouts.
|
|
710
|
+
*
|
|
711
|
+
* @param {Element} target Target element.
|
|
712
|
+
* @returns {void}
|
|
713
|
+
*/
|
|
297
714
|
export const stairsResizeObserver = (target) => {
|
|
298
|
-
|
|
715
|
+
createLayoutObserver(target, setStairsStep, {
|
|
716
|
+
observeIntersection: true,
|
|
717
|
+
observeDirectChildrenResize: true,
|
|
718
|
+
});
|
|
299
719
|
};
|
|
300
720
|
|
|
721
|
+
/**
|
|
722
|
+
* Returns whether the node should be ignored by vertical-writing mutation handling.
|
|
723
|
+
*
|
|
724
|
+
* @param {Node | null | undefined} node Target node.
|
|
725
|
+
* @returns {boolean} Whether the node should be ignored.
|
|
726
|
+
*/
|
|
727
|
+
const isIgnoredVerticalWritingMutationNode = (node) =>
|
|
728
|
+
node?.nodeType === Node.ELEMENT_NODE &&
|
|
729
|
+
[
|
|
730
|
+
'vertical-writing__thresholder',
|
|
731
|
+
'vertical-writing:initialized',
|
|
732
|
+
'vertical-writing:safari',
|
|
733
|
+
].includes(node.getAttribute('data-unitone-layout'));
|
|
734
|
+
|
|
735
|
+
/**
|
|
736
|
+
* Returns whether vertical-writing mutations require re-application.
|
|
737
|
+
*
|
|
738
|
+
* @param {MutationRecord[]} entries Mutation records.
|
|
739
|
+
* @returns {boolean} Whether re-application is required.
|
|
740
|
+
*/
|
|
741
|
+
const shouldApplyVerticalWritingMutation = (entries) =>
|
|
742
|
+
entries.some((entry) => {
|
|
743
|
+
if ('attributes' === entry.type) {
|
|
744
|
+
return true;
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
if ('childList' !== entry.type) {
|
|
748
|
+
return false;
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
return [...entry.addedNodes, ...entry.removedNodes].some(
|
|
752
|
+
(node) => !isIgnoredVerticalWritingMutationNode(node),
|
|
753
|
+
);
|
|
754
|
+
});
|
|
755
|
+
|
|
756
|
+
/**
|
|
757
|
+
* Recalculates column count and height for vertical-writing layouts.
|
|
758
|
+
*
|
|
759
|
+
* @param {Element} target Target element.
|
|
760
|
+
* @returns {void}
|
|
761
|
+
*/
|
|
301
762
|
export const setColumnCountForVertical = (target) => {
|
|
302
763
|
if (!target) {
|
|
303
764
|
return;
|
|
304
765
|
}
|
|
305
766
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
);
|
|
318
|
-
target.setAttribute('data-unitone-layout', currentLayoutArray.join(' '));
|
|
319
|
-
}
|
|
767
|
+
const currentLayoutTokens = getLayoutTokens(target);
|
|
768
|
+
const baseLayoutTokens = withoutLayoutTokens(currentLayoutTokens, [
|
|
769
|
+
'vertical-writing:safari',
|
|
770
|
+
'-force-switch',
|
|
771
|
+
]);
|
|
772
|
+
const nextLayoutTokens = withoutLayoutTokens(currentLayoutTokens, [
|
|
773
|
+
'vertical-writing:initialized',
|
|
774
|
+
'vertical-writing:safari',
|
|
775
|
+
'-force-switch',
|
|
776
|
+
]);
|
|
777
|
+
setLayoutTokens(target, baseLayoutTokens);
|
|
320
778
|
|
|
321
779
|
let lastChild;
|
|
322
|
-
|
|
323
|
-
.call(target.children)
|
|
780
|
+
Array.from(target.children)
|
|
324
781
|
.reverse()
|
|
325
782
|
.some((child) => {
|
|
326
783
|
if (
|
|
@@ -333,130 +790,92 @@ export const setColumnCountForVertical = (target) => {
|
|
|
333
790
|
});
|
|
334
791
|
|
|
335
792
|
if (!lastChild) {
|
|
336
|
-
|
|
337
|
-
target.setAttribute('data-unitone-layout', currentLayoutArray.join(' '));
|
|
793
|
+
setLayoutTokens(target, [...nextLayoutTokens, 'vertical-writing:initialized']);
|
|
338
794
|
return;
|
|
339
795
|
}
|
|
340
796
|
|
|
341
|
-
// Process of the threshold
|
|
342
797
|
const computedStyle = getComputedStyle(target);
|
|
343
798
|
const threshold = String(computedStyle.getPropertyValue('--unitone--threshold')).trim();
|
|
344
799
|
let forceSwitch = false;
|
|
345
800
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
801
|
+
if (threshold) {
|
|
802
|
+
const thresholder = target.ownerDocument.createElement('div');
|
|
803
|
+
thresholder.setAttribute(layoutAttributeName, 'vertical-writing__thresholder');
|
|
804
|
+
target.appendChild(thresholder);
|
|
805
|
+
forceSwitch = thresholder.offsetWidth >= target.offsetWidth;
|
|
806
|
+
thresholder.remove();
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
if (forceSwitch) {
|
|
810
|
+
nextLayoutTokens.push('-force-switch');
|
|
811
|
+
} else {
|
|
812
|
+
const maybeSafari =
|
|
813
|
+
target.getBoundingClientRect().left > lastChild.getBoundingClientRect().left;
|
|
814
|
+
if (maybeSafari) {
|
|
815
|
+
nextLayoutTokens.push('vertical-writing:safari');
|
|
349
816
|
}
|
|
817
|
+
}
|
|
350
818
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
if (thresholder.parentNode) {
|
|
357
|
-
thresholder.parentNode.removeChild(thresholder);
|
|
358
|
-
}
|
|
819
|
+
setLayoutTokens(target, [...nextLayoutTokens, 'vertical-writing:initialized']);
|
|
820
|
+
|
|
821
|
+
requestAnimationFrame(() => {
|
|
822
|
+
if (!target?.isConnected) {
|
|
823
|
+
return;
|
|
359
824
|
}
|
|
360
825
|
|
|
361
|
-
if (
|
|
362
|
-
|
|
363
|
-
if (target.parentNode?.style) {
|
|
826
|
+
if (target.parentNode?.style) {
|
|
827
|
+
if (forceSwitch) {
|
|
364
828
|
target.parentNode.style.height = '';
|
|
365
|
-
|
|
366
|
-
} else {
|
|
367
|
-
// For Safari
|
|
368
|
-
const maybeSafari =
|
|
369
|
-
target.getBoundingClientRect().left > lastChild.getBoundingClientRect().left;
|
|
370
|
-
if (maybeSafari) {
|
|
371
|
-
currentLayoutArray.push('vertical-writing:safari');
|
|
829
|
+
return;
|
|
372
830
|
}
|
|
373
831
|
|
|
374
|
-
target.
|
|
375
|
-
|
|
376
|
-
requestAnimationFrame(() => {
|
|
377
|
-
if (!target?.isConnected) {
|
|
378
|
-
return;
|
|
379
|
-
}
|
|
832
|
+
const targetRect = target.getBoundingClientRect();
|
|
833
|
+
const lastChildRect = lastChild.getBoundingClientRect();
|
|
380
834
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
const lastChildY = lastChildRect.top + lastChildRect.height;
|
|
386
|
-
if (targetY !== lastChildY) {
|
|
387
|
-
if (target.parentNode?.style) {
|
|
388
|
-
target.parentNode.style.height = `${Math.ceil(lastChildY - targetRect.top)}px`;
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
});
|
|
835
|
+
const targetY = targetRect.top + targetRect.height;
|
|
836
|
+
const lastChildY = lastChildRect.top + lastChildRect.height;
|
|
837
|
+
target.parentNode.style.height =
|
|
838
|
+
targetY !== lastChildY ? `${Math.ceil(lastChildY - targetRect.top)}px` : '';
|
|
392
839
|
}
|
|
393
|
-
|
|
394
|
-
currentLayoutArray.push('vertical-writing:initialized');
|
|
395
|
-
target.setAttribute('data-unitone-layout', currentLayoutArray.join(' '));
|
|
396
|
-
}, 250);
|
|
840
|
+
});
|
|
397
841
|
};
|
|
398
842
|
|
|
843
|
+
/**
|
|
844
|
+
* Creates the observer bundle for vertical-writing layouts.
|
|
845
|
+
*
|
|
846
|
+
* @param {Element} target Target element.
|
|
847
|
+
* @returns {void}
|
|
848
|
+
*/
|
|
399
849
|
export const verticalsResizeObserver = (target) => {
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
for (const entry of entries) {
|
|
405
|
-
const width = entry.contentRect?.width;
|
|
406
|
-
if (parseInt(width) !== parseInt(prevWidth)) {
|
|
407
|
-
prevWidth = width;
|
|
408
|
-
entry.target.parentNode.style.height = '';
|
|
409
|
-
setColumnCountForVertical(entry.target);
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
}, 250),
|
|
413
|
-
);
|
|
414
|
-
|
|
415
|
-
observer.observe(target);
|
|
850
|
+
const applyVerticalColumns = (element) => {
|
|
851
|
+
if (element.parentNode?.style) {
|
|
852
|
+
element.parentNode.style.height = '';
|
|
853
|
+
}
|
|
416
854
|
|
|
417
|
-
|
|
418
|
-
attributes: true,
|
|
419
|
-
attributeFilter: ['style'],
|
|
420
|
-
childList: true,
|
|
421
|
-
subtree: true,
|
|
855
|
+
setColumnCountForVertical(element);
|
|
422
856
|
};
|
|
423
857
|
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
'vertical-writing:initialized' === addedNode.getAttribute('data-unitone-layout')) ||
|
|
437
|
-
(removedNode?.nodeType === Node.ELEMENT_NODE &&
|
|
438
|
-
'vertical-writing:initialized' === removedNode.getAttribute('data-unitone-layout')) ||
|
|
439
|
-
(addedNode?.nodeType === Node.ELEMENT_NODE &&
|
|
440
|
-
'vertical-writing:safari' === addedNode.getAttribute('data-unitone-layout')) ||
|
|
441
|
-
(removedNode?.nodeType === Node.ELEMENT_NODE &&
|
|
442
|
-
'vertical-writing:safari' === removedNode.getAttribute('data-unitone-layout'))
|
|
443
|
-
) {
|
|
444
|
-
return;
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
setColumnCountForVertical(target);
|
|
448
|
-
}
|
|
449
|
-
});
|
|
858
|
+
createLayoutObserver(target, applyVerticalColumns, {
|
|
859
|
+
getResizeValue: getContentRectWidth,
|
|
860
|
+
observeIntersection: true,
|
|
861
|
+
targetMutation: {
|
|
862
|
+
options: {
|
|
863
|
+
attributes: true,
|
|
864
|
+
attributeFilter: ['style'],
|
|
865
|
+
childList: true,
|
|
866
|
+
subtree: true,
|
|
867
|
+
},
|
|
868
|
+
shouldApply: shouldApplyVerticalWritingMutation,
|
|
869
|
+
},
|
|
450
870
|
});
|
|
451
|
-
|
|
452
|
-
mObserver.observe(target, mObserverArgs);
|
|
453
|
-
|
|
454
|
-
return {
|
|
455
|
-
resizeObserver: observer,
|
|
456
|
-
mutationObserver: mObserver,
|
|
457
|
-
};
|
|
458
871
|
};
|
|
459
872
|
|
|
873
|
+
/**
|
|
874
|
+
* Writes the computed 1em value to a CSS custom property for Firefox.
|
|
875
|
+
*
|
|
876
|
+
* @param {HTMLElement} target Target element.
|
|
877
|
+
* @returns {void}
|
|
878
|
+
*/
|
|
460
879
|
export const setResult1emPxForFireFox = (target) => {
|
|
461
880
|
const ownerDocument = target.ownerDocument;
|
|
462
881
|
const defaultView = ownerDocument.defaultView;
|
|
@@ -471,6 +890,12 @@ export const setResult1emPxForFireFox = (target) => {
|
|
|
471
890
|
target.style.setProperty('--unitone--result--1em-px', fontSize);
|
|
472
891
|
};
|
|
473
892
|
|
|
893
|
+
/**
|
|
894
|
+
* Creates the observer bundle for the Firefox 1em measurement workaround.
|
|
895
|
+
*
|
|
896
|
+
* @param {HTMLElement} target Target element.
|
|
897
|
+
* @returns {void}
|
|
898
|
+
*/
|
|
474
899
|
export const result1emPxForFireFoxObserver = (target) => {
|
|
475
900
|
const ownerDocument = target.ownerDocument;
|
|
476
901
|
const defaultView = ownerDocument.defaultView;
|
|
@@ -480,26 +905,25 @@ export const result1emPxForFireFoxObserver = (target) => {
|
|
|
480
905
|
return;
|
|
481
906
|
}
|
|
482
907
|
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
908
|
+
createLayoutObserver(target, setResult1emPxForFireFox, {
|
|
909
|
+
getResizeValue: getBorderBoxInlineSize,
|
|
910
|
+
targetMutation: {
|
|
911
|
+
options: {
|
|
912
|
+
attributes: true,
|
|
913
|
+
attributeFilter: ['style', 'data-unitone-layout', 'class'],
|
|
914
|
+
characterData: true,
|
|
915
|
+
},
|
|
916
|
+
shouldApply: () => true,
|
|
917
|
+
},
|
|
491
918
|
});
|
|
492
|
-
|
|
493
|
-
const mObserver = createMutationObserver(target, mObserverArgs, () => {
|
|
494
|
-
setResult1emPxForFireFox(target);
|
|
495
|
-
});
|
|
496
|
-
|
|
497
|
-
return {
|
|
498
|
-
resizeObserver: observer,
|
|
499
|
-
mutationObserver: mObserver,
|
|
500
|
-
};
|
|
501
919
|
};
|
|
502
920
|
|
|
921
|
+
/**
|
|
922
|
+
* Creates duplicated marquee content and refreshes initialization markers.
|
|
923
|
+
*
|
|
924
|
+
* @param {Element} target Target element.
|
|
925
|
+
* @returns {Element | undefined} The duplicated marquee element, if created.
|
|
926
|
+
*/
|
|
503
927
|
export const setMarquee = (target) => {
|
|
504
928
|
let clonedMarquee;
|
|
505
929
|
|
|
@@ -526,6 +950,10 @@ export const setMarquee = (target) => {
|
|
|
526
950
|
return;
|
|
527
951
|
}
|
|
528
952
|
|
|
953
|
+
const shouldRestartAnimation = Array.from(marquees).some((marquee) =>
|
|
954
|
+
(marquee.getAttribute(layoutAttributeName) ?? '').split(/\s+/).includes('marquee:initialized'),
|
|
955
|
+
);
|
|
956
|
+
|
|
529
957
|
if (1 === target.childElementCount && 1 === marquees.length) {
|
|
530
958
|
const marquee = marquees[0];
|
|
531
959
|
clonedMarquee = marquee.cloneNode(true);
|
|
@@ -534,6 +962,14 @@ export const setMarquee = (target) => {
|
|
|
534
962
|
}
|
|
535
963
|
|
|
536
964
|
marquees = getMarquees();
|
|
965
|
+
|
|
966
|
+
if (!shouldRestartAnimation) {
|
|
967
|
+
marquees.forEach((marquee) => {
|
|
968
|
+
addInitializedToken(marquee);
|
|
969
|
+
});
|
|
970
|
+
return clonedMarquee;
|
|
971
|
+
}
|
|
972
|
+
|
|
537
973
|
marquees.forEach((marquee) => {
|
|
538
974
|
removeInitializedToken(marquee);
|
|
539
975
|
});
|
|
@@ -550,6 +986,12 @@ export const setMarquee = (target) => {
|
|
|
550
986
|
return clonedMarquee;
|
|
551
987
|
};
|
|
552
988
|
|
|
989
|
+
/**
|
|
990
|
+
* Creates the observer bundle for marquee layouts.
|
|
991
|
+
*
|
|
992
|
+
* @param {Element} target Target element.
|
|
993
|
+
* @returns {void}
|
|
994
|
+
*/
|
|
553
995
|
export const marqueeResizeObserver = (target) => {
|
|
554
996
|
let clonedMarquee;
|
|
555
997
|
|
|
@@ -557,38 +999,30 @@ export const marqueeResizeObserver = (target) => {
|
|
|
557
999
|
clonedMarquee = setMarquee(element);
|
|
558
1000
|
};
|
|
559
1001
|
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
return;
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
const addedNodes = entries.flatMap((entry) => Array.from(entry.addedNodes ?? []));
|
|
574
|
-
const removedNodes = entries.flatMap((entry) => Array.from(entry.removedNodes ?? []));
|
|
1002
|
+
createLayoutObserver(target, applyMarquee, {
|
|
1003
|
+
observeResize: false,
|
|
1004
|
+
observeIntersection: true,
|
|
1005
|
+
targetMutation: {
|
|
1006
|
+
options: {
|
|
1007
|
+
childList: true,
|
|
1008
|
+
},
|
|
1009
|
+
shouldApply: (entries) => {
|
|
1010
|
+
const addedNodes = entries.flatMap((entry) => Array.from(entry.addedNodes ?? []));
|
|
1011
|
+
const removedNodes = entries.flatMap((entry) => Array.from(entry.removedNodes ?? []));
|
|
575
1012
|
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
1013
|
+
if (
|
|
1014
|
+
clonedMarquee?.isConnected &&
|
|
1015
|
+
1 === addedNodes.length &&
|
|
1016
|
+
0 === removedNodes.length &&
|
|
1017
|
+
addedNodes[0] === clonedMarquee
|
|
1018
|
+
) {
|
|
1019
|
+
clonedMarquee = null;
|
|
1020
|
+
return false;
|
|
1021
|
+
}
|
|
585
1022
|
|
|
586
|
-
|
|
587
|
-
|
|
1023
|
+
clonedMarquee = null;
|
|
1024
|
+
return true;
|
|
1025
|
+
},
|
|
1026
|
+
},
|
|
588
1027
|
});
|
|
589
|
-
|
|
590
|
-
return {
|
|
591
|
-
resizeObserver: observer,
|
|
592
|
-
mutationObserver: mObserver,
|
|
593
|
-
};
|
|
594
1028
|
};
|