Skip to content

Safari: striking a word also strikes the word before it #613

Description

@maboa

Striking a word in Safari also strikes the word before it. Chrome is unaffected, and a double-click selection is unaffected in both — which is what kept it hidden.

Reproduced

Dragging over the third word of alpha bravo charlie delta and pressing the strikethrough button:

double-click drag from first letter drag right-to-left drag two words
WebKit ok bravo+charlie bravo+charlie bravo+charlie+delta
Chromium ok ok ok ok

That matches the report exactly: every word regardless of punctuation, either drag direction, and multi-word selections picking up one extra neighbour.

Cause

applyStrikeThroughToSelection collects spans with range.intersectsNode(span), which is true for a span the range merely touches.

The two engines anchor a drag differently when it starts on a word's first letter:

WebKit    selected "charlie"  anchored in text("bravo ")@6   <- END of the PREVIOUS span
Chromium  selected "charlie"  anchored in text("charlie ")@0

In WebKit the previous span contains the range's start boundary, so intersectsNode reports it even though the selection contains none of its characters.

The existing leading-space trim cannot catch this:

let selectedText = range.toString();
while (selectedText.startsWith(' ') && startIndex < endIndex) { startIndex++; ... }

The selected string is "charlie" with no leading space — the space sits before the anchor, inside the previous span — so the loop never runs. The trim handles a selection that drags into the previous word's trailing space, which is a different case and still works.

Fix

Require a span to actually contribute text: clamp the selection to the span and ask whether any non-whitespace remains. It uses only like-for-like boundary comparisons (START_TO_START, END_TO_END), which are unambiguous, and falls back to the old inclusive behaviour if the boundaries are ever unexpected.

Verified as a matrix in both engines: after the fix all eight combinations are correct, and Chromium is unchanged in all four — a WebKit-specific anchoring difference should not alter Blink's behaviour.

Not a recent regression, as far as I can tell

editor-audio-cut.js has not changed since v1.3.12, and this depends on WebKit's anchoring rather than anything recent. It may have been present since strikethrough landed and simply never noticed, since Chrome is unaffected and double-click hides it.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions