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 |