| 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 659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 670 { | 670 { |
| 671 typedef Vector<RefPtr<Node> > NodeVector; | 671 typedef Vector<RefPtr<Node> > NodeVector; |
| 672 | 672 |
| 673 RefPtr<DocumentFragment> fragment; | 673 RefPtr<DocumentFragment> fragment; |
| 674 if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) | 674 if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) |
| 675 fragment = DocumentFragment::create(*m_ownerDocument.get()); | 675 fragment = DocumentFragment::create(*m_ownerDocument.get()); |
| 676 | 676 |
| 677 if (collapsed(exceptionState)) | 677 if (collapsed(exceptionState)) |
| 678 return fragment.release(); | 678 return fragment.release(); |
| 679 if (exceptionState.hadException()) | 679 if (exceptionState.hadException()) |
| 680 return 0; | 680 return nullptr; |
| 681 | 681 |
| 682 RefPtr<Node> commonRoot = commonAncestorContainer(exceptionState); | 682 RefPtr<Node> commonRoot = commonAncestorContainer(exceptionState); |
| 683 if (exceptionState.hadException()) | 683 if (exceptionState.hadException()) |
| 684 return 0; | 684 return nullptr; |
| 685 ASSERT(commonRoot); | 685 ASSERT(commonRoot); |
| 686 | 686 |
| 687 if (m_start.container() == m_end.container()) { | 687 if (m_start.container() == m_end.container()) { |
| 688 processContentsBetweenOffsets(action, fragment, m_start.container(), m_s
tart.offset(), m_end.offset(), exceptionState); | 688 processContentsBetweenOffsets(action, fragment, m_start.container(), m_s
tart.offset(), m_end.offset(), exceptionState); |
| 689 return fragment; | 689 return fragment; |
| 690 } | 690 } |
| 691 | 691 |
| 692 // Since mutation observers can modify the range during the process, the bou
ndary points need to be saved. | 692 // Since mutation observers can modify the range during the process, the bou
ndary points need to be saved. |
| 693 RangeBoundaryPoint originalStart(m_start); | 693 RangeBoundaryPoint originalStart(m_start); |
| 694 RangeBoundaryPoint originalEnd(m_end); | 694 RangeBoundaryPoint originalEnd(m_end); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 712 // in which case the last lot of nodes either goes from the first or last | 712 // in which case the last lot of nodes either goes from the first or last |
| 713 // child of commonRoot. | 713 // child of commonRoot. |
| 714 // | 714 // |
| 715 // These are deleted, cloned, or extracted (i.e. both) depending on action. | 715 // These are deleted, cloned, or extracted (i.e. both) depending on action. |
| 716 | 716 |
| 717 // Note that we are verifying that our common root hierarchy is still intact | 717 // Note that we are verifying that our common root hierarchy is still intact |
| 718 // after any DOM mutation event, at various stages below. See webkit bug 603
50. | 718 // after any DOM mutation event, at various stages below. See webkit bug 603
50. |
| 719 | 719 |
| 720 RefPtr<Node> leftContents; | 720 RefPtr<Node> leftContents; |
| 721 if (originalStart.container() != commonRoot && commonRoot->contains(original
Start.container())) { | 721 if (originalStart.container() != commonRoot && commonRoot->contains(original
Start.container())) { |
| 722 leftContents = processContentsBetweenOffsets(action, 0, originalStart.co
ntainer(), originalStart.offset(), lengthOfContentsInNode(originalStart.containe
r()), exceptionState); | 722 leftContents = processContentsBetweenOffsets(action, nullptr, originalSt
art.container(), originalStart.offset(), lengthOfContentsInNode(originalStart.co
ntainer()), exceptionState); |
| 723 leftContents = processAncestorsAndTheirSiblings(action, originalStart.co
ntainer(), ProcessContentsForward, leftContents, commonRoot.get(), exceptionStat
e); | 723 leftContents = processAncestorsAndTheirSiblings(action, originalStart.co
ntainer(), ProcessContentsForward, leftContents, commonRoot.get(), exceptionStat
e); |
| 724 } | 724 } |
| 725 | 725 |
| 726 RefPtr<Node> rightContents; | 726 RefPtr<Node> rightContents; |
| 727 if (m_end.container() != commonRoot && commonRoot->contains(originalEnd.cont
ainer())) { | 727 if (m_end.container() != commonRoot && commonRoot->contains(originalEnd.cont
ainer())) { |
| 728 rightContents = processContentsBetweenOffsets(action, 0, originalEnd.con
tainer(), 0, originalEnd.offset(), exceptionState); | 728 rightContents = processContentsBetweenOffsets(action, nullptr, originalE
nd.container(), 0, originalEnd.offset(), exceptionState); |
| 729 rightContents = processAncestorsAndTheirSiblings(action, originalEnd.con
tainer(), ProcessContentsBackward, rightContents, commonRoot.get(), exceptionSta
te); | 729 rightContents = processAncestorsAndTheirSiblings(action, originalEnd.con
tainer(), ProcessContentsBackward, rightContents, commonRoot.get(), exceptionSta
te); |
| 730 } | 730 } |
| 731 | 731 |
| 732 // delete all children of commonRoot between the start and end container | 732 // delete all children of commonRoot between the start and end container |
| 733 RefPtr<Node> processStart = childOfCommonRootBeforeOffset(originalStart.cont
ainer(), originalStart.offset(), commonRoot.get()); | 733 RefPtr<Node> processStart = childOfCommonRootBeforeOffset(originalStart.cont
ainer(), originalStart.offset(), commonRoot.get()); |
| 734 if (processStart && originalStart.container() != commonRoot) // processStart
contains nodes before m_start. | 734 if (processStart && originalStart.container() != commonRoot) // processStart
contains nodes before m_start. |
| 735 processStart = processStart->nextSibling(); | 735 processStart = processStart->nextSibling(); |
| 736 RefPtr<Node> processEnd = childOfCommonRootBeforeOffset(originalEnd.containe
r(), originalEnd.offset(), commonRoot.get()); | 736 RefPtr<Node> processEnd = childOfCommonRootBeforeOffset(originalEnd.containe
r(), originalEnd.offset(), commonRoot.get()); |
| 737 | 737 |
| 738 // Collapse the range, making sure that the result is not within a node that
was partially selected. | 738 // Collapse the range, making sure that the result is not within a node that
was partially selected. |
| 739 if (action == EXTRACT_CONTENTS || action == DELETE_CONTENTS) { | 739 if (action == EXTRACT_CONTENTS || action == DELETE_CONTENTS) { |
| 740 if (partialStart && commonRoot->contains(partialStart.get())) { | 740 if (partialStart && commonRoot->contains(partialStart.get())) { |
| 741 // FIXME: We should not continue if we have an earlier error. | 741 // FIXME: We should not continue if we have an earlier error. |
| 742 exceptionState.clearException(); | 742 exceptionState.clearException(); |
| 743 setStart(partialStart->parentNode(), partialStart->nodeIndex() + 1,
exceptionState); | 743 setStart(partialStart->parentNode(), partialStart->nodeIndex() + 1,
exceptionState); |
| 744 } else if (partialEnd && commonRoot->contains(partialEnd.get())) { | 744 } else if (partialEnd && commonRoot->contains(partialEnd.get())) { |
| 745 // FIXME: We should not continue if we have an earlier error. | 745 // FIXME: We should not continue if we have an earlier error. |
| 746 exceptionState.clearException(); | 746 exceptionState.clearException(); |
| 747 setStart(partialEnd->parentNode(), partialEnd->nodeIndex(), exceptio
nState); | 747 setStart(partialEnd->parentNode(), partialEnd->nodeIndex(), exceptio
nState); |
| 748 } | 748 } |
| 749 if (exceptionState.hadException()) | 749 if (exceptionState.hadException()) |
| 750 return 0; | 750 return nullptr; |
| 751 m_end = m_start; | 751 m_end = m_start; |
| 752 } | 752 } |
| 753 | 753 |
| 754 originalStart.clear(); | 754 originalStart.clear(); |
| 755 originalEnd.clear(); | 755 originalEnd.clear(); |
| 756 | 756 |
| 757 // Now add leftContents, stuff in between, and rightContents to the fragment | 757 // Now add leftContents, stuff in between, and rightContents to the fragment |
| 758 // (or just delete the stuff in between) | 758 // (or just delete the stuff in between) |
| 759 | 759 |
| 760 if ((action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) && leftContents
) | 760 if ((action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) && leftContents
) |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 920 firstChildInAncestorToProcess = direction == ProcessContentsForward ? an
cestor->nextSibling() : ancestor->previousSibling(); | 920 firstChildInAncestorToProcess = direction == ProcessContentsForward ? an
cestor->nextSibling() : ancestor->previousSibling(); |
| 921 } | 921 } |
| 922 | 922 |
| 923 return clonedContainer.release(); | 923 return clonedContainer.release(); |
| 924 } | 924 } |
| 925 | 925 |
| 926 PassRefPtr<DocumentFragment> Range::extractContents(ExceptionState& exceptionSta
te) | 926 PassRefPtr<DocumentFragment> Range::extractContents(ExceptionState& exceptionSta
te) |
| 927 { | 927 { |
| 928 checkDeleteExtract(exceptionState); | 928 checkDeleteExtract(exceptionState); |
| 929 if (exceptionState.hadException()) | 929 if (exceptionState.hadException()) |
| 930 return 0; | 930 return nullptr; |
| 931 | 931 |
| 932 return processContents(EXTRACT_CONTENTS, exceptionState); | 932 return processContents(EXTRACT_CONTENTS, exceptionState); |
| 933 } | 933 } |
| 934 | 934 |
| 935 PassRefPtr<DocumentFragment> Range::cloneContents(ExceptionState& exceptionState
) | 935 PassRefPtr<DocumentFragment> Range::cloneContents(ExceptionState& exceptionState
) |
| 936 { | 936 { |
| 937 if (!m_start.container()) { | 937 if (!m_start.container()) { |
| 938 exceptionState.throwDOMException(InvalidStateError, "The range has no co
ntainer. Perhaps 'detatch()' has been invoked on this object?"); | 938 exceptionState.throwDOMException(InvalidStateError, "The range has no co
ntainer. Perhaps 'detatch()' has been invoked on this object?"); |
| 939 return 0; | 939 return nullptr; |
| 940 } | 940 } |
| 941 | 941 |
| 942 return processContents(CLONE_CONTENTS, exceptionState); | 942 return processContents(CLONE_CONTENTS, exceptionState); |
| 943 } | 943 } |
| 944 | 944 |
| 945 void Range::insertNode(PassRefPtr<Node> prpNewNode, ExceptionState& exceptionSta
te) | 945 void Range::insertNode(PassRefPtr<Node> prpNewNode, ExceptionState& exceptionSta
te) |
| 946 { | 946 { |
| 947 RefPtr<Node> newNode = prpNewNode; | 947 RefPtr<Node> newNode = prpNewNode; |
| 948 | 948 |
| 949 if (!m_start.container()) { | 949 if (!m_start.container()) { |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1091 // FIXME: As with innerText, we'd like this to work even if there are no ren
der objects. | 1091 // FIXME: As with innerText, we'd like this to work even if there are no ren
der objects. |
| 1092 m_start.container()->document().updateLayout(); | 1092 m_start.container()->document().updateLayout(); |
| 1093 | 1093 |
| 1094 return plainText(this); | 1094 return plainText(this); |
| 1095 } | 1095 } |
| 1096 | 1096 |
| 1097 PassRefPtr<DocumentFragment> Range::createContextualFragment(const String& marku
p, ExceptionState& exceptionState) | 1097 PassRefPtr<DocumentFragment> Range::createContextualFragment(const String& marku
p, ExceptionState& exceptionState) |
| 1098 { | 1098 { |
| 1099 if (!m_start.container()) { | 1099 if (!m_start.container()) { |
| 1100 exceptionState.throwDOMException(InvalidStateError, "The range has no co
ntainer. Perhaps 'detatch()' has been invoked on this object?"); | 1100 exceptionState.throwDOMException(InvalidStateError, "The range has no co
ntainer. Perhaps 'detatch()' has been invoked on this object?"); |
| 1101 return 0; | 1101 return nullptr; |
| 1102 } | 1102 } |
| 1103 | 1103 |
| 1104 Node* element = m_start.container()->isElementNode() ? m_start.container() :
m_start.container()->parentNode(); | 1104 Node* element = m_start.container()->isElementNode() ? m_start.container() :
m_start.container()->parentNode(); |
| 1105 if (!element || !element->isHTMLElement()) { | 1105 if (!element || !element->isHTMLElement()) { |
| 1106 exceptionState.throwDOMException(NotSupportedError, "The range's contain
er must be an HTML element."); | 1106 exceptionState.throwDOMException(NotSupportedError, "The range's contain
er must be an HTML element."); |
| 1107 return 0; | 1107 return nullptr; |
| 1108 } | 1108 } |
| 1109 | 1109 |
| 1110 RefPtr<DocumentFragment> fragment = WebCore::createContextualFragment(markup
, toHTMLElement(element), AllowScriptingContentAndDoNotMarkAlreadyStarted, excep
tionState); | 1110 RefPtr<DocumentFragment> fragment = WebCore::createContextualFragment(markup
, toHTMLElement(element), AllowScriptingContentAndDoNotMarkAlreadyStarted, excep
tionState); |
| 1111 if (!fragment) | 1111 if (!fragment) |
| 1112 return 0; | 1112 return nullptr; |
| 1113 | 1113 |
| 1114 return fragment.release(); | 1114 return fragment.release(); |
| 1115 } | 1115 } |
| 1116 | 1116 |
| 1117 | 1117 |
| 1118 void Range::detach(ExceptionState& exceptionState) | 1118 void Range::detach(ExceptionState& exceptionState) |
| 1119 { | 1119 { |
| 1120 // Check first to see if we've already detached: | 1120 // Check first to see if we've already detached: |
| 1121 if (!m_start.container()) { | 1121 if (!m_start.container()) { |
| 1122 exceptionState.throwDOMException(InvalidStateError, "The range has no co
ntainer. Perhaps 'detatch()' has been invoked on this object?"); | 1122 exceptionState.throwDOMException(InvalidStateError, "The range has no co
ntainer. Perhaps 'detatch()' has been invoked on this object?"); |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1214 case Node::TEXT_NODE: | 1214 case Node::TEXT_NODE: |
| 1215 exceptionState.throwDOMException(InvalidNodeTypeError, "The node pro
vided is of type '" + n->nodeName() + "'."); | 1215 exceptionState.throwDOMException(InvalidNodeTypeError, "The node pro
vided is of type '" + n->nodeName() + "'."); |
| 1216 return; | 1216 return; |
| 1217 } | 1217 } |
| 1218 } | 1218 } |
| 1219 | 1219 |
| 1220 PassRefPtr<Range> Range::cloneRange(ExceptionState& exceptionState) const | 1220 PassRefPtr<Range> Range::cloneRange(ExceptionState& exceptionState) const |
| 1221 { | 1221 { |
| 1222 if (!m_start.container()) { | 1222 if (!m_start.container()) { |
| 1223 exceptionState.throwDOMException(InvalidStateError, "The range has no co
ntainer. Perhaps 'detatch()' has been invoked on this object?"); | 1223 exceptionState.throwDOMException(InvalidStateError, "The range has no co
ntainer. Perhaps 'detatch()' has been invoked on this object?"); |
| 1224 return 0; | 1224 return nullptr; |
| 1225 } | 1225 } |
| 1226 | 1226 |
| 1227 return Range::create(*m_ownerDocument.get(), m_start.container(), m_start.of
fset(), m_end.container(), m_end.offset()); | 1227 return Range::create(*m_ownerDocument.get(), m_start.container(), m_start.of
fset(), m_end.container(), m_end.offset()); |
| 1228 } | 1228 } |
| 1229 | 1229 |
| 1230 void Range::setStartAfter(Node* refNode, ExceptionState& exceptionState) | 1230 void Range::setStartAfter(Node* refNode, ExceptionState& exceptionState) |
| 1231 { | 1231 { |
| 1232 checkNodeBA(refNode, exceptionState); | 1232 checkNodeBA(refNode, exceptionState); |
| 1233 if (exceptionState.hadException()) | 1233 if (exceptionState.hadException()) |
| 1234 return; | 1234 return; |
| (...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1887 | 1887 |
| 1888 void showTree(const WebCore::Range* range) | 1888 void showTree(const WebCore::Range* range) |
| 1889 { | 1889 { |
| 1890 if (range && range->boundaryPointsValid()) { | 1890 if (range && range->boundaryPointsValid()) { |
| 1891 range->startContainer()->showTreeAndMark(range->startContainer(), "S", r
ange->endContainer(), "E"); | 1891 range->startContainer()->showTreeAndMark(range->startContainer(), "S", r
ange->endContainer(), "E"); |
| 1892 fprintf(stderr, "start offset: %d, end offset: %d\n", range->startOffset
(), range->endOffset()); | 1892 fprintf(stderr, "start offset: %d, end offset: %d\n", range->startOffset
(), range->endOffset()); |
| 1893 } | 1893 } |
| 1894 } | 1894 } |
| 1895 | 1895 |
| 1896 #endif | 1896 #endif |
| OLD | NEW |