Skip to content

[pull] develop from marktext:develop#99

Merged
pull[bot] merged 7 commits into
code:developfrom
marktext:develop
Jun 25, 2026
Merged

[pull] develop from marktext:develop#99
pull[bot] merged 7 commits into
code:developfrom
marktext:develop

Conversation

@pull

@pull pull Bot commented Jun 25, 2026

Copy link
Copy Markdown

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

Renakoni and others added 7 commits June 25, 2026 19:25
…3937) (#4713)

The key bindings table is an Element Plus el-table, which colours its cells
with --el-text-color-regular. The app never themes that variable, so the list
rendered in Element Plus's default grey (#606266) on every theme, ignoring the
active theme's text colour. On dark themes the contrast dropped to ~2.3:1 —
well below the WCAG AA 4.5:1 minimum — making the bindings hard to read or
practically invisible, as reported.

Point the table cells at the theme's own --editorColor so the bindings inherit
the editor text colour and stay readable on every theme (light unchanged at
8.45:1, dark themes now 5.6-13.4:1).
* fix: wrap selected text when typing auto-pair characters

* fix: mark history boundary for selection auto-pair wrapping

* test: wait for selection before auto-pair e2e input

* fix: preserve selection after auto-pair wrapping
#4644) (#4715)

previousContentInContext / nextContentInContext returned null when the
adjacent sibling was an empty container with no content descendant — e.g. a
list item whose only paragraph was removed during editing, or an empty
`*  ` item parsed from markdown. That left ArrowUp/ArrowDown unable to cross
the empty item, so the caret got stuck and could only be moved by clicking.

Walk the previous/next siblings and skip empty containers, falling through to
the parent only when no sibling holds content. Add regression tests covering
ArrowUp and ArrowDown across an empty list item (they fail without the fix).
…#4686) (#4714)

* fix(muya): make the paragraph front-menu single-shot so it can't act on a stale block (#4686)

ParagraphFrontMenu stored the block it opened on in `_block`, hid itself on a deferred `setTimeout`, and never checked the block was still in the document before acting. Two real interactions broke it: opening the menu on a list and then using the app menu bar to unwrap it (the native menu never closes the float, so `_block` detaches), and a fast double-click running a second action before the deferred hide().

Either way the next action ran on a detached block, dereferencing a null `parent` (e.g. `_unwrapToParagraphs`, or Duplicate/New's `block.parent!.insertAfter`) and crashing with "Cannot read properties of null (reading 'insertAfter')".

`selectItem` now consumes `_block` synchronously and bails unless it is still attached, so a single menu open performs at most one action on a live block (covers turn-into, duplicate, new, delete).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(muya): make resetToParagraph a no-op on a detached block (#4686)

Defense in depth for the front-menu fix: `_unwrapToParagraphs` asserted `block.parent!`, so the public `resetToParagraph` crashed if ever handed a block already removed from the document. Replace the assertion with a real null guard so it is a safe no-op instead.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ply throws (#4716) (#4717)

`Editor.updateContents` dispatches an op to the authoritative json state
first, then rebuilds the live block tree incrementally via the pick/drop
walker. The walker is not atomic: `pick` removes the blocks an op deletes,
then `drop` re-creates the blocks it inserts. If any block throws while being
rebuilt (e.g. a KaTeX / diagram / code block whose `create` or render fails),
`drop` aborts after `pick` already emptied the tree — leaving the live
ScrollPage half-applied, often with NO children at all.

Because the json state was updated first, `getMarkdown()` still returned the
correct document, masking the desync. But the live tree was empty, so the next
click on the editor's blank area dereferenced `this.lastChild` (null) in
`ScrollPage._clickHandler` and crashed the renderer:

    TypeError: Cannot read properties of null (reading 'lastContentInDescendant')

An empty ScrollPage is never a valid state. Wrap the incremental apply in
try/catch and, on failure, rebuild the live tree wholesale from the
authoritative json state (the same safe path `rebuildContents`/`setContent`
use) so the document can never be left half-applied or empty.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
#3957) (#4718)

The main process set a freshly-created window's backgroundColor from a switch
that only covered six themes; every other theme — including dark ones like
dracula, nord, and tokyo-night — fell back to #ffffff. Because the window is
shown immediately, those themes flashed white on launch before the renderer
painted the real theme.

Move the lookup into common/theme as getThemeBackgroundColor, backed by a
per-theme map of every built-in theme's editor background (kept in sync with
each theme's --editorBgColor) plus a dark/light fallback for unknown themes.
BaseWindow._getPreferredBackgroundColor now delegates to it.

Adds a unit test asserting no dark theme resolves to white.
@pull pull Bot locked and limited conversation to collaborators Jun 25, 2026
@pull pull Bot added the ⤵️ pull label Jun 25, 2026
@pull
pull Bot merged commit b9722dc into code:develop Jun 25, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants