| OLD | NEW |
| 1 /* | 1 /* |
| 2 * (C) 1999 Lars Knoll (knoll@kde.org) | 2 * (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * (C) 2000 Gunnstein Lye (gunnstein@netcom.no) | 3 * (C) 2000 Gunnstein Lye (gunnstein@netcom.no) |
| 4 * (C) 2000 Frederik Holljen (frederik.holljen@hig.no) | 4 * (C) 2000 Frederik Holljen (frederik.holljen@hig.no) |
| 5 * (C) 2001 Peter Kelly (pmk@post.com) | 5 * (C) 2001 Peter Kelly (pmk@post.com) |
| 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r
ights reserved. | 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r
ights reserved. |
| 7 * Copyright (C) 2011 Motorola Mobility. All rights reserved. | 7 * Copyright (C) 2011 Motorola Mobility. All rights reserved. |
| 8 * | 8 * |
| 9 * This library is free software; you can redistribute it and/or | 9 * This library is free software; you can redistribute it and/or |
| 10 * modify it under the terms of the GNU Library General Public | 10 * modify it under the terms of the GNU Library General Public |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 89 { | 89 { |
| 90 return new Range(ownerDocument, start.computeContainerNode(), start.computeO
ffsetInContainerNode(), end.computeContainerNode(), end.computeOffsetInContainer
Node()); | 90 return new Range(ownerDocument, start.computeContainerNode(), start.computeO
ffsetInContainerNode(), end.computeContainerNode(), end.computeOffsetInContainer
Node()); |
| 91 } | 91 } |
| 92 | 92 |
| 93 RawPtr<Range> Range::createAdjustedToTreeScope(const TreeScope& treeScope, const
Position& position) | 93 RawPtr<Range> Range::createAdjustedToTreeScope(const TreeScope& treeScope, const
Position& position) |
| 94 { | 94 { |
| 95 RawPtr<Range> range = create(treeScope.document(), position, position); | 95 RawPtr<Range> range = create(treeScope.document(), position, position); |
| 96 | 96 |
| 97 // Make sure the range is in this scope. | 97 // Make sure the range is in this scope. |
| 98 Node* firstNode = range->firstNode(); | 98 Node* firstNode = range->firstNode(); |
| 99 ASSERT(firstNode); | 99 DCHECK(firstNode); |
| 100 Node* shadowHostInThisScopeOrFirstNode = treeScope.ancestorInThisScope(first
Node); | 100 Node* shadowHostInThisScopeOrFirstNode = treeScope.ancestorInThisScope(first
Node); |
| 101 ASSERT(shadowHostInThisScopeOrFirstNode); | 101 DCHECK(shadowHostInThisScopeOrFirstNode); |
| 102 if (shadowHostInThisScopeOrFirstNode == firstNode) | 102 if (shadowHostInThisScopeOrFirstNode == firstNode) |
| 103 return range.release(); | 103 return range.release(); |
| 104 | 104 |
| 105 // If not, create a range for the shadow host in this scope. | 105 // If not, create a range for the shadow host in this scope. |
| 106 ContainerNode* container = shadowHostInThisScopeOrFirstNode->parentNode(); | 106 ContainerNode* container = shadowHostInThisScopeOrFirstNode->parentNode(); |
| 107 ASSERT(container); | 107 DCHECK(container); |
| 108 unsigned offset = shadowHostInThisScopeOrFirstNode->nodeIndex(); | 108 unsigned offset = shadowHostInThisScopeOrFirstNode->nodeIndex(); |
| 109 return Range::create(treeScope.document(), container, offset, container, off
set); | 109 return Range::create(treeScope.document(), container, offset, container, off
set); |
| 110 } | 110 } |
| 111 | 111 |
| 112 void Range::dispose() | 112 void Range::dispose() |
| 113 { | 113 { |
| 114 #if ENABLE(OILPAN) | 114 #if ENABLE(OILPAN) |
| 115 // A prompt detach from the owning Document helps avoid GC overhead. | 115 // A prompt detach from the owning Document helps avoid GC overhead. |
| 116 m_ownerDocument->detachRange(this); | 116 m_ownerDocument->detachRange(this); |
| 117 #endif | 117 #endif |
| 118 } | 118 } |
| 119 | 119 |
| 120 bool Range::inShadowIncludingDocument() const | 120 bool Range::inShadowIncludingDocument() const |
| 121 { | 121 { |
| 122 ASSERT(m_start.inShadowIncludingDocument() == m_end.inShadowIncludingDocumen
t()); | 122 DCHECK_EQ(m_start.inShadowIncludingDocument(), m_end.inShadowIncludingDocume
nt()); |
| 123 return m_start.inShadowIncludingDocument(); | 123 return m_start.inShadowIncludingDocument(); |
| 124 } | 124 } |
| 125 | 125 |
| 126 void Range::setDocument(Document& document) | 126 void Range::setDocument(Document& document) |
| 127 { | 127 { |
| 128 ASSERT(m_ownerDocument != document); | 128 DCHECK_NE(m_ownerDocument, document); |
| 129 ASSERT(m_ownerDocument); | 129 DCHECK(m_ownerDocument); |
| 130 m_ownerDocument->detachRange(this); | 130 m_ownerDocument->detachRange(this); |
| 131 m_ownerDocument = &document; | 131 m_ownerDocument = &document; |
| 132 m_start.setToStartOfNode(document); | 132 m_start.setToStartOfNode(document); |
| 133 m_end.setToStartOfNode(document); | 133 m_end.setToStartOfNode(document); |
| 134 m_ownerDocument->attachRange(this); | 134 m_ownerDocument->attachRange(this); |
| 135 } | 135 } |
| 136 | 136 |
| 137 Node* Range::commonAncestorContainer() const | 137 Node* Range::commonAncestorContainer() const |
| 138 { | 138 { |
| 139 return commonAncestorContainer(m_start.container(), m_end.container()); | 139 return commonAncestorContainer(m_start.container(), m_end.container()); |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 346 } | 346 } |
| 347 | 347 |
| 348 bool Range::boundaryPointsValid() const | 348 bool Range::boundaryPointsValid() const |
| 349 { | 349 { |
| 350 TrackExceptionState exceptionState; | 350 TrackExceptionState exceptionState; |
| 351 return compareBoundaryPoints(m_start, m_end, exceptionState) <= 0 && !except
ionState.hadException(); | 351 return compareBoundaryPoints(m_start, m_end, exceptionState) <= 0 && !except
ionState.hadException(); |
| 352 } | 352 } |
| 353 | 353 |
| 354 void Range::deleteContents(ExceptionState& exceptionState) | 354 void Range::deleteContents(ExceptionState& exceptionState) |
| 355 { | 355 { |
| 356 ASSERT(boundaryPointsValid()); | 356 DCHECK(boundaryPointsValid()); |
| 357 | 357 |
| 358 { | 358 { |
| 359 EventQueueScope eventQueueScope; | 359 EventQueueScope eventQueueScope; |
| 360 processContents(DELETE_CONTENTS, exceptionState); | 360 processContents(DELETE_CONTENTS, exceptionState); |
| 361 } | 361 } |
| 362 } | 362 } |
| 363 | 363 |
| 364 static bool nodeValidForIntersects(Node* refNode, Document* expectedDocument, Ex
ceptionState& exceptionState) | 364 static bool nodeValidForIntersects(Node* refNode, Document* expectedDocument, Ex
ceptionState& exceptionState) |
| 365 { | 365 { |
| 366 if (!refNode) { | 366 if (!refNode) { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 414 if (!parentNode) | 414 if (!parentNode) |
| 415 return true; | 415 return true; |
| 416 | 416 |
| 417 int nodeIndex = refNode->nodeIndex(); | 417 int nodeIndex = refNode->nodeIndex(); |
| 418 | 418 |
| 419 Node* startContainerNode = start.computeContainerNode(); | 419 Node* startContainerNode = start.computeContainerNode(); |
| 420 int startOffset = start.computeOffsetInContainerNode(); | 420 int startOffset = start.computeOffsetInContainerNode(); |
| 421 | 421 |
| 422 if (compareBoundaryPoints(parentNode, nodeIndex, startContainerNode, startOf
fset, exceptionState) < 0 // starts before start | 422 if (compareBoundaryPoints(parentNode, nodeIndex, startContainerNode, startOf
fset, exceptionState) < 0 // starts before start |
| 423 && compareBoundaryPoints(parentNode, nodeIndex + 1, startContainerNode,
startOffset, exceptionState) < 0) { // ends before start | 423 && compareBoundaryPoints(parentNode, nodeIndex + 1, startContainerNode,
startOffset, exceptionState) < 0) { // ends before start |
| 424 ASSERT(!exceptionState.hadException()); | 424 DCHECK(!exceptionState.hadException()); |
| 425 return false; | 425 return false; |
| 426 } | 426 } |
| 427 | 427 |
| 428 Node* endContainerNode = end.computeContainerNode(); | 428 Node* endContainerNode = end.computeContainerNode(); |
| 429 int endOffset = end.computeOffsetInContainerNode(); | 429 int endOffset = end.computeOffsetInContainerNode(); |
| 430 | 430 |
| 431 if (compareBoundaryPoints(parentNode, nodeIndex, endContainerNode, endOffset
, exceptionState) > 0 // starts after end | 431 if (compareBoundaryPoints(parentNode, nodeIndex, endContainerNode, endOffset
, exceptionState) > 0 // starts after end |
| 432 && compareBoundaryPoints(parentNode, nodeIndex + 1, endContainerNode, en
dOffset, exceptionState) > 0) { // ends after end | 432 && compareBoundaryPoints(parentNode, nodeIndex + 1, endContainerNode, en
dOffset, exceptionState) > 0) { // ends after end |
| 433 ASSERT(!exceptionState.hadException()); | 433 DCHECK(!exceptionState.hadException()); |
| 434 return false; | 434 return false; |
| 435 } | 435 } |
| 436 | 436 |
| 437 return true; // all other cases | 437 return true; // all other cases |
| 438 } | 438 } |
| 439 | 439 |
| 440 static inline Node* highestAncestorUnderCommonRoot(Node* node, Node* commonRoot) | 440 static inline Node* highestAncestorUnderCommonRoot(Node* node, Node* commonRoot) |
| 441 { | 441 { |
| 442 if (node == commonRoot) | 442 if (node == commonRoot) |
| 443 return 0; | 443 return 0; |
| 444 | 444 |
| 445 ASSERT(commonRoot->contains(node)); | 445 DCHECK(commonRoot->contains(node)); |
| 446 | 446 |
| 447 while (node->parentNode() != commonRoot) | 447 while (node->parentNode() != commonRoot) |
| 448 node = node->parentNode(); | 448 node = node->parentNode(); |
| 449 | 449 |
| 450 return node; | 450 return node; |
| 451 } | 451 } |
| 452 | 452 |
| 453 static inline Node* childOfCommonRootBeforeOffset(Node* container, unsigned offs
et, Node* commonRoot) | 453 static inline Node* childOfCommonRootBeforeOffset(Node* container, unsigned offs
et, Node* commonRoot) |
| 454 { | 454 { |
| 455 ASSERT(container); | 455 DCHECK(container); |
| 456 ASSERT(commonRoot); | 456 DCHECK(commonRoot); |
| 457 | 457 |
| 458 if (!commonRoot->contains(container)) | 458 if (!commonRoot->contains(container)) |
| 459 return 0; | 459 return 0; |
| 460 | 460 |
| 461 if (container == commonRoot) { | 461 if (container == commonRoot) { |
| 462 container = container->firstChild(); | 462 container = container->firstChild(); |
| 463 for (unsigned i = 0; container && i < offset; i++) | 463 for (unsigned i = 0; container && i < offset; i++) |
| 464 container = container->nextSibling(); | 464 container = container->nextSibling(); |
| 465 } else { | 465 } else { |
| 466 while (container->parentNode() != commonRoot) | 466 while (container->parentNode() != commonRoot) |
| 467 container = container->parentNode(); | 467 container = container->parentNode(); |
| 468 } | 468 } |
| 469 | 469 |
| 470 return container; | 470 return container; |
| 471 } | 471 } |
| 472 | 472 |
| 473 RawPtr<DocumentFragment> Range::processContents(ActionType action, ExceptionStat
e& exceptionState) | 473 RawPtr<DocumentFragment> Range::processContents(ActionType action, ExceptionStat
e& exceptionState) |
| 474 { | 474 { |
| 475 typedef HeapVector<Member<Node>> NodeVector; | 475 typedef HeapVector<Member<Node>> NodeVector; |
| 476 | 476 |
| 477 RawPtr<DocumentFragment> fragment = nullptr; | 477 RawPtr<DocumentFragment> fragment = nullptr; |
| 478 if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) | 478 if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) |
| 479 fragment = DocumentFragment::create(*m_ownerDocument.get()); | 479 fragment = DocumentFragment::create(*m_ownerDocument.get()); |
| 480 | 480 |
| 481 if (collapsed()) | 481 if (collapsed()) |
| 482 return fragment.release(); | 482 return fragment.release(); |
| 483 | 483 |
| 484 RawPtr<Node> commonRoot = commonAncestorContainer(); | 484 RawPtr<Node> commonRoot = commonAncestorContainer(); |
| 485 ASSERT(commonRoot); | 485 DCHECK(commonRoot); |
| 486 | 486 |
| 487 if (m_start.container() == m_end.container()) { | 487 if (m_start.container() == m_end.container()) { |
| 488 processContentsBetweenOffsets(action, fragment, m_start.container(), m_s
tart.offset(), m_end.offset(), exceptionState); | 488 processContentsBetweenOffsets(action, fragment, m_start.container(), m_s
tart.offset(), m_end.offset(), exceptionState); |
| 489 return fragment; | 489 return fragment; |
| 490 } | 490 } |
| 491 | 491 |
| 492 // Since mutation observers can modify the range during the process, the bou
ndary points need to be saved. | 492 // Since mutation observers can modify the range during the process, the bou
ndary points need to be saved. |
| 493 RangeBoundaryPoint originalStart(m_start); | 493 RangeBoundaryPoint originalStart(m_start); |
| 494 RangeBoundaryPoint originalEnd(m_end); | 494 RangeBoundaryPoint originalEnd(m_end); |
| 495 | 495 |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 577 { | 577 { |
| 578 if (data->length() - endOffset) | 578 if (data->length() - endOffset) |
| 579 data->deleteData(endOffset, data->length() - endOffset, exceptionState); | 579 data->deleteData(endOffset, data->length() - endOffset, exceptionState); |
| 580 if (startOffset) | 580 if (startOffset) |
| 581 data->deleteData(0, startOffset, exceptionState); | 581 data->deleteData(0, startOffset, exceptionState); |
| 582 } | 582 } |
| 583 | 583 |
| 584 RawPtr<Node> Range::processContentsBetweenOffsets(ActionType action, RawPtr<Docu
mentFragment> fragment, | 584 RawPtr<Node> Range::processContentsBetweenOffsets(ActionType action, RawPtr<Docu
mentFragment> fragment, |
| 585 Node* container, unsigned startOffset, unsigned endOffset, ExceptionState& e
xceptionState) | 585 Node* container, unsigned startOffset, unsigned endOffset, ExceptionState& e
xceptionState) |
| 586 { | 586 { |
| 587 ASSERT(container); | 587 DCHECK(container); |
| 588 ASSERT(startOffset <= endOffset); | 588 DCHECK_LE(startOffset, endOffset); |
| 589 | 589 |
| 590 // This switch statement must be consistent with that of Node::lengthOfConte
nts. | 590 // This switch statement must be consistent with that of Node::lengthOfConte
nts. |
| 591 RawPtr<Node> result = nullptr; | 591 RawPtr<Node> result = nullptr; |
| 592 switch (container->getNodeType()) { | 592 switch (container->getNodeType()) { |
| 593 case Node::TEXT_NODE: | 593 case Node::TEXT_NODE: |
| 594 case Node::CDATA_SECTION_NODE: | 594 case Node::CDATA_SECTION_NODE: |
| 595 case Node::COMMENT_NODE: | 595 case Node::COMMENT_NODE: |
| 596 case Node::PROCESSING_INSTRUCTION_NODE: | 596 case Node::PROCESSING_INSTRUCTION_NODE: |
| 597 endOffset = std::min(endOffset, toCharacterData(container)->length()); | 597 endOffset = std::min(endOffset, toCharacterData(container)->length()); |
| 598 if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) { | 598 if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) { |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 666 if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) { | 666 if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) { |
| 667 if (RawPtr<Node> clonedAncestor = ancestor->cloneNode(false)) { // M
ight have been removed already during mutation event. | 667 if (RawPtr<Node> clonedAncestor = ancestor->cloneNode(false)) { // M
ight have been removed already during mutation event. |
| 668 clonedAncestor->appendChild(clonedContainer, exceptionState); | 668 clonedAncestor->appendChild(clonedContainer, exceptionState); |
| 669 clonedContainer = clonedAncestor; | 669 clonedContainer = clonedAncestor; |
| 670 } | 670 } |
| 671 } | 671 } |
| 672 | 672 |
| 673 // Copy siblings of an ancestor of start/end containers | 673 // Copy siblings of an ancestor of start/end containers |
| 674 // FIXME: This assertion may fail if DOM is modified during mutation eve
nt | 674 // FIXME: This assertion may fail if DOM is modified during mutation eve
nt |
| 675 // FIXME: Share code with Range::processNodes | 675 // FIXME: Share code with Range::processNodes |
| 676 ASSERT(!firstChildInAncestorToProcess || firstChildInAncestorToProcess->
parentNode() == ancestor); | 676 DCHECK(!firstChildInAncestorToProcess || firstChildInAncestorToProcess->
parentNode() == ancestor); |
| 677 | 677 |
| 678 NodeVector nodes; | 678 NodeVector nodes; |
| 679 for (Node* child = firstChildInAncestorToProcess.get(); child; | 679 for (Node* child = firstChildInAncestorToProcess.get(); child; |
| 680 child = (direction == ProcessContentsForward) ? child->nextSibling()
: child->previousSibling()) | 680 child = (direction == ProcessContentsForward) ? child->nextSibling()
: child->previousSibling()) |
| 681 nodes.append(child); | 681 nodes.append(child); |
| 682 | 682 |
| 683 for (const RawPtr<Node>& node : nodes) { | 683 for (const RawPtr<Node>& node : nodes) { |
| 684 Node* child = node.get(); | 684 Node* child = node.get(); |
| 685 switch (action) { | 685 switch (action) { |
| 686 case DELETE_CONTENTS: | 686 case DELETE_CONTENTS: |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 815 return; | 815 return; |
| 816 } | 816 } |
| 817 m_end.setToBeforeChild(*newText); | 817 m_end.setToBeforeChild(*newText); |
| 818 } | 818 } |
| 819 } else { | 819 } else { |
| 820 RawPtr<Node> lastChild = (newNodeType == Node::DOCUMENT_FRAGMENT_NODE) ?
toDocumentFragment(newNode)->lastChild() : newNode.get(); | 820 RawPtr<Node> lastChild = (newNodeType == Node::DOCUMENT_FRAGMENT_NODE) ?
toDocumentFragment(newNode)->lastChild() : newNode.get(); |
| 821 if (lastChild && lastChild == m_start.childBefore()) { | 821 if (lastChild && lastChild == m_start.childBefore()) { |
| 822 // The insertion will do nothing, but we need to extend the range to
include | 822 // The insertion will do nothing, but we need to extend the range to
include |
| 823 // the inserted nodes. | 823 // the inserted nodes. |
| 824 Node* firstChild = (newNodeType == Node::DOCUMENT_FRAGMENT_NODE) ? t
oDocumentFragment(newNode)->firstChild() : newNode.get(); | 824 Node* firstChild = (newNodeType == Node::DOCUMENT_FRAGMENT_NODE) ? t
oDocumentFragment(newNode)->firstChild() : newNode.get(); |
| 825 ASSERT(firstChild); | 825 DCHECK(firstChild); |
| 826 m_start.setToBeforeChild(*firstChild); | 826 m_start.setToBeforeChild(*firstChild); |
| 827 return; | 827 return; |
| 828 } | 828 } |
| 829 | 829 |
| 830 container = m_start.container(); | 830 container = m_start.container(); |
| 831 container->insertBefore(newNode.release(), NodeTraversal::childAt(*conta
iner, m_start.offset()), exceptionState); | 831 container->insertBefore(newNode.release(), NodeTraversal::childAt(*conta
iner, m_start.offset()), exceptionState); |
| 832 if (exceptionState.hadException()) | 832 if (exceptionState.hadException()) |
| 833 return; | 833 return; |
| 834 | 834 |
| 835 // Note that m_start.offset() may have changed as a result of container-
>insertBefore, | 835 // Note that m_start.offset() may have changed as a result of container-
>insertBefore, |
| (...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1215 { | 1215 { |
| 1216 checkNodeBA(refNode, exceptionState); | 1216 checkNodeBA(refNode, exceptionState); |
| 1217 if (exceptionState.hadException()) | 1217 if (exceptionState.hadException()) |
| 1218 return; | 1218 return; |
| 1219 | 1219 |
| 1220 setStart(refNode->parentNode(), refNode->nodeIndex(), exceptionState); | 1220 setStart(refNode->parentNode(), refNode->nodeIndex(), exceptionState); |
| 1221 } | 1221 } |
| 1222 | 1222 |
| 1223 void Range::checkExtractPrecondition(ExceptionState& exceptionState) | 1223 void Range::checkExtractPrecondition(ExceptionState& exceptionState) |
| 1224 { | 1224 { |
| 1225 ASSERT(boundaryPointsValid()); | 1225 DCHECK(boundaryPointsValid()); |
| 1226 | 1226 |
| 1227 if (!commonAncestorContainer()) | 1227 if (!commonAncestorContainer()) |
| 1228 return; | 1228 return; |
| 1229 | 1229 |
| 1230 Node* pastLast = pastLastNode(); | 1230 Node* pastLast = pastLastNode(); |
| 1231 for (Node* n = firstNode(); n != pastLast; n = NodeTraversal::next(*n)) { | 1231 for (Node* n = firstNode(); n != pastLast; n = NodeTraversal::next(*n)) { |
| 1232 if (n->isDocumentTypeNode()) { | 1232 if (n->isDocumentTypeNode()) { |
| 1233 exceptionState.throwDOMException(HierarchyRequestError, "The Range c
ontains a doctype node."); | 1233 exceptionState.throwDOMException(HierarchyRequestError, "The Range c
ontains a doctype node."); |
| 1234 return; | 1234 return; |
| 1235 } | 1235 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1267 Vector<IntRect> rects; | 1267 Vector<IntRect> rects; |
| 1268 textRects(rects); | 1268 textRects(rects); |
| 1269 for (const IntRect& rect : rects) | 1269 for (const IntRect& rect : rects) |
| 1270 result.unite(rect); | 1270 result.unite(rect); |
| 1271 return result; | 1271 return result; |
| 1272 } | 1272 } |
| 1273 | 1273 |
| 1274 void Range::textRects(Vector<IntRect>& rects, bool useSelectionHeight) const | 1274 void Range::textRects(Vector<IntRect>& rects, bool useSelectionHeight) const |
| 1275 { | 1275 { |
| 1276 Node* startContainer = m_start.container(); | 1276 Node* startContainer = m_start.container(); |
| 1277 ASSERT(startContainer); | 1277 DCHECK(startContainer); |
| 1278 Node* endContainer = m_end.container(); | 1278 Node* endContainer = m_end.container(); |
| 1279 ASSERT(endContainer); | 1279 DCHECK(endContainer); |
| 1280 | 1280 |
| 1281 Node* stopNode = pastLastNode(); | 1281 Node* stopNode = pastLastNode(); |
| 1282 for (Node* node = firstNode(); node != stopNode; node = NodeTraversal::next(
*node)) { | 1282 for (Node* node = firstNode(); node != stopNode; node = NodeTraversal::next(
*node)) { |
| 1283 LayoutObject* r = node->layoutObject(); | 1283 LayoutObject* r = node->layoutObject(); |
| 1284 if (!r || !r->isText()) | 1284 if (!r || !r->isText()) |
| 1285 continue; | 1285 continue; |
| 1286 LayoutText* layoutText = toLayoutText(r); | 1286 LayoutText* layoutText = toLayoutText(r); |
| 1287 int startOffset = node == startContainer ? m_start.offset() : 0; | 1287 int startOffset = node == startContainer ? m_start.offset() : 0; |
| 1288 int endOffset = node == endContainer ? m_end.offset() : std::numeric_lim
its<int>::max(); | 1288 int endOffset = node == endContainer ? m_end.offset() : std::numeric_lim
its<int>::max(); |
| 1289 layoutText->absoluteRectsForRange(rects, startOffset, endOffset, useSele
ctionHeight); | 1289 layoutText->absoluteRectsForRange(rects, startOffset, endOffset, useSele
ctionHeight); |
| 1290 } | 1290 } |
| 1291 } | 1291 } |
| 1292 | 1292 |
| 1293 void Range::textQuads(Vector<FloatQuad>& quads, bool useSelectionHeight) const | 1293 void Range::textQuads(Vector<FloatQuad>& quads, bool useSelectionHeight) const |
| 1294 { | 1294 { |
| 1295 Node* startContainer = m_start.container(); | 1295 Node* startContainer = m_start.container(); |
| 1296 ASSERT(startContainer); | 1296 DCHECK(startContainer); |
| 1297 Node* endContainer = m_end.container(); | 1297 Node* endContainer = m_end.container(); |
| 1298 ASSERT(endContainer); | 1298 DCHECK(endContainer); |
| 1299 | 1299 |
| 1300 Node* stopNode = pastLastNode(); | 1300 Node* stopNode = pastLastNode(); |
| 1301 for (Node* node = firstNode(); node != stopNode; node = NodeTraversal::next(
*node)) { | 1301 for (Node* node = firstNode(); node != stopNode; node = NodeTraversal::next(
*node)) { |
| 1302 LayoutObject* r = node->layoutObject(); | 1302 LayoutObject* r = node->layoutObject(); |
| 1303 if (!r || !r->isText()) | 1303 if (!r || !r->isText()) |
| 1304 continue; | 1304 continue; |
| 1305 LayoutText* layoutText = toLayoutText(r); | 1305 LayoutText* layoutText = toLayoutText(r); |
| 1306 int startOffset = node == startContainer ? m_start.offset() : 0; | 1306 int startOffset = node == startContainer ? m_start.offset() : 0; |
| 1307 int endOffset = node == endContainer ? m_end.offset() : std::numeric_lim
its<int>::max(); | 1307 int endOffset = node == endContainer ? m_end.offset() : std::numeric_lim
its<int>::max(); |
| 1308 layoutText->absoluteQuadsForRange(quads, startOffset, endOffset, useSele
ctionHeight); | 1308 layoutText->absoluteQuadsForRange(quads, startOffset, endOffset, useSele
ctionHeight); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1344 { | 1344 { |
| 1345 if (!boundary.childBefore()) | 1345 if (!boundary.childBefore()) |
| 1346 return; | 1346 return; |
| 1347 if (boundary.container() != container) | 1347 if (boundary.container() != container) |
| 1348 return; | 1348 return; |
| 1349 boundary.invalidateOffset(); | 1349 boundary.invalidateOffset(); |
| 1350 } | 1350 } |
| 1351 | 1351 |
| 1352 void Range::nodeChildrenChanged(ContainerNode* container) | 1352 void Range::nodeChildrenChanged(ContainerNode* container) |
| 1353 { | 1353 { |
| 1354 ASSERT(container); | 1354 DCHECK(container); |
| 1355 ASSERT(container->document() == m_ownerDocument); | 1355 DCHECK_EQ(container->document(), m_ownerDocument); |
| 1356 boundaryNodeChildrenChanged(m_start, container); | 1356 boundaryNodeChildrenChanged(m_start, container); |
| 1357 boundaryNodeChildrenChanged(m_end, container); | 1357 boundaryNodeChildrenChanged(m_end, container); |
| 1358 } | 1358 } |
| 1359 | 1359 |
| 1360 static inline void boundaryNodeChildrenWillBeRemoved(RangeBoundaryPoint& boundar
y, ContainerNode& container) | 1360 static inline void boundaryNodeChildrenWillBeRemoved(RangeBoundaryPoint& boundar
y, ContainerNode& container) |
| 1361 { | 1361 { |
| 1362 for (Node* nodeToBeRemoved = container.firstChild(); nodeToBeRemoved; nodeTo
BeRemoved = nodeToBeRemoved->nextSibling()) { | 1362 for (Node* nodeToBeRemoved = container.firstChild(); nodeToBeRemoved; nodeTo
BeRemoved = nodeToBeRemoved->nextSibling()) { |
| 1363 if (boundary.childBefore() == nodeToBeRemoved) { | 1363 if (boundary.childBefore() == nodeToBeRemoved) { |
| 1364 boundary.setToStartOfNode(container); | 1364 boundary.setToStartOfNode(container); |
| 1365 return; | 1365 return; |
| 1366 } | 1366 } |
| 1367 | 1367 |
| 1368 for (Node* n = boundary.container(); n; n = n->parentNode()) { | 1368 for (Node* n = boundary.container(); n; n = n->parentNode()) { |
| 1369 if (n == nodeToBeRemoved) { | 1369 if (n == nodeToBeRemoved) { |
| 1370 boundary.setToStartOfNode(container); | 1370 boundary.setToStartOfNode(container); |
| 1371 return; | 1371 return; |
| 1372 } | 1372 } |
| 1373 } | 1373 } |
| 1374 } | 1374 } |
| 1375 } | 1375 } |
| 1376 | 1376 |
| 1377 void Range::nodeChildrenWillBeRemoved(ContainerNode& container) | 1377 void Range::nodeChildrenWillBeRemoved(ContainerNode& container) |
| 1378 { | 1378 { |
| 1379 ASSERT(container.document() == m_ownerDocument); | 1379 DCHECK_EQ(container.document(), m_ownerDocument); |
| 1380 boundaryNodeChildrenWillBeRemoved(m_start, container); | 1380 boundaryNodeChildrenWillBeRemoved(m_start, container); |
| 1381 boundaryNodeChildrenWillBeRemoved(m_end, container); | 1381 boundaryNodeChildrenWillBeRemoved(m_end, container); |
| 1382 } | 1382 } |
| 1383 | 1383 |
| 1384 static inline void boundaryNodeWillBeRemoved(RangeBoundaryPoint& boundary, Node&
nodeToBeRemoved) | 1384 static inline void boundaryNodeWillBeRemoved(RangeBoundaryPoint& boundary, Node&
nodeToBeRemoved) |
| 1385 { | 1385 { |
| 1386 if (boundary.childBefore() == nodeToBeRemoved) { | 1386 if (boundary.childBefore() == nodeToBeRemoved) { |
| 1387 boundary.childBeforeWillBeRemoved(); | 1387 boundary.childBeforeWillBeRemoved(); |
| 1388 return; | 1388 return; |
| 1389 } | 1389 } |
| 1390 | 1390 |
| 1391 for (Node* n = boundary.container(); n; n = n->parentNode()) { | 1391 for (Node* n = boundary.container(); n; n = n->parentNode()) { |
| 1392 if (n == nodeToBeRemoved) { | 1392 if (n == nodeToBeRemoved) { |
| 1393 boundary.setToBeforeChild(nodeToBeRemoved); | 1393 boundary.setToBeforeChild(nodeToBeRemoved); |
| 1394 return; | 1394 return; |
| 1395 } | 1395 } |
| 1396 } | 1396 } |
| 1397 } | 1397 } |
| 1398 | 1398 |
| 1399 void Range::nodeWillBeRemoved(Node& node) | 1399 void Range::nodeWillBeRemoved(Node& node) |
| 1400 { | 1400 { |
| 1401 ASSERT(node.document() == m_ownerDocument); | 1401 DCHECK_EQ(node.document(), m_ownerDocument); |
| 1402 ASSERT(node != m_ownerDocument.get()); | 1402 DCHECK_NE(node, m_ownerDocument.get()); |
| 1403 | 1403 |
| 1404 // FIXME: Once DOMNodeRemovedFromDocument mutation event removed, we | 1404 // FIXME: Once DOMNodeRemovedFromDocument mutation event removed, we |
| 1405 // should change following if-statement to ASSERT(!node->parentNode). | 1405 // should change following if-statement to DCHECK(!node->parentNode). |
| 1406 if (!node.parentNode()) | 1406 if (!node.parentNode()) |
| 1407 return; | 1407 return; |
| 1408 boundaryNodeWillBeRemoved(m_start, node); | 1408 boundaryNodeWillBeRemoved(m_start, node); |
| 1409 boundaryNodeWillBeRemoved(m_end, node); | 1409 boundaryNodeWillBeRemoved(m_end, node); |
| 1410 } | 1410 } |
| 1411 | 1411 |
| 1412 static inline void boundaryTextInserted(RangeBoundaryPoint& boundary, Node* text
, unsigned offset, unsigned length) | 1412 static inline void boundaryTextInserted(RangeBoundaryPoint& boundary, Node* text
, unsigned offset, unsigned length) |
| 1413 { | 1413 { |
| 1414 if (boundary.container() != text) | 1414 if (boundary.container() != text) |
| 1415 return; | 1415 return; |
| 1416 unsigned boundaryOffset = boundary.offset(); | 1416 unsigned boundaryOffset = boundary.offset(); |
| 1417 if (offset >= boundaryOffset) | 1417 if (offset >= boundaryOffset) |
| 1418 return; | 1418 return; |
| 1419 boundary.setOffset(boundaryOffset + length); | 1419 boundary.setOffset(boundaryOffset + length); |
| 1420 } | 1420 } |
| 1421 | 1421 |
| 1422 void Range::didInsertText(Node* text, unsigned offset, unsigned length) | 1422 void Range::didInsertText(Node* text, unsigned offset, unsigned length) |
| 1423 { | 1423 { |
| 1424 ASSERT(text); | 1424 DCHECK(text); |
| 1425 ASSERT(text->document() == m_ownerDocument); | 1425 DCHECK_EQ(text->document(), m_ownerDocument); |
| 1426 boundaryTextInserted(m_start, text, offset, length); | 1426 boundaryTextInserted(m_start, text, offset, length); |
| 1427 boundaryTextInserted(m_end, text, offset, length); | 1427 boundaryTextInserted(m_end, text, offset, length); |
| 1428 } | 1428 } |
| 1429 | 1429 |
| 1430 static inline void boundaryTextRemoved(RangeBoundaryPoint& boundary, Node* text,
unsigned offset, unsigned length) | 1430 static inline void boundaryTextRemoved(RangeBoundaryPoint& boundary, Node* text,
unsigned offset, unsigned length) |
| 1431 { | 1431 { |
| 1432 if (boundary.container() != text) | 1432 if (boundary.container() != text) |
| 1433 return; | 1433 return; |
| 1434 unsigned boundaryOffset = boundary.offset(); | 1434 unsigned boundaryOffset = boundary.offset(); |
| 1435 if (offset >= boundaryOffset) | 1435 if (offset >= boundaryOffset) |
| 1436 return; | 1436 return; |
| 1437 if (offset + length >= boundaryOffset) | 1437 if (offset + length >= boundaryOffset) |
| 1438 boundary.setOffset(offset); | 1438 boundary.setOffset(offset); |
| 1439 else | 1439 else |
| 1440 boundary.setOffset(boundaryOffset - length); | 1440 boundary.setOffset(boundaryOffset - length); |
| 1441 } | 1441 } |
| 1442 | 1442 |
| 1443 void Range::didRemoveText(Node* text, unsigned offset, unsigned length) | 1443 void Range::didRemoveText(Node* text, unsigned offset, unsigned length) |
| 1444 { | 1444 { |
| 1445 ASSERT(text); | 1445 DCHECK(text); |
| 1446 ASSERT(text->document() == m_ownerDocument); | 1446 DCHECK_EQ(text->document(), m_ownerDocument); |
| 1447 boundaryTextRemoved(m_start, text, offset, length); | 1447 boundaryTextRemoved(m_start, text, offset, length); |
| 1448 boundaryTextRemoved(m_end, text, offset, length); | 1448 boundaryTextRemoved(m_end, text, offset, length); |
| 1449 } | 1449 } |
| 1450 | 1450 |
| 1451 static inline void boundaryTextNodesMerged(RangeBoundaryPoint& boundary, const N
odeWithIndex& oldNode, unsigned offset) | 1451 static inline void boundaryTextNodesMerged(RangeBoundaryPoint& boundary, const N
odeWithIndex& oldNode, unsigned offset) |
| 1452 { | 1452 { |
| 1453 if (boundary.container() == oldNode.node()) | 1453 if (boundary.container() == oldNode.node()) |
| 1454 boundary.set(oldNode.node().previousSibling(), boundary.offset() + offse
t, 0); | 1454 boundary.set(oldNode.node().previousSibling(), boundary.offset() + offse
t, 0); |
| 1455 else if (boundary.container() == oldNode.node().parentNode() && boundary.off
set() == oldNode.index()) | 1455 else if (boundary.container() == oldNode.node().parentNode() && boundary.off
set() == oldNode.index()) |
| 1456 boundary.set(oldNode.node().previousSibling(), offset, 0); | 1456 boundary.set(oldNode.node().previousSibling(), offset, 0); |
| 1457 } | 1457 } |
| 1458 | 1458 |
| 1459 void Range::didMergeTextNodes(const NodeWithIndex& oldNode, unsigned offset) | 1459 void Range::didMergeTextNodes(const NodeWithIndex& oldNode, unsigned offset) |
| 1460 { | 1460 { |
| 1461 ASSERT(oldNode.node().document() == m_ownerDocument); | 1461 DCHECK_EQ(oldNode.node().document(), m_ownerDocument); |
| 1462 ASSERT(oldNode.node().parentNode()); | 1462 DCHECK(oldNode.node().parentNode()); |
| 1463 ASSERT(oldNode.node().isTextNode()); | 1463 DCHECK(oldNode.node().isTextNode()); |
| 1464 ASSERT(oldNode.node().previousSibling()); | 1464 DCHECK(oldNode.node().previousSibling()); |
| 1465 ASSERT(oldNode.node().previousSibling()->isTextNode()); | 1465 DCHECK(oldNode.node().previousSibling()->isTextNode()); |
| 1466 boundaryTextNodesMerged(m_start, oldNode, offset); | 1466 boundaryTextNodesMerged(m_start, oldNode, offset); |
| 1467 boundaryTextNodesMerged(m_end, oldNode, offset); | 1467 boundaryTextNodesMerged(m_end, oldNode, offset); |
| 1468 } | 1468 } |
| 1469 | 1469 |
| 1470 void Range::updateOwnerDocumentIfNeeded() | 1470 void Range::updateOwnerDocumentIfNeeded() |
| 1471 { | 1471 { |
| 1472 ASSERT(m_start.container()); | 1472 DCHECK(m_start.container()); |
| 1473 ASSERT(m_end.container()); | 1473 DCHECK(m_end.container()); |
| 1474 Document& newDocument = m_start.container()->document(); | 1474 Document& newDocument = m_start.container()->document(); |
| 1475 ASSERT(newDocument == m_end.container()->document()); | 1475 DCHECK_EQ(newDocument, m_end.container()->document()); |
| 1476 if (newDocument == m_ownerDocument) | 1476 if (newDocument == m_ownerDocument) |
| 1477 return; | 1477 return; |
| 1478 m_ownerDocument->detachRange(this); | 1478 m_ownerDocument->detachRange(this); |
| 1479 m_ownerDocument = &newDocument; | 1479 m_ownerDocument = &newDocument; |
| 1480 m_ownerDocument->attachRange(this); | 1480 m_ownerDocument->attachRange(this); |
| 1481 } | 1481 } |
| 1482 | 1482 |
| 1483 static inline void boundaryTextNodeSplit(RangeBoundaryPoint& boundary, Text& old
Node) | 1483 static inline void boundaryTextNodeSplit(RangeBoundaryPoint& boundary, Text& old
Node) |
| 1484 { | 1484 { |
| 1485 Node* boundaryContainer = boundary.container(); | 1485 Node* boundaryContainer = boundary.container(); |
| 1486 unsigned boundaryOffset = boundary.offset(); | 1486 unsigned boundaryOffset = boundary.offset(); |
| 1487 if (boundary.childBefore() == &oldNode) | 1487 if (boundary.childBefore() == &oldNode) |
| 1488 boundary.set(boundaryContainer, boundaryOffset + 1, oldNode.nextSibling(
)); | 1488 boundary.set(boundaryContainer, boundaryOffset + 1, oldNode.nextSibling(
)); |
| 1489 else if (boundary.container() == &oldNode && boundaryOffset > oldNode.length
()) | 1489 else if (boundary.container() == &oldNode && boundaryOffset > oldNode.length
()) |
| 1490 boundary.set(oldNode.nextSibling(), boundaryOffset - oldNode.length(), 0
); | 1490 boundary.set(oldNode.nextSibling(), boundaryOffset - oldNode.length(), 0
); |
| 1491 } | 1491 } |
| 1492 | 1492 |
| 1493 void Range::didSplitTextNode(Text& oldNode) | 1493 void Range::didSplitTextNode(Text& oldNode) |
| 1494 { | 1494 { |
| 1495 ASSERT(oldNode.document() == m_ownerDocument); | 1495 DCHECK_EQ(oldNode.document(), m_ownerDocument); |
| 1496 ASSERT(oldNode.parentNode()); | 1496 DCHECK(oldNode.parentNode()); |
| 1497 ASSERT(oldNode.nextSibling()); | 1497 DCHECK(oldNode.nextSibling()); |
| 1498 ASSERT(oldNode.nextSibling()->isTextNode()); | 1498 DCHECK(oldNode.nextSibling()->isTextNode()); |
| 1499 boundaryTextNodeSplit(m_start, oldNode); | 1499 boundaryTextNodeSplit(m_start, oldNode); |
| 1500 boundaryTextNodeSplit(m_end, oldNode); | 1500 boundaryTextNodeSplit(m_end, oldNode); |
| 1501 ASSERT(boundaryPointsValid()); | 1501 DCHECK(boundaryPointsValid()); |
| 1502 } | 1502 } |
| 1503 | 1503 |
| 1504 void Range::expand(const String& unit, ExceptionState& exceptionState) | 1504 void Range::expand(const String& unit, ExceptionState& exceptionState) |
| 1505 { | 1505 { |
| 1506 VisiblePosition start = createVisiblePosition(startPosition()); | 1506 VisiblePosition start = createVisiblePosition(startPosition()); |
| 1507 VisiblePosition end = createVisiblePosition(endPosition()); | 1507 VisiblePosition end = createVisiblePosition(endPosition()); |
| 1508 if (unit == "word") { | 1508 if (unit == "word") { |
| 1509 start = startOfWord(start); | 1509 start = startOfWord(start); |
| 1510 end = endOfWord(end); | 1510 end = endOfWord(end); |
| 1511 } else if (unit == "sentence") { | 1511 } else if (unit == "sentence") { |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1614 { | 1614 { |
| 1615 if (range && range->boundaryPointsValid()) { | 1615 if (range && range->boundaryPointsValid()) { |
| 1616 range->startContainer()->showTreeAndMark(range->startContainer(), "S", r
ange->endContainer(), "E"); | 1616 range->startContainer()->showTreeAndMark(range->startContainer(), "S", r
ange->endContainer(), "E"); |
| 1617 fprintf(stderr, "start offset: %d, end offset: %d\n", range->startOffset
(), range->endOffset()); | 1617 fprintf(stderr, "start offset: %d, end offset: %d\n", range->startOffset
(), range->endOffset()); |
| 1618 } else { | 1618 } else { |
| 1619 fprintf(stderr, "Cannot show tree if range is null, or if boundary point
s are invalid.\n"); | 1619 fprintf(stderr, "Cannot show tree if range is null, or if boundary point
s are invalid.\n"); |
| 1620 } | 1620 } |
| 1621 } | 1621 } |
| 1622 | 1622 |
| 1623 #endif | 1623 #endif |
| OLD | NEW |