accessify-widget 0.2.3 → 0.2.5
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/accessify.min.js +1 -1
- package/dist/accessify.min.js.map +1 -1
- package/dist/accessify.mjs +1 -1
- package/dist/animation-stop-C6ToNlBr.js +505 -0
- package/dist/animation-stop-C6ToNlBr.js.map +1 -0
- package/dist/hide-images-B_LeCBcd.js +105 -0
- package/dist/hide-images-B_LeCBcd.js.map +1 -0
- package/dist/{index-CsJDqdBW.js → index-eprjFXa3.js} +37 -10
- package/dist/{index-CsJDqdBW.js.map → index-eprjFXa3.js.map} +1 -1
- package/dist/{keyboard-nav-CkAYxUc1.js → keyboard-nav-CAWn30Tw.js} +64 -2
- package/dist/keyboard-nav-CAWn30Tw.js.map +1 -0
- package/dist/{page-structure-yWkBKmwo.js → page-structure-DDjJeVCc.js} +75 -2
- package/dist/page-structure-DDjJeVCc.js.map +1 -0
- package/dist/{text-simplify-C9gzE3t0.js → text-simplify-B1v6Muvn.js} +117 -16
- package/dist/text-simplify-B1v6Muvn.js.map +1 -0
- package/dist/widget.js +1 -1
- package/dist/widget.js.map +1 -1
- package/package.json +2 -2
- package/dist/animation-stop-DXebPS8D.js +0 -88
- package/dist/animation-stop-DXebPS8D.js.map +0 -1
- package/dist/hide-images-DJwmsV2C.js +0 -39
- package/dist/hide-images-DJwmsV2C.js.map +0 -1
- package/dist/keyboard-nav-CkAYxUc1.js.map +0 -1
- package/dist/page-structure-yWkBKmwo.js.map +0 -1
- package/dist/text-simplify-C9gzE3t0.js.map +0 -1
package/dist/accessify.mjs
CHANGED
|
@@ -0,0 +1,505 @@
|
|
|
1
|
+
function createAnimationStopModule() {
|
|
2
|
+
let enabled = false;
|
|
3
|
+
const STYLE_ID = "accessify-animation-stop";
|
|
4
|
+
const STORAGE_KEY = "accessify-animation-stop";
|
|
5
|
+
let pausedVideos = [];
|
|
6
|
+
let pausedAnimations = [];
|
|
7
|
+
let originalAnimate = null;
|
|
8
|
+
let originalRAF = null;
|
|
9
|
+
let originalMatchMedia = null;
|
|
10
|
+
let mutationObserver = null;
|
|
11
|
+
let rafLoopTracker = /* @__PURE__ */ new Map();
|
|
12
|
+
let blockedRAFs = /* @__PURE__ */ new Set();
|
|
13
|
+
let gifOriginals = /* @__PURE__ */ new Map();
|
|
14
|
+
let styleObserver = null;
|
|
15
|
+
let delayedTimers = [];
|
|
16
|
+
let frozenInlineElements = /* @__PURE__ */ new Map();
|
|
17
|
+
function getStyles() {
|
|
18
|
+
return `
|
|
19
|
+
/* accessify animation stop - WCAG 2.3.1 compliance */
|
|
20
|
+
*, *::before, *::after {
|
|
21
|
+
animation-duration: 0.01s !important;
|
|
22
|
+
animation-delay: 0s !important;
|
|
23
|
+
animation-iteration-count: 1 !important;
|
|
24
|
+
animation-play-state: paused !important;
|
|
25
|
+
transition-duration: 0.01s !important;
|
|
26
|
+
transition-delay: 0s !important;
|
|
27
|
+
scroll-behavior: auto !important;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/* Framer appear elements — force visible (they start at opacity:0.001) */
|
|
31
|
+
[data-framer-appear-id] {
|
|
32
|
+
opacity: 1 !important;
|
|
33
|
+
transform: none !important;
|
|
34
|
+
will-change: auto !important;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/* Framer page containers with near-zero opacity */
|
|
38
|
+
[data-framer-component-type] [style*="opacity"] {
|
|
39
|
+
opacity: 1 !important;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* Generic: any element with will-change:transform that might be hidden by animation libs */
|
|
43
|
+
[style*="will-change"][style*="opacity:0"],
|
|
44
|
+
[style*="will-change"][style*="opacity: 0"] {
|
|
45
|
+
opacity: 1 !important;
|
|
46
|
+
transform: none !important;
|
|
47
|
+
will-change: auto !important;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
marquee { -moz-binding: none; }
|
|
51
|
+
`;
|
|
52
|
+
}
|
|
53
|
+
function injectStyles() {
|
|
54
|
+
let styleEl = document.getElementById(STYLE_ID);
|
|
55
|
+
if (!styleEl) {
|
|
56
|
+
styleEl = document.createElement("style");
|
|
57
|
+
styleEl.id = STYLE_ID;
|
|
58
|
+
document.head.appendChild(styleEl);
|
|
59
|
+
}
|
|
60
|
+
styleEl.textContent = getStyles();
|
|
61
|
+
}
|
|
62
|
+
function removeStyles() {
|
|
63
|
+
document.getElementById(STYLE_ID)?.remove();
|
|
64
|
+
}
|
|
65
|
+
function pauseAllWebAnimations() {
|
|
66
|
+
try {
|
|
67
|
+
const animations = document.getAnimations();
|
|
68
|
+
for (const anim of animations) {
|
|
69
|
+
if (anim.playState === "running" || anim.playState === "pending") {
|
|
70
|
+
anim.pause();
|
|
71
|
+
pausedAnimations.push(anim);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
} catch {
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function overrideElementAnimate() {
|
|
78
|
+
if (originalAnimate) return;
|
|
79
|
+
originalAnimate = Element.prototype.animate;
|
|
80
|
+
Element.prototype.animate = function(keyframes, options) {
|
|
81
|
+
const anim = originalAnimate.call(this, keyframes, options);
|
|
82
|
+
if (enabled) {
|
|
83
|
+
anim.pause();
|
|
84
|
+
pausedAnimations.push(anim);
|
|
85
|
+
}
|
|
86
|
+
return anim;
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
function restoreElementAnimate() {
|
|
90
|
+
if (originalAnimate) {
|
|
91
|
+
Element.prototype.animate = originalAnimate;
|
|
92
|
+
originalAnimate = null;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
function resumePausedAnimations() {
|
|
96
|
+
for (const anim of pausedAnimations) {
|
|
97
|
+
try {
|
|
98
|
+
anim.play();
|
|
99
|
+
} catch {
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
pausedAnimations = [];
|
|
103
|
+
}
|
|
104
|
+
function overrideRAF() {
|
|
105
|
+
if (originalRAF) return;
|
|
106
|
+
originalRAF = window.requestAnimationFrame;
|
|
107
|
+
const origCancel = window.cancelAnimationFrame;
|
|
108
|
+
window.requestAnimationFrame = function(callback) {
|
|
109
|
+
if (!enabled) return originalRAF.call(window, callback);
|
|
110
|
+
const key = callback.toString().slice(0, 200);
|
|
111
|
+
const now = performance.now();
|
|
112
|
+
const entry = rafLoopTracker.get(key);
|
|
113
|
+
if (entry) {
|
|
114
|
+
entry.count++;
|
|
115
|
+
if (now - entry.lastTime < 100 && entry.count > 3) {
|
|
116
|
+
const id = originalRAF.call(window, () => {
|
|
117
|
+
});
|
|
118
|
+
blockedRAFs.add(id);
|
|
119
|
+
return id;
|
|
120
|
+
}
|
|
121
|
+
entry.lastTime = now;
|
|
122
|
+
} else {
|
|
123
|
+
rafLoopTracker.set(key, { count: 1, lastTime: now });
|
|
124
|
+
}
|
|
125
|
+
return originalRAF.call(window, callback);
|
|
126
|
+
};
|
|
127
|
+
window.cancelAnimationFrame = function(id) {
|
|
128
|
+
blockedRAFs.delete(id);
|
|
129
|
+
return origCancel.call(window, id);
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
function restoreRAF() {
|
|
133
|
+
if (originalRAF) {
|
|
134
|
+
window.requestAnimationFrame = originalRAF;
|
|
135
|
+
originalRAF = null;
|
|
136
|
+
}
|
|
137
|
+
rafLoopTracker.clear();
|
|
138
|
+
blockedRAFs.clear();
|
|
139
|
+
}
|
|
140
|
+
function setupMutationObserver() {
|
|
141
|
+
if (mutationObserver) return;
|
|
142
|
+
mutationObserver = new MutationObserver((mutations) => {
|
|
143
|
+
if (!enabled) return;
|
|
144
|
+
for (const mutation of mutations) {
|
|
145
|
+
for (const node of mutation.addedNodes) {
|
|
146
|
+
if (!(node instanceof HTMLElement)) continue;
|
|
147
|
+
try {
|
|
148
|
+
const anims = node.getAnimations({ subtree: true });
|
|
149
|
+
for (const anim of anims) {
|
|
150
|
+
if (anim.playState === "running" || anim.playState === "pending") {
|
|
151
|
+
anim.pause();
|
|
152
|
+
pausedAnimations.push(anim);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
} catch {
|
|
156
|
+
}
|
|
157
|
+
if (node.tagName === "VIDEO") {
|
|
158
|
+
const video = node;
|
|
159
|
+
if (!video.paused) {
|
|
160
|
+
video.pause();
|
|
161
|
+
pausedVideos.push(video);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
node.querySelectorAll?.("video")?.forEach((video) => {
|
|
165
|
+
if (!video.paused) {
|
|
166
|
+
video.pause();
|
|
167
|
+
pausedVideos.push(video);
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
if (node.tagName === "IMG") {
|
|
171
|
+
freezeGif(node);
|
|
172
|
+
}
|
|
173
|
+
node.querySelectorAll?.("img")?.forEach((img) => freezeGif(img));
|
|
174
|
+
if (node.hasAttribute?.("data-framer-appear-id")) {
|
|
175
|
+
forceFramerAppearVisibleSingle(node);
|
|
176
|
+
}
|
|
177
|
+
node.querySelectorAll?.("[data-framer-appear-id]")?.forEach((el) => {
|
|
178
|
+
forceFramerAppearVisibleSingle(el);
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
mutationObserver.observe(document.body, {
|
|
184
|
+
childList: true,
|
|
185
|
+
subtree: true
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
function disconnectMutationObserver() {
|
|
189
|
+
mutationObserver?.disconnect();
|
|
190
|
+
mutationObserver = null;
|
|
191
|
+
}
|
|
192
|
+
function emulateReducedMotion() {
|
|
193
|
+
if (originalMatchMedia) return;
|
|
194
|
+
originalMatchMedia = window.matchMedia;
|
|
195
|
+
window.matchMedia = function(query) {
|
|
196
|
+
const mql = originalMatchMedia.call(window, query);
|
|
197
|
+
if (query.includes("prefers-reduced-motion")) {
|
|
198
|
+
const proxy = Object.create(mql);
|
|
199
|
+
Object.defineProperty(proxy, "matches", { get: () => enabled, configurable: true });
|
|
200
|
+
Object.defineProperty(proxy, "media", { get: () => query, configurable: true });
|
|
201
|
+
return proxy;
|
|
202
|
+
}
|
|
203
|
+
return mql;
|
|
204
|
+
};
|
|
205
|
+
try {
|
|
206
|
+
const mql = originalMatchMedia.call(window, "(prefers-reduced-motion: reduce)");
|
|
207
|
+
mql.dispatchEvent(new MediaQueryListEvent("change", { matches: true, media: mql.media }));
|
|
208
|
+
} catch {
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
function restoreMatchMedia() {
|
|
212
|
+
if (originalMatchMedia) {
|
|
213
|
+
window.matchMedia = originalMatchMedia;
|
|
214
|
+
originalMatchMedia = null;
|
|
215
|
+
try {
|
|
216
|
+
const mql = window.matchMedia("(prefers-reduced-motion: reduce)");
|
|
217
|
+
mql.dispatchEvent(new MediaQueryListEvent("change", { matches: mql.matches, media: mql.media }));
|
|
218
|
+
} catch {
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
function freezeGif(img) {
|
|
223
|
+
const src = img.src || img.getAttribute("src") || "";
|
|
224
|
+
if (!src.toLowerCase().includes(".gif")) return;
|
|
225
|
+
if (gifOriginals.has(img)) return;
|
|
226
|
+
const freeze = () => {
|
|
227
|
+
try {
|
|
228
|
+
const canvas = document.createElement("canvas");
|
|
229
|
+
canvas.width = img.naturalWidth || img.width;
|
|
230
|
+
canvas.height = img.naturalHeight || img.height;
|
|
231
|
+
if (canvas.width === 0 || canvas.height === 0) return;
|
|
232
|
+
const ctx = canvas.getContext("2d");
|
|
233
|
+
if (!ctx) return;
|
|
234
|
+
ctx.drawImage(img, 0, 0);
|
|
235
|
+
gifOriginals.set(img, src);
|
|
236
|
+
img.src = canvas.toDataURL("image/png");
|
|
237
|
+
} catch {
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
if (img.complete && img.naturalWidth > 0) {
|
|
241
|
+
freeze();
|
|
242
|
+
} else {
|
|
243
|
+
img.addEventListener("load", freeze, { once: true });
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
function freezeAllGifs() {
|
|
247
|
+
document.querySelectorAll("img").forEach(freezeGif);
|
|
248
|
+
}
|
|
249
|
+
function restoreGifs() {
|
|
250
|
+
for (const [img, originalSrc] of gifOriginals) {
|
|
251
|
+
try {
|
|
252
|
+
img.src = originalSrc;
|
|
253
|
+
} catch {
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
gifOriginals.clear();
|
|
257
|
+
}
|
|
258
|
+
const FRAMER_FIXED_ATTR = "data-accessify-framer-fixed";
|
|
259
|
+
let framerFixedElements = [];
|
|
260
|
+
function forceFramerAppearVisible() {
|
|
261
|
+
const appearEls = document.querySelectorAll("[data-framer-appear-id]");
|
|
262
|
+
for (const el of appearEls) {
|
|
263
|
+
if (el.hasAttribute(FRAMER_FIXED_ATTR)) continue;
|
|
264
|
+
const computed = getComputedStyle(el);
|
|
265
|
+
const opacity = parseFloat(computed.opacity);
|
|
266
|
+
if (opacity < 0.95) {
|
|
267
|
+
framerFixedElements.push({ el, origStyle: el.getAttribute("style") || "" });
|
|
268
|
+
el.style.setProperty("opacity", "1", "important");
|
|
269
|
+
el.style.setProperty("transform", "none", "important");
|
|
270
|
+
el.style.setProperty("will-change", "auto", "important");
|
|
271
|
+
el.setAttribute(FRAMER_FIXED_ATTR, "true");
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
const allWillChange = document.querySelectorAll('[style*="will-change"]');
|
|
275
|
+
for (const el of allWillChange) {
|
|
276
|
+
if (el.hasAttribute(FRAMER_FIXED_ATTR)) continue;
|
|
277
|
+
if (el.closest("#accessify-root")) continue;
|
|
278
|
+
const computed = getComputedStyle(el);
|
|
279
|
+
const opacity = parseFloat(computed.opacity);
|
|
280
|
+
if (opacity < 0.1 && computed.willChange.includes("transform")) {
|
|
281
|
+
framerFixedElements.push({ el, origStyle: el.getAttribute("style") || "" });
|
|
282
|
+
el.style.setProperty("opacity", "1", "important");
|
|
283
|
+
el.style.setProperty("transform", "none", "important");
|
|
284
|
+
el.style.setProperty("will-change", "auto", "important");
|
|
285
|
+
el.setAttribute(FRAMER_FIXED_ATTR, "true");
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
function restoreFramerAppear() {
|
|
290
|
+
for (const { el, origStyle } of framerFixedElements) {
|
|
291
|
+
try {
|
|
292
|
+
el.setAttribute("style", origStyle);
|
|
293
|
+
el.removeAttribute(FRAMER_FIXED_ATTR);
|
|
294
|
+
} catch {
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
framerFixedElements = [];
|
|
298
|
+
}
|
|
299
|
+
function forceFramerAppearVisibleSingle(el) {
|
|
300
|
+
if (el.hasAttribute(FRAMER_FIXED_ATTR)) return;
|
|
301
|
+
const computed = getComputedStyle(el);
|
|
302
|
+
const opacity = parseFloat(computed.opacity);
|
|
303
|
+
if (opacity < 0.95) {
|
|
304
|
+
framerFixedElements.push({ el, origStyle: el.getAttribute("style") || "" });
|
|
305
|
+
el.style.setProperty("opacity", "1", "important");
|
|
306
|
+
el.style.setProperty("transform", "none", "important");
|
|
307
|
+
el.style.setProperty("will-change", "auto", "important");
|
|
308
|
+
el.setAttribute(FRAMER_FIXED_ATTR, "true");
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
function setupStyleObserver() {
|
|
312
|
+
if (styleObserver) return;
|
|
313
|
+
let isOurChange = false;
|
|
314
|
+
styleObserver = new MutationObserver((mutations) => {
|
|
315
|
+
if (!enabled || isOurChange) return;
|
|
316
|
+
isOurChange = true;
|
|
317
|
+
for (const m of mutations) {
|
|
318
|
+
if (m.type !== "attributes" || m.attributeName !== "style") continue;
|
|
319
|
+
const el = m.target;
|
|
320
|
+
const isFramerEl = el.hasAttribute("data-framer-appear-id") || el.hasAttribute("data-framer-component-type") || el.closest("[data-framer-appear-id]") !== null;
|
|
321
|
+
const hasWillChange = el.style.willChange?.includes("transform") || el.style.willChange?.includes("opacity");
|
|
322
|
+
if (!isFramerEl && !hasWillChange) continue;
|
|
323
|
+
const opacity = parseFloat(el.style.opacity);
|
|
324
|
+
if (!isNaN(opacity) && opacity < 0.1) {
|
|
325
|
+
el.style.setProperty("opacity", "1", "important");
|
|
326
|
+
el.style.setProperty("transform", "none", "important");
|
|
327
|
+
el.style.setProperty("will-change", "auto", "important");
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
isOurChange = false;
|
|
331
|
+
});
|
|
332
|
+
styleObserver.observe(document.body, {
|
|
333
|
+
attributes: true,
|
|
334
|
+
attributeFilter: ["style"],
|
|
335
|
+
subtree: true
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
function disconnectStyleObserver() {
|
|
339
|
+
styleObserver?.disconnect();
|
|
340
|
+
styleObserver = null;
|
|
341
|
+
}
|
|
342
|
+
function scheduleDelayedScans() {
|
|
343
|
+
const delays = [500, 1e3, 2e3, 4e3];
|
|
344
|
+
for (const delay of delays) {
|
|
345
|
+
const timer = setTimeout(() => {
|
|
346
|
+
if (!enabled) return;
|
|
347
|
+
forceAllHiddenVisible();
|
|
348
|
+
pauseAllWebAnimations();
|
|
349
|
+
freezeAllGifs();
|
|
350
|
+
pauseSVGAnimations();
|
|
351
|
+
stopMarquees();
|
|
352
|
+
}, delay);
|
|
353
|
+
delayedTimers.push(timer);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
function clearDelayedScans() {
|
|
357
|
+
for (const timer of delayedTimers) clearTimeout(timer);
|
|
358
|
+
delayedTimers = [];
|
|
359
|
+
}
|
|
360
|
+
function forceAllHiddenVisible() {
|
|
361
|
+
forceFramerAppearVisible();
|
|
362
|
+
const candidates = document.querySelectorAll(
|
|
363
|
+
'[data-framer-appear-id], [data-framer-component-type] *, [style*="will-change"], [style*="opacity"]'
|
|
364
|
+
);
|
|
365
|
+
for (const el of candidates) {
|
|
366
|
+
if (el.hasAttribute(FRAMER_FIXED_ATTR)) continue;
|
|
367
|
+
if (el.closest("#accessify-root")) continue;
|
|
368
|
+
const computed = getComputedStyle(el);
|
|
369
|
+
const opacity = parseFloat(computed.opacity);
|
|
370
|
+
if (opacity < 0.1) {
|
|
371
|
+
frozenInlineElements.set(el, el.getAttribute("style") || "");
|
|
372
|
+
el.style.setProperty("opacity", "1", "important");
|
|
373
|
+
el.style.setProperty("transform", "none", "important");
|
|
374
|
+
el.style.setProperty("will-change", "auto", "important");
|
|
375
|
+
el.setAttribute(FRAMER_FIXED_ATTR, "true");
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
function restoreFrozenInlineElements() {
|
|
380
|
+
for (const [el, origStyle] of frozenInlineElements) {
|
|
381
|
+
try {
|
|
382
|
+
el.setAttribute("style", origStyle);
|
|
383
|
+
el.removeAttribute(FRAMER_FIXED_ATTR);
|
|
384
|
+
} catch {
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
frozenInlineElements.clear();
|
|
388
|
+
}
|
|
389
|
+
function stopMarquees() {
|
|
390
|
+
document.querySelectorAll("marquee").forEach((el) => {
|
|
391
|
+
try {
|
|
392
|
+
el.stop();
|
|
393
|
+
} catch {
|
|
394
|
+
}
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
function startMarquees() {
|
|
398
|
+
document.querySelectorAll("marquee").forEach((el) => {
|
|
399
|
+
try {
|
|
400
|
+
el.start();
|
|
401
|
+
} catch {
|
|
402
|
+
}
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
function pauseSVGAnimations() {
|
|
406
|
+
document.querySelectorAll("svg").forEach((svg) => {
|
|
407
|
+
try {
|
|
408
|
+
if (typeof svg.pauseAnimations === "function") {
|
|
409
|
+
svg.pauseAnimations();
|
|
410
|
+
}
|
|
411
|
+
} catch {
|
|
412
|
+
}
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
function resumeSVGAnimations() {
|
|
416
|
+
document.querySelectorAll("svg").forEach((svg) => {
|
|
417
|
+
try {
|
|
418
|
+
if (typeof svg.unpauseAnimations === "function") {
|
|
419
|
+
svg.unpauseAnimations();
|
|
420
|
+
}
|
|
421
|
+
} catch {
|
|
422
|
+
}
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
function pauseAutoplayVideos() {
|
|
426
|
+
const videos = document.querySelectorAll("video[autoplay], video");
|
|
427
|
+
pausedVideos = [];
|
|
428
|
+
videos.forEach((video) => {
|
|
429
|
+
if (!video.paused) {
|
|
430
|
+
video.pause();
|
|
431
|
+
pausedVideos.push(video);
|
|
432
|
+
}
|
|
433
|
+
});
|
|
434
|
+
}
|
|
435
|
+
function resumePausedVideos() {
|
|
436
|
+
pausedVideos.forEach((video) => {
|
|
437
|
+
try {
|
|
438
|
+
video.play();
|
|
439
|
+
} catch {
|
|
440
|
+
}
|
|
441
|
+
});
|
|
442
|
+
pausedVideos = [];
|
|
443
|
+
}
|
|
444
|
+
function activate() {
|
|
445
|
+
if (enabled) return;
|
|
446
|
+
enabled = true;
|
|
447
|
+
injectStyles();
|
|
448
|
+
pauseAllWebAnimations();
|
|
449
|
+
overrideElementAnimate();
|
|
450
|
+
overrideRAF();
|
|
451
|
+
setupMutationObserver();
|
|
452
|
+
emulateReducedMotion();
|
|
453
|
+
freezeAllGifs();
|
|
454
|
+
forceFramerAppearVisible();
|
|
455
|
+
stopMarquees();
|
|
456
|
+
pauseSVGAnimations();
|
|
457
|
+
setupStyleObserver();
|
|
458
|
+
scheduleDelayedScans();
|
|
459
|
+
pauseAutoplayVideos();
|
|
460
|
+
forceAllHiddenVisible();
|
|
461
|
+
localStorage.setItem(STORAGE_KEY, "true");
|
|
462
|
+
}
|
|
463
|
+
function deactivate() {
|
|
464
|
+
enabled = false;
|
|
465
|
+
clearDelayedScans();
|
|
466
|
+
disconnectStyleObserver();
|
|
467
|
+
restoreFrozenInlineElements();
|
|
468
|
+
resumePausedVideos();
|
|
469
|
+
resumeSVGAnimations();
|
|
470
|
+
startMarquees();
|
|
471
|
+
restoreFramerAppear();
|
|
472
|
+
restoreGifs();
|
|
473
|
+
restoreMatchMedia();
|
|
474
|
+
disconnectMutationObserver();
|
|
475
|
+
restoreRAF();
|
|
476
|
+
restoreElementAnimate();
|
|
477
|
+
resumePausedAnimations();
|
|
478
|
+
removeStyles();
|
|
479
|
+
localStorage.removeItem(STORAGE_KEY);
|
|
480
|
+
}
|
|
481
|
+
return {
|
|
482
|
+
id: "animation-stop",
|
|
483
|
+
name: () => "Stop Animations",
|
|
484
|
+
description: "Pause all animations, transitions, and auto-playing videos (WCAG 2.3.1)",
|
|
485
|
+
icon: "animation-stop",
|
|
486
|
+
category: "visual",
|
|
487
|
+
activate,
|
|
488
|
+
deactivate,
|
|
489
|
+
getState: () => ({
|
|
490
|
+
id: "animation-stop",
|
|
491
|
+
enabled
|
|
492
|
+
}),
|
|
493
|
+
setState: (state) => {
|
|
494
|
+
if (state.enabled) {
|
|
495
|
+
activate();
|
|
496
|
+
} else {
|
|
497
|
+
deactivate();
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
};
|
|
501
|
+
}
|
|
502
|
+
export {
|
|
503
|
+
createAnimationStopModule as default
|
|
504
|
+
};
|
|
505
|
+
//# sourceMappingURL=animation-stop-C6ToNlBr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"animation-stop-C6ToNlBr.js","sources":["../src/features/animation-stop.ts"],"sourcesContent":["import type { FeatureModule, FeatureState } from '../types';\n\nexport default function createAnimationStopModule(): FeatureModule {\n let enabled = false;\n const STYLE_ID = 'accessify-animation-stop';\n const STORAGE_KEY = 'accessify-animation-stop';\n\n // --- State for clean restore ---\n let pausedVideos: HTMLVideoElement[] = [];\n let pausedAnimations: Animation[] = [];\n let originalAnimate: typeof Element.prototype.animate | null = null;\n let originalRAF: typeof window.requestAnimationFrame | null = null;\n let originalMatchMedia: typeof window.matchMedia | null = null;\n let mutationObserver: MutationObserver | null = null;\n let rafLoopTracker = new Map<string, { count: number; lastTime: number }>();\n let blockedRAFs = new Set<number>();\n let gifOriginals = new Map<HTMLImageElement, string>();\n let reducedMotionListeners: Array<{ mql: MediaQueryList; handler: () => void }> = [];\n let styleObserver: MutationObserver | null = null;\n let delayedTimers: ReturnType<typeof setTimeout>[] = [];\n let frozenInlineElements = new Map<HTMLElement, string>();\n\n // -------------------------------------------------------------------------\n // Layer 0: CSS overrides (existing — catches pure CSS animations)\n // -------------------------------------------------------------------------\n\n function getStyles(): string {\n return `\n /* accessify animation stop - WCAG 2.3.1 compliance */\n *, *::before, *::after {\n animation-duration: 0.01s !important;\n animation-delay: 0s !important;\n animation-iteration-count: 1 !important;\n animation-play-state: paused !important;\n transition-duration: 0.01s !important;\n transition-delay: 0s !important;\n scroll-behavior: auto !important;\n }\n\n /* Framer appear elements — force visible (they start at opacity:0.001) */\n [data-framer-appear-id] {\n opacity: 1 !important;\n transform: none !important;\n will-change: auto !important;\n }\n\n /* Framer page containers with near-zero opacity */\n [data-framer-component-type] [style*=\"opacity\"] {\n opacity: 1 !important;\n }\n\n /* Generic: any element with will-change:transform that might be hidden by animation libs */\n [style*=\"will-change\"][style*=\"opacity:0\"],\n [style*=\"will-change\"][style*=\"opacity: 0\"] {\n opacity: 1 !important;\n transform: none !important;\n will-change: auto !important;\n }\n\n marquee { -moz-binding: none; }\n `;\n }\n\n function injectStyles() {\n let styleEl = document.getElementById(STYLE_ID);\n if (!styleEl) {\n styleEl = document.createElement('style');\n styleEl.id = STYLE_ID;\n document.head.appendChild(styleEl);\n }\n styleEl.textContent = getStyles();\n }\n\n function removeStyles() {\n document.getElementById(STYLE_ID)?.remove();\n }\n\n // -------------------------------------------------------------------------\n // Layer 1: Web Animations API — pause all running + intercept new\n // -------------------------------------------------------------------------\n\n function pauseAllWebAnimations() {\n try {\n const animations = document.getAnimations();\n for (const anim of animations) {\n if (anim.playState === 'running' || anim.playState === 'pending') {\n anim.pause();\n pausedAnimations.push(anim);\n }\n }\n } catch { /* getAnimations not supported */ }\n }\n\n function overrideElementAnimate() {\n if (originalAnimate) return;\n originalAnimate = Element.prototype.animate;\n\n Element.prototype.animate = function (\n this: Element,\n keyframes: Keyframe[] | PropertyIndexedKeyframes | null,\n options?: number | KeyframeAnimationOptions,\n ): Animation {\n const anim = originalAnimate!.call(this, keyframes, options);\n if (enabled) {\n anim.pause();\n pausedAnimations.push(anim);\n }\n return anim;\n };\n }\n\n function restoreElementAnimate() {\n if (originalAnimate) {\n Element.prototype.animate = originalAnimate;\n originalAnimate = null;\n }\n }\n\n function resumePausedAnimations() {\n for (const anim of pausedAnimations) {\n try { anim.play(); } catch { /* animation may be gone */ }\n }\n pausedAnimations = [];\n }\n\n // -------------------------------------------------------------------------\n // Layer 2: requestAnimationFrame loop detection\n // -------------------------------------------------------------------------\n\n function overrideRAF() {\n if (originalRAF) return;\n originalRAF = window.requestAnimationFrame;\n const origCancel = window.cancelAnimationFrame;\n\n window.requestAnimationFrame = function (callback: FrameRequestCallback): number {\n if (!enabled) return originalRAF!.call(window, callback);\n\n // Fingerprint callback to detect animation loops\n const key = callback.toString().slice(0, 200);\n const now = performance.now();\n const entry = rafLoopTracker.get(key);\n\n if (entry) {\n entry.count++;\n if (now - entry.lastTime < 100 && entry.count > 3) {\n // This callback is re-registering rapidly — animation loop detected\n const id = originalRAF!.call(window, () => {}); // no-op\n blockedRAFs.add(id);\n return id;\n }\n entry.lastTime = now;\n } else {\n rafLoopTracker.set(key, { count: 1, lastTime: now });\n }\n\n // Allow through but wrap to track re-registration\n return originalRAF!.call(window, callback);\n };\n\n window.cancelAnimationFrame = function (id: number) {\n blockedRAFs.delete(id);\n return origCancel.call(window, id);\n };\n }\n\n function restoreRAF() {\n if (originalRAF) {\n window.requestAnimationFrame = originalRAF;\n originalRAF = null;\n }\n rafLoopTracker.clear();\n blockedRAFs.clear();\n }\n\n // -------------------------------------------------------------------------\n // Layer 3: MutationObserver — catch dynamically added animated elements\n // -------------------------------------------------------------------------\n\n function setupMutationObserver() {\n if (mutationObserver) return;\n\n mutationObserver = new MutationObserver((mutations) => {\n if (!enabled) return;\n for (const mutation of mutations) {\n for (const node of mutation.addedNodes) {\n if (!(node instanceof HTMLElement)) continue;\n // Pause animations on newly added elements\n try {\n const anims = node.getAnimations({ subtree: true });\n for (const anim of anims) {\n if (anim.playState === 'running' || anim.playState === 'pending') {\n anim.pause();\n pausedAnimations.push(anim);\n }\n }\n } catch { /* not supported */ }\n\n // Pause new videos\n if (node.tagName === 'VIDEO') {\n const video = node as HTMLVideoElement;\n if (!video.paused) {\n video.pause();\n pausedVideos.push(video);\n }\n }\n node.querySelectorAll?.('video')?.forEach((video) => {\n if (!video.paused) {\n video.pause();\n pausedVideos.push(video);\n }\n });\n\n // Freeze new GIFs\n if (node.tagName === 'IMG') {\n freezeGif(node as HTMLImageElement);\n }\n node.querySelectorAll?.('img')?.forEach((img) => freezeGif(img));\n\n // Fix Framer appear elements added dynamically\n if (node.hasAttribute?.('data-framer-appear-id')) {\n forceFramerAppearVisibleSingle(node);\n }\n node.querySelectorAll?.('[data-framer-appear-id]')?.forEach((el) => {\n forceFramerAppearVisibleSingle(el as HTMLElement);\n });\n }\n }\n });\n\n mutationObserver.observe(document.body, {\n childList: true,\n subtree: true,\n });\n }\n\n function disconnectMutationObserver() {\n mutationObserver?.disconnect();\n mutationObserver = null;\n }\n\n // -------------------------------------------------------------------------\n // Layer 4: prefers-reduced-motion emulation\n // -------------------------------------------------------------------------\n\n function emulateReducedMotion() {\n if (originalMatchMedia) return;\n originalMatchMedia = window.matchMedia;\n\n window.matchMedia = function (query: string): MediaQueryList {\n const mql = originalMatchMedia!.call(window, query);\n\n if (query.includes('prefers-reduced-motion')) {\n // Return a proxy that always reports matches: true\n const proxy = Object.create(mql);\n Object.defineProperty(proxy, 'matches', { get: () => enabled, configurable: true });\n Object.defineProperty(proxy, 'media', { get: () => query, configurable: true });\n return proxy;\n }\n return mql;\n };\n\n // Trigger change event on existing reduced-motion media queries\n // so frameworks (Framer Motion, GSAP) react immediately\n try {\n const mql = originalMatchMedia.call(window, '(prefers-reduced-motion: reduce)');\n mql.dispatchEvent(new MediaQueryListEvent('change', { matches: true, media: mql.media }));\n } catch { /* older browsers */ }\n }\n\n function restoreMatchMedia() {\n if (originalMatchMedia) {\n window.matchMedia = originalMatchMedia;\n originalMatchMedia = null;\n\n // Dispatch change event to signal motion is allowed again\n try {\n const mql = window.matchMedia('(prefers-reduced-motion: reduce)');\n mql.dispatchEvent(new MediaQueryListEvent('change', { matches: mql.matches, media: mql.media }));\n } catch { /* older browsers */ }\n }\n }\n\n // -------------------------------------------------------------------------\n // Layer 5: GIF freeze — replace with static first frame\n // -------------------------------------------------------------------------\n\n function freezeGif(img: HTMLImageElement) {\n const src = img.src || img.getAttribute('src') || '';\n if (!src.toLowerCase().includes('.gif')) return;\n if (gifOriginals.has(img)) return;\n\n const freeze = () => {\n try {\n const canvas = document.createElement('canvas');\n canvas.width = img.naturalWidth || img.width;\n canvas.height = img.naturalHeight || img.height;\n if (canvas.width === 0 || canvas.height === 0) return;\n const ctx = canvas.getContext('2d');\n if (!ctx) return;\n ctx.drawImage(img, 0, 0);\n gifOriginals.set(img, src);\n img.src = canvas.toDataURL('image/png');\n } catch { /* cross-origin, skip */ }\n };\n\n if (img.complete && img.naturalWidth > 0) {\n freeze();\n } else {\n img.addEventListener('load', freeze, { once: true });\n }\n }\n\n function freezeAllGifs() {\n document.querySelectorAll<HTMLImageElement>('img').forEach(freezeGif);\n }\n\n function restoreGifs() {\n for (const [img, originalSrc] of gifOriginals) {\n try { img.src = originalSrc; } catch { /* element may be gone */ }\n }\n gifOriginals.clear();\n }\n\n // -------------------------------------------------------------------------\n // Layer 6: Framer appear animations — force visible\n // Framer renders elements with opacity:0.001 + will-change:transform and\n // animates them in via JS. When we stop animations, they stay invisible.\n // Fix: force all Framer appear elements to their final visible state.\n // -------------------------------------------------------------------------\n\n const FRAMER_FIXED_ATTR = 'data-accessify-framer-fixed';\n let framerFixedElements: Array<{ el: HTMLElement; origStyle: string }> = [];\n\n function forceFramerAppearVisible() {\n // Framer appear elements — force ALL to visible, not just opacity:0.001\n const appearEls = document.querySelectorAll<HTMLElement>('[data-framer-appear-id]');\n for (const el of appearEls) {\n if (el.hasAttribute(FRAMER_FIXED_ATTR)) continue;\n const computed = getComputedStyle(el);\n const opacity = parseFloat(computed.opacity);\n // Fix any element that is less than fully visible\n if (opacity < 0.95) {\n framerFixedElements.push({ el, origStyle: el.getAttribute('style') || '' });\n el.style.setProperty('opacity', '1', 'important');\n el.style.setProperty('transform', 'none', 'important');\n el.style.setProperty('will-change', 'auto', 'important');\n el.setAttribute(FRAMER_FIXED_ATTR, 'true');\n }\n }\n\n // Generic: any element with near-zero opacity that has will-change:transform\n // (common pattern in animation libraries for scroll-reveal)\n const allWillChange = document.querySelectorAll<HTMLElement>('[style*=\"will-change\"]');\n for (const el of allWillChange) {\n if (el.hasAttribute(FRAMER_FIXED_ATTR)) continue;\n if (el.closest('#accessify-root')) continue;\n const computed = getComputedStyle(el);\n const opacity = parseFloat(computed.opacity);\n if (opacity < 0.1 && computed.willChange.includes('transform')) {\n framerFixedElements.push({ el, origStyle: el.getAttribute('style') || '' });\n el.style.setProperty('opacity', '1', 'important');\n el.style.setProperty('transform', 'none', 'important');\n el.style.setProperty('will-change', 'auto', 'important');\n el.setAttribute(FRAMER_FIXED_ATTR, 'true');\n }\n }\n }\n\n function restoreFramerAppear() {\n for (const { el, origStyle } of framerFixedElements) {\n try {\n el.setAttribute('style', origStyle);\n el.removeAttribute(FRAMER_FIXED_ATTR);\n } catch { /* element may be gone */ }\n }\n framerFixedElements = [];\n }\n\n function forceFramerAppearVisibleSingle(el: HTMLElement) {\n if (el.hasAttribute(FRAMER_FIXED_ATTR)) return;\n const computed = getComputedStyle(el);\n const opacity = parseFloat(computed.opacity);\n if (opacity < 0.95) {\n framerFixedElements.push({ el, origStyle: el.getAttribute('style') || '' });\n el.style.setProperty('opacity', '1', 'important');\n el.style.setProperty('transform', 'none', 'important');\n el.style.setProperty('will-change', 'auto', 'important');\n el.setAttribute(FRAMER_FIXED_ATTR, 'true');\n }\n }\n\n // -------------------------------------------------------------------------\n // Layer 8: Style attribute mutation observer — counter inline style animations\n // Framer, GSAP, and other JS libs set transform/opacity directly via\n // element.style on every frame. CSS !important should win, but some libs\n // use setProperty with 'important' or the style attribute gets fully\n // rewritten. This observer catches and re-forces visibility.\n // -------------------------------------------------------------------------\n\n function setupStyleObserver() {\n if (styleObserver) return;\n let isOurChange = false;\n\n styleObserver = new MutationObserver((mutations) => {\n if (!enabled || isOurChange) return;\n isOurChange = true;\n\n for (const m of mutations) {\n if (m.type !== 'attributes' || m.attributeName !== 'style') continue;\n const el = m.target as HTMLElement;\n\n // Only act on Framer elements or elements that look like animation targets\n const isFramerEl = el.hasAttribute('data-framer-appear-id') ||\n el.hasAttribute('data-framer-component-type') ||\n el.closest('[data-framer-appear-id]') !== null;\n const hasWillChange = el.style.willChange?.includes('transform') ||\n el.style.willChange?.includes('opacity');\n\n if (!isFramerEl && !hasWillChange) continue;\n\n const opacity = parseFloat(el.style.opacity);\n if (!isNaN(opacity) && opacity < 0.1) {\n el.style.setProperty('opacity', '1', 'important');\n el.style.setProperty('transform', 'none', 'important');\n el.style.setProperty('will-change', 'auto', 'important');\n }\n }\n\n isOurChange = false;\n });\n\n styleObserver.observe(document.body, {\n attributes: true,\n attributeFilter: ['style'],\n subtree: true,\n });\n }\n\n function disconnectStyleObserver() {\n styleObserver?.disconnect();\n styleObserver = null;\n }\n\n // -------------------------------------------------------------------------\n // Layer 9: Delayed re-scans — Framer loads async, elements appear late\n // -------------------------------------------------------------------------\n\n function scheduleDelayedScans() {\n const delays = [500, 1000, 2000, 4000];\n for (const delay of delays) {\n const timer = setTimeout(() => {\n if (!enabled) return;\n forceAllHiddenVisible();\n pauseAllWebAnimations();\n freezeAllGifs();\n pauseSVGAnimations();\n stopMarquees();\n }, delay);\n delayedTimers.push(timer);\n }\n }\n\n function clearDelayedScans() {\n for (const timer of delayedTimers) clearTimeout(timer);\n delayedTimers = [];\n }\n\n // -------------------------------------------------------------------------\n // Force ALL hidden animation targets visible — aggressive sweep\n // -------------------------------------------------------------------------\n\n function forceAllHiddenVisible() {\n // 1. Framer appear elements\n forceFramerAppearVisible();\n\n // 2. Broad sweep: any element with computed opacity < 0.1\n // that has animation-related attributes or styles\n const candidates = document.querySelectorAll<HTMLElement>(\n '[data-framer-appear-id], [data-framer-component-type] *, [style*=\"will-change\"], [style*=\"opacity\"]'\n );\n for (const el of candidates) {\n if (el.hasAttribute(FRAMER_FIXED_ATTR)) continue;\n if (el.closest('#accessify-root')) continue;\n const computed = getComputedStyle(el);\n const opacity = parseFloat(computed.opacity);\n if (opacity < 0.1) {\n frozenInlineElements.set(el, el.getAttribute('style') || '');\n el.style.setProperty('opacity', '1', 'important');\n el.style.setProperty('transform', 'none', 'important');\n el.style.setProperty('will-change', 'auto', 'important');\n el.setAttribute(FRAMER_FIXED_ATTR, 'true');\n }\n }\n }\n\n function restoreFrozenInlineElements() {\n for (const [el, origStyle] of frozenInlineElements) {\n try {\n el.setAttribute('style', origStyle);\n el.removeAttribute(FRAMER_FIXED_ATTR);\n } catch { /* element may be gone */ }\n }\n frozenInlineElements.clear();\n }\n\n // -------------------------------------------------------------------------\n // Layer 7: Marquee & SVG SMIL animations\n // -------------------------------------------------------------------------\n\n function stopMarquees() {\n document.querySelectorAll('marquee').forEach((el) => {\n try { (el as any).stop(); } catch { /* not supported */ }\n });\n }\n\n function startMarquees() {\n document.querySelectorAll('marquee').forEach((el) => {\n try { (el as any).start(); } catch { /* not supported */ }\n });\n }\n\n function pauseSVGAnimations() {\n document.querySelectorAll('svg').forEach((svg) => {\n try {\n if (typeof (svg as any).pauseAnimations === 'function') {\n (svg as any).pauseAnimations();\n }\n } catch { /* not supported */ }\n });\n }\n\n function resumeSVGAnimations() {\n document.querySelectorAll('svg').forEach((svg) => {\n try {\n if (typeof (svg as any).unpauseAnimations === 'function') {\n (svg as any).unpauseAnimations();\n }\n } catch { /* not supported */ }\n });\n }\n\n // -------------------------------------------------------------------------\n // Video control (existing)\n // -------------------------------------------------------------------------\n\n function pauseAutoplayVideos() {\n const videos = document.querySelectorAll<HTMLVideoElement>('video[autoplay], video');\n pausedVideos = [];\n videos.forEach((video) => {\n if (!video.paused) {\n video.pause();\n pausedVideos.push(video);\n }\n });\n }\n\n function resumePausedVideos() {\n pausedVideos.forEach((video) => {\n try { video.play(); } catch { /* removed from DOM */ }\n });\n pausedVideos = [];\n }\n\n // -------------------------------------------------------------------------\n // Lifecycle\n // -------------------------------------------------------------------------\n\n function activate() {\n if (enabled) return;\n enabled = true;\n\n // Layer 0: CSS overrides (includes Framer-specific !important rules)\n injectStyles();\n\n // Layer 1: Web Animations API\n pauseAllWebAnimations();\n overrideElementAnimate();\n\n // Layer 2: RAF loop detection\n overrideRAF();\n\n // Layer 3: MutationObserver for dynamic content\n setupMutationObserver();\n\n // Layer 4: prefers-reduced-motion emulation\n emulateReducedMotion();\n\n // Layer 5: GIF freeze\n freezeAllGifs();\n\n // Layer 6: Framer appear — force visible\n forceFramerAppearVisible();\n\n // Layer 7: Marquee & SVG SMIL\n stopMarquees();\n pauseSVGAnimations();\n\n // Layer 8: Style attribute mutation observer (counters Framer inline style updates)\n setupStyleObserver();\n\n // Layer 9: Delayed re-scans (Framer loads elements async)\n scheduleDelayedScans();\n\n // Videos\n pauseAutoplayVideos();\n\n // Aggressive sweep — force all hidden animation targets visible\n forceAllHiddenVisible();\n\n localStorage.setItem(STORAGE_KEY, 'true');\n }\n\n function deactivate() {\n enabled = false;\n\n // Reverse order for clean teardown\n clearDelayedScans();\n disconnectStyleObserver();\n restoreFrozenInlineElements();\n resumePausedVideos();\n resumeSVGAnimations();\n startMarquees();\n restoreFramerAppear();\n restoreGifs();\n restoreMatchMedia();\n disconnectMutationObserver();\n restoreRAF();\n restoreElementAnimate();\n resumePausedAnimations();\n removeStyles();\n\n localStorage.removeItem(STORAGE_KEY);\n }\n\n return {\n id: 'animation-stop',\n name: () => 'Stop Animations',\n description: 'Pause all animations, transitions, and auto-playing videos (WCAG 2.3.1)',\n icon: 'animation-stop',\n category: 'visual',\n activate,\n deactivate,\n getState: (): FeatureState => ({\n id: 'animation-stop',\n enabled,\n }),\n setState: (state: { enabled: boolean }) => {\n if (state.enabled) {\n activate();\n } else {\n deactivate();\n }\n },\n };\n}\n"],"names":[],"mappings":"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"}
|