@commentray/render 0.3.4 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/block-stretch-buffer-sync.d.ts.map +1 -1
- package/dist/block-stretch-buffer-sync.js +21 -1
- package/dist/block-stretch-buffer-sync.js.map +1 -1
- package/dist/code-browser-client.bundle.js +11 -11
- package/dist/code-browser-client.js +92 -35
- package/dist/code-browser-client.js.map +1 -1
- package/dist/code-browser-shell.css +43 -6
- package/package.json +2 -2
|
@@ -13,7 +13,7 @@ import { parseDualPaneScrollSyncStrategy } from "./code-browser-scroll-sync-stra
|
|
|
13
13
|
import { DUAL_PANE_BLOCK_REVEAL_LEAD_CSS_PX, READING_LEAD_ALIGN_TOLERANCE_CSS_PX, READING_VIEWPORT_BOTTOM_EDGE_CSS_PX, readingViewportTopInsetCssPx, } from "./reading-viewport-comfort.js";
|
|
14
14
|
import { wireWideModeIntroTour } from "./code-browser-wide-intro-controller.js";
|
|
15
15
|
import { readWebStorageItem, writeWebStorageItem } from "./code-browser-web-storage.js";
|
|
16
|
-
import { dispatchCommentrayMermaidDone, wireBlockStretchBufferSync, } from "./block-stretch-buffer-sync.js";
|
|
16
|
+
import { applyBlockStretchRowBuffers, dispatchCommentrayMermaidDone, wireBlockStretchBufferSync, } from "./block-stretch-buffer-sync.js";
|
|
17
17
|
import { COMMENTRAY_MERMAID_MODULE_READY_EVENT } from "./commentray-mermaid-events.js";
|
|
18
18
|
/**
|
|
19
19
|
* Hub pages emit `./browse/…` relative to the site root. From `/…/browse/current.html` the browser
|
|
@@ -2490,6 +2490,38 @@ const DUAL_MOBILE_SINGLE_PANE_MQ = "(max-width: 767px)";
|
|
|
2490
2490
|
function normalizedDualMobilePane(v) {
|
|
2491
2491
|
return v === "code" ? "code" : "doc";
|
|
2492
2492
|
}
|
|
2493
|
+
function splitLocationHashTokens(rawHash) {
|
|
2494
|
+
const hash = rawHash.replace(/^#/, "").trim();
|
|
2495
|
+
if (hash.length === 0)
|
|
2496
|
+
return [];
|
|
2497
|
+
return hash
|
|
2498
|
+
.split(/--|&/)
|
|
2499
|
+
.map((t) => t.trim())
|
|
2500
|
+
.filter((t) => t.length > 0);
|
|
2501
|
+
}
|
|
2502
|
+
function mobilePaneHashToken(pane) {
|
|
2503
|
+
return `mobile-pane-${pane}`;
|
|
2504
|
+
}
|
|
2505
|
+
function mobilePaneFromLocationHash(rawHash) {
|
|
2506
|
+
const tokens = splitLocationHashTokens(rawHash);
|
|
2507
|
+
for (const token of tokens) {
|
|
2508
|
+
if (token === "mobile-pane-code")
|
|
2509
|
+
return "code";
|
|
2510
|
+
if (token === "mobile-pane-doc")
|
|
2511
|
+
return "doc";
|
|
2512
|
+
}
|
|
2513
|
+
return null;
|
|
2514
|
+
}
|
|
2515
|
+
function updateLocationHashToken(token, shouldReplace) {
|
|
2516
|
+
const tokens = splitLocationHashTokens(globalThis.location.hash).filter((t) => !shouldReplace(t));
|
|
2517
|
+
tokens.push(token);
|
|
2518
|
+
const u = new URL(globalThis.location.href);
|
|
2519
|
+
u.hash = tokens.length > 0 ? tokens.join("&") : "";
|
|
2520
|
+
globalThis.history.replaceState(globalThis.history.state, "", u.toString());
|
|
2521
|
+
}
|
|
2522
|
+
function updateLocationHashForMobilePane(pane) {
|
|
2523
|
+
updateLocationHashToken(mobilePaneHashToken(pane), (t) => /^mobile-pane-(?:code|doc)$/.test(t));
|
|
2524
|
+
}
|
|
2493
2525
|
function isNarrowViewport() {
|
|
2494
2526
|
return globalThis.matchMedia(DUAL_MOBILE_SINGLE_PANE_MQ).matches;
|
|
2495
2527
|
}
|
|
@@ -2713,6 +2745,7 @@ function wireSourceMarkdownPaneFlip(shell, codePane, flipBtn, flipScrollBtn, sig
|
|
|
2713
2745
|
if (curPane === "doc") {
|
|
2714
2746
|
shell.setAttribute("data-dual-mobile-pane", "code");
|
|
2715
2747
|
writeWebStorageItem(localStorage, STORAGE_DUAL_MOBILE_PANE, "code");
|
|
2748
|
+
updateLocationHashForMobilePane("code");
|
|
2716
2749
|
}
|
|
2717
2750
|
}
|
|
2718
2751
|
syncSourceMarkdownFlipA11y();
|
|
@@ -2741,6 +2774,9 @@ function wireSourceMarkdownPaneFlip(shell, codePane, flipBtn, flipScrollBtn, sig
|
|
|
2741
2774
|
function wireDualMobilePaneFlip(shell, flipBtn, scrollRunners, flipScrollBtn) {
|
|
2742
2775
|
const mq = globalThis.matchMedia(DUAL_MOBILE_SINGLE_PANE_MQ);
|
|
2743
2776
|
function readStoredPane() {
|
|
2777
|
+
const fromHash = mobilePaneFromLocationHash(globalThis.location.hash);
|
|
2778
|
+
if (fromHash !== null)
|
|
2779
|
+
return fromHash;
|
|
2744
2780
|
return normalizedDualMobilePane(readWebStorageItem(localStorage, STORAGE_DUAL_MOBILE_PANE));
|
|
2745
2781
|
}
|
|
2746
2782
|
function applyForViewport() {
|
|
@@ -2767,6 +2803,7 @@ function wireDualMobilePaneFlip(shell, flipBtn, scrollRunners, flipScrollBtn) {
|
|
|
2767
2803
|
}
|
|
2768
2804
|
shell.setAttribute("data-dual-mobile-pane", next);
|
|
2769
2805
|
writeWebStorageItem(localStorage, STORAGE_DUAL_MOBILE_PANE, next);
|
|
2806
|
+
updateLocationHashForMobilePane(next);
|
|
2770
2807
|
globalThis.requestAnimationFrame(() => {
|
|
2771
2808
|
globalThis.requestAnimationFrame(() => {
|
|
2772
2809
|
if (next === "code") {
|
|
@@ -2793,49 +2830,64 @@ function wireDualMobilePaneFlip(shell, flipBtn, scrollRunners, flipScrollBtn) {
|
|
|
2793
2830
|
wireDualMobilePaneFlipScrollAffordance(flipBtn, flipScrollBtn, mq);
|
|
2794
2831
|
}
|
|
2795
2832
|
mq.addEventListener("change", applyForViewport);
|
|
2833
|
+
globalThis.addEventListener("hashchange", applyForViewport);
|
|
2796
2834
|
applyForViewport();
|
|
2797
2835
|
}
|
|
2798
2836
|
function wireStretchMobilePaneFlip(shell, codePane, flipBtn, flipScrollBtn, onAfterFlip) {
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
if (
|
|
2807
|
-
|
|
2808
|
-
|
|
2837
|
+
const stretchTable = codePane instanceof HTMLTableElement ? codePane : null;
|
|
2838
|
+
let anchorRow = null;
|
|
2839
|
+
let anchorTopBefore = 0;
|
|
2840
|
+
let rootTopBefore = 0;
|
|
2841
|
+
const captureAnchor = () => {
|
|
2842
|
+
const root = rootScrollingElement();
|
|
2843
|
+
rootTopBefore = root.scrollTop;
|
|
2844
|
+
if (stretchTable === null) {
|
|
2845
|
+
anchorRow = null;
|
|
2846
|
+
anchorTopBefore = 0;
|
|
2847
|
+
return;
|
|
2809
2848
|
}
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2849
|
+
const rows = stretchBlockRows(stretchTable);
|
|
2850
|
+
anchorRow = rows.find((row) => row.getBoundingClientRect().bottom > 0) ?? null;
|
|
2851
|
+
anchorTopBefore = anchorRow?.getBoundingClientRect().top ?? 0;
|
|
2852
|
+
};
|
|
2853
|
+
const restoreAnchor = () => {
|
|
2854
|
+
const root = rootScrollingElement();
|
|
2855
|
+
if (anchorRow !== null) {
|
|
2856
|
+
const delta = anchorRow.getBoundingClientRect().top - anchorTopBefore;
|
|
2857
|
+
if (Math.abs(delta) > 0.5) {
|
|
2858
|
+
const maxY = Math.max(0, root.scrollHeight - root.clientHeight);
|
|
2859
|
+
root.scrollTop = clamp(root.scrollTop + delta, 0, maxY);
|
|
2860
|
+
return;
|
|
2861
|
+
}
|
|
2813
2862
|
}
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2863
|
+
const maxY = Math.max(0, root.scrollHeight - root.clientHeight);
|
|
2864
|
+
root.scrollTop = clamp(rootTopBefore, 0, maxY);
|
|
2865
|
+
};
|
|
2866
|
+
const applyBuffersAndRestore = () => {
|
|
2867
|
+
if (stretchTable !== null)
|
|
2868
|
+
applyBlockStretchRowBuffers(stretchTable);
|
|
2869
|
+
restoreAnchor();
|
|
2870
|
+
};
|
|
2871
|
+
const runners = {
|
|
2872
|
+
syncFromCodeToDoc: () => { },
|
|
2873
|
+
syncFromDocToCode: () => { },
|
|
2874
|
+
prepareMobileFlipToCode: captureAnchor,
|
|
2875
|
+
prepareMobileFlipToDoc: captureAnchor,
|
|
2876
|
+
finishMobileFlipToCode: () => {
|
|
2877
|
+
applyBuffersAndRestore();
|
|
2878
|
+
onAfterFlip?.();
|
|
2879
|
+
},
|
|
2880
|
+
finishMobileFlipToDoc: () => {
|
|
2881
|
+
applyBuffersAndRestore();
|
|
2882
|
+
onAfterFlip?.();
|
|
2883
|
+
void runMermaidOnFreshDocNodes(shell).then(() => {
|
|
2826
2884
|
requestAnimationFrame(() => {
|
|
2827
|
-
|
|
2885
|
+
applyBuffersAndRestore();
|
|
2828
2886
|
});
|
|
2829
2887
|
});
|
|
2830
|
-
}
|
|
2888
|
+
},
|
|
2831
2889
|
};
|
|
2832
|
-
|
|
2833
|
-
if (flipScrollBtn) {
|
|
2834
|
-
flipScrollBtn.addEventListener("click", runFlip);
|
|
2835
|
-
wireDualMobilePaneFlipScrollAffordance(flipBtn, flipScrollBtn, mq);
|
|
2836
|
-
}
|
|
2837
|
-
mq.addEventListener("change", applyForViewport);
|
|
2838
|
-
applyForViewport();
|
|
2890
|
+
wireDualMobilePaneFlip(shell, flipBtn, runners, flipScrollBtn);
|
|
2839
2891
|
}
|
|
2840
2892
|
/** Multi-angle stretch swaps `#shell` innerHTML; disconnect the previous table observer so listeners do not accumulate. */
|
|
2841
2893
|
let stretchRowBufferSyncHandle = null;
|
|
@@ -3766,6 +3818,11 @@ function permalinkHashSuffixFromUi() {
|
|
|
3766
3818
|
pushUnique(`angle-${encodeURIComponent(id)}`);
|
|
3767
3819
|
}
|
|
3768
3820
|
}
|
|
3821
|
+
const shell = document.getElementById("shell");
|
|
3822
|
+
if (shell instanceof HTMLElement && shell.getAttribute("data-mobile-single-pane") === "true") {
|
|
3823
|
+
const pane = normalizedDualMobilePane(shell.getAttribute("data-dual-mobile-pane"));
|
|
3824
|
+
pushUnique(mobilePaneHashToken(pane));
|
|
3825
|
+
}
|
|
3769
3826
|
const activeAnchor = activeCommentrayHashTokenFromViewport();
|
|
3770
3827
|
if (activeAnchor)
|
|
3771
3828
|
pushUnique(activeAnchor);
|