markdown-design-doc-viewer-embed 1.5.4 → 1.5.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/index.js CHANGED
@@ -22668,6 +22668,255 @@ function groupChanges(changes) {
22668
22668
  flush();
22669
22669
  return grouped;
22670
22670
  }
22671
+ function similarity(before, after, segmenter2) {
22672
+ if (before === after) {
22673
+ return 1;
22674
+ }
22675
+ const total = before.length + after.length;
22676
+ if (total === 0) {
22677
+ return 1;
22678
+ }
22679
+ let common = 0;
22680
+ for (const change of diffWordLists(splitWords(before, segmenter2), splitWords(after, segmenter2)) ?? []) {
22681
+ if (change.type === "equal") {
22682
+ common += change.tokens.join("").length;
22683
+ }
22684
+ }
22685
+ return 2 * common / total;
22686
+ }
22687
+
22688
+ // src/diff/diffRender.ts
22689
+ var SIMILAR = 0.4;
22690
+ var CONTAINERS = /* @__PURE__ */ new Set(["bullet_list_open", "ordered_list_open", "table_open"]);
22691
+ var WRAPPED = /* @__PURE__ */ new Set(["fence", "html_block", "front_matter"]);
22692
+ var isWrapped = (token) => WRAPPED.has(token.type) && !isMermaidFence(token);
22693
+ function isCommentsOnly(html2) {
22694
+ let s = html2.trim();
22695
+ if (!s.startsWith("<!--")) {
22696
+ return false;
22697
+ }
22698
+ while (s.startsWith("<!--")) {
22699
+ const end = s.indexOf("-->", 4);
22700
+ if (end < 0) {
22701
+ return false;
22702
+ }
22703
+ s = s.slice(end + 3).trimStart();
22704
+ }
22705
+ return s === "";
22706
+ }
22707
+ var LIST_MARKER_RE = /^[ \t]*(?:[-*+]|\d{1,9}[.)])[ \t]?/;
22708
+ var SPACED = /* @__PURE__ */ new Set(["fence", "mermaid", "code_block", "html_block"]);
22709
+ var MAX_COMPARED_PAIRS = 2500;
22710
+ function kindOf(token) {
22711
+ if (token.type === "heading_open") {
22712
+ return token.tag;
22713
+ }
22714
+ if (token.type === "fence") {
22715
+ return isMermaidFence(token) ? "mermaid" : "fence";
22716
+ }
22717
+ return token.type;
22718
+ }
22719
+ function unitsOf(tokens, lines, start, end, level, env) {
22720
+ const units = [];
22721
+ for (let i = start; i < end; ) {
22722
+ const token = tokens[i];
22723
+ if (token.level !== level || token.nesting === -1 || !token.block) {
22724
+ i++;
22725
+ continue;
22726
+ }
22727
+ let close = i;
22728
+ if (token.nesting === 1) {
22729
+ while (close < end && !(tokens[close].level === level && tokens[close].nesting === -1)) {
22730
+ close++;
22731
+ }
22732
+ }
22733
+ if (token.map) {
22734
+ const kind = kindOf(token);
22735
+ let key = lines.slice(token.map[0], token.map[1]).join("\n");
22736
+ if (token.type === "list_item_open") {
22737
+ key = key.replace(LIST_MARKER_RE, "");
22738
+ }
22739
+ key = SPACED.has(kind) ? key.trimEnd() : key.replace(/\s+/g, " ").trim();
22740
+ const hidden = token.type === "html_block" && isCommentsOnly(token.content) || token.type === "front_matter" && env.frontMatter === false;
22741
+ units.push({ start: i, end: close + 1, key, kind, hidden });
22742
+ }
22743
+ i = close + 1;
22744
+ }
22745
+ return units;
22746
+ }
22747
+ function align(before, after, alike) {
22748
+ const ops = [];
22749
+ let removed = [];
22750
+ let added = [];
22751
+ const flush = () => {
22752
+ const pairs = [];
22753
+ const compareText = removed.length * added.length <= MAX_COMPARED_PAIRS;
22754
+ let next = 0;
22755
+ added.forEach((b, j3) => {
22756
+ const i3 = removed.findIndex((a, k) => k >= next && alike(a, b, compareText));
22757
+ if (i3 >= 0) {
22758
+ pairs.push([i3, j3]);
22759
+ next = i3 + 1;
22760
+ }
22761
+ });
22762
+ let i2 = 0;
22763
+ let j2 = 0;
22764
+ for (const [pi, pj] of [...pairs, [removed.length, added.length]]) {
22765
+ while (i2 < pi) {
22766
+ ops.push({ type: "deleted", before: removed[i2++] });
22767
+ }
22768
+ while (j2 < pj) {
22769
+ ops.push({ type: "added", after: added[j2++] });
22770
+ }
22771
+ if (pi < removed.length) {
22772
+ ops.push({ type: "changed", before: removed[pi], after: added[pj] });
22773
+ i2 = pi + 1;
22774
+ j2 = pj + 1;
22775
+ }
22776
+ }
22777
+ removed = [];
22778
+ added = [];
22779
+ };
22780
+ let i = 0;
22781
+ let j = 0;
22782
+ for (const change of diffArrays(
22783
+ before.map((u) => u.key),
22784
+ after.map((u) => u.key)
22785
+ )) {
22786
+ if (change.removed) {
22787
+ removed.push(...before.slice(i, i += change.count));
22788
+ } else if (change.added) {
22789
+ added.push(...after.slice(j, j += change.count));
22790
+ } else {
22791
+ flush();
22792
+ for (let k = 0; k < change.count; k++) {
22793
+ ops.push({ type: "equal", before: before[i++], after: after[j++] });
22794
+ }
22795
+ }
22796
+ }
22797
+ flush();
22798
+ return ops;
22799
+ }
22800
+ function renderDiff(md2, beforeSource, afterSource, env = {}) {
22801
+ const segmenter2 = wordSegmenter();
22802
+ const beforeEnv = {
22803
+ resolveResource: env.resolveResource,
22804
+ t: env.t,
22805
+ frontMatter: env.frontMatter,
22806
+ headingNumbers: env.headingNumbers,
22807
+ messageWrapWidth: env.messageWrapWidth,
22808
+ wireframes: env.wireframes,
22809
+ forExport: true,
22810
+ docId: "seqnotes-old"
22811
+ };
22812
+ const beforeTokens = md2.parse(beforeSource, beforeEnv);
22813
+ const afterTokens = md2.parse(afterSource, env);
22814
+ for (const token of beforeTokens) {
22815
+ if (token.type === "heading_open" && token.attrs) {
22816
+ token.attrs = token.attrs.filter(([name]) => name !== "id");
22817
+ }
22818
+ }
22819
+ const beforeLines = beforeSource.split(/\r\n?|\n/);
22820
+ const afterLines = afterSource.split(/\r\n?|\n/);
22821
+ const old = [];
22822
+ const stats = { added: 0, changed: 0, deleted: 0 };
22823
+ const inserted = /* @__PURE__ */ new Map();
22824
+ const insert = (index, token) => {
22825
+ inserted.set(index, [...inserted.get(index) ?? [], token]);
22826
+ };
22827
+ const htmlToken = (content, level) => {
22828
+ const token = new MarkdownItCallable.Token("html_block", "", 0);
22829
+ token.content = content;
22830
+ token.block = true;
22831
+ token.level = level;
22832
+ token.meta = { [RENDERED_HTML]: true };
22833
+ return token;
22834
+ };
22835
+ const wrapped = (mark2, html2) => `<div class="seqnotes-diff-block" data-seqnotes-diff="${mark2}">
22836
+ ${html2}</div>
22837
+ `;
22838
+ const renderBefore = (unit) => md2.renderer.render(beforeTokens.slice(unit.start, unit.end), md2.options, beforeEnv);
22839
+ const mark = (unit, value, oldIndex) => {
22840
+ const token = afterTokens[unit.start];
22841
+ if (isWrapped(token)) {
22842
+ const attrs = oldIndex === void 0 ? "" : ` data-seqnotes-diff-old="${oldIndex}"`;
22843
+ insert(unit.start, htmlToken(`<div class="seqnotes-diff-block" data-seqnotes-diff="${value}"${attrs}>
22844
+ `, token.level));
22845
+ insert(unit.end, htmlToken("</div>\n", token.level));
22846
+ return;
22847
+ }
22848
+ token.attrSet("data-seqnotes-diff", value);
22849
+ if (oldIndex !== void 0) {
22850
+ token.attrSet("data-seqnotes-diff-old", String(oldIndex));
22851
+ }
22852
+ };
22853
+ const alike = (a, b, compareText) => a.kind === b.kind && (CONTAINERS.has(a.kind) || a.kind === "mermaid" || compareText && similarity(a.key, b.key, segmenter2) >= SIMILAR);
22854
+ const numberItems = (tokens2, list2, items) => {
22855
+ const start = Number(tokens2[list2.start].attrGet("start") ?? 1);
22856
+ items.forEach((item, i) => tokens2[item.start].attrSet("value", String(start + i)));
22857
+ };
22858
+ const compare = (before, after, level) => {
22859
+ const ops = align(before, after, alike);
22860
+ let deleted = [];
22861
+ const flushDeleted = (index) => {
22862
+ for (const unit of deleted) {
22863
+ const token = beforeTokens[unit.start];
22864
+ let html2;
22865
+ if (isWrapped(token)) {
22866
+ html2 = wrapped("deleted", renderBefore(unit));
22867
+ } else {
22868
+ token.attrSet("data-seqnotes-diff", "deleted");
22869
+ html2 = renderBefore(unit);
22870
+ }
22871
+ insert(index, htmlToken(html2, level));
22872
+ stats.deleted++;
22873
+ }
22874
+ deleted = [];
22875
+ };
22876
+ for (const op of ops) {
22877
+ if (op.type === "deleted") {
22878
+ if (!op.before.hidden) {
22879
+ deleted.push(op.before);
22880
+ }
22881
+ continue;
22882
+ }
22883
+ flushDeleted(op.after.start);
22884
+ if (op.after.hidden) {
22885
+ continue;
22886
+ }
22887
+ if (op.type === "added") {
22888
+ mark(op.after, "added");
22889
+ stats.added++;
22890
+ } else if (op.type === "changed") {
22891
+ const kind = op.after.kind;
22892
+ if (CONTAINERS.has(kind)) {
22893
+ const depth = kind === "table_open" ? 2 : 1;
22894
+ const beforeItems = unitsOf(beforeTokens, beforeLines, op.before.start + 1, op.before.end - 1, level + depth, beforeEnv);
22895
+ const afterItems = unitsOf(afterTokens, afterLines, op.after.start + 1, op.after.end - 1, level + depth, env);
22896
+ if (kind === "ordered_list_open") {
22897
+ numberItems(beforeTokens, op.before, beforeItems);
22898
+ numberItems(afterTokens, op.after, afterItems);
22899
+ }
22900
+ compare(beforeItems, afterItems, level + depth);
22901
+ } else {
22902
+ old.push(renderBefore(op.before));
22903
+ mark(op.after, "changed", old.length - 1);
22904
+ stats.changed++;
22905
+ }
22906
+ }
22907
+ }
22908
+ flushDeleted(after.length > 0 ? after[after.length - 1].end : 0);
22909
+ };
22910
+ compare(unitsOf(beforeTokens, beforeLines, 0, beforeTokens.length, 0, beforeEnv), unitsOf(afterTokens, afterLines, 0, afterTokens.length, 0, env), 0);
22911
+ const tokens = [];
22912
+ for (let i = 0; i <= afterTokens.length; i++) {
22913
+ tokens.push(...inserted.get(i) ?? []);
22914
+ if (i < afterTokens.length) {
22915
+ tokens.push(afterTokens[i]);
22916
+ }
22917
+ }
22918
+ return { html: renderTokens(md2, tokens, env), old, stats };
22919
+ }
22671
22920
 
22672
22921
  // src/export/exportPage.ts
22673
22922
  var SCHEME_RE2 = /^[a-z][a-z0-9+.-]*:/i;
@@ -22710,6 +22959,17 @@ async function renderForExport(md2, source, env, resolveImage) {
22710
22959
  const { result, resolve } = await withImages((resolveResource) => renderDocument(md2, source, { ...env, forExport: true, resolveResource }), resolveImage);
22711
22960
  return resolve(result);
22712
22961
  }
22962
+ async function renderDiffForExport(md2, beforeSource, afterSource, env, resolveImage) {
22963
+ const { result, resolve } = await withImages(
22964
+ (resolveResource) => renderDiff(md2, beforeSource, afterSource, { ...env, forExport: true, resolveResource }),
22965
+ resolveImage
22966
+ );
22967
+ return { html: resolve(result.html), old: result.old.map(resolve), stats: result.stats };
22968
+ }
22969
+ var DIFF_TITLES = ["diff-added", "diff-changed", "diff-deleted", "diff-no-changes", "diff-previous-title", "diff-next-title", "diff-hide-title", "diff-show-title"];
22970
+ function exportDiff({ label, stats }, t) {
22971
+ return { label, stats, titles: Object.fromEntries(DIFF_TITLES.map((name) => [`data-seqnotes-${name}`, t(WEBVIEW_TITLES[name])])) };
22972
+ }
22713
22973
  function exportPage({ lang, title, body, styles, script, settings, tocTitle, splitterTitle, diff }) {
22714
22974
  const classes = [
22715
22975
  "seqnotes-viewer",
@@ -25027,7 +25287,12 @@ function setupDiffBar(root, action, { container, titles, scroll }) {
25027
25287
  clearTimeout(focusTimer);
25028
25288
  focusTimer = setTimeout(() => target.classList.remove("seqnotes-diff-focus"), FOCUS_MS);
25029
25289
  }
25290
+ function setLabel(text3) {
25291
+ label.textContent = text3;
25292
+ label.title = text3;
25293
+ }
25030
25294
  return {
25295
+ setLabel,
25031
25296
  show(diff) {
25032
25297
  bar.hidden = !diff;
25033
25298
  current = void 0;
@@ -25035,8 +25300,7 @@ function setupDiffBar(root, action, { container, titles, scroll }) {
25035
25300
  if (!diff) {
25036
25301
  return;
25037
25302
  }
25038
- label.textContent = diff.label;
25039
- label.title = diff.label;
25303
+ setLabel(diff.label);
25040
25304
  const { added, changed, deleted } = diff.stats;
25041
25305
  const items = [
25042
25306
  ["added", added, titles.seqnotesDiffAdded],
@@ -26773,7 +27037,7 @@ ${source}`;
26773
27037
  }
26774
27038
  });
26775
27039
  setUpWarnings();
26776
- diffBar.show(diff);
27040
+ diffBar.show(lastDiff);
26777
27041
  layoutWireframes(root);
26778
27042
  addZoomButtons();
26779
27043
  markZoomableImages();
@@ -27413,7 +27677,13 @@ ${source}`;
27413
27677
  el.classList.remove("seqnotes-wide", "seqnotes-limit-width", "seqnotes-sticky-table-header", "seqnotes-table-tree-highlight");
27414
27678
  el.style.removeProperty("--seqnotes-split");
27415
27679
  }
27416
- return { handle, destroy };
27680
+ function relabelDiff(label) {
27681
+ if (lastDiff) {
27682
+ lastDiff = { ...lastDiff, label };
27683
+ diffBar.setLabel(label);
27684
+ }
27685
+ }
27686
+ return { handle, destroy, relabelDiff };
27417
27687
  }
27418
27688
 
27419
27689
  // webview/viewerContext.ts
@@ -27472,6 +27742,110 @@ function writeTitles(el, t) {
27472
27742
  }
27473
27743
  }
27474
27744
 
27745
+ // src/export/exportIndex.ts
27746
+ function documentInfo(md2, source, fallback, frontMatter2 = true) {
27747
+ const tokens = md2.parse(source, {});
27748
+ const entries2 = frontMatterEntries(tokens);
27749
+ const meta = {};
27750
+ for (const { key } of frontMatter2 ? DESIGN_DOC_META : []) {
27751
+ const value = frontMatterValue(entries2, key)?.trim();
27752
+ if (value !== void 0) {
27753
+ meta[key] = value;
27754
+ }
27755
+ }
27756
+ return { title: titleOf(tokens, fallback), meta, designDoc: isDesignDoc(entries2) };
27757
+ }
27758
+ function compareFolders(a, b) {
27759
+ const as = a === "" ? [] : a.split("/");
27760
+ const bs = b === "" ? [] : b.split("/");
27761
+ for (let i = 0; i < Math.min(as.length, bs.length); i++) {
27762
+ const order = as[i].localeCompare(bs[i]);
27763
+ if (order !== 0) {
27764
+ return order;
27765
+ }
27766
+ }
27767
+ return as.length - bs.length;
27768
+ }
27769
+ var NO_DESIGN_DOCS = "There are no design docs (Markdown files with type: design_doc in their front matter).";
27770
+ function changesCell(changes, t) {
27771
+ const { added, changed, deleted } = changes.stats;
27772
+ const total = added + changed + deleted;
27773
+ let content;
27774
+ if (changes.isNew) {
27775
+ content = `<span class="seqnotes-index-new">${escapeHtml2(t("New"))}</span>`;
27776
+ } else if (total === 0) {
27777
+ content = `<span class="seqnotes-index-unchanged">${escapeHtml2(t("No changes"))}</span>`;
27778
+ } else {
27779
+ const counts = [
27780
+ ["added", added, "{0} added"],
27781
+ ["changed", changed, "{0} changed"],
27782
+ ["deleted", deleted, "{0} deleted"]
27783
+ ];
27784
+ content = '<span class="seqnotes-diff-counts">' + counts.filter(([, count]) => count > 0).map(([kind, count, text3]) => `<span class="seqnotes-diff-count" data-kind="${kind}">${escapeHtml2(t(text3, count))}</span>`).join("") + "</span>";
27785
+ }
27786
+ return `<td class="seqnotes-index-changes" data-seqnotes-sort="${changes.isNew ? Number.MAX_SAFE_INTEGER : total}">${content}</td>`;
27787
+ }
27788
+ function groupByFolder(entries2, keepOrder = false) {
27789
+ const unique = [...new Set(entries2.map((entry) => entry.folder))];
27790
+ const folders = keepOrder ? unique : unique.sort(compareFolders);
27791
+ return folders.map((folder) => {
27792
+ const rows = entries2.filter((entry) => entry.folder === folder);
27793
+ return { folder, entries: keepOrder ? rows : rows.sort((a, b) => a.file.localeCompare(b.file)) };
27794
+ });
27795
+ }
27796
+ function indexBody(title, entries2, t, { empty = "", fileLabel, filterPlaceholder, keepOrder = false } = {}) {
27797
+ const columns = DESIGN_DOC_META.filter(({ key }) => entries2.some((entry) => key in entry.meta));
27798
+ const changes = entries2.some((entry) => entry.changes !== void 0);
27799
+ const headers = [
27800
+ { key: "title", label: t("Title") },
27801
+ { key: "file", label: fileLabel ?? t("File") },
27802
+ ...columns.map(({ key, label }) => ({ key, label: t(label) })),
27803
+ ...changes ? [{ key: "changes", label: t("Changes") }] : []
27804
+ ];
27805
+ const head = "<thead><tr>" + headers.map(({ key, label }) => `<th data-seqnotes-column="${key}">${escapeHtml2(label)}</th>`).join("") + "</tr></thead>\n";
27806
+ const row = (entry) => `<tr><td class="seqnotes-index-title"><a href="${escapeHtml2(entry.href)}">${escapeHtml2(entry.title)}</a></td><td class="seqnotes-index-file">${escapeHtml2(entry.file)}</td>` + columns.map(({ key }) => {
27807
+ const value = entry.meta[key];
27808
+ return `<td class="seqnotes-index-${key}">${value === void 0 ? "" : `<span>${escapeHtml2(value)}</span>`}</td>`;
27809
+ }).join("") + (!changes ? "" : entry.changes ? changesCell(entry.changes, t) : '<td class="seqnotes-index-changes"></td>') + "</tr>\n";
27810
+ const tables = groupByFolder(entries2, keepOrder).map(
27811
+ ({ folder, entries: rows }) => (folder === "" ? "" : `<h2>${escapeHtml2(folder)}/</h2>
27812
+ `) + `<table>
27813
+ ${head}<tbody>
27814
+ ${rows.map(row).join("")}</tbody>
27815
+ </table>
27816
+ `
27817
+ );
27818
+ const texts = {
27819
+ "filter-label": t("Filter"),
27820
+ "filter-placeholder": filterPlaceholder ?? t("Filter by title, file name or metadata"),
27821
+ // `{0}` documents shown of `{1}`, filled in by the script.
27822
+ count: t("{0} of {1} documents"),
27823
+ "no-match": t("No documents match the filter."),
27824
+ "sort-title": t("Sort by this column")
27825
+ };
27826
+ const attrs = Object.entries(texts).map(([key, text3]) => ` data-seqnotes-${key}="${escapeHtml2(text3)}"`).join("");
27827
+ const body = entries2.length === 0 ? `<p class="seqnotes-index-empty">${escapeHtml2(empty)}</p>
27828
+ ` : tables.join("");
27829
+ return `<div class="seqnotes-index"${attrs}>
27830
+ <h1>${escapeHtml2(title)}</h1>
27831
+ ${body}</div>`;
27832
+ }
27833
+
27834
+ // embed/designDocList.ts
27835
+ function designDocListHtml(md2, content, t) {
27836
+ const entries2 = content.documents.map((doc) => {
27837
+ const file = doc.file ?? "";
27838
+ const info = documentInfo(md2, doc.markdown, file || doc.href);
27839
+ return { title: doc.title ?? info.title, meta: info.meta, href: doc.href, folder: doc.folder ?? "", file };
27840
+ });
27841
+ return indexBody(content.title ?? t("Design Docs"), entries2, t, {
27842
+ empty: content.empty ?? t(NO_DESIGN_DOCS),
27843
+ fileLabel: content.fileLabel,
27844
+ filterPlaceholder: content.filterPlaceholder,
27845
+ keepOrder: content.keepOrder
27846
+ });
27847
+ }
27848
+
27475
27849
  // embed/viewer.ts
27476
27850
  function openLinkInNewTab(href) {
27477
27851
  if (/^(?:https?|mailto):/i.test(href)) {
@@ -27514,14 +27888,21 @@ async function readWireframes(markdown, { readFile, baseUrl }) {
27514
27888
  }
27515
27889
  return loadWireframes(md, wireframeSources(md.parse(markdown, {})), (path) => Promise.resolve().then(() => read(path)).catch(() => void 0));
27516
27890
  }
27517
- var CONTENT_OPTIONS = ["markdown", "baseUrl", "readFile", "resolveResource", "frontMatter", "headingNumbers", "messageWrapWidth"];
27891
+ function viewerContent(markdown, env, compareWith, compareLabel) {
27892
+ if (compareWith === void 0) {
27893
+ return { html: renderDocument(md, markdown, env) };
27894
+ }
27895
+ const result = renderDiff(md, compareWith, markdown, env);
27896
+ return { html: result.html, diff: diffView(result, compareLabel) };
27897
+ }
27898
+ function diffView({ old, stats }, compareLabel) {
27899
+ return { label: compareLabel ?? "", old, stats };
27900
+ }
27901
+ var CONTENT_OPTIONS = ["markdown", "baseUrl", "readFile", "resolveResource", "frontMatter", "headingNumbers", "messageWrapWidth", "compareWith"];
27518
27902
  var VIEW_OPTIONS = ["documentId", "splitMinWidth", "toc", "diagramLook", "limitContentWidth", "stickyTableHeader", "tableTreeHighlight"];
27519
- function createViewer(container, options) {
27520
- let current = { ...options };
27521
- const lang = langOf(options.lang);
27522
- const t = translator(lang);
27903
+ function mountViewer(container, lang, t, options, className = "") {
27523
27904
  const el = document.createElement("div");
27524
- el.className = "seqnotes-viewer seqnotes-embedded";
27905
+ el.className = `seqnotes-viewer seqnotes-embedded ${className}`.trim();
27525
27906
  el.lang = lang;
27526
27907
  el.dataset.seqnotesTheme = "auto";
27527
27908
  writeTitles(el, t);
@@ -27540,9 +27921,11 @@ function createViewer(container, options) {
27540
27921
  let state;
27541
27922
  const post = (message) => {
27542
27923
  if (message.type === "openLink") {
27543
- (current.onOpenLink ?? openLinkInNewTab)(message.href);
27924
+ (options().onOpenLink ?? openLinkInNewTab)(message.href);
27544
27925
  } else if (message.type === "revealLine") {
27545
- current.onRevealLine?.(message.line);
27926
+ options().onRevealLine?.(message.line);
27927
+ } else if (message.type === "closeDiff") {
27928
+ options().onCloseDiff?.();
27546
27929
  }
27547
27930
  };
27548
27931
  const preview = createPreview({
@@ -27556,21 +27939,51 @@ function createViewer(container, options) {
27556
27939
  });
27557
27940
  const systemDark = window.matchMedia("(prefers-color-scheme: dark)");
27558
27941
  const applyTheme = () => {
27559
- const dark = current.theme === "dark" || current.theme !== "light" && systemDark.matches;
27942
+ const { theme } = options();
27943
+ const dark = theme === "dark" || theme !== "light" && systemDark.matches;
27560
27944
  el.classList.toggle("vscode-dark", dark);
27561
27945
  el.classList.toggle("vscode-light", !dark);
27562
27946
  };
27563
27947
  systemDark.addEventListener("change", applyTheme);
27564
27948
  applyTheme();
27949
+ return {
27950
+ preview,
27951
+ applyTheme,
27952
+ destroy() {
27953
+ preview.destroy();
27954
+ systemDark.removeEventListener("change", applyTheme);
27955
+ stopSizing();
27956
+ el.remove();
27957
+ }
27958
+ };
27959
+ }
27960
+ function createViewer(container, options) {
27961
+ let current = { ...options };
27962
+ const lang = langOf(options.lang);
27963
+ const t = translator(lang);
27565
27964
  let destroyed = false;
27566
27965
  let resolveReady;
27567
27966
  const ready = new Promise((resolve) => resolveReady = resolve);
27568
27967
  let html2;
27968
+ let diff;
27969
+ let wireframesRead;
27569
27970
  let rendering = Promise.resolve();
27570
27971
  let pending = false;
27571
27972
  let renders = 0;
27572
27973
  let shown = 0;
27573
- async function show(rendered) {
27974
+ let dismissed;
27975
+ const closeDiff = () => {
27976
+ if (current.onCloseDiff) {
27977
+ current.onCloseDiff();
27978
+ } else if (!destroyed && current.compareWith !== void 0 && current.compareWith !== dismissed) {
27979
+ dismissed = current.compareWith;
27980
+ if (!pending) {
27981
+ rendering = render(true);
27982
+ }
27983
+ }
27984
+ };
27985
+ const { preview, applyTheme, destroy: unmount } = mountViewer(container, lang, t, () => ({ ...current, onCloseDiff: closeDiff }));
27986
+ async function show(rendered, differences) {
27574
27987
  const seq = ++shown;
27575
27988
  await preview.handle({
27576
27989
  type: "update",
@@ -27584,24 +27997,32 @@ function createViewer(container, options) {
27584
27997
  theme: "auto",
27585
27998
  limitContentWidth: current.limitContentWidth ?? true,
27586
27999
  stickyTableHeader: current.stickyTableHeader ?? true,
27587
- tableTreeHighlight: current.tableTreeHighlight ?? true
28000
+ tableTreeHighlight: current.tableTreeHighlight ?? true,
28001
+ ...differences ? { diff: differences } : {}
27588
28002
  });
27589
28003
  if (seq === shown) {
27590
28004
  resolveReady();
27591
28005
  }
27592
28006
  }
27593
- async function render() {
28007
+ async function render(sameWireframes = false) {
27594
28008
  const seq = ++renders;
27595
28009
  pending = true;
27596
28010
  const { markdown, baseUrl } = current;
27597
28011
  const resolveResource = current.resolveResource ?? (baseUrl === void 0 ? void 0 : (src) => resolveUrl(src, baseUrl) ?? src);
27598
- const wireframes2 = await readWireframes(markdown, current);
28012
+ const wireframes2 = sameWireframes && wireframesRead ? wireframesRead.files : await readWireframes(markdown, current);
27599
28013
  if (destroyed || seq !== renders) {
27600
28014
  return;
27601
28015
  }
27602
28016
  pending = false;
27603
- html2 = renderDocument(md, markdown, { t, frontMatter: current.frontMatter, headingNumbers: current.headingNumbers, messageWrapWidth: current.messageWrapWidth, wireframes: wireframes2, resolveResource });
27604
- await show(html2);
28017
+ wireframesRead = { files: wireframes2 };
28018
+ const compareWith = current.compareWith === dismissed ? void 0 : current.compareWith;
28019
+ ({ html: html2, diff } = viewerContent(
28020
+ markdown,
28021
+ { t, frontMatter: current.frontMatter, headingNumbers: current.headingNumbers, messageWrapWidth: current.messageWrapWidth, wireframes: wireframes2, resolveResource },
28022
+ compareWith,
28023
+ current.compareLabel
28024
+ ));
28025
+ await show(html2, diff);
27605
28026
  }
27606
28027
  rendering = render();
27607
28028
  return {
@@ -27613,6 +28034,9 @@ function createViewer(container, options) {
27613
28034
  const previous = current;
27614
28035
  current = { ...current, ...changes, lang: current.lang };
27615
28036
  applyTheme();
28037
+ if (current.compareWith !== previous.compareWith) {
28038
+ dismissed = void 0;
28039
+ }
27616
28040
  if (html2 === void 0 || CONTENT_OPTIONS.some((name) => current[name] !== previous[name])) {
27617
28041
  rendering = render();
27618
28042
  return rendering;
@@ -27620,9 +28044,13 @@ function createViewer(container, options) {
27620
28044
  if (pending) {
27621
28045
  return rendering;
27622
28046
  }
28047
+ if (diff !== void 0 && current.compareLabel !== previous.compareLabel) {
28048
+ diff = diffView(diff, current.compareLabel);
28049
+ preview.relabelDiff(diff.label);
28050
+ }
27623
28051
  const revealing = (options2) => options2.onRevealLine !== void 0;
27624
28052
  if (VIEW_OPTIONS.some((name) => current[name] !== previous[name]) || revealing(current) !== revealing(previous)) {
27625
- return show(html2);
28053
+ return show(html2, diff);
27626
28054
  }
27627
28055
  return Promise.resolve();
27628
28056
  },
@@ -27637,16 +28065,90 @@ function createViewer(container, options) {
27637
28065
  return;
27638
28066
  }
27639
28067
  destroyed = true;
27640
- preview.destroy();
27641
- systemDark.removeEventListener("change", applyTheme);
27642
- stopSizing();
27643
- el.remove();
28068
+ unmount();
28069
+ resolveReady();
28070
+ }
28071
+ };
28072
+ }
28073
+ var LIST_URI = "seqnotes-design-doc-list";
28074
+ var LIST_CONTENT_OPTIONS = ["documents", "title", "fileLabel", "filterPlaceholder", "empty", "keepOrder"];
28075
+ var SCRIPT_SCHEMES = /* @__PURE__ */ new Set(["javascript:", "data:", "vbscript:"]);
28076
+ function openLinkInPage(href) {
28077
+ let url;
28078
+ try {
28079
+ url = new URL(href, document.baseURI);
28080
+ } catch {
28081
+ return;
28082
+ }
28083
+ if (!SCRIPT_SCHEMES.has(url.protocol)) {
28084
+ window.location.assign(url.href);
28085
+ }
28086
+ }
28087
+ function createDesignDocList(container, options) {
28088
+ let current = { ...options };
28089
+ const lang = langOf(options.lang);
28090
+ const t = translator(lang);
28091
+ const { preview, applyTheme, destroy: unmount } = mountViewer(
28092
+ container,
28093
+ lang,
28094
+ t,
28095
+ () => ({ ...current, onOpenLink: current.onOpenLink ?? openLinkInPage }),
28096
+ "seqnotes-embedded-list"
28097
+ );
28098
+ let destroyed = false;
28099
+ let resolveReady;
28100
+ const ready = new Promise((resolve) => resolveReady = resolve);
28101
+ let html2 = designDocListHtml(md, current, t);
28102
+ let shown = 0;
28103
+ async function show() {
28104
+ if (destroyed) {
28105
+ return;
28106
+ }
28107
+ const seq = ++shown;
28108
+ await preview.handle({
28109
+ type: "update",
28110
+ uri: LIST_URI,
28111
+ html: html2,
28112
+ splitMinWidth: 1e3,
28113
+ syncEditor: false,
28114
+ toc: false,
28115
+ diagramLook: "neo",
28116
+ theme: "auto",
28117
+ limitContentWidth: current.limitContentWidth ?? true,
28118
+ stickyTableHeader: false,
28119
+ tableTreeHighlight: false
28120
+ });
28121
+ if (seq === shown) {
28122
+ resolveReady();
28123
+ }
28124
+ }
28125
+ void show();
28126
+ return {
28127
+ ready,
28128
+ update(changes) {
28129
+ if (destroyed) {
28130
+ return Promise.resolve();
28131
+ }
28132
+ const previous = current;
28133
+ current = { ...current, ...changes, lang: current.lang };
28134
+ applyTheme();
28135
+ if (LIST_CONTENT_OPTIONS.some((name) => current[name] !== previous[name])) {
28136
+ html2 = designDocListHtml(md, current, t);
28137
+ }
28138
+ return show();
28139
+ },
28140
+ destroy() {
28141
+ if (destroyed) {
28142
+ return;
28143
+ }
28144
+ destroyed = true;
28145
+ unmount();
27644
28146
  resolveReady();
27645
28147
  }
27646
28148
  };
27647
28149
  }
27648
28150
  var exportCount = 0;
27649
- async function renderExportBody(html2, t, diagramLook) {
28151
+ async function renderExportBody(html2, t, diagramLook, diff) {
27650
28152
  const el = document.createElement("div");
27651
28153
  el.className = "seqnotes-viewer seqnotes-embedded vscode-light";
27652
28154
  el.dataset.seqnotesTheme = "light";
@@ -27671,7 +28173,7 @@ async function renderExportBody(html2, t, diagramLook) {
27671
28173
  setState: (next) => state = next
27672
28174
  });
27673
28175
  });
27674
- await preview.handle({ type: "export", id: 1, html: html2, diagramLook });
28176
+ await preview.handle({ type: "export", id: 1, html: html2, diagramLook, ...diff ? { diff } : {} });
27675
28177
  const { body, error: error2 } = await exported;
27676
28178
  if (body === void 0) {
27677
28179
  throw new Error(error2 ?? "The diagrams could not be rendered.");
@@ -27695,8 +28197,17 @@ async function exportDocument(options, assets) {
27695
28197
  () => path
27696
28198
  );
27697
28199
  };
27698
- const html2 = await renderForExport(md, markdown, { t, frontMatter: options.frontMatter, headingNumbers: options.headingNumbers, messageWrapWidth: options.messageWrapWidth, wireframes: wireframes2 }, image2);
27699
- const body = await renderExportBody(html2, t, options.diagramLook ?? "neo");
28200
+ const env = { t, frontMatter: options.frontMatter, headingNumbers: options.headingNumbers, messageWrapWidth: options.messageWrapWidth, wireframes: wireframes2 };
28201
+ let html2;
28202
+ let diff;
28203
+ if (options.compareWith !== void 0) {
28204
+ const result = await renderDiffForExport(md, options.compareWith, markdown, env, image2);
28205
+ html2 = result.html;
28206
+ diff = diffView(result, options.compareLabel);
28207
+ } else {
28208
+ html2 = await renderForExport(md, markdown, env, image2);
28209
+ }
28210
+ const body = await renderExportBody(html2, t, options.diagramLook ?? "neo", diff);
27700
28211
  return exportPage({
27701
28212
  lang,
27702
28213
  title: documentTitle(md, markdown, options.title ?? ""),
@@ -27711,13 +28222,17 @@ async function exportDocument(options, assets) {
27711
28222
  toc: options.toc ?? true
27712
28223
  },
27713
28224
  tocTitle: t(WEBVIEW_TITLES["toc-title"]),
27714
- splitterTitle: t(WEBVIEW_TITLES["splitter-title"])
28225
+ splitterTitle: t(WEBVIEW_TITLES["splitter-title"]),
28226
+ ...diff ? { diff: exportDiff(diff, t) } : {}
27715
28227
  });
27716
28228
  }
27717
28229
  export {
28230
+ createDesignDocList,
27718
28231
  createViewer,
27719
28232
  exportDocument,
27720
- openLinkInNewTab
28233
+ openLinkInNewTab,
28234
+ openLinkInPage,
28235
+ viewerContent
27721
28236
  };
27722
28237
  /*! Bundled license information:
27723
28238