Skip to content

Commit 3acff53

Browse files
[WK2] Add support for keeping the selection in a focused editable element when dragging begins
https://bugs.webkit.org/show_bug.cgi?id=171585 <rdar://problem/31544320> Reviewed by Beth Dakin and Zalan Bujtas. Source/WebCore: Covered by 4 API tests. * dom/DocumentMarker.h: Introduces the DraggedContent DocumentMarker type, which applies to the Range in the DOM that is being used as a drag source. Also adds DraggedContentData, which contains nodes found by the TextIterator in the process of finding Ranges to mark. (WebCore::DocumentMarker::AllMarkers::AllMarkers): * dom/DocumentMarkerController.cpp: (WebCore::DocumentMarkerController::addDraggedContentMarker): (WebCore::shouldInsertAsSeparateMarker): (WebCore::DocumentMarkerController::addMarker): When adding DocumentMarkers of type DraggedContent, keep adjacent RenderReplaced elements separate, rather than merging them into existing RenderedDocumentMarkers. This is because the data for each of these (i.e. the target node) needs to be preserved. (WebCore::DocumentMarkerController::markersFor): Bail and return an empty list if the map of document markers cannot possibly contain a dragged content marker. * dom/DocumentMarkerController.h: * page/DragController.h: * page/DragState.h: Add draggedContentRange to DragState. This tracks the Range that is being dragged; it is created when the drag session has begun, and ends when drag session finishes (either via WebPage::dragEnded or WebPage::dragCancelled). * page/EventHandler.cpp: (WebCore::repaintContentsOfRange): (WebCore::EventHandler::dragCancelled): Called when a drag is cancelled in the UI process without a session ever getting a chance to begin. We use this as a hook to remove all DraggedContent document markers from the document of the dragged content range. (WebCore::EventHandler::didStartDrag): Called when a drag session has begun in the UI process. We use this as a hook to set up document markers for the Range of content being dragged. (WebCore::EventHandler::dragSourceEndedAt): Called when a drag session ends. We use this as a hook to remove all DraggedContent document markers from the document of the dragged content range. (WebCore::EventHandler::draggedElement): * page/EventHandler.h: * page/FocusController.cpp: (WebCore::shouldClearSelectionWhenChangingFocusedElement): Prevent the selection from clearing when the previously focused element is editable and also contains the drag source element. Ideally, we should experiment with clearing out the selection whenever the element is blurred (and not have additional restrictions on editability and containing the drag source), but this change is much riskier. (WebCore::FocusController::setFocusedElement): * rendering/InlineTextBox.cpp: (WebCore::InlineTextBox::paint): Use RenderText::draggedContentStartEnd to find the range of text (if any) that is dragged content, and paint these ranges of text at a lower alpha using TextPainter::paintTextInRange. * rendering/RenderReplaced.cpp: (WebCore::draggedContentContainsReplacedElement): Determines whether or not the element being rendered is contained within a dragged content range. Assuming that the DraggedContent type flag is set in DocumentMarkerController, we first look to see whether or not the container node is in the document marker map. If so, instead of consulting node offset ranges (since this is, in the worst-case, linear in the number of sibling nodes per RenderReplaced) we simply check the DraggedContentData to see if the current element being rendered matches one of the target nodes. (WebCore::RenderReplaced::paint): If the element rendered by this RenderReplaced is dragged content, then render it at a low alpha. * rendering/RenderText.cpp: (WebCore::RenderText::draggedContentRangesBetweenOffsets): Determines what range of text, if any, contains dragged content by consulting the Document's DocumentMarkers. * rendering/RenderText.h: * rendering/TextPainter.cpp: (WebCore::TextPainter::paintTextInRange): Teach TextPainter to only paint a given range in a TextRun. * rendering/TextPainter.h: Add TextPainter support for specifying special text offset ranges when rendering a TextRun, such that each special range in text is rendered after applying some modification to the GraphicsContext. Source/WebKit2: Minor adjustments and refactoring in WebKit2. See WebCore ChangeLog for more details. * UIProcess/WebPageProxy.cpp: (WebKit::WebPageProxy::startDrag): (WebKit::WebPageProxy::didStartDrag): Factor out code in WebPageProxy that sends a WebPage::DidStartDrag message to the web process into a separate helper, and tweak the places where we directly send this IPC message to the web process to instead call this helper. * UIProcess/WebPageProxy.h: * UIProcess/mac/WebPageProxyMac.mm: (WebKit::WebPageProxy::setDragImage): * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::didStartDrag): (WebKit::WebPage::dragCancelled): Clear out state in the web process and call out to the EventHandler to handle drag cancellation and the drag start response from the UI process. * WebProcess/WebPage/WebPage.h: (WebKit::WebPage::didStartDrag): Deleted. (WebKit::WebPage::dragCancelled): Deleted. Tools: Adds 1 new unit test and tweaks existing tests to check that when first responder status is lost after beginning a drag while editing, content is still moved (and not copied) when performing data interaction on a different element. ContentEditableMoveParagraphs checks that content can be shifted within a single element via a move operation rather than a copy. See WebCore ChangeLog for more details. Tests: DataInteractionSimulator.ContentEditableToContentEditable DataInteractionSimulator.ContentEditableToTextarea DataInteractionSimulator.ContentEditableMoveParagraphs DataInteractionSimulator.TextAreaToInput * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: * TestWebKitAPI/Tests/WebKit2Cocoa/two-paragraph-contenteditable.html: Added. * TestWebKitAPI/Tests/ios/DataInteractionTests.mm: (TestWebKitAPI::TEST): * TestWebKitAPI/ios/DataInteractionSimulator.h: * TestWebKitAPI/ios/DataInteractionSimulator.mm: (-[DataInteractionSimulator initWithWebView:]): (-[DataInteractionSimulator dealloc]): (-[DataInteractionSimulator _advanceProgress]): (-[DataInteractionSimulator waitForInputSession]): (-[DataInteractionSimulator _webView:focusShouldStartInputSession:]): (-[DataInteractionSimulator _webView:didStartInputSession:]): git-svn-id: http://svn.webkit.org/repository/webkit/trunk@216212 268f45cc-cd09-0410-ab3c-d52691b4dbfc
1 parent 8e8c3bd commit 3acff53

27 files changed

+498
-17
lines changed

Source/WebCore/ChangeLog

+100
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,103 @@
1+
2017-05-04 Wenson Hsieh <[email protected]>
2+
3+
[WK2] Add support for keeping the selection in a focused editable element when dragging begins
4+
https://bugs.webkit.org/show_bug.cgi?id=171585
5+
<rdar://problem/31544320>
6+
7+
Reviewed by Beth Dakin and Zalan Bujtas.
8+
9+
Covered by 4 API tests.
10+
11+
* dom/DocumentMarker.h:
12+
13+
Introduces the DraggedContent DocumentMarker type, which applies to the Range in the DOM that is being used as
14+
a drag source. Also adds DraggedContentData, which contains nodes found by the TextIterator in the process of
15+
finding Ranges to mark.
16+
17+
(WebCore::DocumentMarker::AllMarkers::AllMarkers):
18+
* dom/DocumentMarkerController.cpp:
19+
(WebCore::DocumentMarkerController::addDraggedContentMarker):
20+
(WebCore::shouldInsertAsSeparateMarker):
21+
(WebCore::DocumentMarkerController::addMarker):
22+
23+
When adding DocumentMarkers of type DraggedContent, keep adjacent RenderReplaced elements separate, rather than
24+
merging them into existing RenderedDocumentMarkers. This is because the data for each of these (i.e. the target
25+
node) needs to be preserved.
26+
27+
(WebCore::DocumentMarkerController::markersFor):
28+
29+
Bail and return an empty list if the map of document markers cannot possibly contain a dragged content marker.
30+
31+
* dom/DocumentMarkerController.h:
32+
* page/DragController.h:
33+
* page/DragState.h:
34+
35+
Add draggedContentRange to DragState. This tracks the Range that is being dragged; it is created when the drag
36+
session has begun, and ends when drag session finishes (either via WebPage::dragEnded or WebPage::dragCancelled).
37+
38+
* page/EventHandler.cpp:
39+
(WebCore::repaintContentsOfRange):
40+
(WebCore::EventHandler::dragCancelled):
41+
42+
Called when a drag is cancelled in the UI process without a session ever getting a chance to begin. We use this
43+
as a hook to remove all DraggedContent document markers from the document of the dragged content range.
44+
45+
(WebCore::EventHandler::didStartDrag):
46+
47+
Called when a drag session has begun in the UI process. We use this as a hook to set up document markers for the
48+
Range of content being dragged.
49+
50+
(WebCore::EventHandler::dragSourceEndedAt):
51+
52+
Called when a drag session ends. We use this as a hook to remove all DraggedContent document markers from the
53+
document of the dragged content range.
54+
55+
(WebCore::EventHandler::draggedElement):
56+
* page/EventHandler.h:
57+
* page/FocusController.cpp:
58+
(WebCore::shouldClearSelectionWhenChangingFocusedElement):
59+
60+
Prevent the selection from clearing when the previously focused element is editable and also contains the drag
61+
source element. Ideally, we should experiment with clearing out the selection whenever the element is blurred
62+
(and not have additional restrictions on editability and containing the drag source), but this change is much
63+
riskier.
64+
65+
(WebCore::FocusController::setFocusedElement):
66+
* rendering/InlineTextBox.cpp:
67+
(WebCore::InlineTextBox::paint):
68+
69+
Use RenderText::draggedContentStartEnd to find the range of text (if any) that is dragged content, and paint
70+
these ranges of text at a lower alpha using TextPainter::paintTextInRange.
71+
72+
* rendering/RenderReplaced.cpp:
73+
(WebCore::draggedContentContainsReplacedElement):
74+
75+
Determines whether or not the element being rendered is contained within a dragged content range. Assuming that
76+
the DraggedContent type flag is set in DocumentMarkerController, we first look to see whether or not the
77+
container node is in the document marker map. If so, instead of consulting node offset ranges (since this is, in
78+
the worst-case, linear in the number of sibling nodes per RenderReplaced) we simply check the DraggedContentData
79+
to see if the current element being rendered matches one of the target nodes.
80+
81+
(WebCore::RenderReplaced::paint):
82+
83+
If the element rendered by this RenderReplaced is dragged content, then render it at a low alpha.
84+
85+
* rendering/RenderText.cpp:
86+
(WebCore::RenderText::draggedContentRangesBetweenOffsets):
87+
88+
Determines what range of text, if any, contains dragged content by consulting the Document's DocumentMarkers.
89+
90+
* rendering/RenderText.h:
91+
* rendering/TextPainter.cpp:
92+
(WebCore::TextPainter::paintTextInRange):
93+
94+
Teach TextPainter to only paint a given range in a TextRun.
95+
96+
* rendering/TextPainter.h:
97+
98+
Add TextPainter support for specifying special text offset ranges when rendering a TextRun, such that each
99+
special range in text is rendered after applying some modification to the GraphicsContext.
100+
1101
2017-05-04 Jeremy Jones <[email protected]>
2102

3103
Crash when pointer lock element is removed before pointer lock allowed arrives.

Source/WebCore/dom/DocumentMarker.h

+9-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121
#pragma once
2222

23+
#include "Node.h"
24+
2325
#include <wtf/Forward.h>
2426
#include <wtf/Variant.h>
2527
#include <wtf/text/WTFString.h>
@@ -75,6 +77,8 @@ class DocumentMarker {
7577
#endif
7678
// This marker indicates that the user has selected a text candidate.
7779
AcceptedCandidate = 1 << 13,
80+
// This marker indicates that the user has initiated a drag with this content.
81+
DraggedContent = 1 << 14
7882
};
7983

8084
class MarkerTypes {
@@ -115,6 +119,7 @@ class DocumentMarker {
115119
| DictationPhraseWithAlternatives
116120
| DictationResult
117121
#endif
122+
| DraggedContent
118123
)
119124
{
120125
}
@@ -132,7 +137,10 @@ class DocumentMarker {
132137
RetainPtr<id> metadata;
133138
#endif
134139
};
135-
using Data = Variant<IsActiveMatchData, DescriptionData, DictationData, DictationAlternativesData>;
140+
struct DraggedContentData {
141+
RefPtr<Node> targetNode;
142+
};
143+
using Data = Variant<IsActiveMatchData, DescriptionData, DictationData, DictationAlternativesData, DraggedContentData>;
136144

137145
DocumentMarker(unsigned startOffset, unsigned endOffset, bool isActiveMatch);
138146
DocumentMarker(MarkerType, unsigned startOffset, unsigned endOffset, const String& description = String());

Source/WebCore/dom/DocumentMarkerController.cpp

+27-3
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,15 @@ void DocumentMarkerController::addDictationResultMarker(Range* range, const Reta
135135

136136
#endif
137137

138+
void DocumentMarkerController::addDraggedContentMarker(RefPtr<Range> range)
139+
{
140+
for (TextIterator markedText(range.get()); !markedText.atEnd(); markedText.advance()) {
141+
RefPtr<Range> textPiece = markedText.range();
142+
DocumentMarker::DraggedContentData draggedContentData { markedText.node() };
143+
addMarker(&textPiece->startContainer(), { DocumentMarker::DraggedContent, textPiece->startOffset(), textPiece->endOffset(), WTFMove(draggedContentData) });
144+
}
145+
}
146+
138147
void DocumentMarkerController::removeMarkers(Range* range, DocumentMarker::MarkerTypes markerTypes, RemovePartiallyOverlappingMarkerOrNot shouldRemovePartiallyOverlappingMarker)
139148
{
140149
for (TextIterator markedText(range); !markedText.atEnd(); markedText.advance()) {
@@ -293,6 +302,20 @@ Vector<FloatRect> DocumentMarkerController::renderedRectsForMarkers(DocumentMark
293302
return result;
294303
}
295304

305+
static bool shouldInsertAsSeparateMarker(const DocumentMarker& newMarker)
306+
{
307+
#if PLATFORM(IOS)
308+
if (newMarker.type() == DocumentMarker::DictationPhraseWithAlternatives || newMarker.type() == DocumentMarker::DictationResult)
309+
return true;
310+
#endif
311+
if (newMarker.type() == DocumentMarker::DraggedContent) {
312+
if (auto targetNode = WTF::get<DocumentMarker::DraggedContentData>(newMarker.data()).targetNode)
313+
return targetNode->renderer() && targetNode->renderer()->isRenderReplaced();
314+
}
315+
316+
return false;
317+
}
318+
296319
// Markers are stored in order sorted by their start offset.
297320
// Markers of the same type do not overlap each other.
298321

@@ -317,8 +340,7 @@ void DocumentMarkerController::addMarker(Node* node, const DocumentMarker& newMa
317340
if (!list) {
318341
list = std::make_unique<MarkerList>();
319342
list->append(RenderedDocumentMarker(newMarker));
320-
#if PLATFORM(IOS)
321-
} else if (newMarker.type() == DocumentMarker::DictationPhraseWithAlternatives || newMarker.type() == DocumentMarker::DictationResult) {
343+
} else if (shouldInsertAsSeparateMarker(newMarker)) {
322344
// We don't merge dictation markers.
323345
size_t i;
324346
size_t numberOfMarkers = list->size();
@@ -328,7 +350,6 @@ void DocumentMarkerController::addMarker(Node* node, const DocumentMarker& newMa
328350
break;
329351
}
330352
list->insert(i, RenderedDocumentMarker(newMarker));
331-
#endif
332353
} else {
333354
RenderedDocumentMarker toInsert(newMarker);
334355
size_t numMarkers = list->size();
@@ -504,6 +525,9 @@ DocumentMarker* DocumentMarkerController::markerContainingPoint(const LayoutPoin
504525

505526
Vector<RenderedDocumentMarker*> DocumentMarkerController::markersFor(Node* node, DocumentMarker::MarkerTypes markerTypes)
506527
{
528+
if (!possiblyHasMarkers(markerTypes))
529+
return { };
530+
507531
Vector<RenderedDocumentMarker*> result;
508532
MarkerList* list = m_markers.get(node);
509533
if (!list)

Source/WebCore/dom/DocumentMarkerController.h

+1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ class DocumentMarkerController {
5959
void addDictationPhraseWithAlternativesMarker(Range*, const Vector<String>& interpretations);
6060
void addDictationResultMarker(Range*, const RetainPtr<id>& metadata);
6161
#endif
62+
void addDraggedContentMarker(RefPtr<Range>);
6263

6364
void copyMarkers(Node* srcNode, unsigned startOffset, int length, Node* dstNode, int delta);
6465
bool hasMarkers() const

Source/WebCore/page/DragController.h

+1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ struct DragState;
6262
WEBCORE_EXPORT void dragExited(const DragData&);
6363
WEBCORE_EXPORT DragOperation dragUpdated(const DragData&);
6464
WEBCORE_EXPORT bool performDragOperation(const DragData&);
65+
WEBCORE_EXPORT void dragCancelled();
6566

6667
bool mouseIsOverFileInput() const { return m_fileInputElementUnderMouse; }
6768
unsigned numberOfItemsToBeAccepted() const { return m_numberOfItemsToBeAccepted; }

Source/WebCore/page/DragState.h

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ namespace WebCore {
3434

3535
struct DragState {
3636
RefPtr<Element> source; // Element that may be a drag source, for the current mouse gesture.
37+
RefPtr<Range> draggedContentRange;
3738
bool shouldDispatchEvents;
3839
DragSourceAction type;
3940
RefPtr<DataTransfer> dataTransfer; // Used on only the source side of dragging.

Source/WebCore/page/EventHandler.cpp

+66
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "Chrome.h"
3535
#include "ChromeClient.h"
3636
#include "CursorList.h"
37+
#include "DocumentMarkerController.h"
3738
#include "DragController.h"
3839
#include "DragState.h"
3940
#include "Editing.h"
@@ -3451,6 +3452,60 @@ void EventHandler::invalidateDataTransfer()
34513452
dragState().dataTransfer = nullptr;
34523453
}
34533454

3455+
static void repaintContentsOfRange(RefPtr<Range> range)
3456+
{
3457+
if (!range)
3458+
return;
3459+
3460+
auto* container = range->commonAncestorContainer();
3461+
if (!container)
3462+
return;
3463+
3464+
// This ensures that all nodes enclosed in this Range are repainted.
3465+
if (auto rendererToRepaint = container->renderer()) {
3466+
if (auto* containingRenderer = rendererToRepaint->container())
3467+
rendererToRepaint = containingRenderer;
3468+
rendererToRepaint->repaint();
3469+
}
3470+
}
3471+
3472+
void EventHandler::dragCancelled()
3473+
{
3474+
#if ENABLE(DATA_INTERACTION)
3475+
if (auto range = dragState().draggedContentRange) {
3476+
range->ownerDocument().markers().removeMarkers(DocumentMarker::DraggedContent);
3477+
repaintContentsOfRange(range);
3478+
}
3479+
dragState().draggedContentRange = nullptr;
3480+
#endif
3481+
}
3482+
3483+
void EventHandler::didStartDrag()
3484+
{
3485+
#if ENABLE(DATA_INTERACTION)
3486+
auto dragSource = dragState().source;
3487+
if (!dragSource)
3488+
return;
3489+
3490+
auto* renderer = dragSource->renderer();
3491+
if (!renderer)
3492+
return;
3493+
3494+
if (dragState().type & DragSourceActionSelection)
3495+
dragState().draggedContentRange = m_frame.selection().selection().toNormalizedRange();
3496+
else {
3497+
Position startPosition(dragSource.get(), Position::PositionIsBeforeAnchor);
3498+
Position endPosition(dragSource.get(), Position::PositionIsAfterAnchor);
3499+
dragState().draggedContentRange = Range::create(dragSource->document(), startPosition, endPosition);
3500+
}
3501+
3502+
if (auto range = dragState().draggedContentRange) {
3503+
range->ownerDocument().markers().addDraggedContentMarker(range.get());
3504+
repaintContentsOfRange(range);
3505+
}
3506+
#endif
3507+
}
3508+
34543509
void EventHandler::dragSourceEndedAt(const PlatformMouseEvent& event, DragOperation operation)
34553510
{
34563511
// Send a hit test request so that RenderLayer gets a chance to update the :hover and :active pseudoclasses.
@@ -3463,6 +3518,12 @@ void EventHandler::dragSourceEndedAt(const PlatformMouseEvent& event, DragOperat
34633518
dispatchDragSrcEvent(eventNames().dragendEvent, event);
34643519
}
34653520
invalidateDataTransfer();
3521+
3522+
if (auto range = dragState().draggedContentRange) {
3523+
range->ownerDocument().markers().removeMarkers(DocumentMarker::DraggedContent);
3524+
repaintContentsOfRange(range);
3525+
}
3526+
34663527
dragState().source = nullptr;
34673528
// In case the drag was ended due to an escape key press we need to ensure
34683529
// that consecutive mousemove events don't reinitiate the drag and drop.
@@ -3487,6 +3548,11 @@ static bool ExactlyOneBitSet(DragSourceAction n)
34873548
return n && !(n & (n - 1));
34883549
}
34893550

3551+
RefPtr<Element> EventHandler::draggedElement() const
3552+
{
3553+
return dragState().source;
3554+
}
3555+
34903556
bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event, CheckDragHysteresis checkDragHysteresis)
34913557
{
34923558
if (event.event().button() != LeftButton || event.event().type() != PlatformEvent::MouseMoved) {

Source/WebCore/page/EventHandler.h

+3
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ class EventHandler {
159159
void cancelDragAndDrop(const PlatformMouseEvent&, DataTransfer&);
160160
bool performDragAndDrop(const PlatformMouseEvent&, DataTransfer&);
161161
void updateDragStateAfterEditDragIfNeeded(Element& rootEditableElement);
162+
RefPtr<Element> draggedElement() const;
162163
#endif
163164

164165
void scheduleHoverStateUpdate();
@@ -253,6 +254,8 @@ class EventHandler {
253254
#if ENABLE(DRAG_SUPPORT)
254255
WEBCORE_EXPORT bool eventMayStartDrag(const PlatformMouseEvent&) const;
255256

257+
WEBCORE_EXPORT void didStartDrag();
258+
WEBCORE_EXPORT void dragCancelled();
256259
WEBCORE_EXPORT void dragSourceEndedAt(const PlatformMouseEvent&, DragOperation);
257260
#endif
258261

Source/WebCore/page/FocusController.cpp

+25-1
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,29 @@ static void clearSelectionIfNeeded(Frame* oldFocusedFrame, Frame* newFocusedFram
765765
oldFocusedFrame->selection().clear();
766766
}
767767

768+
static bool shouldClearSelectionWhenChangingFocusedElement(const Page& page, RefPtr<Element> oldFocusedElement, RefPtr<Element> newFocusedElement)
769+
{
770+
#if ENABLE(DATA_INTERACTION)
771+
if (newFocusedElement || !oldFocusedElement)
772+
return true;
773+
774+
// FIXME: These additional checks should not be necessary. We should consider generally keeping the selection whenever the
775+
// focused element is blurred, with no new element taking focus.
776+
if (!oldFocusedElement->isRootEditableElement() && !is<HTMLInputElement>(oldFocusedElement.get()) && !is<HTMLTextAreaElement>(oldFocusedElement.get()))
777+
return true;
778+
779+
for (auto ancestor = page.mainFrame().eventHandler().draggedElement(); ancestor; ancestor = ancestor->parentOrShadowHostElement()) {
780+
if (ancestor == oldFocusedElement)
781+
return false;
782+
}
783+
#else
784+
UNUSED_PARAM(page);
785+
UNUSED_PARAM(oldFocusedElement);
786+
UNUSED_PARAM(newFocusedElement);
787+
#endif
788+
return true;
789+
}
790+
768791
bool FocusController::setFocusedElement(Element* element, Frame& newFocusedFrame, FocusDirection direction)
769792
{
770793
Ref<Frame> protectedNewFocusedFrame = newFocusedFrame;
@@ -781,7 +804,8 @@ bool FocusController::setFocusedElement(Element* element, Frame& newFocusedFrame
781804

782805
m_page.editorClient().willSetInputMethodState();
783806

784-
clearSelectionIfNeeded(oldFocusedFrame.get(), &newFocusedFrame, element);
807+
if (shouldClearSelectionWhenChangingFocusedElement(m_page, oldFocusedElement, element))
808+
clearSelectionIfNeeded(oldFocusedFrame.get(), &newFocusedFrame, element);
785809

786810
if (!element) {
787811
if (oldDocument)

0 commit comments

Comments
 (0)