@ox-content/vite-plugin 3.0.0-alpha.8 → 3.0.0-beta.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/index.cjs +8898 -2585
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2050 -221
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +2050 -221
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +8839 -2531
- package/dist/index.mjs.map +1 -1
- package/dist/markdown-tables.cjs +70 -0
- package/dist/markdown-tables.cjs.map +1 -0
- package/dist/markdown-tables.d.cts +22 -0
- package/dist/markdown-tables.d.cts.map +1 -0
- package/dist/markdown-tables.d.mts +22 -0
- package/dist/markdown-tables.d.mts.map +1 -0
- package/dist/markdown-tables.mjs +66 -0
- package/dist/markdown-tables.mjs.map +1 -0
- package/dist/napi.cjs +44 -0
- package/dist/napi.cjs.map +1 -0
- package/dist/napi.mjs +34 -0
- package/dist/napi.mjs.map +1 -0
- package/dist/reader-chrome-client.cjs +103 -0
- package/dist/reader-chrome-client.d.cts +2 -0
- package/dist/reader-chrome-client.d.mts +2 -0
- package/dist/reader-chrome-client.mjs +102 -0
- package/dist/reader-chrome.cjs +109 -0
- package/dist/reader-chrome.cjs.map +1 -0
- package/dist/reader-chrome.d.cts +103 -0
- package/dist/reader-chrome.d.mts +103 -0
- package/dist/reader-chrome.mjs +98 -0
- package/dist/reader-chrome.mjs.map +1 -0
- package/dist/styles/all.css +15 -0
- package/dist/styles/citations.css +62 -0
- package/dist/styles/core.css +2261 -0
- package/dist/styles/github.css +262 -0
- package/dist/styles/graphviz.css +34 -0
- package/dist/styles/magic-links.css +33 -0
- package/dist/styles/markdown-tables.css +16 -0
- package/dist/styles/mermaid.css +151 -0
- package/dist/styles/not-by-ai.css +43 -0
- package/dist/styles/ogp.css +170 -0
- package/dist/styles/reader-chrome.css +163 -0
- package/dist/styles/social.css +678 -0
- package/dist/styles/tabs.css +210 -0
- package/dist/styles/theme-transition.css +37 -0
- package/dist/styles/twitter-full.css +598 -0
- package/dist/styles/youtube.css +87 -0
- package/dist/theme-tokens.cjs +95 -0
- package/dist/theme-tokens.cjs.map +1 -0
- package/dist/theme-tokens.d.cts +72 -0
- package/dist/theme-tokens.d.cts.map +1 -0
- package/dist/theme-tokens.d.mts +72 -0
- package/dist/theme-tokens.d.mts.map +1 -0
- package/dist/theme-tokens.mjs +91 -0
- package/dist/theme-tokens.mjs.map +1 -0
- package/dist/theme-transition-client.cjs +161 -0
- package/dist/theme-transition-client.d.cts +21 -0
- package/dist/theme-transition-client.d.mts +21 -0
- package/dist/theme-transition-client.mjs +160 -0
- package/dist/twitter-client.cjs +84 -0
- package/dist/twitter-client.d.cts +11 -0
- package/dist/twitter-client.d.mts +11 -0
- package/dist/twitter-client.mjs +83 -0
- package/dist/vitepress.cjs +614 -77
- package/dist/vitepress.cjs.map +1 -1
- package/dist/vitepress.mjs +588 -65
- package/dist/vitepress.mjs.map +1 -1
- package/package.json +89 -4
- package/dist/api.cjs +0 -6563
- package/dist/api.cjs.map +0 -1
- package/dist/api.mjs +0 -6456
- package/dist/api.mjs.map +0 -1
- package/dist/interop.cjs +0 -31
- package/dist/interop.cjs.map +0 -1
- package/dist/interop.mjs +0 -26
- package/dist/interop.mjs.map +0 -1
- package/dist/tabs.cjs +0 -98
- package/dist/tabs.cjs.map +0 -1
- package/dist/tabs.mjs +0 -99
- package/dist/tabs.mjs.map +0 -1
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
// Generated from crates/ox_content_ssg/src/html/theme_transition_runtime.js.
|
|
2
|
+
// Run npm/vite-plugin-ox-content/scripts/build-theme-transition-client.mjs.
|
|
3
|
+
|
|
4
|
+
// Circular reveal for a same-document colour-scheme change.
|
|
5
|
+
//
|
|
6
|
+
// Prior art: @hooray's VitePress implementation, by way of @ryoppippi's
|
|
7
|
+
// svelte-fancy-darkmode, which this is a framework-neutral port of.
|
|
8
|
+
//
|
|
9
|
+
// This wraps a *same-document* theme mutation. It is unrelated to the
|
|
10
|
+
// cross-document `@view-transition` used for MPA navigation, and the CSS it
|
|
11
|
+
// depends on is scoped to `data-ox-theme-transition` so the two lifecycles
|
|
12
|
+
// cannot reach each other's snapshots.
|
|
13
|
+
|
|
14
|
+
const OX_THEME_TRANSITION_ATTR = "data-ox-theme-transition";
|
|
15
|
+
const OX_THEME_TRANSITION_SUPPRESS_ATTR = "data-ox-theme-transition-suppress";
|
|
16
|
+
|
|
17
|
+
let oxThemeTransitionCurrent = null;
|
|
18
|
+
|
|
19
|
+
function oxThemeTransitionRoot() {
|
|
20
|
+
return typeof document === "undefined" ? null : document.documentElement;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function oxThemeTransitionReducedMotion() {
|
|
24
|
+
return typeof matchMedia === "function" && matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function oxThemeTransitionSupported(root) {
|
|
28
|
+
return Boolean(
|
|
29
|
+
root &&
|
|
30
|
+
typeof document !== "undefined" &&
|
|
31
|
+
typeof document.startViewTransition === "function" &&
|
|
32
|
+
typeof root.animate === "function",
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// A keyboard or programmatic activation still produces a click event, but with
|
|
37
|
+
// no meaningful coordinates: `detail` is 0 and clientX/clientY report 0. Only
|
|
38
|
+
// a real pointer press is trusted, so the reveal never starts from the corner
|
|
39
|
+
// of the screen when someone tabs to the button.
|
|
40
|
+
function oxThemeTransitionOrigin(event) {
|
|
41
|
+
const viewportCentre = {
|
|
42
|
+
x: (typeof innerWidth === "number" ? innerWidth : 0) / 2,
|
|
43
|
+
y: (typeof innerHeight === "number" ? innerHeight : 0) / 2,
|
|
44
|
+
};
|
|
45
|
+
if (!event) return viewportCentre;
|
|
46
|
+
|
|
47
|
+
const fromPointer =
|
|
48
|
+
typeof event.clientX === "number" &&
|
|
49
|
+
typeof event.clientY === "number" &&
|
|
50
|
+
(event.detail > 0 || (typeof event.pointerType === "string" && event.pointerType !== ""));
|
|
51
|
+
if (fromPointer) return { x: event.clientX, y: event.clientY };
|
|
52
|
+
|
|
53
|
+
const target = event.currentTarget ?? event.target;
|
|
54
|
+
if (target && typeof target.getBoundingClientRect === "function") {
|
|
55
|
+
const rect = target.getBoundingClientRect();
|
|
56
|
+
if (rect.width > 0 || rect.height > 0) {
|
|
57
|
+
return { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2 };
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return viewportCentre;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// The circle has to reach whichever viewport corner is furthest away, or the
|
|
64
|
+
// old theme stays visible in one corner when the animation ends.
|
|
65
|
+
function oxThemeTransitionRadius(origin) {
|
|
66
|
+
const width = typeof innerWidth === "number" ? innerWidth : 0;
|
|
67
|
+
const height = typeof innerHeight === "number" ? innerHeight : 0;
|
|
68
|
+
return Math.hypot(Math.max(origin.x, width - origin.x), Math.max(origin.y, height - origin.y));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Element-level colour transitions would otherwise animate underneath the
|
|
72
|
+
// snapshot and bleed the old palette into the new one. They are suppressed
|
|
73
|
+
// only while the mutation happens, and restored as soon as both snapshots
|
|
74
|
+
// have been captured.
|
|
75
|
+
function oxThemeTransitionSuppress(root) {
|
|
76
|
+
root.setAttribute(OX_THEME_TRANSITION_SUPPRESS_ATTR, "");
|
|
77
|
+
return () => {
|
|
78
|
+
// Reading a layout property flushes the suppressed styles before they are
|
|
79
|
+
// allowed to animate again.
|
|
80
|
+
void root.offsetHeight;
|
|
81
|
+
root.removeAttribute(OX_THEME_TRANSITION_SUPPRESS_ATTR);
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// eslint-disable-next-line no-unused-vars
|
|
86
|
+
function applyThemeTransition(options) {
|
|
87
|
+
const settings = options ?? {};
|
|
88
|
+
const apply = settings.apply;
|
|
89
|
+
if (typeof apply !== "function") return Promise.resolve();
|
|
90
|
+
|
|
91
|
+
const root = oxThemeTransitionRoot();
|
|
92
|
+
if (!oxThemeTransitionSupported(root) || oxThemeTransitionReducedMotion()) {
|
|
93
|
+
apply();
|
|
94
|
+
return Promise.resolve();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// A second toggle while one is still running would capture a half-animated
|
|
98
|
+
// snapshot. Settle the running one first; its cleanup is synchronous.
|
|
99
|
+
if (oxThemeTransitionCurrent) {
|
|
100
|
+
const running = oxThemeTransitionCurrent;
|
|
101
|
+
oxThemeTransitionCurrent = null;
|
|
102
|
+
if (typeof running.skipTransition === "function") running.skipTransition();
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Going dark expands the incoming snapshot over the outgoing one; going
|
|
106
|
+
// light shrinks the outgoing snapshot away to reveal the incoming one
|
|
107
|
+
// underneath. Either way the circle grows out of, or collapses into, the
|
|
108
|
+
// point the reader activated.
|
|
109
|
+
const expanding = settings.nextTheme !== "light";
|
|
110
|
+
const origin = oxThemeTransitionOrigin(settings.event);
|
|
111
|
+
const radius = oxThemeTransitionRadius(origin);
|
|
112
|
+
const duration = typeof settings.duration === "number" ? settings.duration : 420;
|
|
113
|
+
const easing = typeof settings.easing === "string" ? settings.easing : "ease-in-out";
|
|
114
|
+
|
|
115
|
+
root.setAttribute(OX_THEME_TRANSITION_ATTR, expanding ? "expand" : "shrink");
|
|
116
|
+
|
|
117
|
+
let restore = () => {};
|
|
118
|
+
const transition = document.startViewTransition(() => {
|
|
119
|
+
restore = oxThemeTransitionSuppress(root);
|
|
120
|
+
apply();
|
|
121
|
+
});
|
|
122
|
+
oxThemeTransitionCurrent = transition;
|
|
123
|
+
|
|
124
|
+
const clipFrom = `circle(0px at ${origin.x}px ${origin.y}px)`;
|
|
125
|
+
const clipTo = `circle(${radius}px at ${origin.x}px ${origin.y}px)`;
|
|
126
|
+
|
|
127
|
+
transition.ready.then(
|
|
128
|
+
() => {
|
|
129
|
+
restore();
|
|
130
|
+
root.animate(
|
|
131
|
+
{ clipPath: expanding ? [clipFrom, clipTo] : [clipTo, clipFrom] },
|
|
132
|
+
{
|
|
133
|
+
duration,
|
|
134
|
+
easing,
|
|
135
|
+
pseudoElement: expanding ? "::view-transition-new(root)" : "::view-transition-old(root)",
|
|
136
|
+
},
|
|
137
|
+
);
|
|
138
|
+
},
|
|
139
|
+
() => {
|
|
140
|
+
// A skipped or unsupported transition still has to hand the suppressed
|
|
141
|
+
// styles back.
|
|
142
|
+
restore();
|
|
143
|
+
},
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
const settled = () => {
|
|
147
|
+
restore();
|
|
148
|
+
// A rapid second toggle skips this one, which lands here *after* the newer
|
|
149
|
+
// transition has already claimed the attribute. Only the transition still
|
|
150
|
+
// holding the slot is allowed to clear it.
|
|
151
|
+
if (oxThemeTransitionCurrent !== transition) return;
|
|
152
|
+
oxThemeTransitionCurrent = null;
|
|
153
|
+
root.removeAttribute(OX_THEME_TRANSITION_ATTR);
|
|
154
|
+
};
|
|
155
|
+
// `finished` rejects when a transition is skipped, which is a normal outcome
|
|
156
|
+
// here — both arms clean up and neither leaves an unhandled rejection.
|
|
157
|
+
return transition.finished.then(settled, settled);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export { applyThemeTransition };
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// Generated from crates/ox_content_ssg/src/html/plugins/twitter.js.
|
|
2
|
+
// Run npm/vite-plugin-ox-content/scripts/build-twitter-client.mjs.
|
|
3
|
+
|
|
4
|
+
"use strict";
|
|
5
|
+
const TWEET_COPY_RESET_MS = 6000;
|
|
6
|
+
const oxTweetInitializedRoots = new WeakSet();
|
|
7
|
+
const oxTweetCopyResetTimers = new WeakMap();
|
|
8
|
+
const oxTweetHandledEvents = new WeakSet();
|
|
9
|
+
|
|
10
|
+
// eslint-disable-next-line no-unused-vars
|
|
11
|
+
function initTweetCards(rootInput, options) {
|
|
12
|
+
const fallbackDocument = typeof document === "undefined" ? undefined : document;
|
|
13
|
+
const root = rootInput ?? fallbackDocument;
|
|
14
|
+
if (!root || oxTweetInitializedRoots.has(root) || typeof root.addEventListener !== "function") {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
oxTweetInitializedRoots.add(root);
|
|
19
|
+
const copiedMs =
|
|
20
|
+
options && Number.isFinite(options.copiedMs)
|
|
21
|
+
? Math.max(0, options.copiedMs)
|
|
22
|
+
: TWEET_COPY_RESET_MS;
|
|
23
|
+
const getClipboard = () =>
|
|
24
|
+
options && options.clipboard
|
|
25
|
+
? options.clipboard
|
|
26
|
+
: typeof navigator === "undefined"
|
|
27
|
+
? undefined
|
|
28
|
+
: navigator.clipboard;
|
|
29
|
+
|
|
30
|
+
root.addEventListener("click", (event) => {
|
|
31
|
+
if (oxTweetHandledEvents.has(event) || event.defaultPrevented) return;
|
|
32
|
+
const action = closestTweetCopyAction(event.target);
|
|
33
|
+
if (!action) return;
|
|
34
|
+
|
|
35
|
+
const url = action.getAttribute("data-ox-tweet-copy-url") || action.getAttribute("href");
|
|
36
|
+
const clipboard = getClipboard();
|
|
37
|
+
if (!url || !clipboard || typeof clipboard.writeText !== "function") return;
|
|
38
|
+
|
|
39
|
+
oxTweetHandledEvents.add(event);
|
|
40
|
+
event.preventDefault();
|
|
41
|
+
clipboard
|
|
42
|
+
.writeText(url)
|
|
43
|
+
.then(() => setTweetCopyState(action, "copied", copiedMs))
|
|
44
|
+
.catch(() => setTweetCopyState(action, "failed", copiedMs));
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// eslint-disable-next-line no-unused-vars
|
|
49
|
+
const initTwitterCards = initTweetCards;
|
|
50
|
+
|
|
51
|
+
function closestTweetCopyAction(target) {
|
|
52
|
+
if (!target || typeof target.closest !== "function") return undefined;
|
|
53
|
+
const action = target.closest("[data-ox-tweet-copy]");
|
|
54
|
+
if (!action || typeof action.getAttribute !== "function") return undefined;
|
|
55
|
+
return action;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function setTweetCopyState(action, state, copiedMs) {
|
|
59
|
+
const previousTimer = oxTweetCopyResetTimers.get(action);
|
|
60
|
+
if (previousTimer) clearTimeout(previousTimer);
|
|
61
|
+
|
|
62
|
+
const label = state === "copied" ? "Copied!" : state === "failed" ? "Copy failed" : "Copy link";
|
|
63
|
+
const status =
|
|
64
|
+
typeof action.querySelector === "function"
|
|
65
|
+
? action.querySelector("[data-ox-tweet-copy-status]")
|
|
66
|
+
: undefined;
|
|
67
|
+
|
|
68
|
+
if (state === "copied") action.setAttribute("data-ox-tweet-copied", "");
|
|
69
|
+
else action.removeAttribute("data-ox-tweet-copied");
|
|
70
|
+
action.setAttribute("aria-label", label);
|
|
71
|
+
action.setAttribute("title", label);
|
|
72
|
+
if (status) status.textContent = state ? label : "";
|
|
73
|
+
|
|
74
|
+
if (state) {
|
|
75
|
+
oxTweetCopyResetTimers.set(
|
|
76
|
+
action,
|
|
77
|
+
setTimeout(() => setTweetCopyState(action, undefined, copiedMs), copiedMs),
|
|
78
|
+
);
|
|
79
|
+
} else {
|
|
80
|
+
oxTweetCopyResetTimers.delete(action);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
module.exports = { TWEET_COPY_RESET_MS, initTweetCards, initTwitterCards };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type TweetCardsRoot = Document | Element;
|
|
2
|
+
export interface InitTweetCardsOptions {
|
|
3
|
+
clipboard?: Pick<Clipboard, "writeText">;
|
|
4
|
+
copiedMs?: number;
|
|
5
|
+
}
|
|
6
|
+
export declare const TWEET_COPY_RESET_MS = 6000;
|
|
7
|
+
export declare function initTweetCards(
|
|
8
|
+
root?: TweetCardsRoot,
|
|
9
|
+
options?: InitTweetCardsOptions,
|
|
10
|
+
): void;
|
|
11
|
+
export declare const initTwitterCards: typeof initTweetCards;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type TweetCardsRoot = Document | Element;
|
|
2
|
+
export interface InitTweetCardsOptions {
|
|
3
|
+
clipboard?: Pick<Clipboard, "writeText">;
|
|
4
|
+
copiedMs?: number;
|
|
5
|
+
}
|
|
6
|
+
export declare const TWEET_COPY_RESET_MS = 6000;
|
|
7
|
+
export declare function initTweetCards(
|
|
8
|
+
root?: TweetCardsRoot,
|
|
9
|
+
options?: InitTweetCardsOptions,
|
|
10
|
+
): void;
|
|
11
|
+
export declare const initTwitterCards: typeof initTweetCards;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// Generated from crates/ox_content_ssg/src/html/plugins/twitter.js.
|
|
2
|
+
// Run npm/vite-plugin-ox-content/scripts/build-twitter-client.mjs.
|
|
3
|
+
|
|
4
|
+
const TWEET_COPY_RESET_MS = 6000;
|
|
5
|
+
const oxTweetInitializedRoots = new WeakSet();
|
|
6
|
+
const oxTweetCopyResetTimers = new WeakMap();
|
|
7
|
+
const oxTweetHandledEvents = new WeakSet();
|
|
8
|
+
|
|
9
|
+
// eslint-disable-next-line no-unused-vars
|
|
10
|
+
function initTweetCards(rootInput, options) {
|
|
11
|
+
const fallbackDocument = typeof document === "undefined" ? undefined : document;
|
|
12
|
+
const root = rootInput ?? fallbackDocument;
|
|
13
|
+
if (!root || oxTweetInitializedRoots.has(root) || typeof root.addEventListener !== "function") {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
oxTweetInitializedRoots.add(root);
|
|
18
|
+
const copiedMs =
|
|
19
|
+
options && Number.isFinite(options.copiedMs)
|
|
20
|
+
? Math.max(0, options.copiedMs)
|
|
21
|
+
: TWEET_COPY_RESET_MS;
|
|
22
|
+
const getClipboard = () =>
|
|
23
|
+
options && options.clipboard
|
|
24
|
+
? options.clipboard
|
|
25
|
+
: typeof navigator === "undefined"
|
|
26
|
+
? undefined
|
|
27
|
+
: navigator.clipboard;
|
|
28
|
+
|
|
29
|
+
root.addEventListener("click", (event) => {
|
|
30
|
+
if (oxTweetHandledEvents.has(event) || event.defaultPrevented) return;
|
|
31
|
+
const action = closestTweetCopyAction(event.target);
|
|
32
|
+
if (!action) return;
|
|
33
|
+
|
|
34
|
+
const url = action.getAttribute("data-ox-tweet-copy-url") || action.getAttribute("href");
|
|
35
|
+
const clipboard = getClipboard();
|
|
36
|
+
if (!url || !clipboard || typeof clipboard.writeText !== "function") return;
|
|
37
|
+
|
|
38
|
+
oxTweetHandledEvents.add(event);
|
|
39
|
+
event.preventDefault();
|
|
40
|
+
clipboard
|
|
41
|
+
.writeText(url)
|
|
42
|
+
.then(() => setTweetCopyState(action, "copied", copiedMs))
|
|
43
|
+
.catch(() => setTweetCopyState(action, "failed", copiedMs));
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// eslint-disable-next-line no-unused-vars
|
|
48
|
+
const initTwitterCards = initTweetCards;
|
|
49
|
+
|
|
50
|
+
function closestTweetCopyAction(target) {
|
|
51
|
+
if (!target || typeof target.closest !== "function") return undefined;
|
|
52
|
+
const action = target.closest("[data-ox-tweet-copy]");
|
|
53
|
+
if (!action || typeof action.getAttribute !== "function") return undefined;
|
|
54
|
+
return action;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function setTweetCopyState(action, state, copiedMs) {
|
|
58
|
+
const previousTimer = oxTweetCopyResetTimers.get(action);
|
|
59
|
+
if (previousTimer) clearTimeout(previousTimer);
|
|
60
|
+
|
|
61
|
+
const label = state === "copied" ? "Copied!" : state === "failed" ? "Copy failed" : "Copy link";
|
|
62
|
+
const status =
|
|
63
|
+
typeof action.querySelector === "function"
|
|
64
|
+
? action.querySelector("[data-ox-tweet-copy-status]")
|
|
65
|
+
: undefined;
|
|
66
|
+
|
|
67
|
+
if (state === "copied") action.setAttribute("data-ox-tweet-copied", "");
|
|
68
|
+
else action.removeAttribute("data-ox-tweet-copied");
|
|
69
|
+
action.setAttribute("aria-label", label);
|
|
70
|
+
action.setAttribute("title", label);
|
|
71
|
+
if (status) status.textContent = state ? label : "";
|
|
72
|
+
|
|
73
|
+
if (state) {
|
|
74
|
+
oxTweetCopyResetTimers.set(
|
|
75
|
+
action,
|
|
76
|
+
setTimeout(() => setTweetCopyState(action, undefined, copiedMs), copiedMs),
|
|
77
|
+
);
|
|
78
|
+
} else {
|
|
79
|
+
oxTweetCopyResetTimers.delete(action);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export { TWEET_COPY_RESET_MS, initTweetCards, initTwitterCards };
|