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 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 notifyLayoutObjectOfSelectionChange(userTriggered); | 217 notifyLayoutObjectOfSelectionChange(userTriggered); |
218 return; | 218 return; |
219 } | 219 } |
220 | 220 |
221 const VisibleSelectionTemplate<Strategy> oldSelection = | 221 const VisibleSelectionTemplate<Strategy> oldSelection = |
222 visibleSelection<Strategy>(); | 222 visibleSelection<Strategy>(); |
223 const Position& oldSelectionStart = selection().start(); | 223 const Position& oldSelectionStart = selection().start(); |
224 | 224 |
225 m_handleVisibility = handleVisibility; | 225 m_handleVisibility = handleVisibility; |
226 m_selectionEditor->setVisibleSelection(s, options); | 226 m_selectionEditor->setVisibleSelection(s, options); |
227 m_frameCaret->setCaretRectNeedsUpdate(); | 227 scheduleVisualUpdateForPaintInvalidationIfNeeded(); |
228 | 228 |
229 if (!s.isNone() && !(options & DoNotSetFocus)) { | 229 if (!s.isNone() && !(options & DoNotSetFocus)) { |
230 setFocusedNodeIfNeeded(); | 230 setFocusedNodeIfNeeded(); |
231 // |setFocusedNodeIfNeeded()| dispatches sync events "FocusOut" and | 231 // |setFocusedNodeIfNeeded()| dispatches sync events "FocusOut" and |
232 // "FocusIn", |m_frame| may associate to another document. | 232 // "FocusIn", |m_frame| may associate to another document. |
233 if (!isAvailable() || document() != currentDocument) { | 233 if (!isAvailable() || document() != currentDocument) { |
234 // Once we get test case to reach here, we should change this | 234 // Once we get test case to reach here, we should change this |
235 // if-statement to |DCHECK()|. | 235 // if-statement to |DCHECK()|. |
236 NOTREACHED(); | 236 NOTREACHED(); |
237 return; | 237 return; |
238 } | 238 } |
239 } | 239 } |
240 | 240 |
241 if (!(options & DoNotUpdateAppearance)) { | 241 if (!(options & DoNotUpdateAppearance)) { |
242 // Hits in | |
243 // compositing/overflow/do-not-paint-outline-into-composited-scrolling-conte
nts.html | |
244 DisableCompositingQueryAsserts disabler; | |
245 m_frameCaret->stopCaretBlinkTimer(); | 242 m_frameCaret->stopCaretBlinkTimer(); |
246 updateAppearance(); | 243 updateAppearance(); |
247 } | 244 } |
248 | 245 |
249 // Always clear the x position used for vertical arrow navigation. | 246 // Always clear the x position used for vertical arrow navigation. |
250 // It will be restored by the vertical arrow navigation code if necessary. | 247 // It will be restored by the vertical arrow navigation code if necessary. |
251 m_xPosForVerticalArrowNavigation = NoXPosForVerticalArrowNavigation(); | 248 m_xPosForVerticalArrowNavigation = NoXPosForVerticalArrowNavigation(); |
252 // This may dispatch a synchronous focus-related events. | 249 // This may dispatch a synchronous focus-related events. |
253 selectFrameElementInParentIfFullySelected(); | 250 selectFrameElementInParentIfFullySelected(); |
254 if (!isAvailable() || document() != currentDocument) { | 251 if (!isAvailable() || document() != currentDocument) { |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
379 const Position& oldExtent = selection().extent(); | 376 const Position& oldExtent = selection().extent(); |
380 const Position& newExtent = | 377 const Position& newExtent = |
381 computePositionForChildrenRemoval(oldExtent, container); | 378 computePositionForChildrenRemoval(oldExtent, container); |
382 if (newStart == oldStart && newEnd == oldEnd && newBase == oldBase && | 379 if (newStart == oldStart && newEnd == oldEnd && newBase == oldBase && |
383 newExtent == oldExtent) | 380 newExtent == oldExtent) |
384 return; | 381 return; |
385 if (selection().isBaseFirst()) | 382 if (selection().isBaseFirst()) |
386 m_selectionEditor->setWithoutValidation(newStart, newEnd); | 383 m_selectionEditor->setWithoutValidation(newStart, newEnd); |
387 else | 384 else |
388 m_selectionEditor->setWithoutValidation(newEnd, newStart); | 385 m_selectionEditor->setWithoutValidation(newEnd, newStart); |
389 m_frameCaret->setCaretRectNeedsUpdate(); | |
390 if (document().isRunningExecCommand()) | 386 if (document().isRunningExecCommand()) |
391 return; | 387 return; |
392 TypingCommand::closeTyping(m_frame); | 388 TypingCommand::closeTyping(m_frame); |
393 } | 389 } |
394 | 390 |
395 void FrameSelection::nodeWillBeRemoved(Node& node) { | 391 void FrameSelection::nodeWillBeRemoved(Node& node) { |
396 // There can't be a selection inside a fragment, so if a fragment's node is | 392 // There can't be a selection inside a fragment, so if a fragment's node is |
397 // being removed, the selection in the document that created the fragment | 393 // being removed, the selection in the document that created the fragment |
398 // needs no adjustment. | 394 // needs no adjustment. |
399 if (isNone() || !node.inActiveDocument()) | 395 if (isNone() || !node.inActiveDocument()) |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
459 // TODO(yosin): We should paint changed area only rather than whole | 455 // TODO(yosin): We should paint changed area only rather than whole |
460 // selected range. | 456 // selected range. |
461 clearLayoutTreeSelection = true; | 457 clearLayoutTreeSelection = true; |
462 } | 458 } |
463 | 459 |
464 if (clearLayoutTreeSelection) | 460 if (clearLayoutTreeSelection) |
465 selection().start().document()->layoutViewItem().clearSelection(); | 461 selection().start().document()->layoutViewItem().clearSelection(); |
466 | 462 |
467 if (clearDOMTreeSelection) | 463 if (clearDOMTreeSelection) |
468 setSelection(SelectionInDOMTree(), DoNotSetFocus); | 464 setSelection(SelectionInDOMTree(), DoNotSetFocus); |
469 m_frameCaret->setCaretRectNeedsUpdate(); | |
470 | 465 |
471 // TODO(yosin): We should move to call |TypingCommand::closeTyping()| to | 466 // TODO(yosin): We should move to call |TypingCommand::closeTyping()| to |
472 // |Editor| class. | 467 // |Editor| class. |
473 if (!document().isRunningExecCommand()) | 468 if (!document().isRunningExecCommand()) |
474 TypingCommand::closeTyping(m_frame); | 469 TypingCommand::closeTyping(m_frame); |
475 } | 470 } |
476 | 471 |
477 static Position updatePositionAfterAdoptingTextReplacement( | 472 static Position updatePositionAfterAdoptingTextReplacement( |
478 const Position& position, | 473 const Position& position, |
479 CharacterData* node, | 474 CharacterData* node, |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
670 CloseTyping | ClearTypingStyle | userTriggered; | 665 CloseTyping | ClearTypingStyle | userTriggered; |
671 setSelection(selectionModifier.selection(), options); | 666 setSelection(selectionModifier.selection(), options); |
672 | 667 |
673 if (granularity == LineGranularity || granularity == ParagraphGranularity) | 668 if (granularity == LineGranularity || granularity == ParagraphGranularity) |
674 m_xPosForVerticalArrowNavigation = | 669 m_xPosForVerticalArrowNavigation = |
675 selectionModifier.xPosForVerticalArrowNavigation(); | 670 selectionModifier.xPosForVerticalArrowNavigation(); |
676 | 671 |
677 if (userTriggered == UserTriggered) | 672 if (userTriggered == UserTriggered) |
678 m_granularity = CharacterGranularity; | 673 m_granularity = CharacterGranularity; |
679 | 674 |
680 m_frameCaret->setCaretRectNeedsUpdate(); | 675 scheduleVisualUpdateForPaintInvalidationIfNeeded(); |
681 | 676 |
682 return true; | 677 return true; |
683 } | 678 } |
684 | 679 |
685 bool FrameSelection::modify(EAlteration alter, | 680 bool FrameSelection::modify(EAlteration alter, |
686 unsigned verticalDistance, | 681 unsigned verticalDistance, |
687 VerticalDirection direction) { | 682 VerticalDirection direction) { |
688 SelectionModifier selectionModifier(*frame(), selection()); | 683 SelectionModifier selectionModifier(*frame(), selection()); |
689 if (!selectionModifier.modifyWithPageGranularity(alter, verticalDistance, | 684 if (!selectionModifier.modifyWithPageGranularity(alter, verticalDistance, |
690 direction)) { | 685 direction)) { |
(...skipping 14 matching lines...) Expand all Loading... |
705 m_granularity = CharacterGranularity; | 700 m_granularity = CharacterGranularity; |
706 if (m_granularityStrategy) | 701 if (m_granularityStrategy) |
707 m_granularityStrategy->Clear(); | 702 m_granularityStrategy->Clear(); |
708 setSelection(SelectionInDOMTree()); | 703 setSelection(SelectionInDOMTree()); |
709 } | 704 } |
710 | 705 |
711 void FrameSelection::documentAttached(Document* document) { | 706 void FrameSelection::documentAttached(Document* document) { |
712 DCHECK(document); | 707 DCHECK(document); |
713 m_useSecureKeyboardEntryWhenActive = false; | 708 m_useSecureKeyboardEntryWhenActive = false; |
714 m_selectionEditor->documentAttached(document); | 709 m_selectionEditor->documentAttached(document); |
715 m_frameCaret->documentAttached(document); | |
716 setContext(document); | 710 setContext(document); |
717 } | 711 } |
718 | 712 |
719 void FrameSelection::contextDestroyed(Document* document) { | 713 void FrameSelection::contextDestroyed(Document* document) { |
720 m_granularity = CharacterGranularity; | 714 m_granularity = CharacterGranularity; |
721 | 715 |
722 LayoutViewItem view = m_frame->contentLayoutItem(); | 716 LayoutViewItem view = m_frame->contentLayoutItem(); |
723 if (!view.isNull()) | 717 if (!view.isNull()) |
724 view.clearSelection(); | 718 view.clearSelection(); |
725 | 719 |
726 m_frame->editor().clearTypingStyle(); | 720 m_frame->editor().clearTypingStyle(); |
727 m_selectionEditor->documentDetached(*document); | 721 m_selectionEditor->documentDetached(*document); |
728 } | 722 } |
729 | 723 |
730 bool FrameSelection::hasCaretIn(const LayoutBlock& layoubBlock) const { | 724 void FrameSelection::clearPreviousCaretVisualRect(const LayoutBlock& block) { |
| 725 m_frameCaret->clearPreviousVisualRect(block); |
| 726 } |
| 727 |
| 728 void FrameSelection::layoutBlockWillBeDestroyed(const LayoutBlock& block) { |
| 729 m_frameCaret->layoutBlockWillBeDestroyed(block); |
| 730 } |
| 731 |
| 732 void FrameSelection::updateStyleAndLayoutIfNeeded() { |
| 733 m_frameCaret->updateStyleAndLayoutIfNeeded(); |
| 734 } |
| 735 |
| 736 void FrameSelection::invalidatePaintIfNeeded( |
| 737 const LayoutBlock& block, |
| 738 const PaintInvalidatorContext& context, |
| 739 PaintInvalidationReason reason) { |
| 740 m_frameCaret->invalidatePaintIfNeeded(block, context, reason); |
| 741 } |
| 742 |
| 743 bool FrameSelection::shouldPaintCaret(const LayoutBlock& block) const { |
731 DCHECK(selection().isValidFor(document())); | 744 DCHECK(selection().isValidFor(document())); |
732 if (!isCaret()) | 745 |
733 return false; | 746 bool result = m_frameCaret->shouldPaintCaret(block); |
734 return CaretDisplayItemClient::caretLayoutObject( | 747 DCHECK(!result || (isCaret() && hasEditableStyle())); |
735 selection().start().anchorNode()) == layoubBlock && | 748 return result; |
736 hasEditableStyle(); | |
737 } | 749 } |
738 | 750 |
739 IntRect FrameSelection::absoluteCaretBounds() { | 751 IntRect FrameSelection::absoluteCaretBounds() { |
740 DCHECK(selection().isValidFor(*m_frame->document())); | 752 DCHECK(selection().isValidFor(*m_frame->document())); |
741 return m_frameCaret->absoluteCaretBounds(); | 753 return m_frameCaret->absoluteCaretBounds(); |
742 } | 754 } |
743 | 755 |
744 void FrameSelection::invalidateCaretRect(bool forceInvalidation) { | |
745 m_frameCaret->invalidateCaretRect(forceInvalidation); | |
746 } | |
747 | |
748 void FrameSelection::dataWillChange(const CharacterData& node) { | |
749 m_frameCaret->dataWillChange(node); | |
750 } | |
751 | |
752 void FrameSelection::paintCaret(GraphicsContext& context, | 756 void FrameSelection::paintCaret(GraphicsContext& context, |
753 const LayoutPoint& paintOffset) { | 757 const LayoutPoint& paintOffset) { |
754 m_frameCaret->paintCaret(context, paintOffset); | 758 m_frameCaret->paintCaret(context, paintOffset); |
755 } | 759 } |
756 | 760 |
757 bool FrameSelection::contains(const LayoutPoint& point) { | 761 bool FrameSelection::contains(const LayoutPoint& point) { |
758 if (document().layoutViewItem().isNull()) | 762 if (document().layoutViewItem().isNull()) |
759 return false; | 763 return false; |
760 | 764 |
761 // Treat a collapsed selection like no selection. | 765 // Treat a collapsed selection like no selection. |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1044 | 1048 |
1045 bool FrameSelection::isAppearanceDirty() const { | 1049 bool FrameSelection::isAppearanceDirty() const { |
1046 return m_pendingSelection->hasPendingSelection(); | 1050 return m_pendingSelection->hasPendingSelection(); |
1047 } | 1051 } |
1048 | 1052 |
1049 void FrameSelection::commitAppearanceIfNeeded(LayoutView& layoutView) { | 1053 void FrameSelection::commitAppearanceIfNeeded(LayoutView& layoutView) { |
1050 return m_pendingSelection->commit(layoutView); | 1054 return m_pendingSelection->commit(layoutView); |
1051 } | 1055 } |
1052 | 1056 |
1053 void FrameSelection::didLayout() { | 1057 void FrameSelection::didLayout() { |
1054 setCaretRectNeedsUpdate(); | |
1055 updateAppearance(); | 1058 updateAppearance(); |
1056 } | 1059 } |
1057 | 1060 |
1058 void FrameSelection::updateAppearance() { | 1061 void FrameSelection::updateAppearance() { |
1059 m_frameCaret->updateAppearance(); | 1062 m_frameCaret->updateAppearance(); |
1060 | 1063 |
1061 if (m_frame->contentLayoutItem().isNull()) | 1064 if (m_frame->contentLayoutItem().isNull()) |
1062 return; | 1065 return; |
1063 m_pendingSelection->setHasPendingSelection(); | 1066 m_pendingSelection->setHasPendingSelection(); |
1064 } | 1067 } |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1304 visitor->trace(m_selectionEditor); | 1307 visitor->trace(m_selectionEditor); |
1305 visitor->trace(m_frameCaret); | 1308 visitor->trace(m_frameCaret); |
1306 SynchronousMutationObserver::trace(visitor); | 1309 SynchronousMutationObserver::trace(visitor); |
1307 } | 1310 } |
1308 | 1311 |
1309 void FrameSelection::scheduleVisualUpdate() const { | 1312 void FrameSelection::scheduleVisualUpdate() const { |
1310 if (Page* page = m_frame->page()) | 1313 if (Page* page = m_frame->page()) |
1311 page->animator().scheduleVisualUpdate(m_frame->localFrameRoot()); | 1314 page->animator().scheduleVisualUpdate(m_frame->localFrameRoot()); |
1312 } | 1315 } |
1313 | 1316 |
| 1317 void FrameSelection::scheduleVisualUpdateForPaintInvalidationIfNeeded() const { |
| 1318 if (FrameView* frameView = m_frame->view()) |
| 1319 frameView->scheduleVisualUpdateForPaintInvalidationIfNeeded(); |
| 1320 } |
| 1321 |
1314 bool FrameSelection::selectWordAroundPosition(const VisiblePosition& position) { | 1322 bool FrameSelection::selectWordAroundPosition(const VisiblePosition& position) { |
1315 static const EWordSide wordSideList[2] = {RightWordIfOnBoundary, | 1323 static const EWordSide wordSideList[2] = {RightWordIfOnBoundary, |
1316 LeftWordIfOnBoundary}; | 1324 LeftWordIfOnBoundary}; |
1317 for (EWordSide wordSide : wordSideList) { | 1325 for (EWordSide wordSide : wordSideList) { |
1318 VisiblePosition start = startOfWord(position, wordSide); | 1326 VisiblePosition start = startOfWord(position, wordSide); |
1319 VisiblePosition end = endOfWord(position, wordSide); | 1327 VisiblePosition end = endOfWord(position, wordSide); |
1320 String text = | 1328 String text = |
1321 plainText(EphemeralRange(start.deepEquivalent(), end.deepEquivalent())); | 1329 plainText(EphemeralRange(start.deepEquivalent(), end.deepEquivalent())); |
1322 if (!text.isEmpty() && !isSeparator(text.characterStartingAt(0))) { | 1330 if (!text.isEmpty() && !isSeparator(text.characterStartingAt(0))) { |
1323 setSelection(SelectionInDOMTree::Builder() | 1331 setSelection(SelectionInDOMTree::Builder() |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1393 void FrameSelection::updateIfNeeded() { | 1401 void FrameSelection::updateIfNeeded() { |
1394 DCHECK(!m_frame->document()->needsLayoutTreeUpdate()); | 1402 DCHECK(!m_frame->document()->needsLayoutTreeUpdate()); |
1395 m_selectionEditor->updateIfNeeded(); | 1403 m_selectionEditor->updateIfNeeded(); |
1396 } | 1404 } |
1397 | 1405 |
1398 void FrameSelection::setCaretVisible(bool caretIsVisible) { | 1406 void FrameSelection::setCaretVisible(bool caretIsVisible) { |
1399 m_frameCaret->setCaretVisibility(caretIsVisible ? CaretVisibility::Visible | 1407 m_frameCaret->setCaretVisibility(caretIsVisible ? CaretVisibility::Visible |
1400 : CaretVisibility::Hidden); | 1408 : CaretVisibility::Hidden); |
1401 } | 1409 } |
1402 | 1410 |
1403 bool FrameSelection::shouldPaintCaretForTesting() const { | |
1404 return m_frameCaret->shouldPaintCaretForTesting(); | |
1405 } | |
1406 | |
1407 bool FrameSelection::isPreviousCaretDirtyForTesting() const { | |
1408 return m_frameCaret->isPreviousCaretDirtyForTesting(); | |
1409 } | |
1410 | |
1411 void FrameSelection::setCaretRectNeedsUpdate() { | |
1412 m_frameCaret->setCaretRectNeedsUpdate(); | |
1413 } | |
1414 | |
1415 void FrameSelection::setCaretBlinkingSuspended(bool suspended) { | 1411 void FrameSelection::setCaretBlinkingSuspended(bool suspended) { |
1416 m_frameCaret->setCaretBlinkingSuspended(suspended); | 1412 m_frameCaret->setCaretBlinkingSuspended(suspended); |
1417 } | 1413 } |
1418 | 1414 |
1419 bool FrameSelection::isCaretBlinkingSuspended() const { | 1415 bool FrameSelection::isCaretBlinkingSuspended() const { |
1420 return m_frameCaret->isCaretBlinkingSuspended(); | 1416 return m_frameCaret->isCaretBlinkingSuspended(); |
1421 } | 1417 } |
1422 | 1418 |
1423 } // namespace blink | 1419 } // namespace blink |
1424 | 1420 |
1425 #ifndef NDEBUG | 1421 #ifndef NDEBUG |
1426 | 1422 |
1427 void showTree(const blink::FrameSelection& sel) { | 1423 void showTree(const blink::FrameSelection& sel) { |
1428 sel.showTreeForThis(); | 1424 sel.showTreeForThis(); |
1429 } | 1425 } |
1430 | 1426 |
1431 void showTree(const blink::FrameSelection* sel) { | 1427 void showTree(const blink::FrameSelection* sel) { |
1432 if (sel) | 1428 if (sel) |
1433 sel->showTreeForThis(); | 1429 sel->showTreeForThis(); |
1434 else | 1430 else |
1435 LOG(INFO) << "Cannot showTree for <null> FrameSelection."; | 1431 LOG(INFO) << "Cannot showTree for <null> FrameSelection."; |
1436 } | 1432 } |
1437 | 1433 |
1438 #endif | 1434 #endif |
OLD | NEW |