Skip to content

[pull] develop from marktext:develop#96

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

[pull] develop from marktext:develop#96
pull[bot] merged 6 commits into
code:developfrom
marktext:develop

Conversation

@pull

@pull pull Bot commented Jun 24, 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 : )

NSO73 and others added 6 commits June 24, 2026 19:37
)

Selecting a word and opening the find bar is meant to prefill the find input
with the selection. The prefill is driven reactively by `watch(searchMatches)`,
which mirrors the editor's current selection into the input. But opening the
bar steals focus from the editor, and the engine emits a spurious
selection-change for the reset selection. Because the watch is async, that
change coalesces with the intended one and can cancel it, leaving a stale value
in the input (the regression guard observes a single leading character, e.g.
"T").

Fix in two parts:
- Seed the input synchronously from the current selection when the bar opens
  (`prefillFromSelection`), so the prefill can't lose the race with the
  focus-steal selection-change.
- Once open, the bar owns the query: ignore editor selection-changes in the
  `searchMatches` watch while `showSearch` is true, so the focus-steal change
  can't clobber the prefilled/typed value.

Covered by test/e2e/search-prefill-from-selection.spec.ts (the race reproduces
under the Linux/xvfb CI environment).
* fix(muya): preserve nested-list indentation in RTL mode (#4673)

List containers used physical `padding-left` and the task-list checkbox
used physical `left`, neither of which follows `dir="rtl"`. In RTL the
padding stayed on the left while markers flipped to the right, so every
nesting level collapsed onto the same right-hand axis.

Switch to the logical `padding-inline-start` / `inset-inline-start`
equivalents. These are identical to the physical properties under LTR
(no visual change) and mirror to the right under RTL, restoring the
visual hierarchy of nested ordered, bullet, and task lists.

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

* fix(desktop): stop down-compiling CSS logical properties to LTR physical

`postcssPresetEnv({ stage: 0 })` enabled the `logical-properties-and-values`
transform (postcss-logical), which rewrites `padding-inline-start` /
`inset-inline-start` to hard-coded LTR `padding-left` / `left` at build
time. That silently defeated the list-indentation logical properties under
`dir="rtl"` — the served CSS always resolved to the left regardless of text
direction.

Electron ships Chromium, which supports logical properties natively, so the
down-compile is unnecessary. Disable just that feature; everything else in
preset-env is unchanged. Verified in the Electron 42 Chromium: nested lists
now resolve `padding-right: 30px` per level under RTL, stepping the hierarchy
in from the right edge (#4673).

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

---------

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

The math renderers imported the chemistry extension via
`katex/dist/contrib/mhchem.min.js`. That deep path falls through the
katex exports map to the UMD bundle, whose internal `require("katex")`
resolves to the CommonJS build (`dist/katex.js`) — a different module
instance from the ESM `import katex from 'katex'` (`dist/katex.mjs`) the
renderers actually call. mhchem patched the CJS instance while rendering
used the ESM one, so `\ce{...}` stayed an undefined control sequence and
fell back to "Invalid Mathematical Formula".

Import the ESM build `katex/dist/contrib/mhchem.mjs` instead, which
extends the same deduped instance. Also add the import to the HTML-export
render path in marked/extensions/math.ts, which was missing it entirely.

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

A well-formed `[text](url)` (or reference) link was dropped whenever its
destination URL also matched the GFM extended (bare-URL) autolink rule and
was immediately followed by more content — e.g. a CJK comma `[t](https://x)、`,
trailing text `[t](https://x)foo`, or simply the first of two links on one
line. The rendered output showed the raw markdown with the link styling
bleeding into the following text.

Root cause: `tryLink`/`tryReferenceLink` validated the tentative link with
`lowerPriority(..., validateRules)`, the full inline-rule set. Two of those
rules can match a span that runs past the link and falsely veto it:

  - `auto_link_extension` matches the bare destination URL plus any trailing
    punctuation/text, so it extends beyond the link's closing paren.
  - `link`/`image` themselves use a greedy `.*` destination and (before
    `correctUrl` runs) match across to a later link on the same line.

Per CommonMark §6.6 only code spans, raw HTML tags and `<...>` autolinks bind
more tightly than a link, so only those may defer it (the documented CM 0.29
examples 520/521). Introduce `linkValidateRules` containing exactly those three
and use it for both link validators. Extended autolinks and angle autolinks in
plain text, and the code-span/HTML-tag precedence cases, all still behave.

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

* feat(menu): add AppMenu.updateKeybindings to rebuild menus from current bindings

Rebuild every window menu (editor + macOS settings) so accelerators are
re-read from the live keybinding map, re-applying the active window's menu.
Editor menus preserve their runtime toggle state. This is the capability the
keybinding-save flow needs to refresh the menu bar without a restart (#3998).

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

* fix(keybinding): sync menu bar and command palette on keybinding save

After persisting user keybindings, rebuild the application menu via
AppMenu.updateKeybindings() and push the refreshed accelerator map to editor
windows so the command palette updates too. Previously the new bindings only
took effect after an app restart, so the menu bar and command palette kept
showing the old shortcuts (#3998).

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

---------

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

* fix(muya): guard detached block in code language selector (#4654)

Selecting a language from the code-block language picker crashed the
renderer when the picker's target block had been detached from the
document while the picker stayed open (e.g. the code block was converted
back to a paragraph via Backspace at offset 0 of the code body, orphaning
its language-input child).

`selectItem`'s `block.text = name` runs the Content text setter, which
re-computes an OT path for the edit operation. For a language-input that
path walks up to its code block, whose `path` getter dereferences its own
(now null) parent — throwing `Cannot destructure property 'path' of
'this.parent'`. The retired muyajs engine hit the same class at
`ContentState.updateCodeLanguage` (`reading 'functionType'` of null).

Bail out of `selectItem` when `block.outMostBlock` is null — the block
(or any ancestor) is no longer connected to the document root — before
mutating its text/lang. `outMostBlock` walks the full parent chain, so it
catches the detached-grandparent case a shallow `block.parent` check misses.

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

* test(muya-e2e): cover #4654 language selection on a detached code block

Drives the real CodeBlockLanguageSelector float in Chromium: opens the
picker on a code block nested in a list, detaches the block, then clicks a
language item and asserts no uncaught renderer pageerror. Fails on the
pre-fix engine with `Cannot destructure property 'path' of 'this.parent'`.

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

* feat(muya): auto-hide code language picker when caret leaves its block

The language picker only hid on a non-matching query or a document click,
so moving the caret out of the language input (e.g. Left/Right arrow) left
it open over a stale target. Subscribe to `selection-change` and hide the
picker when the caret's anchorBlock is no longer its target block — the
same self-perceiving pattern InlineFormatToolbar uses. This also closes the
window that let the target block be detached from under the picker (#4654);
the selectItem outMostBlock guard remains as defense in depth.

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

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@pull pull Bot locked and limited conversation to collaborators Jun 24, 2026
@pull pull Bot added the ⤵️ pull label Jun 24, 2026
@pull
pull Bot merged commit 09c4046 into code:develop Jun 24, 2026
10 of 14 checks passed
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.

2 participants