Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2004, 2008, 2009, 2010 Apple Inc. All rights reserved. | 2 * Copyright (C) 2004, 2008, 2009, 2010 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 243 // "FocusIn", |m_frame| may associate to another document. | 243 // "FocusIn", |m_frame| may associate to another document. |
| 244 if (!IsAvailable() || GetDocument() != current_document) { | 244 if (!IsAvailable() || GetDocument() != current_document) { |
| 245 // Once we get test case to reach here, we should change this | 245 // Once we get test case to reach here, we should change this |
| 246 // if-statement to |DCHECK()|. | 246 // if-statement to |DCHECK()|. |
| 247 NOTREACHED(); | 247 NOTREACHED(); |
| 248 return; | 248 return; |
| 249 } | 249 } |
| 250 } | 250 } |
| 251 | 251 |
| 252 frame_caret_->StopCaretBlinkTimer(); | 252 frame_caret_->StopCaretBlinkTimer(); |
| 253 UpdateAppearance(LayoutSelection::PaintHint::kPaint); | 253 UpdateAppearance(); |
| 254 | 254 |
| 255 // Always clear the x position used for vertical arrow navigation. | 255 // Always clear the x position used for vertical arrow navigation. |
| 256 // It will be restored by the vertical arrow navigation code if necessary. | 256 // It will be restored by the vertical arrow navigation code if necessary. |
| 257 x_pos_for_vertical_arrow_navigation_ = NoXPosForVerticalArrowNavigation(); | 257 x_pos_for_vertical_arrow_navigation_ = NoXPosForVerticalArrowNavigation(); |
| 258 | 258 |
| 259 // TODO(yosin): Can we move this to at end of this function? | 259 // TODO(yosin): Can we move this to at end of this function? |
| 260 // This may dispatch a synchronous focus-related events. | 260 // This may dispatch a synchronous focus-related events. |
| 261 if (!(options & kDoNotSetFocus)) { | 261 if (!(options & kDoNotSetFocus)) { |
| 262 SelectFrameElementInParentIfFullySelected(); | 262 SelectFrameElementInParentIfFullySelected(); |
| 263 if (!IsAvailable() || GetDocument() != current_document) { | 263 if (!IsAvailable() || GetDocument() != current_document) { |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 328 // TODO(yosin): We should move to call |TypingCommand::closeTyping()| to | 328 // TODO(yosin): We should move to call |TypingCommand::closeTyping()| to |
| 329 // |Editor| class. | 329 // |Editor| class. |
| 330 if (!GetDocument().IsRunningExecCommand()) | 330 if (!GetDocument().IsRunningExecCommand()) |
| 331 TypingCommand::CloseTyping(frame_); | 331 TypingCommand::CloseTyping(frame_); |
| 332 } | 332 } |
| 333 | 333 |
| 334 void FrameSelection::DidChangeFocus() { | 334 void FrameSelection::DidChangeFocus() { |
| 335 // Hits in | 335 // Hits in |
| 336 // virtual/gpu/compositedscrolling/scrollbars/scrollbar-miss-mousemove-disable d.html | 336 // virtual/gpu/compositedscrolling/scrollbars/scrollbar-miss-mousemove-disable d.html |
| 337 DisableCompositingQueryAsserts disabler; | 337 DisableCompositingQueryAsserts disabler; |
| 338 | 338 UpdateAppearance(); |
| 339 // No focused element means document root has focus. | |
| 340 const Element* const focus = GetDocument().FocusedElement() | |
| 341 ? GetDocument().FocusedElement() | |
| 342 : GetDocument().documentElement(); | |
| 343 | |
| 344 // Protection against LayoutTests/editing/selection/selection-crash.html | |
| 345 if (!focus) { | |
| 346 frame_caret_->ScheduleVisualUpdateForPaintInvalidationIfNeeded(); | |
| 347 text_control_focused_ = false; | |
| 348 return; | |
| 349 } | |
| 350 | |
| 351 // Hide the selection when focus goes away from a text-field and into | |
| 352 // something that is not a text-field. When focus enters another text-field we | |
| 353 // do not need to update appearance; the appearance is updated when the new | |
| 354 // selection is set. | |
| 355 if (text_control_focused_ && !focus->IsTextControl()) | |
| 356 UpdateAppearance(LayoutSelection::PaintHint::kHide); | |
| 357 text_control_focused_ = focus->IsTextControl(); | |
| 358 } | 339 } |
| 359 | 340 |
| 360 static DispatchEventResult DispatchSelectStart( | 341 static DispatchEventResult DispatchSelectStart( |
| 361 const VisibleSelection& selection) { | 342 const VisibleSelection& selection) { |
| 362 Node* select_start_target = selection.Extent().ComputeContainerNode(); | 343 Node* select_start_target = selection.Extent().ComputeContainerNode(); |
| 363 if (!select_start_target) | 344 if (!select_start_target) |
| 364 return DispatchEventResult::kNotCanceled; | 345 return DispatchEventResult::kNotCanceled; |
| 365 | 346 |
| 366 return select_start_target->DispatchEvent( | 347 return select_start_target->DispatchEvent( |
| 367 Event::CreateCancelableBubble(EventTypeNames::selectstart)); | 348 Event::CreateCancelableBubble(EventTypeNames::selectstart)); |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 437 return true; | 418 return true; |
| 438 } | 419 } |
| 439 | 420 |
| 440 void FrameSelection::Clear() { | 421 void FrameSelection::Clear() { |
| 441 granularity_ = kCharacterGranularity; | 422 granularity_ = kCharacterGranularity; |
| 442 if (granularity_strategy_) | 423 if (granularity_strategy_) |
| 443 granularity_strategy_->Clear(); | 424 granularity_strategy_->Clear(); |
| 444 SetSelection(SelectionInDOMTree()); | 425 SetSelection(SelectionInDOMTree()); |
| 445 } | 426 } |
| 446 | 427 |
| 428 bool FrameSelection::HasFocus() const { | |
| 429 const Node* current = ComputeVisibleSelectionInDOMTreeDeprecated() | |
|
yosin_UTC9
2017/05/08 05:36:52
nit: Please use |ComputeVisibleSelectionInDOMTree(
hugoh_UTC2
2017/05/08 09:08:13
When I do, I get this crash:
$ out/PcDebug/webkit
| |
| 430 .Start() | |
| 431 .ComputeContainerNode(); | |
| 432 if (!current) | |
| 433 return false; | |
| 434 | |
| 435 // No focused element means document root has focus. | |
| 436 const Element* const focused_element = GetDocument().FocusedElement() | |
| 437 ? GetDocument().FocusedElement() | |
| 438 : GetDocument().documentElement(); | |
| 439 if (!focused_element) | |
| 440 return false; | |
| 441 | |
| 442 if (focused_element->IsTextControl()) | |
| 443 return focused_element->ContainsIncludingHostElements(*current); | |
| 444 | |
| 445 bool has_editable_style = HasEditableStyle(*current); | |
| 446 do { | |
| 447 // If the selection is within an editable sub tree and that sub tree | |
| 448 // doesn't have focus, the selection doesn't have focus either. | |
| 449 if (has_editable_style && !HasEditableStyle(*current)) | |
| 450 return false; | |
| 451 | |
| 452 // Selection has focus if its sub tree has focus. | |
| 453 if (current == focused_element) | |
| 454 return true; | |
| 455 current = current->ParentOrShadowHostNode(); | |
| 456 } while (current); | |
| 457 | |
| 458 return false; | |
| 459 } | |
| 460 | |
| 461 bool FrameSelection::IsHidden() const { | |
| 462 if (HasFocus()) | |
| 463 return false; | |
| 464 | |
| 465 const Node* start = ComputeVisibleSelectionInDOMTreeDeprecated() | |
|
yosin_UTC9
2017/05/08 05:36:52
nit: Please use |ComputeVisibleSelectionInDOMTree(
| |
| 466 .Start() | |
| 467 .ComputeContainerNode(); | |
| 468 if (!start) | |
| 469 return true; | |
| 470 | |
| 471 // The selection doesn't have focus, so hide everything but range selections. | |
| 472 if (!GetSelectionInDOMTree().IsRange()) | |
| 473 return true; | |
| 474 | |
| 475 // Here we know we have an unfocused range selection. Let's say that | |
| 476 // selection resides inside a text control. Since the selection doesn't have | |
| 477 // focus neither does the text control. Meaning, if the selection indeed | |
| 478 // resides inside a text control, it should be hidden. | |
| 479 return EnclosingTextControl(start); | |
| 480 } | |
| 481 | |
| 447 void FrameSelection::DocumentAttached(Document* document) { | 482 void FrameSelection::DocumentAttached(Document* document) { |
| 448 DCHECK(document); | 483 DCHECK(document); |
| 449 use_secure_keyboard_entry_when_active_ = false; | 484 use_secure_keyboard_entry_when_active_ = false; |
| 450 selection_editor_->DocumentAttached(document); | 485 selection_editor_->DocumentAttached(document); |
| 451 SetContext(document); | 486 SetContext(document); |
| 452 } | 487 } |
| 453 | 488 |
| 454 void FrameSelection::ContextDestroyed(Document* document) { | 489 void FrameSelection::ContextDestroyed(Document* document) { |
| 455 granularity_ = kCharacterGranularity; | 490 granularity_ = kCharacterGranularity; |
| 456 | 491 |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 789 | 824 |
| 790 bool FrameSelection::NeedsLayoutSelectionUpdate() const { | 825 bool FrameSelection::NeedsLayoutSelectionUpdate() const { |
| 791 return layout_selection_->HasPendingSelection(); | 826 return layout_selection_->HasPendingSelection(); |
| 792 } | 827 } |
| 793 | 828 |
| 794 void FrameSelection::CommitAppearanceIfNeeded() { | 829 void FrameSelection::CommitAppearanceIfNeeded() { |
| 795 return layout_selection_->Commit(); | 830 return layout_selection_->Commit(); |
| 796 } | 831 } |
| 797 | 832 |
| 798 void FrameSelection::DidLayout() { | 833 void FrameSelection::DidLayout() { |
| 799 // Upon relayout, a hidden selection must be kept hidden and a visible | 834 UpdateAppearance(); |
| 800 // selection must be kept visible. | |
| 801 UpdateAppearance(LayoutSelection::PaintHint::kKeep); | |
| 802 } | 835 } |
| 803 | 836 |
| 804 void FrameSelection::UpdateAppearance(LayoutSelection::PaintHint hint) { | 837 void FrameSelection::UpdateAppearance() { |
| 805 DCHECK(!frame_->ContentLayoutItem().IsNull()); | 838 DCHECK(!frame_->ContentLayoutItem().IsNull()); |
| 806 frame_caret_->ScheduleVisualUpdateForPaintInvalidationIfNeeded(); | 839 frame_caret_->ScheduleVisualUpdateForPaintInvalidationIfNeeded(); |
| 807 layout_selection_->SetHasPendingSelection(hint); | 840 layout_selection_->SetHasPendingSelection(); |
| 808 } | 841 } |
| 809 | 842 |
| 810 void FrameSelection::NotifyLayoutObjectOfSelectionChange( | 843 void FrameSelection::NotifyLayoutObjectOfSelectionChange( |
| 811 EUserTriggered user_triggered) { | 844 EUserTriggered user_triggered) { |
| 812 TextControlElement* text_control = | 845 TextControlElement* text_control = |
| 813 EnclosingTextControl(GetSelectionInDOMTree().Base()); | 846 EnclosingTextControl(GetSelectionInDOMTree().Base()); |
| 814 if (!text_control) | 847 if (!text_control) |
| 815 return; | 848 return; |
| 816 text_control->SelectionChanged(user_triggered == kUserTriggered); | 849 text_control->SelectionChanged(user_triggered == kUserTriggered); |
| 817 } | 850 } |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 986 | 1019 |
| 987 Position start = ComputeVisibleSelectionInDOMTreeDeprecated().Start(); | 1020 Position start = ComputeVisibleSelectionInDOMTreeDeprecated().Start(); |
| 988 DCHECK(start.AnchorNode()); | 1021 DCHECK(start.AnchorNode()); |
| 989 if (start.AnchorNode() && start.AnchorNode()->GetLayoutObject()) { | 1022 if (start.AnchorNode() && start.AnchorNode()->GetLayoutObject()) { |
| 990 // FIXME: This code only handles scrolling the startContainer's layer, but | 1023 // FIXME: This code only handles scrolling the startContainer's layer, but |
| 991 // the selection rect could intersect more than just that. | 1024 // the selection rect could intersect more than just that. |
| 992 if (DocumentLoader* document_loader = frame_->Loader().GetDocumentLoader()) | 1025 if (DocumentLoader* document_loader = frame_->Loader().GetDocumentLoader()) |
| 993 document_loader->GetInitialScrollState().was_scrolled_by_user = true; | 1026 document_loader->GetInitialScrollState().was_scrolled_by_user = true; |
| 994 if (start.AnchorNode()->GetLayoutObject()->ScrollRectToVisible( | 1027 if (start.AnchorNode()->GetLayoutObject()->ScrollRectToVisible( |
| 995 rect, alignment, alignment)) | 1028 rect, alignment, alignment)) |
| 996 UpdateAppearance(LayoutSelection::PaintHint::kPaint); | 1029 UpdateAppearance(); |
| 997 } | 1030 } |
| 998 } | 1031 } |
| 999 | 1032 |
| 1000 void FrameSelection::SetSelectionFromNone() { | 1033 void FrameSelection::SetSelectionFromNone() { |
| 1001 // Put a caret inside the body if the entire frame is editable (either the | 1034 // Put a caret inside the body if the entire frame is editable (either the |
| 1002 // entire WebView is editable or designMode is on for this document). | 1035 // entire WebView is editable or designMode is on for this document). |
| 1003 | 1036 |
| 1004 Document* document = frame_->GetDocument(); | 1037 Document* document = frame_->GetDocument(); |
| 1005 if (!ComputeVisibleSelectionInDOMTreeDeprecated().IsNone() || | 1038 if (!ComputeVisibleSelectionInDOMTreeDeprecated().IsNone() || |
| 1006 !(blink::HasEditableStyle(*document))) | 1039 !(blink::HasEditableStyle(*document))) |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1185 } | 1218 } |
| 1186 | 1219 |
| 1187 void showTree(const blink::FrameSelection* sel) { | 1220 void showTree(const blink::FrameSelection* sel) { |
| 1188 if (sel) | 1221 if (sel) |
| 1189 sel->ShowTreeForThis(); | 1222 sel->ShowTreeForThis(); |
| 1190 else | 1223 else |
| 1191 LOG(INFO) << "Cannot showTree for <null> FrameSelection."; | 1224 LOG(INFO) << "Cannot showTree for <null> FrameSelection."; |
| 1192 } | 1225 } |
| 1193 | 1226 |
| 1194 #endif | 1227 #endif |
| OLD | NEW |