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 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 422 return false; | 422 return false; |
| 423 Position start = selection.start().parentAnchoredEquivalent(); | 423 Position start = selection.start().parentAnchoredEquivalent(); |
| 424 Position end = selection.end().parentAnchoredEquivalent(); | 424 Position end = selection.end().parentAnchoredEquivalent(); |
| 425 TrackExceptionState exceptionState; | 425 TrackExceptionState exceptionState; |
| 426 // TODO(yosin) We should avoid to use |Range::intersectsNode()|. | 426 // TODO(yosin) We should avoid to use |Range::intersectsNode()|. |
| 427 return Range::intersectsNode(node, start, end, exceptionState) && !exception State.hadException(); | 427 return Range::intersectsNode(node, start, end, exceptionState) && !exception State.hadException(); |
| 428 } | 428 } |
| 429 | 429 |
| 430 void FrameSelection::respondToNodeModification(Node& node, bool baseRemoved, boo l extentRemoved, bool startRemoved, bool endRemoved) | 430 void FrameSelection::respondToNodeModification(Node& node, bool baseRemoved, boo l extentRemoved, bool startRemoved, bool endRemoved) |
| 431 { | 431 { |
| 432 ASSERT(node.document().isActive()); | 432 DCHECK(node.document().isActive()); |
|
yosin_UTC9
2016/04/14 04:35:00
How about adding |<< node|?
| |
| 433 | 433 |
| 434 bool clearLayoutTreeSelection = false; | 434 bool clearLayoutTreeSelection = false; |
| 435 bool clearDOMTreeSelection = false; | 435 bool clearDOMTreeSelection = false; |
| 436 | 436 |
| 437 if (startRemoved || endRemoved) { | 437 if (startRemoved || endRemoved) { |
| 438 Position start = selection().start(); | 438 Position start = selection().start(); |
| 439 Position end = selection().end(); | 439 Position end = selection().end(); |
| 440 if (startRemoved) | 440 if (startRemoved) |
| 441 updatePositionForNodeRemoval(start, node); | 441 updatePositionForNodeRemoval(start, node); |
| 442 if (endRemoved) | 442 if (endRemoved) |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 480 if (!m_frame->document()->isRunningExecCommand()) | 480 if (!m_frame->document()->isRunningExecCommand()) |
| 481 TypingCommand::closeTyping(m_frame); | 481 TypingCommand::closeTyping(m_frame); |
| 482 } | 482 } |
| 483 | 483 |
| 484 static Position updatePositionAfterAdoptingTextReplacement(const Position& posit ion, CharacterData* node, unsigned offset, unsigned oldLength, unsigned newLengt h) | 484 static Position updatePositionAfterAdoptingTextReplacement(const Position& posit ion, CharacterData* node, unsigned offset, unsigned oldLength, unsigned newLengt h) |
| 485 { | 485 { |
| 486 if (!position.anchorNode() || position.anchorNode() != node || !position.isO ffsetInAnchor()) | 486 if (!position.anchorNode() || position.anchorNode() != node || !position.isO ffsetInAnchor()) |
| 487 return position; | 487 return position; |
| 488 | 488 |
| 489 // See: http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2 -Range-Mutation | 489 // See: http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2 -Range-Mutation |
| 490 ASSERT(position.offsetInContainerNode() >= 0); | 490 DCHECK_GE(position.offsetInContainerNode(), 0); |
| 491 unsigned positionOffset = static_cast<unsigned>(position.offsetInContainerNo de()); | 491 unsigned positionOffset = static_cast<unsigned>(position.offsetInContainerNo de()); |
| 492 // Replacing text can be viewed as a deletion followed by insertion. | 492 // Replacing text can be viewed as a deletion followed by insertion. |
| 493 if (positionOffset >= offset && positionOffset <= offset + oldLength) | 493 if (positionOffset >= offset && positionOffset <= offset + oldLength) |
| 494 positionOffset = offset; | 494 positionOffset = offset; |
| 495 | 495 |
| 496 // Adjust the offset if the position is after the end of the deleted content s | 496 // Adjust the offset if the position is after the end of the deleted content s |
| 497 // (positionOffset > offset + oldLength) to avoid having a stale offset. | 497 // (positionOffset > offset + oldLength) to avoid having a stale offset. |
| 498 if (positionOffset > offset + oldLength) | 498 if (positionOffset > offset + oldLength) |
| 499 positionOffset = positionOffset - oldLength + newLength; | 499 positionOffset = positionOffset - oldLength + newLength; |
| 500 | 500 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 521 Position start = updatePositionAfterAdoptingTextReplacement(selection().star t(), node, offset, oldLength, newLength); | 521 Position start = updatePositionAfterAdoptingTextReplacement(selection().star t(), node, offset, oldLength, newLength); |
| 522 Position end = updatePositionAfterAdoptingTextReplacement(selection().end(), node, offset, oldLength, newLength); | 522 Position end = updatePositionAfterAdoptingTextReplacement(selection().end(), node, offset, oldLength, newLength); |
| 523 updateSelectionIfNeeded(base, extent, start, end); | 523 updateSelectionIfNeeded(base, extent, start, end); |
| 524 } | 524 } |
| 525 | 525 |
| 526 static Position updatePostionAfterAdoptingTextNodesMerged(const Position& positi on, const Text& oldNode, unsigned offset) | 526 static Position updatePostionAfterAdoptingTextNodesMerged(const Position& positi on, const Text& oldNode, unsigned offset) |
| 527 { | 527 { |
| 528 if (!position.anchorNode() || !position.isOffsetInAnchor()) | 528 if (!position.anchorNode() || !position.isOffsetInAnchor()) |
| 529 return position; | 529 return position; |
| 530 | 530 |
| 531 ASSERT(position.offsetInContainerNode() >= 0); | 531 DCHECK_GE(position.offsetInContainerNode(), 0); |
| 532 unsigned positionOffset = static_cast<unsigned>(position.offsetInContainerNo de()); | 532 unsigned positionOffset = static_cast<unsigned>(position.offsetInContainerNo de()); |
| 533 | 533 |
| 534 if (position.anchorNode() == &oldNode) | 534 if (position.anchorNode() == &oldNode) |
| 535 return Position(toText(oldNode.previousSibling()), positionOffset + offs et); | 535 return Position(toText(oldNode.previousSibling()), positionOffset + offs et); |
| 536 | 536 |
| 537 if (position.anchorNode() == oldNode.parentNode() && positionOffset == offse t) | 537 if (position.anchorNode() == oldNode.parentNode() && positionOffset == offse t) |
| 538 return Position(toText(oldNode.previousSibling()), offset); | 538 return Position(toText(oldNode.previousSibling()), offset); |
| 539 | 539 |
| 540 return position; | 540 return position; |
| 541 } | 541 } |
| 542 | 542 |
| 543 void FrameSelection::didMergeTextNodes(const Text& oldNode, unsigned offset) | 543 void FrameSelection::didMergeTextNodes(const Text& oldNode, unsigned offset) |
| 544 { | 544 { |
| 545 if (isNone() || !oldNode.inShadowIncludingDocument()) | 545 if (isNone() || !oldNode.inShadowIncludingDocument()) |
| 546 return; | 546 return; |
| 547 Position base = updatePostionAfterAdoptingTextNodesMerged(selection().base() , oldNode, offset); | 547 Position base = updatePostionAfterAdoptingTextNodesMerged(selection().base() , oldNode, offset); |
| 548 Position extent = updatePostionAfterAdoptingTextNodesMerged(selection().exte nt(), oldNode, offset); | 548 Position extent = updatePostionAfterAdoptingTextNodesMerged(selection().exte nt(), oldNode, offset); |
| 549 Position start = updatePostionAfterAdoptingTextNodesMerged(selection().start (), oldNode, offset); | 549 Position start = updatePostionAfterAdoptingTextNodesMerged(selection().start (), oldNode, offset); |
| 550 Position end = updatePostionAfterAdoptingTextNodesMerged(selection().end(), oldNode, offset); | 550 Position end = updatePostionAfterAdoptingTextNodesMerged(selection().end(), oldNode, offset); |
| 551 updateSelectionIfNeeded(base, extent, start, end); | 551 updateSelectionIfNeeded(base, extent, start, end); |
| 552 } | 552 } |
| 553 | 553 |
| 554 static Position updatePostionAfterAdoptingTextNodeSplit(const Position& position , const Text& oldNode) | 554 static Position updatePostionAfterAdoptingTextNodeSplit(const Position& position , const Text& oldNode) |
| 555 { | 555 { |
| 556 if (!position.anchorNode() || position.anchorNode() != &oldNode || !position .isOffsetInAnchor()) | 556 if (!position.anchorNode() || position.anchorNode() != &oldNode || !position .isOffsetInAnchor()) |
| 557 return position; | 557 return position; |
| 558 // See: http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2 -Range-Mutation | 558 // See: http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2 -Range-Mutation |
| 559 ASSERT(position.offsetInContainerNode() >= 0); | 559 DCHECK_GE(position.offsetInContainerNode(), 0); |
| 560 unsigned positionOffset = static_cast<unsigned>(position.offsetInContainerNo de()); | 560 unsigned positionOffset = static_cast<unsigned>(position.offsetInContainerNo de()); |
| 561 unsigned oldLength = oldNode.length(); | 561 unsigned oldLength = oldNode.length(); |
| 562 if (positionOffset <= oldLength) | 562 if (positionOffset <= oldLength) |
| 563 return position; | 563 return position; |
| 564 return Position(toText(oldNode.nextSibling()), positionOffset - oldLength); | 564 return Position(toText(oldNode.nextSibling()), positionOffset - oldLength); |
| 565 } | 565 } |
| 566 | 566 |
| 567 void FrameSelection::didSplitTextNode(const Text& oldNode) | 567 void FrameSelection::didSplitTextNode(const Text& oldNode) |
| 568 { | 568 { |
| 569 if (isNone() || !oldNode.inShadowIncludingDocument()) | 569 if (isNone() || !oldNode.inShadowIncludingDocument()) |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 673 setSelection(VisibleSelection(selection().base(), pos.deepEquivalent(), pos. affinity(), selectionHasDirection), CloseTyping | ClearTypingStyle | userTrigger ed); | 673 setSelection(VisibleSelection(selection().base(), pos.deepEquivalent(), pos. affinity(), selectionHasDirection), CloseTyping | ClearTypingStyle | userTrigger ed); |
| 674 } | 674 } |
| 675 | 675 |
| 676 static bool isTextFormControl(const VisibleSelection& selection) | 676 static bool isTextFormControl(const VisibleSelection& selection) |
| 677 { | 677 { |
| 678 return enclosingTextFormControl(selection.start()); | 678 return enclosingTextFormControl(selection.start()); |
| 679 } | 679 } |
| 680 | 680 |
| 681 LayoutBlock* FrameSelection::caretLayoutObject() const | 681 LayoutBlock* FrameSelection::caretLayoutObject() const |
| 682 { | 682 { |
| 683 ASSERT(selection().isValidFor(*m_frame->document())); | 683 DCHECK(selection().isValidFor(*m_frame->document())); |
| 684 if (!isCaret()) | 684 if (!isCaret()) |
| 685 return nullptr; | 685 return nullptr; |
| 686 return CaretBase::caretLayoutObject(selection().start().anchorNode()); | 686 return CaretBase::caretLayoutObject(selection().start().anchorNode()); |
| 687 } | 687 } |
| 688 | 688 |
| 689 IntRect FrameSelection::absoluteCaretBounds() | 689 IntRect FrameSelection::absoluteCaretBounds() |
| 690 { | 690 { |
| 691 ASSERT(selection().isValidFor(*m_frame->document())); | 691 DCHECK(selection().isValidFor(*m_frame->document())); |
| 692 ASSERT(m_frame->document()->lifecycle().state() != DocumentLifecycle::InPain tInvalidation); | 692 DCHECK_NE(m_frame->document()->lifecycle().state(), DocumentLifecycle::InPai ntInvalidation); |
| 693 m_frame->document()->updateLayoutIgnorePendingStylesheets(); | 693 m_frame->document()->updateLayoutIgnorePendingStylesheets(); |
| 694 if (!isCaret()) { | 694 if (!isCaret()) { |
| 695 m_caretBase->clearCaretRect(); | 695 m_caretBase->clearCaretRect(); |
| 696 } else { | 696 } else { |
| 697 if (isTextFormControl(selection())) | 697 if (isTextFormControl(selection())) |
| 698 m_caretBase->updateCaretRect(PositionWithAffinity(isVisuallyEquivale ntCandidate(selection().start()) ? selection().start() : Position(), selection() .affinity())); | 698 m_caretBase->updateCaretRect(PositionWithAffinity(isVisuallyEquivale ntCandidate(selection().start()) ? selection().start() : Position(), selection() .affinity())); |
| 699 else | 699 else |
| 700 m_caretBase->updateCaretRect(createVisiblePosition(selection().start (), selection().affinity())); | 700 m_caretBase->updateCaretRect(createVisiblePosition(selection().start (), selection().affinity())); |
| 701 } | 701 } |
| 702 return m_caretBase->absoluteBoundsForLocalRect(selection().start().anchorNod e(), m_caretBase->localCaretRectWithoutUpdate()); | 702 return m_caretBase->absoluteBoundsForLocalRect(selection().start().anchorNod e(), m_caretBase->localCaretRectWithoutUpdate()); |
| 703 } | 703 } |
| 704 | 704 |
| 705 void FrameSelection::invalidateCaretRect() | 705 void FrameSelection::invalidateCaretRect() |
| 706 { | 706 { |
| 707 if (!m_caretRectDirty) | 707 if (!m_caretRectDirty) |
| 708 return; | 708 return; |
| 709 m_caretRectDirty = false; | 709 m_caretRectDirty = false; |
| 710 | 710 |
| 711 ASSERT(selection().isValidFor(*m_frame->document())); | 711 DCHECK(selection().isValidFor(*m_frame->document())); |
| 712 LayoutObject* layoutObject = nullptr; | 712 LayoutObject* layoutObject = nullptr; |
| 713 LayoutRect newRect; | 713 LayoutRect newRect; |
| 714 if (selection().isCaret()) | 714 if (selection().isCaret()) |
| 715 newRect = localCaretRectOfPosition(PositionWithAffinity(selection().star t(), selection().affinity()), layoutObject); | 715 newRect = localCaretRectOfPosition(PositionWithAffinity(selection().star t(), selection().affinity()), layoutObject); |
| 716 Node* newNode = layoutObject ? layoutObject->node() : nullptr; | 716 Node* newNode = layoutObject ? layoutObject->node() : nullptr; |
| 717 | 717 |
| 718 if (!m_caretBlinkTimer.isActive() | 718 if (!m_caretBlinkTimer.isActive() |
| 719 && newNode == m_previousCaretNode | 719 && newNode == m_previousCaretNode |
| 720 && newRect == m_previousCaretRect | 720 && newRect == m_previousCaretRect |
| 721 && m_caretBase->getCaretVisibility() == m_previousCaretVisibility) | 721 && m_caretBase->getCaretVisibility() == m_previousCaretVisibility) |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 869 VisibleSelection newSelection(VisibleSelection::selectionFromContentsOfNode( root)); | 869 VisibleSelection newSelection(VisibleSelection::selectionFromContentsOfNode( root)); |
| 870 setSelection(newSelection); | 870 setSelection(newSelection); |
| 871 selectFrameElementInParentIfFullySelected(); | 871 selectFrameElementInParentIfFullySelected(); |
| 872 notifyLayoutObjectOfSelectionChange(UserTriggered); | 872 notifyLayoutObjectOfSelectionChange(UserTriggered); |
| 873 } | 873 } |
| 874 | 874 |
| 875 bool FrameSelection::setSelectedRange(Range* range, TextAffinity affinity, Selec tionDirectionalMode directional, SetSelectionOptions options) | 875 bool FrameSelection::setSelectedRange(Range* range, TextAffinity affinity, Selec tionDirectionalMode directional, SetSelectionOptions options) |
| 876 { | 876 { |
| 877 if (!range || !range->inShadowIncludingDocument()) | 877 if (!range || !range->inShadowIncludingDocument()) |
| 878 return false; | 878 return false; |
| 879 ASSERT(range->startContainer()->document() == range->endContainer()->documen t()); | 879 DCHECK_EQ(range->startContainer()->document(), range->endContainer()->docume nt()); |
| 880 return setSelectedRange(EphemeralRange(range), affinity, directional, option s); | 880 return setSelectedRange(EphemeralRange(range), affinity, directional, option s); |
| 881 } | 881 } |
| 882 | 882 |
| 883 bool FrameSelection::setSelectedRange(const EphemeralRange& range, TextAffinity affinity, SelectionDirectionalMode directional, SetSelectionOptions options) | 883 bool FrameSelection::setSelectedRange(const EphemeralRange& range, TextAffinity affinity, SelectionDirectionalMode directional, SetSelectionOptions options) |
| 884 { | 884 { |
| 885 return m_selectionEditor->setSelectedRange(range, affinity, directional, opt ions); | 885 return m_selectionEditor->setSelectedRange(range, affinity, directional, opt ions); |
| 886 } | 886 } |
| 887 | 887 |
| 888 Range* FrameSelection::firstRange() const | 888 Range* FrameSelection::firstRange() const |
| 889 { | 889 { |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1051 | 1051 |
| 1052 Element* focusedElement = root->document().focusedElement(); | 1052 Element* focusedElement = root->document().focusedElement(); |
| 1053 if (!focusedElement) | 1053 if (!focusedElement) |
| 1054 return false; | 1054 return false; |
| 1055 | 1055 |
| 1056 return focusedElement->isShadowIncludingInclusiveAncestorOf(selection().star t().anchorNode()); | 1056 return focusedElement->isShadowIncludingInclusiveAncestorOf(selection().star t().anchorNode()); |
| 1057 } | 1057 } |
| 1058 | 1058 |
| 1059 void FrameSelection::caretBlinkTimerFired(Timer<FrameSelection>*) | 1059 void FrameSelection::caretBlinkTimerFired(Timer<FrameSelection>*) |
| 1060 { | 1060 { |
| 1061 ASSERT(m_caretBase->caretIsVisible()); | 1061 DCHECK(m_caretBase->caretIsVisible()); |
| 1062 ASSERT(isCaret()); | 1062 DCHECK(isCaret()); |
| 1063 if (isCaretBlinkingSuspended() && m_shouldPaintCaret) | 1063 if (isCaretBlinkingSuspended() && m_shouldPaintCaret) |
| 1064 return; | 1064 return; |
| 1065 m_shouldPaintCaret = !m_shouldPaintCaret; | 1065 m_shouldPaintCaret = !m_shouldPaintCaret; |
| 1066 setCaretRectNeedsUpdate(); | 1066 setCaretRectNeedsUpdate(); |
| 1067 } | 1067 } |
| 1068 | 1068 |
| 1069 void FrameSelection::stopCaretBlinkTimer() | 1069 void FrameSelection::stopCaretBlinkTimer() |
| 1070 { | 1070 { |
| 1071 if (m_caretBlinkTimer.isActive() || m_shouldPaintCaret) | 1071 if (m_caretBlinkTimer.isActive() || m_shouldPaintCaret) |
| 1072 setCaretRectNeedsUpdate(); | 1072 setCaretRectNeedsUpdate(); |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1229 return; | 1229 return; |
| 1230 case CaretSelection: | 1230 case CaretSelection: |
| 1231 rect = LayoutRect(absoluteCaretBounds()); | 1231 rect = LayoutRect(absoluteCaretBounds()); |
| 1232 break; | 1232 break; |
| 1233 case RangeSelection: | 1233 case RangeSelection: |
| 1234 rect = LayoutRect(revealExtentOption == RevealExtent ? absoluteCaretBoun dsOf(createVisiblePosition(extent())) : enclosingIntRect(unclippedBounds())); | 1234 rect = LayoutRect(revealExtentOption == RevealExtent ? absoluteCaretBoun dsOf(createVisiblePosition(extent())) : enclosingIntRect(unclippedBounds())); |
| 1235 break; | 1235 break; |
| 1236 } | 1236 } |
| 1237 | 1237 |
| 1238 Position start = this->start(); | 1238 Position start = this->start(); |
| 1239 ASSERT(start.anchorNode()); | 1239 DCHECK(start.anchorNode()); |
| 1240 if (start.anchorNode() && start.anchorNode()->layoutObject()) { | 1240 if (start.anchorNode() && start.anchorNode()->layoutObject()) { |
| 1241 // FIXME: This code only handles scrolling the startContainer's layer, b ut | 1241 // FIXME: This code only handles scrolling the startContainer's layer, b ut |
| 1242 // the selection rect could intersect more than just that. | 1242 // the selection rect could intersect more than just that. |
| 1243 if (DocumentLoader* documentLoader = m_frame->loader().documentLoader()) | 1243 if (DocumentLoader* documentLoader = m_frame->loader().documentLoader()) |
| 1244 documentLoader->initialScrollState().wasScrolledByUser = true; | 1244 documentLoader->initialScrollState().wasScrolledByUser = true; |
| 1245 if (start.anchorNode()->layoutObject()->scrollRectToVisible(rect, alignm ent, alignment)) | 1245 if (start.anchorNode()->layoutObject()->scrollRectToVisible(rect, alignm ent, alignment)) |
| 1246 updateAppearance(); | 1246 updateAppearance(); |
| 1247 } | 1247 } |
| 1248 } | 1248 } |
| 1249 | 1249 |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1419 | 1419 |
| 1420 void showTree(const blink::FrameSelection* sel) | 1420 void showTree(const blink::FrameSelection* sel) |
| 1421 { | 1421 { |
| 1422 if (sel) | 1422 if (sel) |
| 1423 sel->showTreeForThis(); | 1423 sel->showTreeForThis(); |
| 1424 else | 1424 else |
| 1425 fprintf(stderr, "Cannot showTree for (nil) FrameSelection.\n"); | 1425 fprintf(stderr, "Cannot showTree for (nil) FrameSelection.\n"); |
| 1426 } | 1426 } |
| 1427 | 1427 |
| 1428 #endif | 1428 #endif |
| OLD | NEW |