@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,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.markdownTableScrollLabel = markdownTableScrollLabel;
|
|
4
|
+
exports.enhanceMarkdownTables = enhanceMarkdownTables;
|
|
5
|
+
const TABINDEX_FLAG = "oxTableScrollTabindex";
|
|
6
|
+
const LABEL_FLAG = "oxTableScrollLabel";
|
|
7
|
+
const SCROLLABLE_ATTR = "data-ox-table-scrollable";
|
|
8
|
+
function markdownTableScrollLabel(locale) {
|
|
9
|
+
const language = locale?.split("-")[0]?.toLowerCase();
|
|
10
|
+
if (language === "ja") {
|
|
11
|
+
return "横スクロールできる表";
|
|
12
|
+
}
|
|
13
|
+
return "Scrollable table";
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Makes overflowing Markdown tables keyboard-scrollable without wrapping or
|
|
17
|
+
* replacing the native `<table>` element.
|
|
18
|
+
*
|
|
19
|
+
* Run this after rendering Markdown and again after layout-changing updates.
|
|
20
|
+
* Narrow tables stay out of the tab order when overflow can be measured.
|
|
21
|
+
*/
|
|
22
|
+
function enhanceMarkdownTables(root, options = {}) {
|
|
23
|
+
const target = root ?? globalThis.document;
|
|
24
|
+
if (!target?.querySelectorAll) {
|
|
25
|
+
return 0;
|
|
26
|
+
}
|
|
27
|
+
const selector = options.selector ?? ".content table";
|
|
28
|
+
const locale = ownerDocument(target)?.documentElement.lang;
|
|
29
|
+
const label = options.label ?? markdownTableScrollLabel(locale);
|
|
30
|
+
let scrollableCount = 0;
|
|
31
|
+
for (const table of target.querySelectorAll(selector)) {
|
|
32
|
+
if (typeof HTMLElement === "undefined" || !(table instanceof HTMLElement)) {
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
if (table.tagName !== "TABLE") {
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
const scrollable = table.scrollWidth > table.clientWidth + 1;
|
|
39
|
+
table.toggleAttribute(SCROLLABLE_ATTR, scrollable);
|
|
40
|
+
if (scrollable) {
|
|
41
|
+
scrollableCount++;
|
|
42
|
+
if (!table.hasAttribute("tabindex")) {
|
|
43
|
+
table.tabIndex = 0;
|
|
44
|
+
table.dataset[TABINDEX_FLAG] = "true";
|
|
45
|
+
}
|
|
46
|
+
if (!table.hasAttribute("aria-label") && !table.hasAttribute("aria-labelledby")) {
|
|
47
|
+
table.setAttribute("aria-label", label);
|
|
48
|
+
table.dataset[LABEL_FLAG] = "true";
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
if (table.dataset[TABINDEX_FLAG] === "true") {
|
|
53
|
+
table.removeAttribute("tabindex");
|
|
54
|
+
delete table.dataset[TABINDEX_FLAG];
|
|
55
|
+
}
|
|
56
|
+
if (table.dataset[LABEL_FLAG] === "true") {
|
|
57
|
+
table.removeAttribute("aria-label");
|
|
58
|
+
delete table.dataset[LABEL_FLAG];
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return scrollableCount;
|
|
63
|
+
}
|
|
64
|
+
function ownerDocument(root) {
|
|
65
|
+
if (typeof Document !== "undefined" && root instanceof Document) {
|
|
66
|
+
return root;
|
|
67
|
+
}
|
|
68
|
+
return root.ownerDocument ?? globalThis.document;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=markdown-tables.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown-tables.cjs","sourceRoot":"","sources":["../../../../home/runner/work/ox-content/ox-content/npm/vite-plugin-ox-content/src/markdown-tables.ts"],"names":[],"mappings":"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","sourcesContent":["export interface MarkdownTableEnhancementOptions {\n /**\n * Tables to enhance. Defaults to Markdown content tables styled by\n * `@ox-content/vite-plugin/styles/core.css`.\n */\n selector?: string;\n /**\n * Accessible name applied only when an overflowing table has no existing\n * `aria-label` or `aria-labelledby`.\n */\n label?: string;\n}\n\nconst TABINDEX_FLAG = \"oxTableScrollTabindex\";\nconst LABEL_FLAG = \"oxTableScrollLabel\";\nconst SCROLLABLE_ATTR = \"data-ox-table-scrollable\";\n\nexport function markdownTableScrollLabel(locale?: string): string {\n const language = locale?.split(\"-\")[0]?.toLowerCase();\n if (language === \"ja\") {\n return \"横スクロールできる表\";\n }\n return \"Scrollable table\";\n}\n\n/**\n * Makes overflowing Markdown tables keyboard-scrollable without wrapping or\n * replacing the native `<table>` element.\n *\n * Run this after rendering Markdown and again after layout-changing updates.\n * Narrow tables stay out of the tab order when overflow can be measured.\n */\nexport function enhanceMarkdownTables(\n root?: ParentNode,\n options: MarkdownTableEnhancementOptions = {},\n): number {\n const target = root ?? globalThis.document;\n if (!target?.querySelectorAll) {\n return 0;\n }\n\n const selector = options.selector ?? \".content table\";\n const locale = ownerDocument(target)?.documentElement.lang;\n const label = options.label ?? markdownTableScrollLabel(locale);\n let scrollableCount = 0;\n\n for (const table of target.querySelectorAll(selector)) {\n if (typeof HTMLElement === \"undefined\" || !(table instanceof HTMLElement)) {\n continue;\n }\n if (table.tagName !== \"TABLE\") {\n continue;\n }\n\n const scrollable = table.scrollWidth > table.clientWidth + 1;\n table.toggleAttribute(SCROLLABLE_ATTR, scrollable);\n if (scrollable) {\n scrollableCount++;\n if (!table.hasAttribute(\"tabindex\")) {\n table.tabIndex = 0;\n table.dataset[TABINDEX_FLAG] = \"true\";\n }\n if (!table.hasAttribute(\"aria-label\") && !table.hasAttribute(\"aria-labelledby\")) {\n table.setAttribute(\"aria-label\", label);\n table.dataset[LABEL_FLAG] = \"true\";\n }\n } else {\n if (table.dataset[TABINDEX_FLAG] === \"true\") {\n table.removeAttribute(\"tabindex\");\n delete table.dataset[TABINDEX_FLAG];\n }\n if (table.dataset[LABEL_FLAG] === \"true\") {\n table.removeAttribute(\"aria-label\");\n delete table.dataset[LABEL_FLAG];\n }\n }\n }\n\n return scrollableCount;\n}\n\nfunction ownerDocument(root: ParentNode): Document | undefined {\n if (typeof Document !== \"undefined\" && root instanceof Document) {\n return root;\n }\n return root.ownerDocument ?? globalThis.document;\n}\n"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface MarkdownTableEnhancementOptions {
|
|
2
|
+
/**
|
|
3
|
+
* Tables to enhance. Defaults to Markdown content tables styled by
|
|
4
|
+
* `@ox-content/vite-plugin/styles/core.css`.
|
|
5
|
+
*/
|
|
6
|
+
selector?: string;
|
|
7
|
+
/**
|
|
8
|
+
* Accessible name applied only when an overflowing table has no existing
|
|
9
|
+
* `aria-label` or `aria-labelledby`.
|
|
10
|
+
*/
|
|
11
|
+
label?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function markdownTableScrollLabel(locale?: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* Makes overflowing Markdown tables keyboard-scrollable without wrapping or
|
|
16
|
+
* replacing the native `<table>` element.
|
|
17
|
+
*
|
|
18
|
+
* Run this after rendering Markdown and again after layout-changing updates.
|
|
19
|
+
* Narrow tables stay out of the tab order when overflow can be measured.
|
|
20
|
+
*/
|
|
21
|
+
export declare function enhanceMarkdownTables(root?: ParentNode, options?: MarkdownTableEnhancementOptions): number;
|
|
22
|
+
//# sourceMappingURL=markdown-tables.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown-tables.d.cts","sourceRoot":"","sources":["../../../../home/runner/work/ox-content/ox-content/npm/vite-plugin-ox-content/src/markdown-tables.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,+BAA+B;IAC9C;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAMD,wBAAgB,wBAAwB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAMhE;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,CAAC,EAAE,UAAU,EACjB,OAAO,GAAE,+BAAoC,GAC5C,MAAM,CA4CR"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface MarkdownTableEnhancementOptions {
|
|
2
|
+
/**
|
|
3
|
+
* Tables to enhance. Defaults to Markdown content tables styled by
|
|
4
|
+
* `@ox-content/vite-plugin/styles/core.css`.
|
|
5
|
+
*/
|
|
6
|
+
selector?: string;
|
|
7
|
+
/**
|
|
8
|
+
* Accessible name applied only when an overflowing table has no existing
|
|
9
|
+
* `aria-label` or `aria-labelledby`.
|
|
10
|
+
*/
|
|
11
|
+
label?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function markdownTableScrollLabel(locale?: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* Makes overflowing Markdown tables keyboard-scrollable without wrapping or
|
|
16
|
+
* replacing the native `<table>` element.
|
|
17
|
+
*
|
|
18
|
+
* Run this after rendering Markdown and again after layout-changing updates.
|
|
19
|
+
* Narrow tables stay out of the tab order when overflow can be measured.
|
|
20
|
+
*/
|
|
21
|
+
export declare function enhanceMarkdownTables(root?: ParentNode, options?: MarkdownTableEnhancementOptions): number;
|
|
22
|
+
//# sourceMappingURL=markdown-tables.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown-tables.d.mts","sourceRoot":"","sources":["../../../../home/runner/work/ox-content/ox-content/npm/vite-plugin-ox-content/src/markdown-tables.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,+BAA+B;IAC9C;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAMD,wBAAgB,wBAAwB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAMhE;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,CAAC,EAAE,UAAU,EACjB,OAAO,GAAE,+BAAoC,GAC5C,MAAM,CA4CR"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
const TABINDEX_FLAG = "oxTableScrollTabindex";
|
|
2
|
+
const LABEL_FLAG = "oxTableScrollLabel";
|
|
3
|
+
const SCROLLABLE_ATTR = "data-ox-table-scrollable";
|
|
4
|
+
export function markdownTableScrollLabel(locale) {
|
|
5
|
+
const language = locale?.split("-")[0]?.toLowerCase();
|
|
6
|
+
if (language === "ja") {
|
|
7
|
+
return "横スクロールできる表";
|
|
8
|
+
}
|
|
9
|
+
return "Scrollable table";
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Makes overflowing Markdown tables keyboard-scrollable without wrapping or
|
|
13
|
+
* replacing the native `<table>` element.
|
|
14
|
+
*
|
|
15
|
+
* Run this after rendering Markdown and again after layout-changing updates.
|
|
16
|
+
* Narrow tables stay out of the tab order when overflow can be measured.
|
|
17
|
+
*/
|
|
18
|
+
export function enhanceMarkdownTables(root, options = {}) {
|
|
19
|
+
const target = root ?? globalThis.document;
|
|
20
|
+
if (!target?.querySelectorAll) {
|
|
21
|
+
return 0;
|
|
22
|
+
}
|
|
23
|
+
const selector = options.selector ?? ".content table";
|
|
24
|
+
const locale = ownerDocument(target)?.documentElement.lang;
|
|
25
|
+
const label = options.label ?? markdownTableScrollLabel(locale);
|
|
26
|
+
let scrollableCount = 0;
|
|
27
|
+
for (const table of target.querySelectorAll(selector)) {
|
|
28
|
+
if (typeof HTMLElement === "undefined" || !(table instanceof HTMLElement)) {
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
if (table.tagName !== "TABLE") {
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
const scrollable = table.scrollWidth > table.clientWidth + 1;
|
|
35
|
+
table.toggleAttribute(SCROLLABLE_ATTR, scrollable);
|
|
36
|
+
if (scrollable) {
|
|
37
|
+
scrollableCount++;
|
|
38
|
+
if (!table.hasAttribute("tabindex")) {
|
|
39
|
+
table.tabIndex = 0;
|
|
40
|
+
table.dataset[TABINDEX_FLAG] = "true";
|
|
41
|
+
}
|
|
42
|
+
if (!table.hasAttribute("aria-label") && !table.hasAttribute("aria-labelledby")) {
|
|
43
|
+
table.setAttribute("aria-label", label);
|
|
44
|
+
table.dataset[LABEL_FLAG] = "true";
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
if (table.dataset[TABINDEX_FLAG] === "true") {
|
|
49
|
+
table.removeAttribute("tabindex");
|
|
50
|
+
delete table.dataset[TABINDEX_FLAG];
|
|
51
|
+
}
|
|
52
|
+
if (table.dataset[LABEL_FLAG] === "true") {
|
|
53
|
+
table.removeAttribute("aria-label");
|
|
54
|
+
delete table.dataset[LABEL_FLAG];
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return scrollableCount;
|
|
59
|
+
}
|
|
60
|
+
function ownerDocument(root) {
|
|
61
|
+
if (typeof Document !== "undefined" && root instanceof Document) {
|
|
62
|
+
return root;
|
|
63
|
+
}
|
|
64
|
+
return root.ownerDocument ?? globalThis.document;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=markdown-tables.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown-tables.mjs","sourceRoot":"","sources":["../../../../home/runner/work/ox-content/ox-content/npm/vite-plugin-ox-content/src/markdown-tables.ts"],"names":[],"mappings":"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","sourcesContent":["export interface MarkdownTableEnhancementOptions {\n /**\n * Tables to enhance. Defaults to Markdown content tables styled by\n * `@ox-content/vite-plugin/styles/core.css`.\n */\n selector?: string;\n /**\n * Accessible name applied only when an overflowing table has no existing\n * `aria-label` or `aria-labelledby`.\n */\n label?: string;\n}\n\nconst TABINDEX_FLAG = \"oxTableScrollTabindex\";\nconst LABEL_FLAG = \"oxTableScrollLabel\";\nconst SCROLLABLE_ATTR = \"data-ox-table-scrollable\";\n\nexport function markdownTableScrollLabel(locale?: string): string {\n const language = locale?.split(\"-\")[0]?.toLowerCase();\n if (language === \"ja\") {\n return \"横スクロールできる表\";\n }\n return \"Scrollable table\";\n}\n\n/**\n * Makes overflowing Markdown tables keyboard-scrollable without wrapping or\n * replacing the native `<table>` element.\n *\n * Run this after rendering Markdown and again after layout-changing updates.\n * Narrow tables stay out of the tab order when overflow can be measured.\n */\nexport function enhanceMarkdownTables(\n root?: ParentNode,\n options: MarkdownTableEnhancementOptions = {},\n): number {\n const target = root ?? globalThis.document;\n if (!target?.querySelectorAll) {\n return 0;\n }\n\n const selector = options.selector ?? \".content table\";\n const locale = ownerDocument(target)?.documentElement.lang;\n const label = options.label ?? markdownTableScrollLabel(locale);\n let scrollableCount = 0;\n\n for (const table of target.querySelectorAll(selector)) {\n if (typeof HTMLElement === \"undefined\" || !(table instanceof HTMLElement)) {\n continue;\n }\n if (table.tagName !== \"TABLE\") {\n continue;\n }\n\n const scrollable = table.scrollWidth > table.clientWidth + 1;\n table.toggleAttribute(SCROLLABLE_ATTR, scrollable);\n if (scrollable) {\n scrollableCount++;\n if (!table.hasAttribute(\"tabindex\")) {\n table.tabIndex = 0;\n table.dataset[TABINDEX_FLAG] = \"true\";\n }\n if (!table.hasAttribute(\"aria-label\") && !table.hasAttribute(\"aria-labelledby\")) {\n table.setAttribute(\"aria-label\", label);\n table.dataset[LABEL_FLAG] = \"true\";\n }\n } else {\n if (table.dataset[TABINDEX_FLAG] === \"true\") {\n table.removeAttribute(\"tabindex\");\n delete table.dataset[TABINDEX_FLAG];\n }\n if (table.dataset[LABEL_FLAG] === \"true\") {\n table.removeAttribute(\"aria-label\");\n delete table.dataset[LABEL_FLAG];\n }\n }\n }\n\n return scrollableCount;\n}\n\nfunction ownerDocument(root: ParentNode): Document | undefined {\n if (typeof Document !== \"undefined\" && root instanceof Document) {\n return root;\n }\n return root.ownerDocument ?? globalThis.document;\n}\n"]}
|
package/dist/napi.cjs
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
//#region src/napi.ts
|
|
2
|
+
const requireNapi = (0, require("node:module").createRequire)(require("url").pathToFileURL(__filename).href);
|
|
3
|
+
function getDefaultExport(value) {
|
|
4
|
+
if (!value || typeof value !== "object" || !("default" in value)) return;
|
|
5
|
+
const defaultExport = value.default;
|
|
6
|
+
return defaultExport && typeof defaultExport === "object" ? defaultExport : void 0;
|
|
7
|
+
}
|
|
8
|
+
function normalizeNapiModule(mod) {
|
|
9
|
+
const defaultExport = getDefaultExport(mod);
|
|
10
|
+
return defaultExport ? {
|
|
11
|
+
...defaultExport,
|
|
12
|
+
...mod
|
|
13
|
+
} : mod;
|
|
14
|
+
}
|
|
15
|
+
async function importNapiModule() {
|
|
16
|
+
return normalizeNapiModule(await import("@ox-content/napi"));
|
|
17
|
+
}
|
|
18
|
+
let syncNapiModule;
|
|
19
|
+
function importNapiModuleSync() {
|
|
20
|
+
if (syncNapiModule) return syncNapiModule;
|
|
21
|
+
if (syncNapiModule === null) throw new Error("[ox-content] @ox-content/napi is required. Please ensure the NAPI module is built.");
|
|
22
|
+
try {
|
|
23
|
+
syncNapiModule = normalizeNapiModule(requireNapi("@ox-content/napi"));
|
|
24
|
+
return syncNapiModule;
|
|
25
|
+
} catch {
|
|
26
|
+
syncNapiModule = null;
|
|
27
|
+
throw new Error("[ox-content] @ox-content/napi is required. Please ensure the NAPI module is built.");
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
//#endregion
|
|
31
|
+
Object.defineProperty(exports, "importNapiModule", {
|
|
32
|
+
enumerable: true,
|
|
33
|
+
get: function() {
|
|
34
|
+
return importNapiModule;
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
Object.defineProperty(exports, "importNapiModuleSync", {
|
|
38
|
+
enumerable: true,
|
|
39
|
+
get: function() {
|
|
40
|
+
return importNapiModuleSync;
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
//# sourceMappingURL=napi.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"napi.cjs","names":["createRequire"],"sources":["../src/napi.ts"],"sourcesContent":["import { createRequire } from \"node:module\";\n\ntype NapiModule = typeof import(\"@ox-content/napi\");\nconst requireNapi = createRequire(import.meta.url);\n\nfunction getDefaultExport(value: unknown): object | undefined {\n if (!value || typeof value !== \"object\" || !(\"default\" in value)) {\n return undefined;\n }\n\n const defaultExport = value.default;\n return defaultExport && typeof defaultExport === \"object\" ? defaultExport : undefined;\n}\n\nfunction normalizeNapiModule(mod: NapiModule): NapiModule {\n const defaultExport = getDefaultExport(mod);\n return defaultExport\n ? ({\n ...defaultExport,\n ...mod,\n } as NapiModule)\n : mod;\n}\n\nexport async function importNapiModule(): Promise<NapiModule> {\n return normalizeNapiModule((await import(\"@ox-content/napi\")) as NapiModule);\n}\n\nlet syncNapiModule: NapiModule | null | undefined;\n\nexport function importNapiModuleSync(): NapiModule {\n if (syncNapiModule) {\n return syncNapiModule;\n }\n\n if (syncNapiModule === null) {\n throw new Error(\n \"[ox-content] @ox-content/napi is required. Please ensure the NAPI module is built.\",\n );\n }\n\n try {\n const mod = requireNapi(\"@ox-content/napi\") as NapiModule;\n syncNapiModule = normalizeNapiModule(mod);\n return syncNapiModule;\n } catch {\n syncNapiModule = null;\n throw new Error(\n \"[ox-content] @ox-content/napi is required. Please ensure the NAPI module is built.\",\n );\n }\n}\n"],"mappings":";AAGA,MAAM,eAAA,wBAAcA,CAAAA,CAAAA,cAAAA,CAAAA,QAAAA,KAAAA,CAAAA,CAAAA,cAAAA,UAAAA,CAAAA,CAAAA,IAA6B;AAEjD,SAAS,iBAAiB,OAAoC;CAC5D,IAAI,CAAC,SAAS,OAAO,UAAU,YAAY,EAAE,aAAa,QACxD;CAGF,MAAM,gBAAgB,MAAM;CAC5B,OAAO,iBAAiB,OAAO,kBAAkB,WAAW,gBAAgB,KAAA;AAC9E;AAEA,SAAS,oBAAoB,KAA6B;CACxD,MAAM,gBAAgB,iBAAiB,GAAG;CAC1C,OAAO,gBACF;EACC,GAAG;EACH,GAAG;CACL,IACA;AACN;AAEA,eAAsB,mBAAwC;CAC5D,OAAO,oBAAqB,MAAM,OAAO,mBAAkC;AAC7E;AAEA,IAAI;AAEJ,SAAgB,uBAAmC;CACjD,IAAI,gBACF,OAAO;CAGT,IAAI,mBAAmB,MACrB,MAAM,IAAI,MACR,oFACF;CAGF,IAAI;EAEF,iBAAiB,oBADL,YAAY,kBACe,CAAC;EACxC,OAAO;CACT,QAAQ;EACN,iBAAiB;EACjB,MAAM,IAAI,MACR,oFACF;CACF;AACF"}
|
package/dist/napi.mjs
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
//#region src/napi.ts
|
|
3
|
+
const requireNapi = createRequire(import.meta.url);
|
|
4
|
+
function getDefaultExport(value) {
|
|
5
|
+
if (!value || typeof value !== "object" || !("default" in value)) return;
|
|
6
|
+
const defaultExport = value.default;
|
|
7
|
+
return defaultExport && typeof defaultExport === "object" ? defaultExport : void 0;
|
|
8
|
+
}
|
|
9
|
+
function normalizeNapiModule(mod) {
|
|
10
|
+
const defaultExport = getDefaultExport(mod);
|
|
11
|
+
return defaultExport ? {
|
|
12
|
+
...defaultExport,
|
|
13
|
+
...mod
|
|
14
|
+
} : mod;
|
|
15
|
+
}
|
|
16
|
+
async function importNapiModule() {
|
|
17
|
+
return normalizeNapiModule(await import("@ox-content/napi"));
|
|
18
|
+
}
|
|
19
|
+
let syncNapiModule;
|
|
20
|
+
function importNapiModuleSync() {
|
|
21
|
+
if (syncNapiModule) return syncNapiModule;
|
|
22
|
+
if (syncNapiModule === null) throw new Error("[ox-content] @ox-content/napi is required. Please ensure the NAPI module is built.");
|
|
23
|
+
try {
|
|
24
|
+
syncNapiModule = normalizeNapiModule(requireNapi("@ox-content/napi"));
|
|
25
|
+
return syncNapiModule;
|
|
26
|
+
} catch {
|
|
27
|
+
syncNapiModule = null;
|
|
28
|
+
throw new Error("[ox-content] @ox-content/napi is required. Please ensure the NAPI module is built.");
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
32
|
+
export { importNapiModuleSync as n, importNapiModule as t };
|
|
33
|
+
|
|
34
|
+
//# sourceMappingURL=napi.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"napi.mjs","names":[],"sources":["../src/napi.ts"],"sourcesContent":["import { createRequire } from \"node:module\";\n\ntype NapiModule = typeof import(\"@ox-content/napi\");\nconst requireNapi = createRequire(import.meta.url);\n\nfunction getDefaultExport(value: unknown): object | undefined {\n if (!value || typeof value !== \"object\" || !(\"default\" in value)) {\n return undefined;\n }\n\n const defaultExport = value.default;\n return defaultExport && typeof defaultExport === \"object\" ? defaultExport : undefined;\n}\n\nfunction normalizeNapiModule(mod: NapiModule): NapiModule {\n const defaultExport = getDefaultExport(mod);\n return defaultExport\n ? ({\n ...defaultExport,\n ...mod,\n } as NapiModule)\n : mod;\n}\n\nexport async function importNapiModule(): Promise<NapiModule> {\n return normalizeNapiModule((await import(\"@ox-content/napi\")) as NapiModule);\n}\n\nlet syncNapiModule: NapiModule | null | undefined;\n\nexport function importNapiModuleSync(): NapiModule {\n if (syncNapiModule) {\n return syncNapiModule;\n }\n\n if (syncNapiModule === null) {\n throw new Error(\n \"[ox-content] @ox-content/napi is required. Please ensure the NAPI module is built.\",\n );\n }\n\n try {\n const mod = requireNapi(\"@ox-content/napi\") as NapiModule;\n syncNapiModule = normalizeNapiModule(mod);\n return syncNapiModule;\n } catch {\n syncNapiModule = null;\n throw new Error(\n \"[ox-content] @ox-content/napi is required. Please ensure the NAPI module is built.\",\n );\n }\n}\n"],"mappings":";;AAGA,MAAM,cAAc,cAAc,YAAY,GAAG;AAEjD,SAAS,iBAAiB,OAAoC;CAC5D,IAAI,CAAC,SAAS,OAAO,UAAU,YAAY,EAAE,aAAa,QACxD;CAGF,MAAM,gBAAgB,MAAM;CAC5B,OAAO,iBAAiB,OAAO,kBAAkB,WAAW,gBAAgB,KAAA;AAC9E;AAEA,SAAS,oBAAoB,KAA6B;CACxD,MAAM,gBAAgB,iBAAiB,GAAG;CAC1C,OAAO,gBACF;EACC,GAAG;EACH,GAAG;CACL,IACA;AACN;AAEA,eAAsB,mBAAwC;CAC5D,OAAO,oBAAqB,MAAM,OAAO,mBAAkC;AAC7E;AAEA,IAAI;AAEJ,SAAgB,uBAAmC;CACjD,IAAI,gBACF,OAAO;CAGT,IAAI,mBAAmB,MACrB,MAAM,IAAI,MACR,oFACF;CAGF,IAAI;EAEF,iBAAiB,oBADL,YAAY,kBACe,CAAC;EACxC,OAAO;CACT,QAAQ;EACN,iBAAiB;EACjB,MAAM,IAAI,MACR,oFACF;CACF;AACF"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
// Generated from crates/ox_content_ssg/src/html/reader_chrome_runtime.js.
|
|
2
|
+
// Run npm/vite-plugin-ox-content/scripts/build-reader-chrome-client.mjs.
|
|
3
|
+
|
|
4
|
+
"use strict";
|
|
5
|
+
const oxReaderChromeInitializedRoots = new WeakSet();
|
|
6
|
+
const oxReaderChromeResetTimers = new WeakMap();
|
|
7
|
+
|
|
8
|
+
// eslint-disable-next-line no-unused-vars
|
|
9
|
+
function initReaderChrome(rootInput) {
|
|
10
|
+
const fallbackDocument = typeof document === "undefined" ? undefined : document;
|
|
11
|
+
const root = rootInput ?? fallbackDocument;
|
|
12
|
+
if (!root || oxReaderChromeInitializedRoots.has(root)) return;
|
|
13
|
+
|
|
14
|
+
const scope = root.nodeType === 9 ? root : root;
|
|
15
|
+
const rootElement = root.nodeType === 9 ? root.documentElement : root;
|
|
16
|
+
if (!rootElement || typeof rootElement.querySelector !== "function") return;
|
|
17
|
+
|
|
18
|
+
const hasRootAttribute =
|
|
19
|
+
typeof rootElement.hasAttribute === "function"
|
|
20
|
+
? (name) => rootElement.hasAttribute(name)
|
|
21
|
+
: () => false;
|
|
22
|
+
const hasCopy =
|
|
23
|
+
hasRootAttribute("data-ox-copy") || Boolean(rootElement.querySelector("[data-ox-copy]"));
|
|
24
|
+
const hasBackToTop =
|
|
25
|
+
hasRootAttribute("data-ox-back-to-top") ||
|
|
26
|
+
Boolean(rootElement.querySelector(".ox-back-to-top[data-ox-back-to-top]"));
|
|
27
|
+
const hasReaderChrome = hasRootAttribute("data-ox-reader-chrome");
|
|
28
|
+
if (!hasReaderChrome && !hasCopy && !hasBackToTop) return;
|
|
29
|
+
|
|
30
|
+
oxReaderChromeInitializedRoots.add(root);
|
|
31
|
+
|
|
32
|
+
const reduced =
|
|
33
|
+
typeof matchMedia === "function" && matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
34
|
+
if (reduced && rootElement.classList)
|
|
35
|
+
rootElement.classList.add("ox-reader-chrome--reduced-motion");
|
|
36
|
+
|
|
37
|
+
if (hasCopy && typeof scope.addEventListener === "function") {
|
|
38
|
+
scope.addEventListener("click", (event) => {
|
|
39
|
+
const button =
|
|
40
|
+
event.target instanceof Element ? event.target.closest("[data-ox-copy]") : null;
|
|
41
|
+
if (!(button instanceof HTMLButtonElement)) return;
|
|
42
|
+
if (event.defaultPrevented) return;
|
|
43
|
+
event.preventDefault();
|
|
44
|
+
const container = button.closest(".ox-code");
|
|
45
|
+
const pre = container?.querySelector("pre");
|
|
46
|
+
const status = container?.querySelector("[data-ox-copy-status]");
|
|
47
|
+
const text = pre ? (pre.getAttribute("data-ox-code-source") ?? pre.textContent ?? "") : "";
|
|
48
|
+
if (!navigator.clipboard?.writeText) {
|
|
49
|
+
setReaderChromeCopyState(button, status, "failed");
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
navigator.clipboard
|
|
53
|
+
.writeText(text)
|
|
54
|
+
.then(() => setReaderChromeCopyState(button, status, "copied"))
|
|
55
|
+
.catch(() => setReaderChromeCopyState(button, status, "failed"));
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (hasBackToTop && fallbackDocument) {
|
|
60
|
+
const findBackToTop = () => rootElement.querySelector(".ox-back-to-top[data-ox-back-to-top]");
|
|
61
|
+
const sync = () => {
|
|
62
|
+
const top = findBackToTop();
|
|
63
|
+
if (top instanceof HTMLElement) top.hidden = window.scrollY < 320;
|
|
64
|
+
};
|
|
65
|
+
sync();
|
|
66
|
+
window.addEventListener("scroll", sync, { passive: true });
|
|
67
|
+
if (typeof scope.addEventListener === "function") {
|
|
68
|
+
scope.addEventListener("click", (event) => {
|
|
69
|
+
const button =
|
|
70
|
+
event.target instanceof Element
|
|
71
|
+
? event.target.closest(".ox-back-to-top[data-ox-back-to-top]")
|
|
72
|
+
: null;
|
|
73
|
+
if (!(button instanceof HTMLElement)) return;
|
|
74
|
+
if (event.defaultPrevented) return;
|
|
75
|
+
event.preventDefault();
|
|
76
|
+
window.scrollTo({ top: 0, behavior: reduced ? "auto" : "smooth" });
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function setReaderChromeCopyState(button, status, state) {
|
|
83
|
+
const previousTimer = oxReaderChromeResetTimers.get(button);
|
|
84
|
+
if (previousTimer) clearTimeout(previousTimer);
|
|
85
|
+
|
|
86
|
+
const label = state === "copied" ? "Copied" : state === "failed" ? "Copy failed" : "Copy code";
|
|
87
|
+
if (state) button.dataset.copyState = state;
|
|
88
|
+
else delete button.dataset.copyState;
|
|
89
|
+
button.setAttribute("aria-label", label);
|
|
90
|
+
button.setAttribute("title", label);
|
|
91
|
+
if (status) status.textContent = state ? label : "";
|
|
92
|
+
|
|
93
|
+
if (state) {
|
|
94
|
+
oxReaderChromeResetTimers.set(
|
|
95
|
+
button,
|
|
96
|
+
setTimeout(() => setReaderChromeCopyState(button, status, null), 1500),
|
|
97
|
+
);
|
|
98
|
+
} else {
|
|
99
|
+
oxReaderChromeResetTimers.delete(button);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
module.exports = { initReaderChrome };
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
// Generated from crates/ox_content_ssg/src/html/reader_chrome_runtime.js.
|
|
2
|
+
// Run npm/vite-plugin-ox-content/scripts/build-reader-chrome-client.mjs.
|
|
3
|
+
|
|
4
|
+
const oxReaderChromeInitializedRoots = new WeakSet();
|
|
5
|
+
const oxReaderChromeResetTimers = new WeakMap();
|
|
6
|
+
|
|
7
|
+
// eslint-disable-next-line no-unused-vars
|
|
8
|
+
function initReaderChrome(rootInput) {
|
|
9
|
+
const fallbackDocument = typeof document === "undefined" ? undefined : document;
|
|
10
|
+
const root = rootInput ?? fallbackDocument;
|
|
11
|
+
if (!root || oxReaderChromeInitializedRoots.has(root)) return;
|
|
12
|
+
|
|
13
|
+
const scope = root.nodeType === 9 ? root : root;
|
|
14
|
+
const rootElement = root.nodeType === 9 ? root.documentElement : root;
|
|
15
|
+
if (!rootElement || typeof rootElement.querySelector !== "function") return;
|
|
16
|
+
|
|
17
|
+
const hasRootAttribute =
|
|
18
|
+
typeof rootElement.hasAttribute === "function"
|
|
19
|
+
? (name) => rootElement.hasAttribute(name)
|
|
20
|
+
: () => false;
|
|
21
|
+
const hasCopy =
|
|
22
|
+
hasRootAttribute("data-ox-copy") || Boolean(rootElement.querySelector("[data-ox-copy]"));
|
|
23
|
+
const hasBackToTop =
|
|
24
|
+
hasRootAttribute("data-ox-back-to-top") ||
|
|
25
|
+
Boolean(rootElement.querySelector(".ox-back-to-top[data-ox-back-to-top]"));
|
|
26
|
+
const hasReaderChrome = hasRootAttribute("data-ox-reader-chrome");
|
|
27
|
+
if (!hasReaderChrome && !hasCopy && !hasBackToTop) return;
|
|
28
|
+
|
|
29
|
+
oxReaderChromeInitializedRoots.add(root);
|
|
30
|
+
|
|
31
|
+
const reduced =
|
|
32
|
+
typeof matchMedia === "function" && matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
33
|
+
if (reduced && rootElement.classList)
|
|
34
|
+
rootElement.classList.add("ox-reader-chrome--reduced-motion");
|
|
35
|
+
|
|
36
|
+
if (hasCopy && typeof scope.addEventListener === "function") {
|
|
37
|
+
scope.addEventListener("click", (event) => {
|
|
38
|
+
const button =
|
|
39
|
+
event.target instanceof Element ? event.target.closest("[data-ox-copy]") : null;
|
|
40
|
+
if (!(button instanceof HTMLButtonElement)) return;
|
|
41
|
+
if (event.defaultPrevented) return;
|
|
42
|
+
event.preventDefault();
|
|
43
|
+
const container = button.closest(".ox-code");
|
|
44
|
+
const pre = container?.querySelector("pre");
|
|
45
|
+
const status = container?.querySelector("[data-ox-copy-status]");
|
|
46
|
+
const text = pre ? (pre.getAttribute("data-ox-code-source") ?? pre.textContent ?? "") : "";
|
|
47
|
+
if (!navigator.clipboard?.writeText) {
|
|
48
|
+
setReaderChromeCopyState(button, status, "failed");
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
navigator.clipboard
|
|
52
|
+
.writeText(text)
|
|
53
|
+
.then(() => setReaderChromeCopyState(button, status, "copied"))
|
|
54
|
+
.catch(() => setReaderChromeCopyState(button, status, "failed"));
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (hasBackToTop && fallbackDocument) {
|
|
59
|
+
const findBackToTop = () => rootElement.querySelector(".ox-back-to-top[data-ox-back-to-top]");
|
|
60
|
+
const sync = () => {
|
|
61
|
+
const top = findBackToTop();
|
|
62
|
+
if (top instanceof HTMLElement) top.hidden = window.scrollY < 320;
|
|
63
|
+
};
|
|
64
|
+
sync();
|
|
65
|
+
window.addEventListener("scroll", sync, { passive: true });
|
|
66
|
+
if (typeof scope.addEventListener === "function") {
|
|
67
|
+
scope.addEventListener("click", (event) => {
|
|
68
|
+
const button =
|
|
69
|
+
event.target instanceof Element
|
|
70
|
+
? event.target.closest(".ox-back-to-top[data-ox-back-to-top]")
|
|
71
|
+
: null;
|
|
72
|
+
if (!(button instanceof HTMLElement)) return;
|
|
73
|
+
if (event.defaultPrevented) return;
|
|
74
|
+
event.preventDefault();
|
|
75
|
+
window.scrollTo({ top: 0, behavior: reduced ? "auto" : "smooth" });
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function setReaderChromeCopyState(button, status, state) {
|
|
82
|
+
const previousTimer = oxReaderChromeResetTimers.get(button);
|
|
83
|
+
if (previousTimer) clearTimeout(previousTimer);
|
|
84
|
+
|
|
85
|
+
const label = state === "copied" ? "Copied" : state === "failed" ? "Copy failed" : "Copy code";
|
|
86
|
+
if (state) button.dataset.copyState = state;
|
|
87
|
+
else delete button.dataset.copyState;
|
|
88
|
+
button.setAttribute("aria-label", label);
|
|
89
|
+
button.setAttribute("title", label);
|
|
90
|
+
if (status) status.textContent = state ? label : "";
|
|
91
|
+
|
|
92
|
+
if (state) {
|
|
93
|
+
oxReaderChromeResetTimers.set(
|
|
94
|
+
button,
|
|
95
|
+
setTimeout(() => setReaderChromeCopyState(button, status, null), 1500),
|
|
96
|
+
);
|
|
97
|
+
} else {
|
|
98
|
+
oxReaderChromeResetTimers.delete(button);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export { initReaderChrome };
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
require("./vitepress.cjs");
|
|
3
|
+
const require_napi = require("./napi.cjs");
|
|
4
|
+
//#region src/reader-chrome.ts
|
|
5
|
+
const EMPTY_ATTRIBUTES = Object.freeze({});
|
|
6
|
+
/**
|
|
7
|
+
* Resolve the public reader-chrome option shape.
|
|
8
|
+
*
|
|
9
|
+
* `true` mirrors `ssg.readerChrome: true`: copy, outbound-link decoration, and
|
|
10
|
+
* back-to-top are enabled. Object fields default on, so `{ copy: false }`
|
|
11
|
+
* disables only the copy button.
|
|
12
|
+
*/
|
|
13
|
+
function resolveReaderChromeInput(input = true) {
|
|
14
|
+
if (!input) return false;
|
|
15
|
+
if (input === true) return {
|
|
16
|
+
copy: true,
|
|
17
|
+
externalLinks: true,
|
|
18
|
+
backToTop: true
|
|
19
|
+
};
|
|
20
|
+
return {
|
|
21
|
+
copy: input.copy ?? true,
|
|
22
|
+
externalLinks: input.externalLinks ?? true,
|
|
23
|
+
backToTop: input.backToTop ?? true
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Apply the same native reader-chrome HTML transform used by the built-in SSG.
|
|
28
|
+
*
|
|
29
|
+
* This rewrites rendered article HTML. It wraps fenced `<pre>` blocks for copy
|
|
30
|
+
* controls and decorates outbound links when enabled. Back-to-top remains a
|
|
31
|
+
* document-shell control, so it is exposed through the asset helpers.
|
|
32
|
+
*/
|
|
33
|
+
function applyReaderChromeHtml(html, input = true) {
|
|
34
|
+
const chrome = resolveReaderChromeInput(input);
|
|
35
|
+
if (!chrome || !chrome.copy && !chrome.externalLinks) return html;
|
|
36
|
+
return require_napi.importNapiModuleSync().applySsgReaderChromeHtml(html, {
|
|
37
|
+
copy: chrome.copy,
|
|
38
|
+
externalLinks: chrome.externalLinks,
|
|
39
|
+
backToTop: chrome.backToTop
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Root attributes consumed by the browser runtime.
|
|
44
|
+
*/
|
|
45
|
+
function readerChromeAttributes(input = true) {
|
|
46
|
+
const chrome = resolveReaderChromeInput(input);
|
|
47
|
+
if (!readerChromeIsEnabled(chrome)) return EMPTY_ATTRIBUTES;
|
|
48
|
+
return {
|
|
49
|
+
"data-ox-reader-chrome": "",
|
|
50
|
+
...chrome.copy ? { "data-ox-copy": "" } : {},
|
|
51
|
+
...chrome.externalLinks ? { "data-ox-external-links": "" } : {},
|
|
52
|
+
...chrome.backToTop ? { "data-ox-back-to-top": "" } : {}
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Render the root attributes as a leading-space HTML fragment.
|
|
57
|
+
*
|
|
58
|
+
* Useful in template strings: `<article${renderReaderChromeAttributes()}>`.
|
|
59
|
+
*/
|
|
60
|
+
function renderReaderChromeAttributes(input = true) {
|
|
61
|
+
return Object.keys(readerChromeAttributes(input)).map((name) => ` ${name}`).join("");
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* CSS shared by the built-in SSG and custom hosts.
|
|
65
|
+
*/
|
|
66
|
+
function readerChromeCss(input = true) {
|
|
67
|
+
return readerChromeIsEnabled(resolveReaderChromeInput(input)) ? require_napi.importNapiModuleSync().getSsgReaderChromeCss() : "";
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Auto-initializing script shared by the built-in SSG and custom hosts.
|
|
71
|
+
*/
|
|
72
|
+
function readerChromeScript(input = true) {
|
|
73
|
+
return readerChromeNeedsJs(resolveReaderChromeInput(input)) ? require_napi.importNapiModuleSync().getSsgReaderChromeScript() : "";
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Inline stylesheet tag for hosts that do not import
|
|
77
|
+
* `@ox-content/vite-plugin/styles/reader-chrome.css`.
|
|
78
|
+
*/
|
|
79
|
+
function renderReaderChromeStyleTag(input = true) {
|
|
80
|
+
const css = readerChromeCss(input);
|
|
81
|
+
return css ? `<style data-ox-style="reader-chrome">\n${css}</style>` : "";
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Inline auto-init script for static hosts that do not bundle
|
|
85
|
+
* `@ox-content/vite-plugin/reader-chrome/client`.
|
|
86
|
+
*/
|
|
87
|
+
function renderReaderChromeScriptTag(input = true) {
|
|
88
|
+
const js = readerChromeScript(input);
|
|
89
|
+
return js ? `<script data-ox-script="reader-chrome">\n${js}<\/script>` : "";
|
|
90
|
+
}
|
|
91
|
+
function readerChromeIsEnabled(chrome) {
|
|
92
|
+
return Boolean(chrome && (chrome.copy || chrome.externalLinks || chrome.backToTop));
|
|
93
|
+
}
|
|
94
|
+
function readerChromeNeedsJs(chrome) {
|
|
95
|
+
return Boolean(chrome && (chrome.copy || chrome.backToTop));
|
|
96
|
+
}
|
|
97
|
+
//#endregion
|
|
98
|
+
exports.applyReaderChromeHtml = applyReaderChromeHtml;
|
|
99
|
+
exports.readerChromeAttributes = readerChromeAttributes;
|
|
100
|
+
exports.readerChromeCss = readerChromeCss;
|
|
101
|
+
exports.readerChromeIsEnabled = readerChromeIsEnabled;
|
|
102
|
+
exports.readerChromeNeedsJs = readerChromeNeedsJs;
|
|
103
|
+
exports.readerChromeScript = readerChromeScript;
|
|
104
|
+
exports.renderReaderChromeAttributes = renderReaderChromeAttributes;
|
|
105
|
+
exports.renderReaderChromeScriptTag = renderReaderChromeScriptTag;
|
|
106
|
+
exports.renderReaderChromeStyleTag = renderReaderChromeStyleTag;
|
|
107
|
+
exports.resolveReaderChromeInput = resolveReaderChromeInput;
|
|
108
|
+
|
|
109
|
+
//# sourceMappingURL=reader-chrome.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reader-chrome.cjs","names":["importNapiModuleSync"],"sources":["../src/reader-chrome.ts"],"sourcesContent":["import { importNapiModuleSync } from \"./napi\";\nimport type { ReaderChromeOptions, ResolvedReaderChrome } from \"./reader-chrome-options\";\n\nexport type { ReaderChromeOptions, ResolvedReaderChrome };\n\ntype EnabledReaderChrome = Exclude<ResolvedReaderChrome, false>;\n\nexport type ReaderChromeInput = boolean | ReaderChromeOptions | EnabledReaderChrome | undefined;\n\nconst EMPTY_ATTRIBUTES = Object.freeze({}) as Readonly<Record<string, \"\">>;\n\n/**\n * Resolve the public reader-chrome option shape.\n *\n * `true` mirrors `ssg.readerChrome: true`: copy, outbound-link decoration, and\n * back-to-top are enabled. Object fields default on, so `{ copy: false }`\n * disables only the copy button.\n */\nexport function resolveReaderChromeInput(input: ReaderChromeInput = true): ResolvedReaderChrome {\n if (!input) {\n return false;\n }\n if (input === true) {\n return { copy: true, externalLinks: true, backToTop: true };\n }\n return {\n copy: input.copy ?? true,\n externalLinks: input.externalLinks ?? true,\n backToTop: input.backToTop ?? true,\n };\n}\n\n/**\n * Apply the same native reader-chrome HTML transform used by the built-in SSG.\n *\n * This rewrites rendered article HTML. It wraps fenced `<pre>` blocks for copy\n * controls and decorates outbound links when enabled. Back-to-top remains a\n * document-shell control, so it is exposed through the asset helpers.\n */\nexport function applyReaderChromeHtml(html: string, input: ReaderChromeInput = true): string {\n const chrome = resolveReaderChromeInput(input);\n if (!chrome || (!chrome.copy && !chrome.externalLinks)) {\n return html;\n }\n return importNapiModuleSync().applySsgReaderChromeHtml(html, {\n copy: chrome.copy,\n externalLinks: chrome.externalLinks,\n backToTop: chrome.backToTop,\n });\n}\n\n/**\n * Root attributes consumed by the browser runtime.\n */\nexport function readerChromeAttributes(\n input: ReaderChromeInput = true,\n): Readonly<Record<string, \"\">> {\n const chrome = resolveReaderChromeInput(input);\n if (!readerChromeIsEnabled(chrome)) {\n return EMPTY_ATTRIBUTES;\n }\n\n return {\n \"data-ox-reader-chrome\": \"\",\n ...(chrome.copy ? { \"data-ox-copy\": \"\" as const } : {}),\n ...(chrome.externalLinks ? { \"data-ox-external-links\": \"\" as const } : {}),\n ...(chrome.backToTop ? { \"data-ox-back-to-top\": \"\" as const } : {}),\n };\n}\n\n/**\n * Render the root attributes as a leading-space HTML fragment.\n *\n * Useful in template strings: `<article${renderReaderChromeAttributes()}>`.\n */\nexport function renderReaderChromeAttributes(input: ReaderChromeInput = true): string {\n return Object.keys(readerChromeAttributes(input))\n .map((name) => ` ${name}`)\n .join(\"\");\n}\n\n/**\n * CSS shared by the built-in SSG and custom hosts.\n */\nexport function readerChromeCss(input: ReaderChromeInput = true): string {\n return readerChromeIsEnabled(resolveReaderChromeInput(input))\n ? importNapiModuleSync().getSsgReaderChromeCss()\n : \"\";\n}\n\n/**\n * Auto-initializing script shared by the built-in SSG and custom hosts.\n */\nexport function readerChromeScript(input: ReaderChromeInput = true): string {\n return readerChromeNeedsJs(resolveReaderChromeInput(input))\n ? importNapiModuleSync().getSsgReaderChromeScript()\n : \"\";\n}\n\n/**\n * Inline stylesheet tag for hosts that do not import\n * `@ox-content/vite-plugin/styles/reader-chrome.css`.\n */\nexport function renderReaderChromeStyleTag(input: ReaderChromeInput = true): string {\n const css = readerChromeCss(input);\n return css ? `<style data-ox-style=\"reader-chrome\">\\n${css}</style>` : \"\";\n}\n\n/**\n * Inline auto-init script for static hosts that do not bundle\n * `@ox-content/vite-plugin/reader-chrome/client`.\n */\nexport function renderReaderChromeScriptTag(input: ReaderChromeInput = true): string {\n const js = readerChromeScript(input);\n return js ? `<script data-ox-script=\"reader-chrome\">\\n${js}</script>` : \"\";\n}\n\nexport function readerChromeIsEnabled(\n chrome: ResolvedReaderChrome,\n): chrome is Exclude<ResolvedReaderChrome, false> {\n return Boolean(chrome && (chrome.copy || chrome.externalLinks || chrome.backToTop));\n}\n\nexport function readerChromeNeedsJs(chrome: ResolvedReaderChrome): boolean {\n return Boolean(chrome && (chrome.copy || chrome.backToTop));\n}\n"],"mappings":";;;;AASA,MAAM,mBAAmB,OAAO,OAAO,CAAC,CAAC;;;;;;;;AASzC,SAAgB,yBAAyB,QAA2B,MAA4B;CAC9F,IAAI,CAAC,OACH,OAAO;CAET,IAAI,UAAU,MACZ,OAAO;EAAE,MAAM;EAAM,eAAe;EAAM,WAAW;CAAK;CAE5D,OAAO;EACL,MAAM,MAAM,QAAQ;EACpB,eAAe,MAAM,iBAAiB;EACtC,WAAW,MAAM,aAAa;CAChC;AACF;;;;;;;;AASA,SAAgB,sBAAsB,MAAc,QAA2B,MAAc;CAC3F,MAAM,SAAS,yBAAyB,KAAK;CAC7C,IAAI,CAAC,UAAW,CAAC,OAAO,QAAQ,CAAC,OAAO,eACtC,OAAO;CAET,OAAOA,aAAAA,qBAAqB,CAAC,CAAC,yBAAyB,MAAM;EAC3D,MAAM,OAAO;EACb,eAAe,OAAO;EACtB,WAAW,OAAO;CACpB,CAAC;AACH;;;;AAKA,SAAgB,uBACd,QAA2B,MACG;CAC9B,MAAM,SAAS,yBAAyB,KAAK;CAC7C,IAAI,CAAC,sBAAsB,MAAM,GAC/B,OAAO;CAGT,OAAO;EACL,yBAAyB;EACzB,GAAI,OAAO,OAAO,EAAE,gBAAgB,GAAY,IAAI,CAAC;EACrD,GAAI,OAAO,gBAAgB,EAAE,0BAA0B,GAAY,IAAI,CAAC;EACxE,GAAI,OAAO,YAAY,EAAE,uBAAuB,GAAY,IAAI,CAAC;CACnE;AACF;;;;;;AAOA,SAAgB,6BAA6B,QAA2B,MAAc;CACpF,OAAO,OAAO,KAAK,uBAAuB,KAAK,CAAC,CAAC,CAC9C,KAAK,SAAS,IAAI,MAAM,CAAC,CACzB,KAAK,EAAE;AACZ;;;;AAKA,SAAgB,gBAAgB,QAA2B,MAAc;CACvE,OAAO,sBAAsB,yBAAyB,KAAK,CAAC,IACxDA,aAAAA,qBAAqB,CAAC,CAAC,sBAAsB,IAC7C;AACN;;;;AAKA,SAAgB,mBAAmB,QAA2B,MAAc;CAC1E,OAAO,oBAAoB,yBAAyB,KAAK,CAAC,IACtDA,aAAAA,qBAAqB,CAAC,CAAC,yBAAyB,IAChD;AACN;;;;;AAMA,SAAgB,2BAA2B,QAA2B,MAAc;CAClF,MAAM,MAAM,gBAAgB,KAAK;CACjC,OAAO,MAAM,0CAA0C,IAAI,YAAY;AACzE;;;;;AAMA,SAAgB,4BAA4B,QAA2B,MAAc;CACnF,MAAM,KAAK,mBAAmB,KAAK;CACnC,OAAO,KAAK,4CAA4C,GAAG,cAAa;AAC1E;AAEA,SAAgB,sBACd,QACgD;CAChD,OAAO,QAAQ,WAAW,OAAO,QAAQ,OAAO,iBAAiB,OAAO,UAAU;AACpF;AAEA,SAAgB,oBAAoB,QAAuC;CACzE,OAAO,QAAQ,WAAW,OAAO,QAAQ,OAAO,UAAU;AAC5D"}
|