[webkit-changes] [WebKit/WebKit] e59afa: [Visual Bidi Selection] Set selection to visually-...
Wenson Hsieh
noreply at github.com
Sat Nov 23 17:46:48 PST 2024
Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: e59afa8f7cc66431f54539e0607a1f2948c8fb89
https://github.com/WebKit/WebKit/commit/e59afa8f7cc66431f54539e0607a1f2948c8fb89
Author: Wenson Hsieh <wenson_hsieh at apple.com>
Date: 2024-11-23 (Sat, 23 Nov 2024)
Changed paths:
M LayoutTests/editing/selection/ios/bidi-visually-contiguous-selection-expected.txt
M LayoutTests/editing/selection/ios/bidi-visually-contiguous-selection.html
M Source/WebCore/editing/Editing.cpp
M Source/WebCore/editing/Editing.h
M Source/WebCore/editing/Editor.h
M Source/WebCore/editing/FrameSelection.h
M Source/WebCore/editing/RenderedPosition.cpp
M Source/WebCore/editing/RenderedPosition.h
M Source/WebCore/editing/ios/EditorIOS.mm
M Source/WebCore/page/EditorClient.h
M Source/WebCore/platform/ios/SelectionGeometry.cpp
M Source/WebCore/platform/ios/SelectionGeometry.h
M Source/WebCore/rendering/RenderObject.cpp
M Source/WebKit/Shared/WebCoreArgumentCoders.serialization.in
M Source/WebKit/UIProcess/Cocoa/WKTextSelectionRect.mm
M Source/WebKit/WebProcess/WebCoreSupport/WebEditorClient.h
M Source/WebKit/WebProcess/WebCoreSupport/ios/WebEditorClientIOS.mm
M Source/WebKit/WebProcess/WebPage/WebPage.h
M Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm
Log Message:
-----------
[Visual Bidi Selection] Set selection to visually- and logically-contiguous boundaries when ending range adjustment
https://bugs.webkit.org/show_bug.cgi?id=283515
rdar://140378287
Reviewed by Ryosuke Niwa and Abrar Rahman Protyasha.
Work towards visual bidi selection support, by limiting visually contiguous bidi selection behavior
to only when the user is selecting text with selection handles on iOS (i.e. range adjustment). When
range adjustment ends, we then snap the selection endpoints to the nearest bidi text run boundaries
that ensure both logical and visual contiguity. See below for more details.
* LayoutTests/editing/selection/ios/bidi-visually-contiguous-selection-expected.txt:
* LayoutTests/editing/selection/ios/bidi-visually-contiguous-selection.html:
Augment an existing layout test to exercise the selection snapping behavior, by verifying that the
final selection is snapped to the start of the Arabic text within the (otherwise English) paragraph.
* Source/WebCore/editing/Editing.cpp:
(WebCore::visualDistanceOnSameLine):
Add a helper function to compute the number of characters (visually) between two `RenderedPosition`s
on the same line box.
(WebCore::visuallyClosestBidiBoundary):
Add a helper function to return the (visually) closest bidi boundary point around a given
`RenderedPosition`, at the given bidi level.
(WebCore::adjustToVisuallyContiguousRange):
Implement the core of the bidi selection snapping heuristic. This new editing helper function,
`adjustToVisuallyContiguousRange`, takes a `SimpleRange` and returns another `SimpleRange` that is
either expanded or contracted to maintain both visual and logical contiguity for bidi text.
This algorithm generally works by determining whether or not the start or end positions (separately)
need to be adjusted to the nearest bidi boundary in order to maintain visual and logical contiguity.
To achieve this, we first examine the line boxes in between the start and end positions for a
single-line selection, or alternately, between the 'selection start and logical end on the first
line' and 'selection end and logical start on the last line' for a multi-line selection. During this
traversal, we keep track of the minimum observed bidi level for any line box we traverse over — if
a selection endpoint has a bidi level exceeding this minimum bidi level, then it'll result in a
visual discontiguity.
Consider, for example, the case of selection endpoints within two nested bidi text runs with the
same bidi level (the selection starts in `bbbbb` and ends in `ddddd`). The entire text in logical
order is `aaaaa bbbbb ccccc ddddd`:
DIRECTION ltr rtl ltr rtl
----> <---- ----> <----
LEVEL 0 1 2 1
TEXT aaaaa ddddd ccccc bbbbb
^ ^
SELECTION End Start
Because the bidi level in between the start and end only *increases*, the selection is already
visually contiguous, so no endpoint adjustment is needed despite the fact that the selection spans
a combination of RTL and LTR text. This is because any bidi text that starts within the selected
range also ends in the same selected range. However, consider this other, vaguely similar-looking
scenario:
DIRECTION ltr rtl ltr rtl
----> <---- ----> <----
LEVEL 0 1 0 1
TEXT aaaaa bbbbb ccccc ddddd
^ ^
SELECTION Start End
Because the selection now encompasses a piece of text with a *lower* bidi level, both endpoints must
be adjusted to their respective boundaries in order to maintain both visual and logical contiguity;
the start must either move to the end of `aaaaa` or the beginning of `ccccc`, and the end must move
to the end of `ccccc` or the end of `ddddd`. This is because this second selected range contains a
run of text that logically continues before the start or after the end (in this example, before the
start).
For each selection endpoint that needs to be adjusted in order to land on a visually contiguous bidi
boundary, we then use the helper methods in `RenderedPosition` to identify the nearest 2 bidi
boundary points on the same line around the endpoint, and select the one that results in the least
amount of (visual) adjustment.
* Source/WebCore/editing/Editing.h:
* Source/WebCore/editing/Editor.h:
* Source/WebCore/editing/FrameSelection.h:
Drive-by fix: delete this unused method declaration.
* Source/WebCore/editing/RenderedPosition.cpp:
(WebCore::RenderedPosition::leftBoundaryOfBidiRun const):
(WebCore::RenderedPosition::rightBoundaryOfBidiRun const):
(WebCore::RenderedPosition::leftBoundaryOfBidiRun): Deleted.
(WebCore::RenderedPosition::rightBoundaryOfBidiRun): Deleted.
* Source/WebCore/editing/RenderedPosition.h:
(WebCore::RenderedPosition::box const):
(WebCore::RenderedPosition::offset const):
Expose a couple of new getters on `RenderedPosition`, for use in the new helper function in
`Editing.cpp`.
* Source/WebCore/editing/ios/EditorIOS.mm:
(WebCore::Editor::shouldDrawVisuallyContiguousBidiSelection const):
* Source/WebCore/page/EditorClient.h:
(WebCore::EditorClient::shouldDrawVisuallyContiguousBidiSelection const):
* Source/WebCore/platform/ios/SelectionGeometry.cpp:
(WebCore::SelectionGeometry::SelectionGeometry):
(WebCore::operator<<):
* Source/WebCore/platform/ios/SelectionGeometry.h:
(WebCore::SelectionGeometry::behavior const):
(WebCore::SelectionGeometry::setBehavior):
(WebCore::SelectionGeometry::mayAppearLogicallyDiscontiguous const): Deleted.
(WebCore::SelectionGeometry::setMayAppearLogicallyDiscontiguous): Deleted.
Remove this incorrect logic; see below for more details.
* Source/WebCore/rendering/RenderObject.cpp:
(WebCore::makeBidiSelectionVisuallyContiguousIfNeeded):
* Source/WebKit/Shared/WebCoreArgumentCoders.serialization.in:
* Source/WebKit/UIProcess/Cocoa/WKTextSelectionRect.mm:
(-[WKTextSelectionRect writingDirection]):
Revert this hack to force LTR selection behavior when visually contiguous bidi selection is enabled.
This is incorrect because it doesn't take line direction into account in RTL paragraphs — in a
future change, I'll fix this properly by correctly setting the text direction of coalesced selection
geometries, based on the primary direction on each line.
* Source/WebKit/WebProcess/WebCoreSupport/WebEditorClient.h:
* Source/WebKit/WebProcess/WebCoreSupport/ios/WebEditorClientIOS.mm:
(WebKit::WebEditorClient::shouldDrawVisuallyContiguousBidiSelection const):
Add an editor client hook to determine whether or not we should draw visually contiguous bidi
selections; we currently only do this when the user is adjusting selection handles on iOS, but in a
future patch I'll update this to include more text interactions, such as tap-and-half, loupe, and
selecting with a mouse cursor using trackpad.
* Source/WebKit/WebProcess/WebPage/WebPage.h:
* Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::setShouldDrawVisuallyContiguousBidiSelection):
(WebKit::WebPage::updateSelectionWithTouches):
Canonical link: https://commits.webkit.org/287021@main
To unsubscribe from these emails, change your notification settings at https://github.com/WebKit/WebKit/settings/notifications
More information about the webkit-changes
mailing list