Chromium Code Reviews| Index: third_party/WebKit/Source/core/editing/FrameSelection.cpp |
| diff --git a/third_party/WebKit/Source/core/editing/FrameSelection.cpp b/third_party/WebKit/Source/core/editing/FrameSelection.cpp |
| index 498a59b19875d097e0408edfb7fb7acc028aca52..60cfcc9bb90de8596238f0ffaba089616ebd4777 100644 |
| --- a/third_party/WebKit/Source/core/editing/FrameSelection.cpp |
| +++ b/third_party/WebKit/Source/core/editing/FrameSelection.cpp |
| @@ -250,7 +250,7 @@ void FrameSelection::DidSetSelectionDeprecated(SetSelectionOptions options, |
| } |
| frame_caret_->StopCaretBlinkTimer(); |
| - UpdateAppearance(LayoutSelection::PaintHint::kPaint); |
| + UpdateAppearance(); |
| // Always clear the x position used for vertical arrow navigation. |
| // It will be restored by the vertical arrow navigation code if necessary. |
| @@ -335,26 +335,7 @@ void FrameSelection::DidChangeFocus() { |
| // Hits in |
| // virtual/gpu/compositedscrolling/scrollbars/scrollbar-miss-mousemove-disabled.html |
| DisableCompositingQueryAsserts disabler; |
| - |
| - // No focused element means document root has focus. |
| - const Element* const focus = GetDocument().FocusedElement() |
| - ? GetDocument().FocusedElement() |
| - : GetDocument().documentElement(); |
| - |
| - // Protection against LayoutTests/editing/selection/selection-crash.html |
| - if (!focus) { |
| - frame_caret_->ScheduleVisualUpdateForPaintInvalidationIfNeeded(); |
| - text_control_focused_ = false; |
| - return; |
| - } |
| - |
| - // Hide the selection when focus goes away from a text-field and into |
| - // something that is not a text-field. When focus enters another text-field we |
| - // do not need to update appearance; the appearance is updated when the new |
| - // selection is set. |
| - if (text_control_focused_ && !focus->IsTextControl()) |
| - UpdateAppearance(LayoutSelection::PaintHint::kHide); |
| - text_control_focused_ = focus->IsTextControl(); |
| + UpdateAppearance(); |
| } |
| static DispatchEventResult DispatchSelectStart( |
| @@ -444,6 +425,61 @@ void FrameSelection::Clear() { |
| SetSelection(SelectionInDOMTree()); |
| } |
| +bool FrameSelection::SelectionHasFocus() const { |
| + // TODO(editing-dev): Hoist updateStyleAndLayoutIgnorePendingStylesheets |
|
Xiaocheng
2017/05/09 18:18:15
nit: s/update/Update/
|
| + // to caller. See http://crbug.com/590369 for more details. |
| + GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets(); |
| + const Node* current = |
| + ComputeVisibleSelectionInDOMTree().Start().ComputeContainerNode(); |
| + if (!current) |
| + return false; |
| + |
| + // No focused element means document root has focus. |
| + const Element* const focused_element = GetDocument().FocusedElement() |
| + ? GetDocument().FocusedElement() |
| + : GetDocument().documentElement(); |
| + if (!focused_element) |
| + return false; |
| + |
| + if (focused_element->IsTextControl()) |
| + return focused_element->ContainsIncludingHostElements(*current); |
| + |
| + bool has_editable_style = HasEditableStyle(*current); |
| + do { |
| + // If the selection is within an editable sub tree and that sub tree |
| + // doesn't have focus, the selection doesn't have focus either. |
| + if (has_editable_style && !HasEditableStyle(*current)) |
| + return false; |
| + |
| + // Selection has focus if its sub tree has focus. |
| + if (current == focused_element) |
| + return true; |
| + current = current->ParentOrShadowHostNode(); |
| + } while (current); |
| + |
| + return false; |
| +} |
| + |
| +bool FrameSelection::IsHidden() const { |
| + if (SelectionHasFocus()) |
| + return false; |
| + |
| + const Node* start = |
| + ComputeVisibleSelectionInDOMTree().Start().ComputeContainerNode(); |
| + if (!start) |
| + return true; |
| + |
| + // The selection doesn't have focus, so hide everything but range selections. |
| + if (!GetSelectionInDOMTree().IsRange()) |
| + return true; |
| + |
| + // Here we know we have an unfocused range selection. Let's say that |
| + // selection resides inside a text control. Since the selection doesn't have |
| + // focus neither does the text control. Meaning, if the selection indeed |
| + // resides inside a text control, it should be hidden. |
| + return EnclosingTextControl(start); |
| +} |
| + |
| void FrameSelection::DocumentAttached(Document* document) { |
| DCHECK(document); |
| use_secure_keyboard_entry_when_active_ = false; |
| @@ -795,15 +831,13 @@ void FrameSelection::CommitAppearanceIfNeeded() { |
| } |
| void FrameSelection::DidLayout() { |
| - // Upon relayout, a hidden selection must be kept hidden and a visible |
| - // selection must be kept visible. |
| - UpdateAppearance(LayoutSelection::PaintHint::kKeep); |
| + UpdateAppearance(); |
| } |
| -void FrameSelection::UpdateAppearance(LayoutSelection::PaintHint hint) { |
| +void FrameSelection::UpdateAppearance() { |
| DCHECK(!frame_->ContentLayoutItem().IsNull()); |
| frame_caret_->ScheduleVisualUpdateForPaintInvalidationIfNeeded(); |
| - layout_selection_->SetHasPendingSelection(hint); |
| + layout_selection_->SetHasPendingSelection(); |
| } |
| void FrameSelection::NotifyLayoutObjectOfSelectionChange( |
| @@ -992,7 +1026,7 @@ void FrameSelection::RevealSelection(const ScrollAlignment& alignment, |
| document_loader->GetInitialScrollState().was_scrolled_by_user = true; |
| if (start.AnchorNode()->GetLayoutObject()->ScrollRectToVisible( |
| rect, alignment, alignment)) |
| - UpdateAppearance(LayoutSelection::PaintHint::kPaint); |
| + UpdateAppearance(); |
| } |
| } |