[pull] develop from marktext:develop#93
Merged
Merged
Conversation
…) (#4655) * fix(muya): ArrowUp at the start of the document moves the caret to offset 0 (#3193) Pressing ArrowUp on the first visual line of the first block (no previous block) called preventDefault/stopPropagation and returned without moving the caret, so the caret stayed put instead of jumping to the start of the line. When there is no previous block, ArrowUp now moves the caret to offset 0 of the current block (a boundary ArrowLeft still has nowhere to go and is left to do nothing). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(muya): don't re-set the selection on a no-op ArrowUp at offset 0 (#3193) When the caret is already at offset 0 of the first block, ArrowUp has nowhere to go, but the handler still called setCursor(0, 0, true) — which unconditionally re-sets the selection (TextSelection.setSelection always emits selection-change, with no equality check) and re-renders the block's innerHTML. Guard the re-set with `start.offset !== 0` so a no-op ArrowUp stays silent. preventDefault is still issued, so the native no-op scroll is suppressed as before. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nodes (#3315) (#4659) `Muya.destroy()` only hid currently-visible float tools; it never invoked each registered UI plugin's `destroy()`. So nodes appended to `document.body` in plugin constructors/init (every BaseFloat's floatBox, the ImageResizeBar `.mu-transformer` container) leaked permanently across destroy/rebuild — e.g. when toggling to browser/source mode. Iterate `_uiPlugins` in `destroy()` and call each plugin's `destroy()` (guarding plugins that don't define one). Also add a `destroy()` to `ImageResizeBar`, which appends its container at construction but had none. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…4656) On a cross-block selection, the clipboard keydown handler cuts (replaces) the selection for an editing keystroke, bailing out for modifier combos. The guard only excluded macOS `metaKey`, never `ctrlKey` — so on Windows/Linux, pressing Ctrl+C to copy fired the handler and deleted the selected text before the browser's copy event ran. Extract the modifier/key decision into a pure `shouldCrossBlockCut` helper and exclude `ctrlKey` as well (mirroring the metaKey guard). Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…uote (#3462) (#4661) `format()` dispatched to the cross-block path via `_selectionInSameBlock()`, which compares the selection endpoints at OUTMOST-block granularity. Two paragraphs nested in the same blockquote share an outmost block (the blockquote), so the check reported "same block" and fell through to the single-leaf path — which then early-returns because the anchor and focus leaves differ, applying no formatting at all. Dispatch inline formatting on LEAF equality instead via a new `_selectionInSameLeaf()` helper (mirroring `_selectionEndpoints` but at leaf granularity). The paragraph-menu path keeps its outmost-block check. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The Theme menu listed all 33 themes as a single flat native submenu, which on Windows expands to the full window height. Group them into nested "Light Themes" / "Dark Themes" submenus so the top-level Theme menu stays short (the alternative the issue suggests; CSS max-height can't constrain a native Electron menu). The same theme ids/labels/order are preserved — verified the new template produces the identical 33 (label, id) set — so theme selection, the radio checked state (recomputed on every menu rebuild via broadcast-preferences- changed), and getMenuItemById lookups (recursive) are unaffected. The repetitive per-theme blocks are replaced by two data tables + a small builder.
…ent corruption (#2938) (#4658) * fix(muya): drop the pending op batch on setContent to prevent cross-document corruption (#2938) `JSONState.setContent` replaced `_state` but left any deferred operation batch in `_operationCache` (with its scheduled requestAnimationFrame). Switching files within the same frame as a pending edit then flushed the outgoing document's op against the new document's state — corrupting it, or throwing and leaving `_isGoing` stuck so all further edits froze. Either way the switched-to file could no longer be saved correctly. Track the scheduled flush's rAF handle; on `setContent` cancel it, clear `_operationCache`, and reset `_isGoing` before swapping the state. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(muya): fold the _isGoing flush guard into _rafId (#2938) `_isGoing` (boolean "a flush is scheduled") and `_rafId` (the rAF handle) were always set and cleared together, so they tracked the same state redundantly. Drop `_isGoing` and use `_rafId !== null` as the batching guard directly. No behavior change — the existing setContent/op-batching tests stay green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(muya): add muya.flush() to apply queued edits synchronously (#2938) The op cache flushes on a requestAnimationFrame, so a same-frame document swap (a tab switch calls setContent right after the last keystroke) drops the pending edit. Add a public flush() that runs the queued batch now and emits json-change, so a caller can make the outgoing edit durable before swapping. Extracted the rAF body into _flushOperationCache, shared by the frame callback and flush(). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(desktop): flush the outgoing editor before a tab switch (#2938) On tab switch the store sets currentFile then synchronously reloads the engine via setContent, so the previous tab's last same-frame keystroke (still queued in the engine) was either lost or applied to the incoming document. Flush the engine while currentFile still points at the outgoing tab (via a new flush-active-editor bus event), so the edit is applied and persisted under the right tab before the swap. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
) (#4657) When a file's folder is moved/deleted while it is open, saving recreates the directory tree and writes the file (fs-extra `outputFile`), matching VS Code so an (auto)save never silently fails. This is intentional but was untested — add unit coverage and a comment documenting the rationale so it isn't mistaken for a bug and "fixed" by switching to a plain write. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…#4644) (#4660) Pressing Enter on the empty first paragraph of a loose list item (one that holds multiple paragraphs) moved every paragraph from the caret's index into a new sibling list item. When the caret was on the first paragraph (index 0), this emptied the original list item, leaving a `list-item` with zero children. A childless list item has no content descendant, so `previousContentInContext`/`nextContentInContext` return null when arrow navigation tries to cross it — Up arrow then stopped moving the caret up a line, the symptom reported in #4644. Split from the next paragraph when the caret is on the first one, mirroring the plain-paragraph "Enter at offset 0" behaviour, so the original list item keeps its empty first paragraph and stays valid. Adds a unit test for the engine invariant and an e2e regression test driving the exact reported keystroke sequence. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 : )