[pull] develop from marktext:develop#116
Merged
Merged
Conversation
…shields.io badges) (#4857) * fix(muya): load extensionless remote images sent with a charset (#3837) checkImageContentType() gates extensionless remote images (shields.io badges, dynamic CDN images) on a HEAD request's Content-Type, but matched it with `/^image\/(?:jpeg|png|gif|svg\+xml|webp)$/` — an exact full-string match. shields.io serves `image/svg+xml;charset=utf-8`, whose `;charset` parameter fails the anchored regex, so the badge is treated as "not an image" and never rendered. Strip any Content-Type parameter before matching so the MIME type alone is tested. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(muya): load remote images when the content-type HEAD is CSP-blocked (#3837) The charset fix alone wasn't enough: for an extensionless remote image (shields.io badge) checkImageContentType does a HEAD fetch, but the renderer CSP has no connect-src and falls back to default-src 'self', so the cross-origin HEAD is refused and the fetch throws. It then returned false, so loadImage rejected the image as "not an image" and the badge never rendered — even though img-src is permissive enough to load it. Have checkImageContentType return null ("couldn't determine") on a blocked/ failed HEAD or a non-200/typeless response, and only reject in loadImage on a positive non-image type. A null now falls through to the actual <img> load, which img-src permits. Verified in a real Electron build: the shields.io badge renders (naturalWidth > 0). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(muya): skip the content-type HEAD for cross-origin images (#3837) The HEAD content-type probe can never work from the renderer for a cross-origin URL: CORS strips the response headers, and the app CSP (no connect-src) refuses the request outright — so it only ever fired a guaranteed-to-fail fetch that logged a CSP console error, then fell through to the <img> load anyway. Since the extensionless remote URLs this runs on are always cross-origin, the probe was effectively dead weight there. Skip the HEAD unless the URL is same-origin (the only case whose Content-Type the renderer can actually read). Cross-origin images load via the permissive img-src exactly as before, now without the wasted request or console noise; the probe still runs for same-origin URLs. Keeps everything in muya — no main-process/IPC dependency. Verified in a real Electron build: the shields.io badge renders with zero CSP console errors. 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): open the link when modifier-clicking a linked image (#3835) A linked image `[](href)` has two independent click listeners on the editor node: ImageSelection (which, on Ctrl/Cmd-click of an image, emits a 'image' format-click that pops the image viewer) and linkMouseEvents (which emits a 'link' format-click that opens the URL). Both fire on the same modifier-click, so the image viewer opened on top of the navigation and the link appeared not to work. Skip ImageSelection's image-preview emission when the image lives inside a link (`span.mu-link`) on a modifier-click, letting the link handler open the URL. Plain (non-linked) images still preview as before. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(muya): reuse shared LINK_SELECTOR for the linked-image guard (#3835) Follow-up cleanup: the linked-image preview guard hand-rolled `.closest('.mu-link')`, which only matches plain markdown links and misses reference links, autolinks, and raw-HTML anchors that can also wrap an image. Export linkMouseEvents' LINK_SELECTOR (the exact set the link handler treats as navigable) and reuse it, so the guard suppresses the image preview for every link variant the link handler will act on. Also only walk the DOM on a modifier-click. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… raw-HTML linked images (#4865) (#4866) * fix(muya): tokenize reference links whose text is an image (#4865) A full reference link whose text is an image — `[][ref]`, the standard README-badge pattern — fragmented into a bare image plus a separate empty reference link, so the image was never nested inside the link. The reference_link anchor group used `[^\]]+?`, which stops at the image's inner `]`. Mirror the inline `link` rule's nesting-capable anchor group so the image is captured as the link's child. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(muya): render image hover icons as spans so linked images survive inside anchors (#4865) An inline image's hover controls (success/fail/close icons) were `<a>` elements carrying no href. When an image sits inside a real anchor — a reference-linked image `[][ref]` (a.mu-reference-link) or a raw-HTML linked image `<a href><img></a>` (a.mu-raw-html) — the nested `<a>`-inside-`<a>` is invalid HTML, so the parser closes the outer anchor early and hoists the image out of the link. The image then renders outside the anchor: it is not recognised as a linked image, so Ctrl/Cmd-click pops the image preview instead of following the link. Render the icons as `<span>` (they are decorative controls, not links) and drop the `a` qualifier from their CSS selectors. The image now stays inside the anchor, so the #3835 modifier-click guard applies and the link is followed. The raw-HTML regression test runs under jsdom, not happy-dom: happy-dom's DOMPurify strips the `<a>` (rendering it as a span, masking the nesting), while jsdom keeps it, matching the real Electron app. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…3791) (#4860) The outline/TOC panel keyed el-tree nodes by the heading's `slug` — a per-render object id (getTOC's stableSlug, a WeakMap keyed by the live block object). Switching tabs calls Editor.setContent -> ScrollPage rebuilds every heading as a brand-new object, so each heading gets a fresh slug, the collapsedKeys lookup misses, and the outline re-expands everything on return. In-place edits (the #3028 case) kept working only because they mutate the existing block objects. Key the tree by the content-derived `githubSlug` instead (already computed by getTOC), which is stable across both content edits and document reloads/tab switches; `slug` is still carried for the click-to-scroll anchor. The keying logic is extracted into a pure `deriveKeyedToc` helper so it can be unit-tested, and listToTree now threads `githubSlug` through. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ke) (#4859) * fix(desktop): flush pending edits before saving so the last keystroke isn't lost (#3803) The engine commits edits to the store's currentFile.markdown on a deferred requestAnimationFrame (json-change). FILE_SAVE / FILE_SAVE_AS snapshotted currentFile.markdown and shipped it to the main process without flushing first, so a keystroke typed in the same frame as Cmd+S (or Save As) — a window that widens under main-thread load on large docs — was dropped from the written file, with no dirty indicator. Tab switching already guards against this by emitting 'flush-active-editor' (the #2938 fix), but the save paths did not. Emit 'flush-active-editor' at the start of FILE_SAVE and FILE_SAVE_AS; the editor flushes the queued op into currentFile synchronously before its markdown is read. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(desktop): extract flushActiveEditor() and cover all persist paths (#3803) Follow-up cleanup: the flush-before-read was a copy-pasted bus.emit at two call sites (and a third pre-existing copy in UPDATE_CURRENT_FILE). Extract a single flushActiveEditor() action and route all of them through it. Also apply it to MOVE_FILE_TO and RESPONSE_FOR_RENAME, which read currentFile.markdown and persist it via the exact same pattern as FILE_SAVE — so "move to" / renaming an untitled file no longer drops a same-frame keystroke either. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(desktop): assert the flushed markdown reaches the save payload (#3803 review) The prior spec only asserted flush-emit < IPC-send ordering, but the #3803 bug lives at the `const { …, markdown } = this.currentFile` read that sits between them — a flush moved after that read would still pass. Wire a real `flush-active-editor` listener that commits the pending keystroke (mirroring editor.vue) and assert the SENT PAYLOAD carries it, so a regression past the read boundary is caught. Also: cover RESPONSE_FOR_RENAME (both the untitled payload path and the existing-file rename-emit path), filter the exact IPC channel in the MOVE_FILE_TO case, and anchor ordering by event name instead of the fragile invocationCallOrder[0]. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- 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 : )