Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(303)

Unified Diff: third_party/WebKit/Source/core/editing/FrameSelection.cpp

Issue 2841093002: Algorithm for deciding if a frame's selection should be hidden (Closed)
Patch Set: Nit Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..d1ebc9c54d429705cbc6efccfae708f66fd1a194 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
+ // 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();
}
}
« no previous file with comments | « third_party/WebKit/Source/core/editing/FrameSelection.h ('k') | third_party/WebKit/Source/core/editing/FrameSelectionTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698