Skip to content

Commit e10123b

Browse files
committed
fix(mdviewer): scroll restore, format bar in code blocks, test stability
- Fix scroll position not restored after reload: send MDVIEWR_SOURCE_LINES only after edit-mode content changes, not during initial load/reload where it would cause reflows that reset scroll position - Force light theme via no-op handleSetTheme (HTML default is light) - Hide format bar when selection is inside code blocks - Add beforeEach cleanup in Document Cache test suite to prevent state leakage between scroll position tests
1 parent a901cd8 commit e10123b

4 files changed

Lines changed: 20 additions & 22 deletions

File tree

src-mdviewer/src/bridge.js

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -800,15 +800,11 @@ function handleReloadFile(data) {
800800

801801
// --- Theme, edit mode, locale ---
802802

803-
function handleSetTheme(data) {
803+
function handleSetTheme(_data) {
804804
// Force light theme for a paper-like appearance regardless of editor theme.
805805
// The theme infrastructure is preserved for future use.
806-
const appliedTheme = "light";
807-
// Skip if already applied to avoid reflows that can reset scroll position
808-
if (document.documentElement.getAttribute("data-theme") === appliedTheme) return;
809-
document.documentElement.setAttribute("data-theme", appliedTheme);
810-
document.documentElement.style.colorScheme = "light";
811-
setState({ theme: appliedTheme });
806+
// Theme is set in index.html (data-theme="light") so no action needed here.
807+
// Avoid setting attributes/styles to prevent reflows that reset scroll position.
812808
}
813809

814810
function handleSetEditMode(data) {

src-mdviewer/src/components/format-bar.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,13 @@ function updatePosition() {
224224
hide();
225225
return;
226226
}
227+
// Skip if selection is inside a code block — formatting doesn't apply
228+
const anchorEl = sel.anchorNode.nodeType === Node.ELEMENT_NODE
229+
? sel.anchorNode : sel.anchorNode.parentElement;
230+
if (anchorEl && anchorEl.closest("pre")) {
231+
hide();
232+
return;
233+
}
227234
// Require some meaningful selection length
228235
const text = sel.toString();
229236
if (text.length < 2) {

src/extensionsIntegrated/Phoenix-live-preview/MarkdownSync.js

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -358,17 +358,12 @@ define(function (require, exports, module) {
358358
return;
359359
}
360360

361-
const mdText = _doc.getText();
362361
iframeWindow.postMessage({
363362
type: "MDVIEWR_SWITCH_FILE",
364-
markdown: mdText,
363+
markdown: _doc.getText(),
365364
baseURL: _baseURL,
366365
filePath: _doc.file.fullPath
367366
}, "*");
368-
iframeWindow.postMessage({
369-
type: "MDVIEWR_SOURCE_LINES",
370-
markdown: mdText
371-
}, "*");
372367
}
373368

374369
function _sendContent() {
@@ -380,19 +375,12 @@ define(function (require, exports, module) {
380375
return;
381376
}
382377

383-
const mdText = _doc.getText();
384378
iframeWindow.postMessage({
385379
type: "MDVIEWR_SET_CONTENT",
386-
markdown: mdText,
380+
markdown: _doc.getText(),
387381
baseURL: _baseURL,
388382
filePath: _doc.file.fullPath
389383
}, "*");
390-
// Send source line mapping so the iframe can annotate sub-element
391-
// lines (e.g. <br> within paragraphs) on first load.
392-
iframeWindow.postMessage({
393-
type: "MDVIEWR_SOURCE_LINES",
394-
markdown: mdText
395-
}, "*");
396384
}
397385

398386
function _sendUpdate(changeOrigin) {

test/spec/md-editor-integ-test.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
*
1919
*/
2020

21-
/*global describe, beforeAll, afterAll, awaitsFor, it, awaitsForDone, expect, awaits*/
21+
/*global describe, beforeAll, beforeEach, afterAll, awaitsFor, it, awaitsForDone, expect, awaits*/
2222

2323
define(function (require, exports, module) {
2424

@@ -629,6 +629,13 @@ define(function (require, exports, module) {
629629
}
630630
}, 30000);
631631

632+
beforeEach(async function () {
633+
// Reset scroll and close files between tests to prevent state leakage
634+
_setViewerScrollTop(0);
635+
await awaitsForDone(CommandManager.execute(Commands.FILE_CLOSE_ALL, { _forceClose: true }),
636+
"close all between cache tests");
637+
}, 10000);
638+
632639
it("should switch between MD files with viewer showing correct content", async function () {
633640
await _openMdFileAndWaitForPreview("doc1.md");
634641
await awaitsFor(() => _getViewerH1Text().includes("Document One"),

0 commit comments

Comments
 (0)