OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv
ed. | 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv
ed. |
3 * Copyright (C) 2008, 2009, 2010, 2011 Google Inc. All rights reserved. | 3 * Copyright (C) 2008, 2009, 2010, 2011 Google Inc. All rights reserved. |
4 * Copyright (C) 2011 Igalia S.L. | 4 * Copyright (C) 2011 Igalia S.L. |
5 * Copyright (C) 2011 Motorola Mobility. All rights reserved. | 5 * Copyright (C) 2011 Motorola Mobility. All rights reserved. |
6 * | 6 * |
7 * Redistribution and use in source and binary forms, with or without | 7 * Redistribution and use in source and binary forms, with or without |
8 * modification, are permitted provided that the following conditions | 8 * modification, are permitted provided that the following conditions |
9 * are met: | 9 * are met: |
10 * 1. Redistributions of source code must retain the above copyright | 10 * 1. Redistributions of source code must retain the above copyright |
(...skipping 617 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
628 { | 628 { |
629 if (!range) | 629 if (!range) |
630 return emptyString(); | 630 return emptyString(); |
631 | 631 |
632 Document& document = range->ownerDocument(); | 632 Document& document = range->ownerDocument(); |
633 const Range* updatedRange = range; | 633 const Range* updatedRange = range; |
634 | 634 |
635 return createMarkupInternal(document, range, updatedRange, nodes, shouldAnno
tate, convertBlocksToInlines, shouldResolveURLs, constrainingAncestor); | 635 return createMarkupInternal(document, range, updatedRange, nodes, shouldAnno
tate, convertBlocksToInlines, shouldResolveURLs, constrainingAncestor); |
636 } | 636 } |
637 | 637 |
638 PassRefPtr<DocumentFragment> createFragmentFromMarkup(Document& document, const
String& markup, const String& baseURL, ParserContentPolicy parserContentPolicy) | 638 PassRefPtrWillBeRawPtr<DocumentFragment> createFragmentFromMarkup(Document& docu
ment, const String& markup, const String& baseURL, ParserContentPolicy parserCon
tentPolicy) |
639 { | 639 { |
640 // We use a fake body element here to trick the HTML parser to using the InB
ody insertion mode. | 640 // We use a fake body element here to trick the HTML parser to using the InB
ody insertion mode. |
641 RefPtr<HTMLBodyElement> fakeBody = HTMLBodyElement::create(document); | 641 RefPtr<HTMLBodyElement> fakeBody = HTMLBodyElement::create(document); |
642 RefPtr<DocumentFragment> fragment = DocumentFragment::create(document); | 642 RefPtrWillBeRawPtr<DocumentFragment> fragment = DocumentFragment::create(doc
ument); |
643 | 643 |
644 fragment->parseHTML(markup, fakeBody.get(), parserContentPolicy); | 644 fragment->parseHTML(markup, fakeBody.get(), parserContentPolicy); |
645 | 645 |
646 if (!baseURL.isEmpty() && baseURL != blankURL() && baseURL != document.baseU
RL()) | 646 if (!baseURL.isEmpty() && baseURL != blankURL() && baseURL != document.baseU
RL()) |
647 completeURLs(*fragment, baseURL); | 647 completeURLs(*fragment, baseURL); |
648 | 648 |
649 return fragment.release(); | 649 return fragment.release(); |
650 } | 650 } |
651 | 651 |
652 static const char fragmentMarkerTag[] = "webkit-fragment-marker"; | 652 static const char fragmentMarkerTag[] = "webkit-fragment-marker"; |
(...skipping 28 matching lines...) Expand all Loading... |
681 break; | 681 break; |
682 } | 682 } |
683 | 683 |
684 ASSERT(nodeAfterContext->parentNode()); | 684 ASSERT(nodeAfterContext->parentNode()); |
685 for (RefPtr<Node> node = nodeAfterContext; node; node = next) { | 685 for (RefPtr<Node> node = nodeAfterContext; node; node = next) { |
686 next = NodeTraversal::nextSkippingChildren(*node); | 686 next = NodeTraversal::nextSkippingChildren(*node); |
687 node->parentNode()->removeChild(node.get(), ASSERT_NO_EXCEPTION); | 687 node->parentNode()->removeChild(node.get(), ASSERT_NO_EXCEPTION); |
688 } | 688 } |
689 } | 689 } |
690 | 690 |
691 PassRefPtr<DocumentFragment> createFragmentFromMarkupWithContext(Document& docum
ent, const String& markup, unsigned fragmentStart, unsigned fragmentEnd, | 691 PassRefPtrWillBeRawPtr<DocumentFragment> createFragmentFromMarkupWithContext(Doc
ument& document, const String& markup, unsigned fragmentStart, unsigned fragment
End, |
692 const String& baseURL, ParserContentPolicy parserContentPolicy) | 692 const String& baseURL, ParserContentPolicy parserContentPolicy) |
693 { | 693 { |
694 // FIXME: Need to handle the case where the markup already contains these ma
rkers. | 694 // FIXME: Need to handle the case where the markup already contains these ma
rkers. |
695 | 695 |
696 StringBuilder taggedMarkup; | 696 StringBuilder taggedMarkup; |
697 taggedMarkup.append(markup.left(fragmentStart)); | 697 taggedMarkup.append(markup.left(fragmentStart)); |
698 MarkupAccumulator::appendComment(taggedMarkup, fragmentMarkerTag); | 698 MarkupAccumulator::appendComment(taggedMarkup, fragmentMarkerTag); |
699 taggedMarkup.append(markup.substring(fragmentStart, fragmentEnd - fragmentSt
art)); | 699 taggedMarkup.append(markup.substring(fragmentStart, fragmentEnd - fragmentSt
art)); |
700 MarkupAccumulator::appendComment(taggedMarkup, fragmentMarkerTag); | 700 MarkupAccumulator::appendComment(taggedMarkup, fragmentMarkerTag); |
701 taggedMarkup.append(markup.substring(fragmentEnd)); | 701 taggedMarkup.append(markup.substring(fragmentEnd)); |
702 | 702 |
703 RefPtr<DocumentFragment> taggedFragment = createFragmentFromMarkup(document,
taggedMarkup.toString(), baseURL, parserContentPolicy); | 703 RefPtrWillBeRawPtr<DocumentFragment> taggedFragment = createFragmentFromMark
up(document, taggedMarkup.toString(), baseURL, parserContentPolicy); |
704 RefPtr<Document> taggedDocument = Document::create(); | 704 RefPtrWillBeRawPtr<Document> taggedDocument = Document::create(); |
705 taggedDocument->setContextFeatures(document.contextFeatures()); | 705 taggedDocument->setContextFeatures(document.contextFeatures()); |
706 | 706 |
707 // FIXME: It's not clear what this code is trying to do. It puts nodes as di
rect children of a | 707 // FIXME: It's not clear what this code is trying to do. It puts nodes as di
rect children of a |
708 // Document that are not normally allowed by using the parser machinery. | 708 // Document that are not normally allowed by using the parser machinery. |
709 taggedDocument->parserTakeAllChildrenFrom(*taggedFragment); | 709 taggedDocument->parserTakeAllChildrenFrom(*taggedFragment); |
710 | 710 |
711 RefPtr<Node> nodeBeforeContext; | 711 RefPtr<Node> nodeBeforeContext; |
712 RefPtr<Node> nodeAfterContext; | 712 RefPtr<Node> nodeAfterContext; |
713 if (!findNodesSurroundingContext(taggedDocument.get(), nodeBeforeContext, no
deAfterContext)) | 713 if (!findNodesSurroundingContext(taggedDocument.get(), nodeBeforeContext, no
deAfterContext)) |
714 return nullptr; | 714 return nullptr; |
715 | 715 |
716 RefPtrWillBeRawPtr<Range> range = Range::create(*taggedDocument.get(), | 716 RefPtrWillBeRawPtr<Range> range = Range::create(*taggedDocument.get(), |
717 positionAfterNode(nodeBeforeContext.get()).parentAnchoredEquivalent(), | 717 positionAfterNode(nodeBeforeContext.get()).parentAnchoredEquivalent(), |
718 positionBeforeNode(nodeAfterContext.get()).parentAnchoredEquivalent()); | 718 positionBeforeNode(nodeAfterContext.get()).parentAnchoredEquivalent()); |
719 | 719 |
720 Node* commonAncestor = range->commonAncestorContainer(); | 720 Node* commonAncestor = range->commonAncestorContainer(); |
721 Node* specialCommonAncestor = ancestorToRetainStructureAndAppearanceWithNoRe
nderer(commonAncestor); | 721 Node* specialCommonAncestor = ancestorToRetainStructureAndAppearanceWithNoRe
nderer(commonAncestor); |
722 | 722 |
723 // When there's a special common ancestor outside of the fragment, we must i
nclude it as well to | 723 // When there's a special common ancestor outside of the fragment, we must i
nclude it as well to |
724 // preserve the structure and appearance of the fragment. For example, if th
e fragment contains | 724 // preserve the structure and appearance of the fragment. For example, if th
e fragment contains |
725 // TD, we need to include the enclosing TABLE tag as well. | 725 // TD, we need to include the enclosing TABLE tag as well. |
726 RefPtr<DocumentFragment> fragment = DocumentFragment::create(document); | 726 RefPtrWillBeRawPtr<DocumentFragment> fragment = DocumentFragment::create(doc
ument); |
727 if (specialCommonAncestor) | 727 if (specialCommonAncestor) |
728 fragment->appendChild(specialCommonAncestor); | 728 fragment->appendChild(specialCommonAncestor); |
729 else | 729 else |
730 fragment->parserTakeAllChildrenFrom(toContainerNode(*commonAncestor)); | 730 fragment->parserTakeAllChildrenFrom(toContainerNode(*commonAncestor)); |
731 | 731 |
732 trimFragment(fragment.get(), nodeBeforeContext.get(), nodeAfterContext.get()
); | 732 trimFragment(fragment.get(), nodeBeforeContext.get(), nodeAfterContext.get()
); |
733 | 733 |
734 return fragment; | 734 return fragment; |
735 } | 735 } |
736 | 736 |
(...skipping 24 matching lines...) Expand all Loading... |
761 size_t numEntries = tabList.size(); | 761 size_t numEntries = tabList.size(); |
762 for (size_t i = 0; i < numEntries; ++i) { | 762 for (size_t i = 0; i < numEntries; ++i) { |
763 const String& s = tabList[i]; | 763 const String& s = tabList[i]; |
764 | 764 |
765 // append the non-tab textual part | 765 // append the non-tab textual part |
766 if (!s.isEmpty()) { | 766 if (!s.isEmpty()) { |
767 if (!tabText.isEmpty()) { | 767 if (!tabText.isEmpty()) { |
768 paragraph->appendChild(createTabSpanElement(document, tabText.to
String())); | 768 paragraph->appendChild(createTabSpanElement(document, tabText.to
String())); |
769 tabText.clear(); | 769 tabText.clear(); |
770 } | 770 } |
771 RefPtr<Node> textNode = document.createTextNode(stringWithRebalanced
Whitespace(s, first, i + 1 == numEntries)); | 771 RefPtrWillBeRawPtr<Node> textNode = document.createTextNode(stringWi
thRebalancedWhitespace(s, first, i + 1 == numEntries)); |
772 paragraph->appendChild(textNode.release()); | 772 paragraph->appendChild(textNode.release()); |
773 } | 773 } |
774 | 774 |
775 // there is a tab after every entry, except the last entry | 775 // there is a tab after every entry, except the last entry |
776 // (if the last character is a tab, the list gets an extra empty entry) | 776 // (if the last character is a tab, the list gets an extra empty entry) |
777 if (i + 1 != numEntries) | 777 if (i + 1 != numEntries) |
778 tabText.append('\t'); | 778 tabText.append('\t'); |
779 else if (!tabText.isEmpty()) | 779 else if (!tabText.isEmpty()) |
780 paragraph->appendChild(createTabSpanElement(document, tabText.toStri
ng())); | 780 paragraph->appendChild(createTabSpanElement(document, tabText.toStri
ng())); |
781 | 781 |
(...skipping 25 matching lines...) Expand all Loading... |
807 } | 807 } |
808 | 808 |
809 if (Node* node = range.startPosition().anchorNode()) { | 809 if (Node* node = range.startPosition().anchorNode()) { |
810 if (RenderObject* renderer = node->renderer()) | 810 if (RenderObject* renderer = node->renderer()) |
811 return renderer->style()->preserveNewline(); | 811 return renderer->style()->preserveNewline(); |
812 } | 812 } |
813 | 813 |
814 return false; | 814 return false; |
815 } | 815 } |
816 | 816 |
817 PassRefPtr<DocumentFragment> createFragmentFromText(Range* context, const String
& text) | 817 PassRefPtrWillBeRawPtr<DocumentFragment> createFragmentFromText(Range* context,
const String& text) |
818 { | 818 { |
819 if (!context) | 819 if (!context) |
820 return nullptr; | 820 return nullptr; |
821 | 821 |
822 Document& document = context->ownerDocument(); | 822 Document& document = context->ownerDocument(); |
823 RefPtr<DocumentFragment> fragment = document.createDocumentFragment(); | 823 RefPtrWillBeRawPtr<DocumentFragment> fragment = document.createDocumentFragm
ent(); |
824 | 824 |
825 if (text.isEmpty()) | 825 if (text.isEmpty()) |
826 return fragment.release(); | 826 return fragment.release(); |
827 | 827 |
828 String string = text; | 828 String string = text; |
829 string.replace("\r\n", "\n"); | 829 string.replace("\r\n", "\n"); |
830 string.replace('\r', '\n'); | 830 string.replace('\r', '\n'); |
831 | 831 |
832 if (shouldPreserveNewline(*context)) { | 832 if (shouldPreserveNewline(*context)) { |
833 fragment->appendChild(document.createTextNode(string)); | 833 fragment->appendChild(document.createTextNode(string)); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
903 { | 903 { |
904 StringBuilder markup; | 904 StringBuilder markup; |
905 markup.appendLiteral("<a href=\""); | 905 markup.appendLiteral("<a href=\""); |
906 markup.append(url.string()); | 906 markup.append(url.string()); |
907 markup.appendLiteral("\">"); | 907 markup.appendLiteral("\">"); |
908 MarkupAccumulator::appendCharactersReplacingEntities(markup, title, 0, title
.length(), EntityMaskInPCDATA); | 908 MarkupAccumulator::appendCharactersReplacingEntities(markup, title, 0, title
.length(), EntityMaskInPCDATA); |
909 markup.appendLiteral("</a>"); | 909 markup.appendLiteral("</a>"); |
910 return markup.toString(); | 910 return markup.toString(); |
911 } | 911 } |
912 | 912 |
913 PassRefPtr<DocumentFragment> createFragmentForInnerOuterHTML(const String& marku
p, Element* contextElement, ParserContentPolicy parserContentPolicy, const char*
method, ExceptionState& exceptionState) | 913 PassRefPtrWillBeRawPtr<DocumentFragment> createFragmentForInnerOuterHTML(const S
tring& markup, Element* contextElement, ParserContentPolicy parserContentPolicy,
const char* method, ExceptionState& exceptionState) |
914 { | 914 { |
915 ASSERT(contextElement); | 915 ASSERT(contextElement); |
916 Document& document = isHTMLTemplateElement(*contextElement) ? contextElement
->document().ensureTemplateDocument() : contextElement->document(); | 916 Document& document = isHTMLTemplateElement(*contextElement) ? contextElement
->document().ensureTemplateDocument() : contextElement->document(); |
917 RefPtr<DocumentFragment> fragment = DocumentFragment::create(document); | 917 RefPtrWillBeRawPtr<DocumentFragment> fragment = DocumentFragment::create(doc
ument); |
918 | 918 |
919 if (document.isHTMLDocument()) { | 919 if (document.isHTMLDocument()) { |
920 fragment->parseHTML(markup, contextElement, parserContentPolicy); | 920 fragment->parseHTML(markup, contextElement, parserContentPolicy); |
921 return fragment; | 921 return fragment; |
922 } | 922 } |
923 | 923 |
924 bool wasValid = fragment->parseXML(markup, contextElement, parserContentPoli
cy); | 924 bool wasValid = fragment->parseXML(markup, contextElement, parserContentPoli
cy); |
925 if (!wasValid) { | 925 if (!wasValid) { |
926 exceptionState.throwDOMException(SyntaxError, "The provided markup is in
valid XML, and therefore cannot be inserted into an XML document."); | 926 exceptionState.throwDOMException(SyntaxError, "The provided markup is in
valid XML, and therefore cannot be inserted into an XML document."); |
927 return nullptr; | 927 return nullptr; |
928 } | 928 } |
929 return fragment.release(); | 929 return fragment.release(); |
930 } | 930 } |
931 | 931 |
932 PassRefPtr<DocumentFragment> createFragmentForTransformToFragment(const String&
sourceString, const String& sourceMIMEType, Document& outputDoc) | 932 PassRefPtrWillBeRawPtr<DocumentFragment> createFragmentForTransformToFragment(co
nst String& sourceString, const String& sourceMIMEType, Document& outputDoc) |
933 { | 933 { |
934 RefPtr<DocumentFragment> fragment = outputDoc.createDocumentFragment(); | 934 RefPtrWillBeRawPtr<DocumentFragment> fragment = outputDoc.createDocumentFrag
ment(); |
935 | 935 |
936 if (sourceMIMEType == "text/html") { | 936 if (sourceMIMEType == "text/html") { |
937 // As far as I can tell, there isn't a spec for how transformToFragment
is supposed to work. | 937 // As far as I can tell, there isn't a spec for how transformToFragment
is supposed to work. |
938 // Based on the documentation I can find, it looks like we want to start
parsing the fragment in the InBody insertion mode. | 938 // Based on the documentation I can find, it looks like we want to start
parsing the fragment in the InBody insertion mode. |
939 // Unfortunately, that's an implementation detail of the parser. | 939 // Unfortunately, that's an implementation detail of the parser. |
940 // We achieve that effect here by passing in a fake body element as cont
ext for the fragment. | 940 // We achieve that effect here by passing in a fake body element as cont
ext for the fragment. |
941 RefPtr<HTMLBodyElement> fakeBody = HTMLBodyElement::create(outputDoc); | 941 RefPtr<HTMLBodyElement> fakeBody = HTMLBodyElement::create(outputDoc); |
942 fragment->parseHTML(sourceString, fakeBody.get()); | 942 fragment->parseHTML(sourceString, fakeBody.get()); |
943 } else if (sourceMIMEType == "text/plain") { | 943 } else if (sourceMIMEType == "text/plain") { |
944 fragment->parserAppendChild(Text::create(outputDoc, sourceString)); | 944 fragment->parserAppendChild(Text::create(outputDoc, sourceString)); |
945 } else { | 945 } else { |
946 bool successfulParse = fragment->parseXML(sourceString, 0); | 946 bool successfulParse = fragment->parseXML(sourceString, 0); |
947 if (!successfulParse) | 947 if (!successfulParse) |
948 return nullptr; | 948 return nullptr; |
949 } | 949 } |
950 | 950 |
951 // FIXME: Do we need to mess with URLs here? | 951 // FIXME: Do we need to mess with URLs here? |
952 | 952 |
953 return fragment.release(); | 953 return fragment.release(); |
954 } | 954 } |
955 | 955 |
956 static inline void removeElementPreservingChildren(PassRefPtr<DocumentFragment>
fragment, HTMLElement* element) | 956 static inline void removeElementPreservingChildren(PassRefPtrWillBeRawPtr<Docume
ntFragment> fragment, HTMLElement* element) |
957 { | 957 { |
958 RefPtr<Node> nextChild; | 958 RefPtr<Node> nextChild; |
959 for (RefPtr<Node> child = element->firstChild(); child; child = nextChild) { | 959 for (RefPtr<Node> child = element->firstChild(); child; child = nextChild) { |
960 nextChild = child->nextSibling(); | 960 nextChild = child->nextSibling(); |
961 element->removeChild(child.get()); | 961 element->removeChild(child.get()); |
962 fragment->insertBefore(child, element); | 962 fragment->insertBefore(child, element); |
963 } | 963 } |
964 fragment->removeChild(element); | 964 fragment->removeChild(element); |
965 } | 965 } |
966 | 966 |
967 PassRefPtr<DocumentFragment> createContextualFragment(const String& markup, HTML
Element* element, ParserContentPolicy parserContentPolicy, ExceptionState& excep
tionState) | 967 PassRefPtrWillBeRawPtr<DocumentFragment> createContextualFragment(const String&
markup, HTMLElement* element, ParserContentPolicy parserContentPolicy, Exception
State& exceptionState) |
968 { | 968 { |
969 ASSERT(element); | 969 ASSERT(element); |
970 if (element->ieForbidsInsertHTML() || element->hasLocalName(colTag) || eleme
nt->hasLocalName(colgroupTag) || element->hasLocalName(framesetTag) | 970 if (element->ieForbidsInsertHTML() || element->hasLocalName(colTag) || eleme
nt->hasLocalName(colgroupTag) || element->hasLocalName(framesetTag) |
971 || element->hasLocalName(headTag) || element->hasLocalName(styleTag) ||
element->hasLocalName(titleTag)) { | 971 || element->hasLocalName(headTag) || element->hasLocalName(styleTag) ||
element->hasLocalName(titleTag)) { |
972 exceptionState.throwDOMException(NotSupportedError, "The range's contain
er is '" + element->localName() + "', which is not supported."); | 972 exceptionState.throwDOMException(NotSupportedError, "The range's contain
er is '" + element->localName() + "', which is not supported."); |
973 return nullptr; | 973 return nullptr; |
974 } | 974 } |
975 | 975 |
976 RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(markup,
element, parserContentPolicy, "createContextualFragment", exceptionState); | 976 RefPtrWillBeRawPtr<DocumentFragment> fragment = createFragmentForInnerOuterH
TML(markup, element, parserContentPolicy, "createContextualFragment", exceptionS
tate); |
977 if (!fragment) | 977 if (!fragment) |
978 return nullptr; | 978 return nullptr; |
979 | 979 |
980 // We need to pop <html> and <body> elements and remove <head> to | 980 // We need to pop <html> and <body> elements and remove <head> to |
981 // accommodate folks passing complete HTML documents to make the | 981 // accommodate folks passing complete HTML documents to make the |
982 // child of an element. | 982 // child of an element. |
983 | 983 |
984 RefPtr<Node> nextNode; | 984 RefPtr<Node> nextNode; |
985 for (RefPtr<Node> node = fragment->firstChild(); node; node = nextNode) { | 985 for (RefPtr<Node> node = fragment->firstChild(); node; node = nextNode) { |
986 nextNode = node->nextSibling(); | 986 nextNode = node->nextSibling(); |
987 if (isHTMLHtmlElement(*node) || isHTMLHeadElement(*node) || isHTMLBodyEl
ement(*node)) { | 987 if (isHTMLHtmlElement(*node) || isHTMLHeadElement(*node) || isHTMLBodyEl
ement(*node)) { |
988 HTMLElement* element = toHTMLElement(node); | 988 HTMLElement* element = toHTMLElement(node); |
989 if (Node* firstChild = element->firstChild()) | 989 if (Node* firstChild = element->firstChild()) |
990 nextNode = firstChild; | 990 nextNode = firstChild; |
991 removeElementPreservingChildren(fragment, element); | 991 removeElementPreservingChildren(fragment, element); |
992 } | 992 } |
993 } | 993 } |
994 return fragment.release(); | 994 return fragment.release(); |
995 } | 995 } |
996 | 996 |
997 void replaceChildrenWithFragment(ContainerNode* container, PassRefPtr<DocumentFr
agment> fragment, ExceptionState& exceptionState) | 997 void replaceChildrenWithFragment(ContainerNode* container, PassRefPtrWillBeRawPt
r<DocumentFragment> fragment, ExceptionState& exceptionState) |
998 { | 998 { |
999 ASSERT(container); | 999 ASSERT(container); |
1000 RefPtr<ContainerNode> containerNode(container); | 1000 RefPtrWillBeRawPtr<ContainerNode> containerNode(container); |
1001 | 1001 |
1002 ChildListMutationScope mutation(*containerNode); | 1002 ChildListMutationScope mutation(*containerNode); |
1003 | 1003 |
1004 if (!fragment->firstChild()) { | 1004 if (!fragment->firstChild()) { |
1005 containerNode->removeChildren(); | 1005 containerNode->removeChildren(); |
1006 return; | 1006 return; |
1007 } | 1007 } |
1008 | 1008 |
1009 // FIXME: This is wrong if containerNode->firstChild() has more than one ref
! | 1009 // FIXME: This is wrong if containerNode->firstChild() has more than one ref
! |
1010 if (containerNode->hasOneTextChild() && fragment->hasOneTextChild()) { | 1010 if (containerNode->hasOneTextChild() && fragment->hasOneTextChild()) { |
1011 toText(containerNode->firstChild())->setData(toText(fragment->firstChild
())->data()); | 1011 toText(containerNode->firstChild())->setData(toText(fragment->firstChild
())->data()); |
1012 return; | 1012 return; |
1013 } | 1013 } |
1014 | 1014 |
1015 // FIXME: No need to replace the child it is a text node and its contents ar
e already == text. | 1015 // FIXME: No need to replace the child it is a text node and its contents ar
e already == text. |
1016 if (containerNode->hasOneChild()) { | 1016 if (containerNode->hasOneChild()) { |
1017 containerNode->replaceChild(fragment, containerNode->firstChild(), excep
tionState); | 1017 containerNode->replaceChild(fragment, containerNode->firstChild(), excep
tionState); |
1018 return; | 1018 return; |
1019 } | 1019 } |
1020 | 1020 |
1021 containerNode->removeChildren(); | 1021 containerNode->removeChildren(); |
1022 containerNode->appendChild(fragment, exceptionState); | 1022 containerNode->appendChild(fragment, exceptionState); |
1023 } | 1023 } |
1024 | 1024 |
1025 void replaceChildrenWithText(ContainerNode* container, const String& text, Excep
tionState& exceptionState) | 1025 void replaceChildrenWithText(ContainerNode* container, const String& text, Excep
tionState& exceptionState) |
1026 { | 1026 { |
1027 ASSERT(container); | 1027 ASSERT(container); |
1028 RefPtr<ContainerNode> containerNode(container); | 1028 RefPtrWillBeRawPtr<ContainerNode> containerNode(container); |
1029 | 1029 |
1030 ChildListMutationScope mutation(*containerNode); | 1030 ChildListMutationScope mutation(*containerNode); |
1031 | 1031 |
1032 // FIXME: This is wrong if containerNode->firstChild() has more than one ref
! Example: | 1032 // FIXME: This is wrong if containerNode->firstChild() has more than one ref
! Example: |
1033 // <div>foo</div> | 1033 // <div>foo</div> |
1034 // <script> | 1034 // <script> |
1035 // var oldText = div.firstChild; | 1035 // var oldText = div.firstChild; |
1036 // console.log(oldText.data); // foo | 1036 // console.log(oldText.data); // foo |
1037 // div.innerText = "bar"; | 1037 // div.innerText = "bar"; |
1038 // console.log(oldText.data); // bar!?! | 1038 // console.log(oldText.data); // bar!?! |
(...skipping 26 matching lines...) Expand all Loading... |
1065 return; | 1065 return; |
1066 | 1066 |
1067 RefPtrWillBeRawPtr<Text> textNode = toText(node.get()); | 1067 RefPtrWillBeRawPtr<Text> textNode = toText(node.get()); |
1068 RefPtrWillBeRawPtr<Text> textNext = toText(next); | 1068 RefPtrWillBeRawPtr<Text> textNext = toText(next); |
1069 textNode->appendData(textNext->data()); | 1069 textNode->appendData(textNext->data()); |
1070 if (textNext->parentNode()) // Might have been removed by mutation event. | 1070 if (textNext->parentNode()) // Might have been removed by mutation event. |
1071 textNext->remove(exceptionState); | 1071 textNext->remove(exceptionState); |
1072 } | 1072 } |
1073 | 1073 |
1074 } | 1074 } |
OLD | NEW |