fix: find the width cap by measuring, not by class name

Measured chain from live preview showed the cap on .cm-content at 700px,
while .cm-sizer - the element closest() matched first - is already
uncapped at 1680px. The class-name shortcut therefore locked onto the
wrong element and returned before the fallback walk could find the real
one, so the cap survived and the container query correctly collapsed the
grid to one column.

widenHost now always measures computed max-width outward from the
dashboard's parent. The decision is extracted as firstCappedIndex and
tested against the real measured chains for both live preview and
reading view, so a class-name assumption cannot silently break it again.
Adds .cm-content to the CSS fallback.
This commit is contained in:
meels
2026-07-28 16:12:53 +02:00
parent c374099a12
commit 70b9e2a44f
3 changed files with 715 additions and 631 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -87,8 +87,8 @@
------------------------------------------------------------------ */ ------------------------------------------------------------------ */
.markdown-preview-sizer:has(.webinar-dash), .markdown-preview-sizer:has(.webinar-dash),
.markdown-preview-view.is-readable-line-width .markdown-preview-sizer:has(.webinar-dash), .markdown-preview-view.is-readable-line-width .markdown-preview-sizer:has(.webinar-dash),
.markdown-source-view.mod-cm6 .cm-sizer:has(.webinar-dash), .markdown-source-view.mod-cm6 .cm-content:has(.webinar-dash),
.markdown-source-view.mod-cm6.is-readable-line-width .cm-sizer:has(.webinar-dash) { .markdown-source-view.mod-cm6 .cm-sizer:has(.webinar-dash) {
max-width: none !important; max-width: none !important;
} }

View File

@@ -0,0 +1,56 @@
"use strict";
const test = require("node:test");
const assert = require("node:assert/strict");
const { firstCappedIndex } = require("../main.js").__test__;
test("firstCappedIndex finds the cap on the real measured live-preview chain", () => {
// Measured in Obsidian live preview via getComputedStyle, walking outward
// from .webinar-dash. The cap is on .cm-content at 700px; .cm-sizer - the
// element a class-name lookup finds first - is already uncapped at 1680px.
// Matching by class name selected .cm-sizer and stopped, leaving the real
// cap in place. This test pins the measurement so that cannot recur.
const chain = [
{ maxWidth: "none", isWorkspaceLeaf: false }, // block-language-webinar-dash
{ maxWidth: "none", isWorkspaceLeaf: false }, // cm-preview-code-block
{ maxWidth: "700px", isWorkspaceLeaf: false }, // cm-content <- the cap
{ maxWidth: "none", isWorkspaceLeaf: false }, // cm-contentContainer
{ maxWidth: "none", isWorkspaceLeaf: false }, // cm-sizer
{ maxWidth: "none", isWorkspaceLeaf: false }, // cm-scroller
];
assert.equal(firstCappedIndex(chain), 2);
});
test("firstCappedIndex finds the cap on a reading-view chain", () => {
const chain = [
{ maxWidth: "none", isWorkspaceLeaf: false }, // block-language-webinar-dash
{ maxWidth: "700px", isWorkspaceLeaf: false }, // markdown-preview-sizer
{ maxWidth: "none", isWorkspaceLeaf: false }, // markdown-preview-view
];
assert.equal(firstCappedIndex(chain), 1);
});
test("firstCappedIndex returns -1 when nothing above the dashboard is capped", () => {
const chain = [
{ maxWidth: "none", isWorkspaceLeaf: false },
{ maxWidth: "none", isWorkspaceLeaf: false },
];
assert.equal(firstCappedIndex(chain), -1);
});
test("firstCappedIndex stops at the workspace leaf rather than widening chrome", () => {
const chain = [
{ maxWidth: "none", isWorkspaceLeaf: false },
{ maxWidth: "none", isWorkspaceLeaf: true }, // workspace-leaf
{ maxWidth: "900px", isWorkspaceLeaf: false }, // must never be reached
];
assert.equal(firstCappedIndex(chain), -1);
});
test("firstCappedIndex takes the innermost cap when several ancestors are capped", () => {
const chain = [
{ maxWidth: "none", isWorkspaceLeaf: false },
{ maxWidth: "700px", isWorkspaceLeaf: false },
{ maxWidth: "1200px", isWorkspaceLeaf: false },
];
assert.equal(firstCappedIndex(chain), 1);
});