Skip to content

v2.3.5

Choose a tag to compare

@Samyssmile Samyssmile released this 16 Aug 17:49
· 6 commits to main since this release

Breaking Changes

  • Theme foreground token split (#217). Active and selected states no longer consume
    --notectl-primary-fg; they now use the new --notectl-accent-fg token. CSS integrations
    that override --notectl-primary-fg for active toolbar buttons, dropdown or picker items,
    or selection outlines must set --notectl-accent-fg instead. --notectl-primary-fg now
    applies only to text on solid primary backgrounds. Existing Theme object literals remain
    source-compatible because accentForeground is optional, but the changed CSS custom-property
    fallback is a behavioral breaking change.

Fixed

  • Pressing below the content inserted a paragraph on mousedown (#219). The
    click-below-content handler in EditorViewEvents ran on mousedown, called
    preventDefault(), and never checked event.button. That made it impossible to start a
    drag-selection from the empty area below the last block (noticeable in full-height
    editors), and a middle- or right-button press appended a paragraph instead of leaving
    autoscroll or the context menu alone. The handler now only records an unmodified
    primary-button press below the last block, without preventing the default, and completes
    the append on mouseup when the pointer stayed within a 4px drag threshold. Drags,
    shift-extensions, modified clicks, and non-primary buttons fall through to native
    behavior; a trailing empty paragraph is still reused instead of stacking new ones.

  • Accepting a native spellcheck suggestion did nothing (#218). InputHandler cancels
    every handled beforeinput event and re-applies the change as a transaction, but the
    insertReplacementText branch only read event.data. On a contenteditable host,
    Chromium and WebKit deliver the replacement string on the event's dataTransfer
    (text/plain) with data === null, so picking a suggestion from the browser's context
    menu (or a macOS autocorrect) inserted nothing while the native replacement was already
    prevented. The handler now reads data with a dataTransfer fallback and applies the
    correction to the exact word range the browser reports via getTargetRanges(). The
    static range is mapped to a model selection by the new view-layer domRangeToState
    (wired through EditorView.resolveDOMRange into the input layer), so the correction
    lands on the right word even when the DOM selection stays collapsed (Safari autocorrect,
    Firefox context menu) and remains undoable as a regular input transaction. Three guards
    harden the new branch: a replacement arriving during an active IME composition is
    swallowed instead of being applied against uncommitted composition text; a reported word
    range that cannot be mapped degrades to a no-op at a collapsed caret instead of
    duplicating the correction next to the typo; and pending caret mark toggles (e.g. Ctrl+B
    pressed before accepting the suggestion) no longer bleed into the corrected word when the
    browser-reported range replaces the selection.

  • Dark preset rendered solid-primary button labels invisible (#217). The dark theme
    shipped the same value (#89b4fa) for primary and primaryForeground, so every control
    that pairs background: var(--notectl-primary) with color: var(--notectl-primary-fg)
    (the formula editor's primary button, the video popup's Embed and Submit buttons, the
    table size editor's Apply button) drew its label in its own background color, a 1:1
    contrast ratio. Root cause: --notectl-primary-fg was overloaded with two conflicting
    roles, text on a solid primary background versus primary-tinted text on neutral
    backgrounds (active toolbar buttons, dropdown and picker active items, selection
    outlines). The token is now split. A new accentForeground primitive
    (--notectl-accent-fg) carries the accent role with the exact values those surfaces used
    before (light #1a5fa0, dark #89b4fa, so they do not change visually), while
    primaryForeground keeps its documented "text on primary background" meaning with
    WCAG-AA-readable values (light #1a1a1a, 5.2:1 on #4a90d9; dark #1e1e2e, 7.8:1 on
    #89b4fa). The theme engine emits --notectl-accent-fg: var(--notectl-primary-fg) for
    themes compiled before the split, preserving their rendering. ThemePrimitives gains an
    optional accentForeground field, so existing full Theme object literals remain
    source-compatible; themes created via createTheme() inherit it from their base
    automatically; createTheme() additionally derives the omitted accentForeground from
    an overridden primaryForeground, so themes derived from a preset before the split keep
    their accent surfaces on the chosen color. The shipped custom-elements manifest documents
    the new --notectl-accent-fg custom property.

  • Pasting text from Word on macOS inserted a screenshot instead of the text (#216).
    Word and Excel on macOS put a bitmap rendition of the copied content on the clipboard
    alongside the HTML flavor, and Chromium exposes that bitmap as a file item. The paste
    pipeline dispatched file items to the registered file handlers before considering the
    HTML, so the image plugin claimed the paste and inserted a picture of the copied text.
    Clipboard HTML that carries real content now takes precedence over accompanying image
    file items. Markup that is nothing but an image representation keeps routing to the file
    handlers, so copied web images still paste through the blob-URL and upload-service path;
    non-image files also retain their registered handler precedence. Precedence is an
    ordering, not a verdict: when the preferred HTML turns out to parse to nothing (design
    tools ship metadata-only markup next to a bitmap), the skipped image files are
    dispatched after all, so such pastes insert the image instead of silently discarding
    the clipboard; if no deferred file handler claims them, the captured plain-text flavor
    remains the final fallback. HTML counts as parsing to nothing when it materializes only
    empty paragraphs (in any number) or text made of zero-width characters; a <br> is a
    content signal, so blank-line-only markup still pastes as blank lines. Contentless HTML
    no longer dispatches an empty paste transaction, so a range selection is not consumed
    before the deferred files run. Embedded rich clipboard metadata is likewise validated
    before replacing a selected range, so an invalid rich flavor falls through without a
    delete-only transaction. Markdown that converts to contentless HTML falls back to a
    plain-text paste of the captured text instead of being silently dropped.
    Known trade-off: a Word copy containing text plus an embedded picture pastes as the
    text without the picture (the picture's file:/// source is unreachable from the
    clipboard HTML); previously such copies pasted as a single bitmap of the whole
    selection.