| 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 |