Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: e59afa8f7cc66431f54539e0607a1f2948c8fb89
https://github.com/WebKit/WebKit/commit/e59afa8f7cc66431f54539e0607a1f2948c8fb89
Author: Wenson Hsieh <[email protected]>
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
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes