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

Side by Side Diff: third_party/WebKit/Source/core/editing/FrameSelection.cpp

Issue 2001083002: Explicit management of FrameSelection availability (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 2016-06-06T17:09:04 Created 4 years, 6 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 unified diff | Download patch
OLDNEW
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 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 FrameSelection::FrameSelection(LocalFrame* frame) 94 FrameSelection::FrameSelection(LocalFrame* frame)
95 : m_frame(frame) 95 : m_frame(frame)
96 , m_pendingSelection(PendingSelection::create(*this)) 96 , m_pendingSelection(PendingSelection::create(*this))
97 , m_selectionEditor(SelectionEditor::create(*this)) 97 , m_selectionEditor(SelectionEditor::create(*this))
98 , m_granularity(CharacterGranularity) 98 , m_granularity(CharacterGranularity)
99 , m_xPosForVerticalArrowNavigation(NoXPosForVerticalArrowNavigation()) 99 , m_xPosForVerticalArrowNavigation(NoXPosForVerticalArrowNavigation())
100 , m_focused(frame->page() && frame->page()->focusController().focusedFrame() == frame) 100 , m_focused(frame->page() && frame->page()->focusController().focusedFrame() == frame)
101 , m_frameCaret(new FrameCaret(frame)) 101 , m_frameCaret(new FrameCaret(frame))
102 { 102 {
103 DCHECK(frame); 103 DCHECK(frame);
104 if (shouldAlwaysUseDirectionalSelection(m_frame))
tkent 2016/06/07 23:41:59 Why can we remove this code block?
yosin_UTC9 2016/06/08 04:06:10 Setting |VisibleSelection.isDirectional| done in |
105 m_selectionEditor->setIsDirectional(true);
106 } 104 }
107 105
108 FrameSelection::~FrameSelection() 106 FrameSelection::~FrameSelection()
109 { 107 {
110 } 108 }
111 109
110 const Document& FrameSelection::document() const
111 {
112 DCHECK(m_document);
113 return *m_document;
114 }
115
116 Document& FrameSelection::document()
117 {
118 DCHECK(m_document);
119 return *m_document;
120 }
121
112 template <> 122 template <>
113 VisiblePosition FrameSelection::originalBase<EditingStrategy>() const 123 VisiblePosition FrameSelection::originalBase<EditingStrategy>() const
114 { 124 {
115 return m_originalBase; 125 return m_originalBase;
116 } 126 }
117 127
118 template <> 128 template <>
119 VisiblePositionInFlatTree FrameSelection::originalBase<EditingInFlatTreeStrategy >() const 129 VisiblePositionInFlatTree FrameSelection::originalBase<EditingInFlatTreeStrategy >() const
120 { 130 {
121 return m_originalBaseInFlatTree; 131 return m_originalBaseInFlatTree;
(...skipping 10 matching lines...) Expand all
132 142
133 template <> 143 template <>
134 const VisibleSelectionInFlatTree& FrameSelection::visibleSelection<EditingInFlat TreeStrategy>() const 144 const VisibleSelectionInFlatTree& FrameSelection::visibleSelection<EditingInFlat TreeStrategy>() const
135 { 145 {
136 return m_selectionEditor->visibleSelection<EditingInFlatTreeStrategy>(); 146 return m_selectionEditor->visibleSelection<EditingInFlatTreeStrategy>();
137 } 147 }
138 148
139 Element* FrameSelection::rootEditableElementOrDocumentElement() const 149 Element* FrameSelection::rootEditableElementOrDocumentElement() const
140 { 150 {
141 Element* selectionRoot = selection().rootEditableElement(); 151 Element* selectionRoot = selection().rootEditableElement();
142 return selectionRoot ? selectionRoot : m_frame->document()->documentElement( ); 152 return selectionRoot ? selectionRoot : document().documentElement();
143 } 153 }
144 154
145 ContainerNode* FrameSelection::rootEditableElementOrTreeScopeRootNode() const 155 ContainerNode* FrameSelection::rootEditableElementOrTreeScopeRootNode() const
146 { 156 {
147 Element* selectionRoot = selection().rootEditableElement(); 157 Element* selectionRoot = selection().rootEditableElement();
148 if (selectionRoot) 158 if (selectionRoot)
149 return selectionRoot; 159 return selectionRoot;
150 160
151 Node* node = selection().base().computeContainerNode(); 161 Node* node = selection().base().computeContainerNode();
152 return node ? &node->treeScope().rootNode() : 0; 162 return node ? &node->treeScope().rootNode() : 0;
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 } 277 }
268 278
269 void FrameSelection::setNonDirectionalSelectionIfNeeded(const VisibleSelectionIn FlatTree& passedNewSelection, TextGranularity granularity, EndPointsAdjustmentMo de endpointsAdjustmentMode) 279 void FrameSelection::setNonDirectionalSelectionIfNeeded(const VisibleSelectionIn FlatTree& passedNewSelection, TextGranularity granularity, EndPointsAdjustmentMo de endpointsAdjustmentMode)
270 { 280 {
271 setNonDirectionalSelectionIfNeededAlgorithm<EditingInFlatTreeStrategy>(passe dNewSelection, granularity, endpointsAdjustmentMode); 281 setNonDirectionalSelectionIfNeededAlgorithm<EditingInFlatTreeStrategy>(passe dNewSelection, granularity, endpointsAdjustmentMode);
272 } 282 }
273 283
274 template <typename Strategy> 284 template <typename Strategy>
275 void FrameSelection::setSelectionAlgorithm(const VisibleSelectionTemplate<Strate gy>& newSelection, SetSelectionOptions options, CursorAlignOnScroll align, TextG ranularity granularity) 285 void FrameSelection::setSelectionAlgorithm(const VisibleSelectionTemplate<Strate gy>& newSelection, SetSelectionOptions options, CursorAlignOnScroll align, TextG ranularity granularity)
276 { 286 {
287 DCHECK(isAvailable());
288 const Document& currentDocument = document();
277 if (m_granularityStrategy && (options & FrameSelection::DoNotClearStrategy) == 0) 289 if (m_granularityStrategy && (options & FrameSelection::DoNotClearStrategy) == 0)
278 m_granularityStrategy->Clear(); 290 m_granularityStrategy->Clear();
279 bool closeTyping = options & CloseTyping; 291 bool closeTyping = options & CloseTyping;
280 bool shouldClearTypingStyle = options & ClearTypingStyle; 292 bool shouldClearTypingStyle = options & ClearTypingStyle;
281 EUserTriggered userTriggered = selectionOptionsToUserTriggered(options); 293 EUserTriggered userTriggered = selectionOptionsToUserTriggered(options);
282 294
283 VisibleSelectionTemplate<Strategy> s = validateSelection(newSelection); 295 VisibleSelectionTemplate<Strategy> s = validateSelection(newSelection);
284 if (shouldAlwaysUseDirectionalSelection(m_frame)) 296 if (shouldAlwaysUseDirectionalSelection(m_frame))
285 s.setIsDirectional(true); 297 s.setIsDirectional(true);
286 298
287 // <http://bugs.webkit.org/show_bug.cgi?id=23464>: Infinite recursion at
tkent 2016/06/07 23:41:59 Why can we remove this code block?
yosin_UTC9 2016/06/08 04:06:10 This can't be happened any more as proofed by no l
288 // |FrameSelection::setSelection|
289 // if |document->frame()| == |m_frame| we can get into an infinite loop
290 if (s.base().anchorNode()) {
291 Document& document = *s.base().document();
292 // TODO(hajimehoshi): validateSelection already checks if the selection
293 // is valid, thus we don't need this 'if' clause any more.
294 if (document.frame() && document.frame() != m_frame && document != m_fra me->document()) {
295 document.frame()->selection().setSelection(s, options, align, granul arity);
296 // It's possible that during the above set selection, this
297 // |FrameSelection| has been modified by
298 // |selectFrameElementInParentIfFullySelected|, but that the
299 // selection is no longer valid since the frame is about to be
300 // destroyed. If this is the case, clear our selection.
301 if (!document.frame()->host() && !selection().isNonOrphanedCaretOrRa nge())
302 clear();
303 return;
304 }
305 }
306
307 m_granularity = granularity; 299 m_granularity = granularity;
308 300
309 // TODO(yosin): We should move to call |TypingCommand::closeTyping()| to 301 // TODO(yosin): We should move to call |TypingCommand::closeTyping()| to
310 // |Editor| class. 302 // |Editor| class.
311 if (closeTyping) 303 if (closeTyping)
312 TypingCommand::closeTyping(m_frame); 304 TypingCommand::closeTyping(m_frame);
313 305
314 if (shouldClearTypingStyle) 306 if (shouldClearTypingStyle)
315 clearTypingStyle(); 307 clearTypingStyle();
316 308
317 if (m_selectionEditor->visibleSelection<Strategy>() == s) { 309 if (m_selectionEditor->visibleSelection<Strategy>() == s) {
318 // Even if selection was not changed, selection offsets may have been 310 // Even if selection was not changed, selection offsets may have been
319 // changed. 311 // changed.
320 m_frame->inputMethodController().cancelCompositionIfSelectionIsInvalid() ; 312 m_frame->inputMethodController().cancelCompositionIfSelectionIsInvalid() ;
321 notifyLayoutObjectOfSelectionChange(userTriggered); 313 notifyLayoutObjectOfSelectionChange(userTriggered);
322 return; 314 return;
323 } 315 }
324 316
325 const VisibleSelectionTemplate<Strategy> oldSelection = visibleSelection<Str ategy>(); 317 const VisibleSelectionTemplate<Strategy> oldSelection = visibleSelection<Str ategy>();
326 const VisibleSelection oldSelectionInDOMTree = selection(); 318 const VisibleSelection oldSelectionInDOMTree = selection();
327 319
328 m_selectionEditor->setVisibleSelection(s, options); 320 m_selectionEditor->setVisibleSelection(s, options);
329 if (s.isCaret()) 321 if (s.isCaret())
330 m_frameCaret->setCaretPosition(PositionWithAffinity(toPositionInDOMTree( s.start()), s.affinity())); 322 m_frameCaret->setCaretPosition(PositionWithAffinity(toPositionInDOMTree( s.start()), s.affinity()));
331 else 323 else
332 m_frameCaret->clear(); 324 m_frameCaret->clear();
333 325
334 if (!s.isNone() && !(options & DoNotSetFocus)) 326 if (!s.isNone() && !(options & DoNotSetFocus)) {
335 setFocusedNodeIfNeeded(); 327 setFocusedNodeIfNeeded();
328 // |setFocusedNodeIfNeeded()| dispatches sync events "FocusOut" and
329 // "FocusIn", |m_frame| may associate to another document.
330 if (!isAvailable() || document() != currentDocument) {
331 // Once we get test case to reach here, we should change this
332 // if-statement to |DCHECK()|.
333 NOTREACHED();
334 return;
335 }
336 }
336 337
337 if (!(options & DoNotUpdateAppearance)) { 338 if (!(options & DoNotUpdateAppearance)) {
338 // Hits in compositing/overflow/do-not-paint-outline-into-composited-scr olling-contents.html 339 // Hits in compositing/overflow/do-not-paint-outline-into-composited-scr olling-contents.html
339 DisableCompositingQueryAsserts disabler; 340 DisableCompositingQueryAsserts disabler;
340 m_frameCaret->stopCaretBlinkTimer(); 341 m_frameCaret->stopCaretBlinkTimer();
341 updateAppearance(); 342 updateAppearance();
342 } 343 }
343 344
344 // Always clear the x position used for vertical arrow navigation. 345 // Always clear the x position used for vertical arrow navigation.
345 // It will be restored by the vertical arrow navigation code if necessary. 346 // It will be restored by the vertical arrow navigation code if necessary.
346 m_xPosForVerticalArrowNavigation = NoXPosForVerticalArrowNavigation(); 347 m_xPosForVerticalArrowNavigation = NoXPosForVerticalArrowNavigation();
347 // This may dispatch a synchronous focus-related events. 348 // This may dispatch a synchronous focus-related events.
348 selectFrameElementInParentIfFullySelected(); 349 selectFrameElementInParentIfFullySelected();
350 if (!isAvailable() || document() != currentDocument) {
351 // editing/selection/selectallchildren-crash.html and
352 // editing/selection/longpress-selection-in-iframe-removed-crash.html
353 // reach here.
354 return;
355 }
349 notifyLayoutObjectOfSelectionChange(userTriggered); 356 notifyLayoutObjectOfSelectionChange(userTriggered);
350 // If the selections are same in the DOM tree but not in the flat tree, 357 // If the selections are same in the DOM tree but not in the flat tree,
351 // don't fire events. For example, if the selection crosses shadow tree 358 // don't fire events. For example, if the selection crosses shadow tree
352 // boundary, selection for the DOM tree is shrunk while that for the 359 // boundary, selection for the DOM tree is shrunk while that for the
353 // flat tree is not. Additionally, this case occurs in some edge cases. 360 // flat tree is not. Additionally, this case occurs in some edge cases.
354 // See also: editing/pasteboard/4076267-3.html 361 // See also: editing/pasteboard/4076267-3.html
355 if (oldSelection == m_selectionEditor->visibleSelection<Strategy>()) { 362 if (oldSelection == m_selectionEditor->visibleSelection<Strategy>()) {
356 m_frame->inputMethodController().cancelCompositionIfSelectionIsInvalid() ; 363 m_frame->inputMethodController().cancelCompositionIfSelectionIsInvalid() ;
357 return; 364 return;
358 } 365 }
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 } else { 480 } else {
474 const VisibleSelection& selection = m_selectionEditor->visibleSelection< EditingStrategy>(); 481 const VisibleSelection& selection = m_selectionEditor->visibleSelection< EditingStrategy>();
475 if (selection.isCaret()) 482 if (selection.isCaret())
476 m_frameCaret->setCaretPosition(PositionWithAffinity(selection.start( ), selection.affinity())); 483 m_frameCaret->setCaretPosition(PositionWithAffinity(selection.start( ), selection.affinity()));
477 else 484 else
478 m_frameCaret->clear(); 485 m_frameCaret->clear();
479 } 486 }
480 487
481 // TODO(yosin): We should move to call |TypingCommand::closeTyping()| to 488 // TODO(yosin): We should move to call |TypingCommand::closeTyping()| to
482 // |Editor| class. 489 // |Editor| class.
483 if (!m_frame->document()->isRunningExecCommand()) 490 if (!document().isRunningExecCommand())
484 TypingCommand::closeTyping(m_frame); 491 TypingCommand::closeTyping(m_frame);
485 } 492 }
486 493
487 static Position updatePositionAfterAdoptingTextReplacement(const Position& posit ion, CharacterData* node, unsigned offset, unsigned oldLength, unsigned newLengt h) 494 static Position updatePositionAfterAdoptingTextReplacement(const Position& posit ion, CharacterData* node, unsigned offset, unsigned oldLength, unsigned newLengt h)
488 { 495 {
489 if (!position.anchorNode() || position.anchorNode() != node || !position.isO ffsetInAnchor()) 496 if (!position.anchorNode() || position.anchorNode() != node || !position.isO ffsetInAnchor())
490 return position; 497 return position;
491 498
492 // See: http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2 -Range-Mutation 499 // See: http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2 -Range-Mutation
493 DCHECK_GE(position.offsetInContainerNode(), 0); 500 DCHECK_GE(position.offsetInContainerNode(), 0);
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
577 Position end = updatePostionAfterAdoptingTextNodeSplit(selection().end(), ol dNode); 584 Position end = updatePostionAfterAdoptingTextNodeSplit(selection().end(), ol dNode);
578 updateSelectionIfNeeded(base, extent, start, end); 585 updateSelectionIfNeeded(base, extent, start, end);
579 } 586 }
580 587
581 void FrameSelection::updateSelectionIfNeeded(const Position& base, const Positio n& extent, const Position& start, const Position& end) 588 void FrameSelection::updateSelectionIfNeeded(const Position& base, const Positio n& extent, const Position& start, const Position& end)
582 { 589 {
583 if (base == selection().base() && extent == selection().extent() && start == selection().start() && end == selection().end()) 590 if (base == selection().base() && extent == selection().extent() && start == selection().start() && end == selection().end())
584 return; 591 return;
585 // TODO(yosin): We should move to call |TypingCommand::closeTyping()| to 592 // TODO(yosin): We should move to call |TypingCommand::closeTyping()| to
586 // |Editor| class. 593 // |Editor| class.
587 if (!m_frame->document()->isRunningExecCommand()) 594 if (!document().isRunningExecCommand())
588 TypingCommand::closeTyping(m_frame); 595 TypingCommand::closeTyping(m_frame);
589 VisibleSelection newSelection; 596 VisibleSelection newSelection;
590 if (selection().isBaseFirst()) 597 if (selection().isBaseFirst())
591 newSelection.setWithoutValidation(start, end); 598 newSelection.setWithoutValidation(start, end);
592 else 599 else
593 newSelection.setWithoutValidation(end, start); 600 newSelection.setWithoutValidation(end, start);
594 setSelection(newSelection, DoNotSetFocus); 601 setSelection(newSelection, DoNotSetFocus);
595 } 602 }
596 603
597 void FrameSelection::didChangeFocus() 604 void FrameSelection::didChangeFocus()
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
656 } 663 }
657 664
658 void FrameSelection::clear() 665 void FrameSelection::clear()
659 { 666 {
660 m_granularity = CharacterGranularity; 667 m_granularity = CharacterGranularity;
661 if (m_granularityStrategy) 668 if (m_granularityStrategy)
662 m_granularityStrategy->Clear(); 669 m_granularityStrategy->Clear();
663 setSelection(VisibleSelection()); 670 setSelection(VisibleSelection());
664 } 671 }
665 672
666 void FrameSelection::prepareForDestruction() 673 void FrameSelection::documentAttached(Document* document)
667 { 674 {
tkent 2016/06/07 23:41:59 We should have DCHECK(document).
yosin_UTC9 2016/06/08 04:06:10 Done.
675 DCHECK(!m_document) << "FrameSelection is already attached to " << m_documen t;
676 m_document = document;
677 m_selectionEditor->documentAttached(document);
678 }
679
680 void FrameSelection::documentDetached(const Document& document)
681 {
682 DCHECK_EQ(m_document, document);
683 m_document = nullptr;
668 m_originalBase = VisiblePosition(); 684 m_originalBase = VisiblePosition();
669 m_originalBaseInFlatTree = VisiblePositionInFlatTree(); 685 m_originalBaseInFlatTree = VisiblePositionInFlatTree();
670 m_granularity = CharacterGranularity; 686 m_granularity = CharacterGranularity;
671 687
672 LayoutViewItem view = m_frame->contentLayoutItem(); 688 LayoutViewItem view = m_frame->contentLayoutItem();
673 if (!view.isNull()) 689 if (!view.isNull())
674 view.clearSelection(); 690 view.clearSelection();
675 691
676 setSelection(VisibleSelection(), CloseTyping | ClearTypingStyle | DoNotUpdat eAppearance); 692 clearTypingStyle();
677 m_selectionEditor->dispose(); 693 m_selectionEditor->documentDetached(document);
678 m_frameCaret->prepareForDestruction(); 694 m_frameCaret->documentDetached();
679 } 695 }
680 696
681 LayoutBlock* FrameSelection::caretLayoutObject() const 697 LayoutBlock* FrameSelection::caretLayoutObject() const
682 { 698 {
683 DCHECK(selection().isValidFor(*m_frame->document())); 699 DCHECK(selection().isValidFor(document()));
684 if (!isCaret()) 700 if (!isCaret())
685 return nullptr; 701 return nullptr;
686 return CaretBase::caretLayoutObject(selection().start().anchorNode()); 702 return CaretBase::caretLayoutObject(selection().start().anchorNode());
687 } 703 }
688 704
689 IntRect FrameSelection::absoluteCaretBounds() 705 IntRect FrameSelection::absoluteCaretBounds()
690 { 706 {
691 DCHECK(selection().isValidFor(*m_frame->document())); 707 DCHECK(selection().isValidFor(*m_frame->document()));
692 return m_frameCaret->absoluteCaretBounds(); 708 return m_frameCaret->absoluteCaretBounds();
693 } 709 }
694 710
695 void FrameSelection::invalidateCaretRect() 711 void FrameSelection::invalidateCaretRect()
696 { 712 {
697 m_frameCaret->invalidateCaretRect(); 713 m_frameCaret->invalidateCaretRect();
698 } 714 }
699 715
700 void FrameSelection::dataWillChange(const CharacterData& node) 716 void FrameSelection::dataWillChange(const CharacterData& node)
701 { 717 {
702 m_frameCaret->dataWillChange(node); 718 m_frameCaret->dataWillChange(node);
703 } 719 }
704 720
705 void FrameSelection::paintCaret(GraphicsContext& context, const LayoutPoint& pai ntOffset) 721 void FrameSelection::paintCaret(GraphicsContext& context, const LayoutPoint& pai ntOffset)
706 { 722 {
707 m_frameCaret->paintCaret(context, paintOffset); 723 m_frameCaret->paintCaret(context, paintOffset);
708 } 724 }
709 725
710 bool FrameSelection::contains(const LayoutPoint& point) 726 bool FrameSelection::contains(const LayoutPoint& point)
711 { 727 {
712 Document* document = m_frame->document(); 728 if (document().layoutViewItem().isNull())
713 if (document->layoutViewItem().isNull())
714 return false; 729 return false;
715 730
716 // Treat a collapsed selection like no selection. 731 // Treat a collapsed selection like no selection.
717 const VisibleSelectionInFlatTree& visibleSelection = this->visibleSelection< EditingInFlatTreeStrategy>(); 732 const VisibleSelectionInFlatTree& visibleSelection = this->visibleSelection< EditingInFlatTreeStrategy>();
718 if (!visibleSelection.isRange()) 733 if (!visibleSelection.isRange())
719 return false; 734 return false;
720 735
721 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active); 736 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active);
722 HitTestResult result(request, point); 737 HitTestResult result(request, point);
723 document->layoutViewItem().hitTest(result); 738 document().layoutViewItem().hitTest(result);
724 Node* innerNode = result.innerNode(); 739 Node* innerNode = result.innerNode();
725 if (!innerNode || !innerNode->layoutObject()) 740 if (!innerNode || !innerNode->layoutObject())
726 return false; 741 return false;
727 742
728 const VisiblePositionInFlatTree& visiblePos = createVisiblePosition(fromPosi tionInDOMTree<EditingInFlatTreeStrategy>(innerNode->layoutObject()->positionForP oint(result.localPoint()))); 743 const VisiblePositionInFlatTree& visiblePos = createVisiblePosition(fromPosi tionInDOMTree<EditingInFlatTreeStrategy>(innerNode->layoutObject()->positionForP oint(result.localPoint())));
729 if (visiblePos.isNull()) 744 if (visiblePos.isNull())
730 return false; 745 return false;
731 746
732 const VisiblePositionInFlatTree& visibleStart = visibleSelection.visibleStar t(); 747 const VisiblePositionInFlatTree& visibleStart = visibleSelection.visibleStar t();
733 const VisiblePositionInFlatTree& visibleEnd = visibleSelection.visibleEnd(); 748 const VisiblePositionInFlatTree& visibleEnd = visibleSelection.visibleEnd();
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
796 811
797 // Returns a shadow tree node for legacy shadow trees, a child of the 812 // Returns a shadow tree node for legacy shadow trees, a child of the
798 // ShadowRoot node for new shadow trees, or 0 for non-shadow trees. 813 // ShadowRoot node for new shadow trees, or 0 for non-shadow trees.
799 static Node* nonBoundaryShadowTreeRootNode(const Position& position) 814 static Node* nonBoundaryShadowTreeRootNode(const Position& position)
800 { 815 {
801 return position.anchorNode() && !position.anchorNode()->isShadowRoot() ? pos ition.anchorNode()->nonBoundaryShadowTreeRootNode() : nullptr; 816 return position.anchorNode() && !position.anchorNode()->isShadowRoot() ? pos ition.anchorNode()->nonBoundaryShadowTreeRootNode() : nullptr;
802 } 817 }
803 818
804 void FrameSelection::selectAll() 819 void FrameSelection::selectAll()
805 { 820 {
806 Document* document = m_frame->document(); 821 if (isHTMLSelectElement(document().focusedElement())) {
807 822 HTMLSelectElement* selectElement = toHTMLSelectElement(document().focuse dElement());
808 if (isHTMLSelectElement(document->focusedElement())) {
809 HTMLSelectElement* selectElement = toHTMLSelectElement(document->focused Element());
810 if (selectElement->canSelectAll()) { 823 if (selectElement->canSelectAll()) {
811 selectElement->selectAll(); 824 selectElement->selectAll();
812 return; 825 return;
813 } 826 }
814 } 827 }
815 828
816 Node* root = nullptr; 829 Node* root = nullptr;
817 Node* selectStartTarget = nullptr; 830 Node* selectStartTarget = nullptr;
818 if (isContentEditable()) { 831 if (isContentEditable()) {
819 root = highestEditableRoot(selection().start()); 832 root = highestEditableRoot(selection().start());
820 if (Node* shadowRoot = nonBoundaryShadowTreeRootNode(selection().start() )) 833 if (Node* shadowRoot = nonBoundaryShadowTreeRootNode(selection().start() ))
821 selectStartTarget = shadowRoot->shadowHost(); 834 selectStartTarget = shadowRoot->shadowHost();
822 else 835 else
823 selectStartTarget = root; 836 selectStartTarget = root;
824 } else { 837 } else {
825 root = nonBoundaryShadowTreeRootNode(selection().start()); 838 root = nonBoundaryShadowTreeRootNode(selection().start());
826 if (root) { 839 if (root) {
827 selectStartTarget = root->shadowHost(); 840 selectStartTarget = root->shadowHost();
828 } else { 841 } else {
829 root = document->documentElement(); 842 root = document().documentElement();
830 selectStartTarget = document->body(); 843 selectStartTarget = document().body();
831 } 844 }
832 } 845 }
833 if (!root || editingIgnoresContent(root)) 846 if (!root || editingIgnoresContent(root))
834 return; 847 return;
835 848
836 if (selectStartTarget) { 849 if (selectStartTarget) {
850 const Document& expectedDocument = document();
837 if (selectStartTarget->dispatchEvent(Event::createCancelableBubble(Event TypeNames::selectstart)) != DispatchEventResult::NotCanceled) 851 if (selectStartTarget->dispatchEvent(Event::createCancelableBubble(Event TypeNames::selectstart)) != DispatchEventResult::NotCanceled)
838 return; 852 return;
839 // |root| may be detached due to selectstart event. 853 // |root| may be detached due to selectstart event.
840 if (!root->inShadowIncludingDocument() || root->document() != document) 854 if (!root->inShadowIncludingDocument() || expectedDocument != root->docu ment())
841 return; 855 return;
842 } 856 }
843 857
844 VisibleSelection newSelection(VisibleSelection::selectionFromContentsOfNode( root)); 858 VisibleSelection newSelection(VisibleSelection::selectionFromContentsOfNode( root));
845 setSelection(newSelection); 859 setSelection(newSelection);
846 selectFrameElementInParentIfFullySelected(); 860 selectFrameElementInParentIfFullySelected();
847 notifyLayoutObjectOfSelectionChange(UserTriggered); 861 notifyLayoutObjectOfSelectionChange(UserTriggered);
848 } 862 }
849 863
850 bool FrameSelection::setSelectedRange(Range* range, TextAffinity affinity, Selec tionDirectionalMode directional, SetSelectionOptions options) 864 bool FrameSelection::setSelectedRange(Range* range, TextAffinity affinity, Selec tionDirectionalMode directional, SetSelectionOptions options)
(...skipping 26 matching lines...) Expand all
877 891
878 bool FrameSelection::isInPasswordField() const 892 bool FrameSelection::isInPasswordField() const
879 { 893 {
880 HTMLTextFormControlElement* textControl = enclosingTextFormControl(start()); 894 HTMLTextFormControlElement* textControl = enclosingTextFormControl(start());
881 return isHTMLInputElement(textControl) && toHTMLInputElement(textControl)->t ype() == InputTypeNames::password; 895 return isHTMLInputElement(textControl) && toHTMLInputElement(textControl)->t ype() == InputTypeNames::password;
882 } 896 }
883 897
884 void FrameSelection::notifyAccessibilityForSelectionChange() 898 void FrameSelection::notifyAccessibilityForSelectionChange()
885 { 899 {
886 if (selection().start().isNotNull() && selection().end().isNotNull()) { 900 if (selection().start().isNotNull() && selection().end().isNotNull()) {
887 if (AXObjectCache* cache = m_frame->document()->existingAXObjectCache()) 901 if (AXObjectCache* cache = document().existingAXObjectCache())
888 cache->selectionChanged(selection().start().computeContainerNode()); 902 cache->selectionChanged(selection().start().computeContainerNode());
889 } 903 }
890 } 904 }
891 905
892 void FrameSelection::notifyCompositorForSelectionChange() 906 void FrameSelection::notifyCompositorForSelectionChange()
893 { 907 {
894 if (!RuntimeEnabledFeatures::compositedSelectionUpdateEnabled()) 908 if (!RuntimeEnabledFeatures::compositedSelectionUpdateEnabled())
895 return; 909 return;
896 910
897 scheduleVisualUpdate(); 911 scheduleVisualUpdate();
898 } 912 }
899 913
900 void FrameSelection::notifyEventHandlerForSelectionChange() 914 void FrameSelection::notifyEventHandlerForSelectionChange()
901 { 915 {
902 m_frame->eventHandler().selectionController().notifySelectionChanged(); 916 m_frame->eventHandler().selectionController().notifySelectionChanged();
903 } 917 }
904 918
905 void FrameSelection::focusedOrActiveStateChanged() 919 void FrameSelection::focusedOrActiveStateChanged()
906 { 920 {
907 bool activeAndFocused = isFocusedAndActive(); 921 bool activeAndFocused = isFocusedAndActive();
908 Document* document = m_frame->document();
909 922
910 // Trigger style invalidation from the focused element. Even though 923 // Trigger style invalidation from the focused element. Even though
911 // the focused element hasn't changed, the evaluation of focus pseudo 924 // the focused element hasn't changed, the evaluation of focus pseudo
912 // selectors are dependent on whether the frame is focused and active. 925 // selectors are dependent on whether the frame is focused and active.
913 if (Element* element = document->focusedElement()) 926 if (Element* element = document().focusedElement())
914 element->focusStateChanged(); 927 element->focusStateChanged();
915 928
916 document->updateStyleAndLayoutTree(); 929 document().updateStyleAndLayoutTree();
917 930
918 // Because LayoutObject::selectionBackgroundColor() and 931 // Because LayoutObject::selectionBackgroundColor() and
919 // LayoutObject::selectionForegroundColor() check if the frame is active, 932 // LayoutObject::selectionForegroundColor() check if the frame is active,
920 // we have to update places those colors were painted. 933 // we have to update places those colors were painted.
921 LayoutViewItem view = document->layoutViewItem(); 934 LayoutViewItem view = document().layoutViewItem();
922 if (!view.isNull()) 935 if (!view.isNull())
923 view.invalidatePaintForSelection(); 936 view.invalidatePaintForSelection();
924 937
925 // Caret appears in the active frame. 938 // Caret appears in the active frame.
926 if (activeAndFocused) 939 if (activeAndFocused)
927 setSelectionFromNone(); 940 setSelectionFromNone();
928 else 941 else
929 m_frame->spellChecker().spellCheckAfterBlur(); 942 m_frame->spellChecker().spellCheckAfterBlur();
930 m_frameCaret->setCaretVisibility(activeAndFocused ? CaretVisibility::Visible : CaretVisibility::Hidden); 943 m_frameCaret->setCaretVisibility(activeAndFocused ? CaretVisibility::Visible : CaretVisibility::Hidden);
931 944
932 // Update for caps lock state 945 // Update for caps lock state
933 m_frame->eventHandler().capsLockStateMayHaveChanged(); 946 m_frame->eventHandler().capsLockStateMayHaveChanged();
934 947
935 // Secure keyboard entry is set by the active frame. 948 // Secure keyboard entry is set by the active frame.
936 if (document->useSecureKeyboardEntryWhenActive()) 949 if (document().useSecureKeyboardEntryWhenActive())
937 setUseSecureKeyboardEntry(activeAndFocused); 950 setUseSecureKeyboardEntry(activeAndFocused);
938 } 951 }
939 952
940 void FrameSelection::pageActivationChanged() 953 void FrameSelection::pageActivationChanged()
941 { 954 {
942 focusedOrActiveStateChanged(); 955 focusedOrActiveStateChanged();
943 } 956 }
944 957
945 void FrameSelection::updateSecureKeyboardEntryIfActive() 958 void FrameSelection::updateSecureKeyboardEntryIfActive()
946 { 959 {
947 if (m_frame->document() && isFocusedAndActive()) 960 if (isFocusedAndActive())
948 setUseSecureKeyboardEntry(m_frame->document()->useSecureKeyboardEntryWhe nActive()); 961 setUseSecureKeyboardEntry(document().useSecureKeyboardEntryWhenActive()) ;
949 } 962 }
950 963
951 void FrameSelection::setUseSecureKeyboardEntry(bool enable) 964 void FrameSelection::setUseSecureKeyboardEntry(bool enable)
952 { 965 {
953 if (enable) 966 if (enable)
954 enableSecureTextInput(); 967 enableSecureTextInput();
955 else 968 else
956 disableSecureTextInput(); 969 disableSecureTextInput();
957 } 970 }
958 971
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1016 bool caretBrowsing = m_frame->settings() && m_frame->settings()->caretBrowsi ngEnabled(); 1029 bool caretBrowsing = m_frame->settings() && m_frame->settings()->caretBrowsi ngEnabled();
1017 if (caretBrowsing) { 1030 if (caretBrowsing) {
1018 if (Element* anchor = enclosingAnchorElement(base())) { 1031 if (Element* anchor = enclosingAnchorElement(base())) {
1019 m_frame->page()->focusController().setFocusedElement(anchor, m_frame ); 1032 m_frame->page()->focusController().setFocusedElement(anchor, m_frame );
1020 return; 1033 return;
1021 } 1034 }
1022 } 1035 }
1023 1036
1024 if (Element* target = rootEditableElement()) { 1037 if (Element* target = rootEditableElement()) {
1025 // Walk up the DOM tree to search for a node to focus. 1038 // Walk up the DOM tree to search for a node to focus.
1026 m_frame->document()->updateStyleAndLayoutTreeIgnorePendingStylesheets(); 1039 document().updateStyleAndLayoutTreeIgnorePendingStylesheets();
1027 while (target) { 1040 while (target) {
1028 // We don't want to set focus on a subframe when selecting in a pare nt frame, 1041 // We don't want to set focus on a subframe when selecting in a pare nt frame,
1029 // so add the !isFrameElement check here. There's probably a better way to make this 1042 // so add the !isFrameElement check here. There's probably a better way to make this
1030 // work in the long term, but this is the safest fix at this time. 1043 // work in the long term, but this is the safest fix at this time.
1031 if (target->isMouseFocusable() && !isFrameElement(target)) { 1044 if (target->isMouseFocusable() && !isFrameElement(target)) {
1032 m_frame->page()->focusController().setFocusedElement(target, m_f rame); 1045 m_frame->page()->focusController().setFocusedElement(target, m_f rame);
1033 return; 1046 return;
1034 } 1047 }
1035 target = target->parentOrShadowHostElement(); 1048 target = target->parentOrShadowHostElement();
1036 } 1049 }
1037 m_frame->document()->clearFocusedElement(); 1050 document().clearFocusedElement();
1038 } 1051 }
1039 1052
1040 if (caretBrowsing) 1053 if (caretBrowsing)
1041 m_frame->page()->focusController().setFocusedElement(0, m_frame); 1054 m_frame->page()->focusController().setFocusedElement(0, m_frame);
1042 } 1055 }
1043 1056
1044 static String extractSelectedText(const FrameSelection& selection, TextIteratorB ehavior behavior) 1057 static String extractSelectedText(const FrameSelection& selection, TextIteratorB ehavior behavior)
1045 { 1058 {
1046 const VisibleSelectionInFlatTree& visibleSelection = selection.visibleSelect ion<EditingInFlatTreeStrategy>(); 1059 const VisibleSelectionInFlatTree& visibleSelection = selection.visibleSelect ion<EditingInFlatTreeStrategy>();
1047 const EphemeralRangeInFlatTree& range = visibleSelection.toNormalizedEphemer alRange(); 1060 const EphemeralRangeInFlatTree& range = visibleSelection.toNormalizedEphemer alRange();
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1112 return frameResult; 1125 return frameResult;
1113 } 1126 }
1114 } 1127 }
1115 return 0; 1128 return 0;
1116 } 1129 }
1117 1130
1118 // We look for either the form containing the current focus, or for one immediat ely after it 1131 // We look for either the form containing the current focus, or for one immediat ely after it
1119 HTMLFormElement* FrameSelection::currentForm() const 1132 HTMLFormElement* FrameSelection::currentForm() const
1120 { 1133 {
1121 // Start looking either at the active (first responder) node, or where the s election is. 1134 // Start looking either at the active (first responder) node, or where the s election is.
1122 Node* start = m_frame->document()->focusedElement(); 1135 Node* start = document().focusedElement();
1123 if (!start) 1136 if (!start)
1124 start = this->start().anchorNode(); 1137 start = this->start().anchorNode();
1125 if (!start) 1138 if (!start)
1126 return 0; 1139 return 0;
1127 1140
1128 // Try walking up the node tree to find a form element. 1141 // Try walking up the node tree to find a form element.
1129 for (HTMLElement* element = Traversal<HTMLElement>::firstAncestorOrSelf(*sta rt); element; element = Traversal<HTMLElement>::firstAncestor(*element)) { 1142 for (HTMLElement* element = Traversal<HTMLElement>::firstAncestorOrSelf(*sta rt); element; element = Traversal<HTMLElement>::firstAncestor(*element)) {
1130 if (HTMLFormElement* form = associatedFormElement(*element)) 1143 if (HTMLFormElement* form = associatedFormElement(*element))
1131 return form; 1144 return form;
1132 } 1145 }
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
1231 1244
1232 void FrameSelection::showTreeForThis() const 1245 void FrameSelection::showTreeForThis() const
1233 { 1246 {
1234 selection().showTreeForThis(); 1247 selection().showTreeForThis();
1235 } 1248 }
1236 1249
1237 #endif 1250 #endif
1238 1251
1239 DEFINE_TRACE(FrameSelection) 1252 DEFINE_TRACE(FrameSelection)
1240 { 1253 {
1254 visitor->trace(m_document);
1241 visitor->trace(m_frame); 1255 visitor->trace(m_frame);
1242 visitor->trace(m_pendingSelection); 1256 visitor->trace(m_pendingSelection);
1243 visitor->trace(m_selectionEditor); 1257 visitor->trace(m_selectionEditor);
1244 visitor->trace(m_originalBase); 1258 visitor->trace(m_originalBase);
1245 visitor->trace(m_originalBaseInFlatTree); 1259 visitor->trace(m_originalBaseInFlatTree);
1246 visitor->trace(m_typingStyle); 1260 visitor->trace(m_typingStyle);
1247 visitor->trace(m_frameCaret); 1261 visitor->trace(m_frameCaret);
1248 } 1262 }
1249 1263
1250 void FrameSelection::scheduleVisualUpdate() const 1264 void FrameSelection::scheduleVisualUpdate() const
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
1364 1378
1365 void showTree(const blink::FrameSelection* sel) 1379 void showTree(const blink::FrameSelection* sel)
1366 { 1380 {
1367 if (sel) 1381 if (sel)
1368 sel->showTreeForThis(); 1382 sel->showTreeForThis();
1369 else 1383 else
1370 fprintf(stderr, "Cannot showTree for (nil) FrameSelection.\n"); 1384 fprintf(stderr, "Cannot showTree for (nil) FrameSelection.\n");
1371 } 1385 }
1372 1386
1373 #endif 1387 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698