@ox-content/vite-plugin 3.0.0-alpha.11 → 3.0.0-alpha.13

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 CHANGED
@@ -1,6 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_vitepress = require("./vitepress.cjs");
3
3
  const require_jsx_html = require("./jsx-html.cjs");
4
+ const require_markdown_tables = require("./markdown-tables.cjs");
4
5
  let path = require("path");
5
6
  path = require_vitepress.__toESM(path, 1);
6
7
  let unified = require("unified");
@@ -1438,6 +1439,37 @@ async function transformYouTube(html, options) {
1438
1439
  return (await require_vitepress.importNapiModule()).transformYoutubeEmbeds(html, options);
1439
1440
  }
1440
1441
  //#endregion
1442
+ //#region src/plugins/media-marker.ts
1443
+ /**
1444
+ * True when the document contains any tag the transform could rewrite.
1445
+ *
1446
+ * The list comes from the Rust registry rather than a copy kept here. The copy
1447
+ * had already drifted: `codesandbox` was missing, so a page whose only embed
1448
+ * was a `<CodeSandbox>` skipped the transform entirely and shipped the raw tag.
1449
+ */
1450
+ async function hasMediaMarker(html) {
1451
+ return (await markerPattern()).test(html);
1452
+ }
1453
+ /**
1454
+ * Providers that live in this package rather than the Rust registry, so the
1455
+ * registry cannot name them. Reddit is fetched here, not rendered there.
1456
+ */
1457
+ const TYPESCRIPT_ONLY_TAGS = ["reddit"];
1458
+ let cachedPattern;
1459
+ async function markerPattern() {
1460
+ if (cachedPattern) return cachedPattern;
1461
+ const tags = (await require_vitepress.importNapiModule()).mediaEmbedTags();
1462
+ const anyCase = [...tags.filter((tag) => !tag.pascalOnly).map((tag) => tag.name), ...TYPESCRIPT_ONLY_TAGS];
1463
+ const pascalOnly = tags.filter((tag) => tag.pascalOnly).map((tag) => tag.name);
1464
+ const parts = [`(?:<(?:${anyCase.join("|")})[\\s/>])`];
1465
+ if (pascalOnly.length > 0) parts.push(`(?:<(?:${pascalOnly.map(capitalize).join("|")})[\\s/>])`);
1466
+ cachedPattern = new RegExp(parts.join("|"), "i");
1467
+ return cachedPattern;
1468
+ }
1469
+ function capitalize(value) {
1470
+ return value.charAt(0).toUpperCase() + value.slice(1);
1471
+ }
1472
+ //#endregion
1441
1473
  //#region src/plugins/provider-failure.ts
1442
1474
  /** Node's fetch reports a missing network through `cause.code`. */
1443
1475
  const OFFLINE_CODES = /* @__PURE__ */ new Set([
@@ -4015,7 +4047,7 @@ async function transformFetchedTweets(html, options) {
4015
4047
  //#endregion
4016
4048
  //#region src/plugins/media.ts
4017
4049
  async function transformMediaEmbeds(html, options) {
4018
- if (!hasEnabledMediaEmbed(options) || !hasMediaMarker(html)) return html;
4050
+ if (!hasEnabledMediaEmbed(options) || !await hasMediaMarker(html)) return html;
4019
4051
  let result = html;
4020
4052
  if (typeof options.twitter === "object") result = await transformFetchedTweets(result, options.twitter);
4021
4053
  if (options.reddit) result = await transformRedditEmbeds(result, typeof options.reddit === "object" ? options.reddit : {});
@@ -4052,16 +4084,18 @@ async function transformMediaEmbeds(html, options) {
4052
4084
  facebook: options.facebook,
4053
4085
  threads: options.threads,
4054
4086
  instagram: options.instagram,
4055
- webContainer: options.webContainer
4087
+ webContainer: options.webContainer,
4088
+ loom: options.loom,
4089
+ asciinema: options.asciinema,
4090
+ figma: options.figma,
4091
+ note: options.note,
4092
+ googleSlides: options.googleSlides
4056
4093
  });
4057
4094
  reportRefusedEmbeds(transformed.diagnostics);
4058
4095
  return transformed.html;
4059
4096
  }
4060
4097
  function hasEnabledMediaEmbed(options) {
4061
- return Boolean(options.spotify || options.appleMusic || options.speakerDeck || options.audio || options.video || options.stackBlitz || options.twitter || options.reddit || options.bluesky || options.googleMaps || options.qiita || options.zenn || options.packageRegistry || options.playgrounds || options.vimeo || options.twitch || options.discord || options.fediverse || options.facebook || options.threads || options.instagram || options.webContainer);
4062
- }
4063
- function hasMediaMarker(html) {
4064
- return /<(spotify|applemusic|speakerdeck|stackblitz|tweet|xpost|reddit|bluesky|googlemaps|qiita|zenn|npmpackage|cratesio|pypi|dockerhub|codepen|jsfiddle|observable|vimeo|twitch|discord|fediverse|mastodon|misskey|mixi2|facebook|threads|instagram|webcontainer)[\s/>]/i.test(html) || /<(Audio|Video)[\s/>]/.test(html);
4098
+ return Boolean(options.spotify || options.appleMusic || options.speakerDeck || options.audio || options.video || options.stackBlitz || options.twitter || options.reddit || options.bluesky || options.googleMaps || options.qiita || options.zenn || options.packageRegistry || options.playgrounds || options.vimeo || options.twitch || options.discord || options.fediverse || options.facebook || options.threads || options.instagram || options.webContainer || options.loom || options.asciinema || options.figma || options.note || options.googleSlides);
4065
4099
  }
4066
4100
  /**
4067
4101
  * Warns about tags an enabled provider refused.
@@ -5989,7 +6023,20 @@ function decodeHtmlAttr$2(value) {
5989
6023
  * All plugins are designed with No-JavaScript-First principle.
5990
6024
  * They generate static HTML at build time and require no client-side JS.
5991
6025
  */
5992
- const SELF_CLOSING_EMBED_TAG = /<(GitHub|OgCard|Tweet|XPost|Reddit|Bluesky|GoogleMaps|Qiita|Zenn|NpmPackage|CratesIo|PyPI|DockerHub|CodePen|JSFiddle|Observable|Vimeo|Twitch|Discord|Fediverse|Mastodon|Misskey|Mixi2|Facebook|Threads|Instagram|Spotify|AppleMusic|SpeakerDeck|Audio|Video|StackBlitz|WebContainer|YouTube|NotByAI)((?:[^>"']|"[^"]*"|'[^']*')*?)\s*\/>(?:\s*<\/\1\s*>)?/gi;
6026
+ /**
6027
+ * Embed tags this package owns, which the Rust provider registry cannot name.
6028
+ *
6029
+ * Everything else in the pattern comes from the registry, because a
6030
+ * hand-maintained copy drifts — and the drift is not cosmetic here.
6031
+ */
6032
+ const TYPESCRIPT_ONLY_EMBED_TAGS = [
6033
+ "GitHub",
6034
+ "OgCard",
6035
+ "Reddit",
6036
+ "YouTube",
6037
+ "NotByAI"
6038
+ ];
6039
+ let selfClosingPattern;
5993
6040
  /**
5994
6041
  * Custom embed tags are not HTML void elements, so a self-closing authoring
5995
6042
  * form like `<GitHub ... />` reaches the HTML re-parsers (syntax highlighting,
@@ -5997,12 +6044,23 @@ const SELF_CLOSING_EMBED_TAG = /<(GitHub|OgCard|Tweet|XPost|Reddit|Bluesky|Googl
5997
6044
  * document. Normalize to an explicit open/close pair before any rehype pass
5998
6045
  * runs. A leftover `</Tweet>` after `/>` (CommonMark HTML + self-close) is
5999
6046
  * consumed so the closer cannot survive the embed rewrite.
6047
+ *
6048
+ * The tag list is built from the provider registry rather than written out
6049
+ * here. It had drifted: `<CodeSandbox … />` was absent, so a page using the
6050
+ * self-closing form lost every element after it.
6000
6051
  */
6001
6052
  function normalizeSelfClosingEmbeds(html) {
6002
- return html.replace(SELF_CLOSING_EMBED_TAG, (_match, tag, attrs) => {
6053
+ return html.replace(selfClosingEmbedPattern(), (_match, tag, attrs) => {
6003
6054
  return `<${tag}${attrs}></${tag}>`;
6004
6055
  });
6005
6056
  }
6057
+ function selfClosingEmbedPattern() {
6058
+ if (selfClosingPattern) return selfClosingPattern;
6059
+ const registryTags = require_vitepress.importNapiModuleSync().mediaEmbedTags().map((tag) => tag.name);
6060
+ const names = [.../* @__PURE__ */ new Set([...TYPESCRIPT_ONLY_EMBED_TAGS, ...registryTags])];
6061
+ selfClosingPattern = new RegExp(`<(${names.join("|")})((?:[^>"']|"[^"]*"|'[^']*')*?)\\s*\\/>(?:\\s*<\\/\\1\\s*>)?`, "gi");
6062
+ return selfClosingPattern;
6063
+ }
6006
6064
  /**
6007
6065
  * Transform all enabled plugins in HTML content.
6008
6066
  */
@@ -6081,7 +6139,12 @@ async function transformBuiltinEmbeds(html, options) {
6081
6139
  facebook: options.facebook,
6082
6140
  threads: options.threads,
6083
6141
  instagram: options.instagram,
6084
- webContainer: options.webContainer
6142
+ webContainer: options.webContainer,
6143
+ loom: options.loom,
6144
+ asciinema: options.asciinema,
6145
+ figma: options.figma,
6146
+ note: options.note,
6147
+ googleSlides: options.googleSlides
6085
6148
  };
6086
6149
  if (Object.values(mediaOptions).some(Boolean)) result = await transformMediaEmbeds(result, mediaOptions);
6087
6150
  return normalizeBlockEmbedParagraphs(result);
@@ -16988,6 +17051,11 @@ async function transformSsgHtml(html, options) {
16988
17051
  threads: options.embeds.threads,
16989
17052
  instagram: options.embeds.instagram,
16990
17053
  webContainer: options.embeds.webContainer,
17054
+ loom: options.embeds.loom,
17055
+ asciinema: options.embeds.asciinema,
17056
+ figma: options.embeds.figma,
17057
+ note: options.embeds.note,
17058
+ googleSlides: options.embeds.googleSlides,
16991
17059
  mermaid: true,
16992
17060
  githubToken: process.env.GITHUB_TOKEN
16993
17061
  });
@@ -17600,6 +17668,11 @@ async function renderPage$1(filePath, options, navGroups, siteName, base, root,
17600
17668
  threads: options.embeds.threads,
17601
17669
  instagram: options.embeds.instagram,
17602
17670
  webContainer: options.embeds.webContainer,
17671
+ loom: options.embeds.loom,
17672
+ asciinema: options.embeds.asciinema,
17673
+ figma: options.embeds.figma,
17674
+ note: options.embeds.note,
17675
+ googleSlides: options.embeds.googleSlides,
17603
17676
  mermaid: true,
17604
17677
  githubToken: process.env.GITHUB_TOKEN
17605
17678
  });
@@ -18224,7 +18297,12 @@ function resolveBuiltinEmbedOptions(options) {
18224
18297
  facebook: false,
18225
18298
  threads: false,
18226
18299
  instagram: false,
18227
- webContainer: false
18300
+ webContainer: false,
18301
+ loom: false,
18302
+ asciinema: false,
18303
+ figma: false,
18304
+ note: false,
18305
+ googleSlides: false
18228
18306
  };
18229
18307
  return {
18230
18308
  github: resolveSingleEmbedOptions(options?.github),
@@ -18251,7 +18329,12 @@ function resolveBuiltinEmbedOptions(options) {
18251
18329
  facebook: options?.facebook === true,
18252
18330
  threads: options?.threads === true,
18253
18331
  instagram: options?.instagram === true,
18254
- webContainer: options?.webContainer === true
18332
+ webContainer: options?.webContainer === true,
18333
+ loom: options?.loom === true,
18334
+ asciinema: options?.asciinema === true,
18335
+ figma: options?.figma === true,
18336
+ note: options?.note === true,
18337
+ googleSlides: options?.googleSlides === true
18255
18338
  };
18256
18339
  }
18257
18340
  function resolveSingleEmbedOptions(options) {
@@ -19288,7 +19371,12 @@ function createFrameworkMarkdownOptions(options) {
19288
19371
  twitter: false,
19289
19372
  reddit: false,
19290
19373
  bluesky: false,
19291
- webContainer: false
19374
+ webContainer: false,
19375
+ loom: false,
19376
+ asciinema: false,
19377
+ figma: false,
19378
+ note: false,
19379
+ googleSlides: false
19292
19380
  },
19293
19381
  i18n: false,
19294
19382
  wikiLinks: {
@@ -20126,61 +20214,6 @@ function createEmptyLintResult() {
20126
20214
  };
20127
20215
  }
20128
20216
  //#endregion
20129
- //#region src/markdown-tables.ts
20130
- const TABINDEX_FLAG = "oxTableScrollTabindex";
20131
- const LABEL_FLAG = "oxTableScrollLabel";
20132
- const SCROLLABLE_ATTR = "data-ox-table-scrollable";
20133
- function markdownTableScrollLabel(locale) {
20134
- if (locale?.split("-")[0]?.toLowerCase() === "ja") return "横スクロールできる表";
20135
- return "Scrollable table";
20136
- }
20137
- /**
20138
- * Makes overflowing Markdown tables keyboard-scrollable without wrapping or
20139
- * replacing the native `<table>` element.
20140
- *
20141
- * Run this after rendering Markdown and again after layout-changing updates.
20142
- * Narrow tables stay out of the tab order when overflow can be measured.
20143
- */
20144
- function enhanceMarkdownTables(root, options = {}) {
20145
- const target = root ?? globalThis.document;
20146
- if (!target?.querySelectorAll) return 0;
20147
- const selector = options.selector ?? ".content table";
20148
- const locale = ownerDocument(target)?.documentElement.lang;
20149
- const label = options.label ?? markdownTableScrollLabel(locale);
20150
- let scrollableCount = 0;
20151
- for (const table of target.querySelectorAll(selector)) {
20152
- if (typeof HTMLElement === "undefined" || !(table instanceof HTMLElement)) continue;
20153
- if (table.tagName !== "TABLE") continue;
20154
- const scrollable = table.scrollWidth > table.clientWidth + 1;
20155
- table.toggleAttribute(SCROLLABLE_ATTR, scrollable);
20156
- if (scrollable) {
20157
- scrollableCount++;
20158
- if (!table.hasAttribute("tabindex")) {
20159
- table.tabIndex = 0;
20160
- table.dataset[TABINDEX_FLAG] = "true";
20161
- }
20162
- if (!table.hasAttribute("aria-label") && !table.hasAttribute("aria-labelledby")) {
20163
- table.setAttribute("aria-label", label);
20164
- table.dataset[LABEL_FLAG] = "true";
20165
- }
20166
- } else {
20167
- if (table.dataset[TABINDEX_FLAG] === "true") {
20168
- table.removeAttribute("tabindex");
20169
- delete table.dataset[TABINDEX_FLAG];
20170
- }
20171
- if (table.dataset[LABEL_FLAG] === "true") {
20172
- table.removeAttribute("aria-label");
20173
- delete table.dataset[LABEL_FLAG];
20174
- }
20175
- }
20176
- }
20177
- return scrollableCount;
20178
- }
20179
- function ownerDocument(root) {
20180
- if (typeof Document !== "undefined" && root instanceof Document) return root;
20181
- return root.ownerDocument ?? globalThis.document;
20182
- }
20183
- //#endregion
20184
20217
  //#region src/ssg-output-write.ts
20185
20218
  /**
20186
20219
  * Writers for composable SSG outputs. Custom hosts call these without `buildSsg()`.
@@ -20783,7 +20816,7 @@ exports.defineTheme = require_vitepress.defineTheme;
20783
20816
  exports.discoverDocumentMdxIslands = discoverDocumentMdxIslands;
20784
20817
  exports.discoverRegisteredMdxComponents = discoverRegisteredMdxComponents;
20785
20818
  exports.each = require_jsx_html.each;
20786
- exports.enhanceMarkdownTables = enhanceMarkdownTables;
20819
+ exports.enhanceMarkdownTables = require_markdown_tables.enhanceMarkdownTables;
20787
20820
  exports.escapeSvelteMarkup = escapeSvelteMarkup;
20788
20821
  exports.extractCodeBlocks = extractCodeBlocks;
20789
20822
  exports.extractDocs = extractDocs;
@@ -20819,7 +20852,7 @@ exports.lintMarkdown = lintMarkdown;
20819
20852
  exports.lintMarkdownAsync = lintMarkdownAsync;
20820
20853
  exports.lintMarkdownFile = lintMarkdownFile;
20821
20854
  exports.lintMarkdownFiles = lintMarkdownFiles;
20822
- exports.markdownTableScrollLabel = markdownTableScrollLabel;
20855
+ exports.markdownTableScrollLabel = require_markdown_tables.markdownTableScrollLabel;
20823
20856
  exports.mergeThemes = require_vitepress.mergeThemes;
20824
20857
  exports.mermaidClientScript = mermaidClientScript;
20825
20858
  exports.normalizeMarkdownExtensions = normalizeMarkdownExtensions;