| 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 631 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 642 | 642 |
| 643 Document& document = range->ownerDocument(); | 643 Document& document = range->ownerDocument(); |
| 644 const Range* updatedRange = range; | 644 const Range* updatedRange = range; |
| 645 | 645 |
| 646 return createMarkupInternal(document, range, updatedRange, nodes, shouldAnno
tate, convertBlocksToInlines, shouldResolveURLs, constrainingAncestor); | 646 return createMarkupInternal(document, range, updatedRange, nodes, shouldAnno
tate, convertBlocksToInlines, shouldResolveURLs, constrainingAncestor); |
| 647 } | 647 } |
| 648 | 648 |
| 649 PassRefPtrWillBeRawPtr<DocumentFragment> createFragmentFromMarkup(Document& docu
ment, const String& markup, const String& baseURL, ParserContentPolicy parserCon
tentPolicy) | 649 PassRefPtrWillBeRawPtr<DocumentFragment> createFragmentFromMarkup(Document& docu
ment, const String& markup, const String& baseURL, ParserContentPolicy parserCon
tentPolicy) |
| 650 { | 650 { |
| 651 // We use a fake body element here to trick the HTML parser to using the InB
ody insertion mode. | 651 // We use a fake body element here to trick the HTML parser to using the InB
ody insertion mode. |
| 652 RefPtr<HTMLBodyElement> fakeBody = HTMLBodyElement::create(document); | 652 RefPtrWillBeRawPtr<HTMLBodyElement> fakeBody = HTMLBodyElement::create(docum
ent); |
| 653 RefPtrWillBeRawPtr<DocumentFragment> fragment = DocumentFragment::create(doc
ument); | 653 RefPtrWillBeRawPtr<DocumentFragment> fragment = DocumentFragment::create(doc
ument); |
| 654 | 654 |
| 655 fragment->parseHTML(markup, fakeBody.get(), parserContentPolicy); | 655 fragment->parseHTML(markup, fakeBody.get(), parserContentPolicy); |
| 656 | 656 |
| 657 if (!baseURL.isEmpty() && baseURL != blankURL() && baseURL != document.baseU
RL()) | 657 if (!baseURL.isEmpty() && baseURL != blankURL() && baseURL != document.baseU
RL()) |
| 658 completeURLs(*fragment, baseURL); | 658 completeURLs(*fragment, baseURL); |
| 659 | 659 |
| 660 return fragment.release(); | 660 return fragment.release(); |
| 661 } | 661 } |
| 662 | 662 |
| 663 static const char fragmentMarkerTag[] = "webkit-fragment-marker"; | 663 static const char fragmentMarkerTag[] = "webkit-fragment-marker"; |
| 664 | 664 |
| 665 static bool findNodesSurroundingContext(Document* document, RefPtr<Node>& nodeBe
foreContext, RefPtr<Node>& nodeAfterContext) | 665 static bool findNodesSurroundingContext(Document* document, RefPtrWillBeRawPtr<N
ode>& nodeBeforeContext, RefPtrWillBeRawPtr<Node>& nodeAfterContext) |
| 666 { | 666 { |
| 667 for (Node* node = document->firstChild(); node; node = NodeTraversal::next(*
node)) { | 667 for (Node* node = document->firstChild(); node; node = NodeTraversal::next(*
node)) { |
| 668 if (node->nodeType() == Node::COMMENT_NODE && toCharacterData(node)->dat
a() == fragmentMarkerTag) { | 668 if (node->nodeType() == Node::COMMENT_NODE && toCharacterData(node)->dat
a() == fragmentMarkerTag) { |
| 669 if (!nodeBeforeContext) | 669 if (!nodeBeforeContext) |
| 670 nodeBeforeContext = node; | 670 nodeBeforeContext = node; |
| 671 else { | 671 else { |
| 672 nodeAfterContext = node; | 672 nodeAfterContext = node; |
| 673 return true; | 673 return true; |
| 674 } | 674 } |
| 675 } | 675 } |
| 676 } | 676 } |
| 677 return false; | 677 return false; |
| 678 } | 678 } |
| 679 | 679 |
| 680 static void trimFragment(DocumentFragment* fragment, Node* nodeBeforeContext, No
de* nodeAfterContext) | 680 static void trimFragment(DocumentFragment* fragment, Node* nodeBeforeContext, No
de* nodeAfterContext) |
| 681 { | 681 { |
| 682 RefPtr<Node> next; | 682 RefPtrWillBeRawPtr<Node> next = nullptr; |
| 683 for (RefPtr<Node> node = fragment->firstChild(); node; node = next) { | 683 for (RefPtrWillBeRawPtr<Node> node = fragment->firstChild(); node; node = ne
xt) { |
| 684 if (nodeBeforeContext->isDescendantOf(node.get())) { | 684 if (nodeBeforeContext->isDescendantOf(node.get())) { |
| 685 next = NodeTraversal::next(*node); | 685 next = NodeTraversal::next(*node); |
| 686 continue; | 686 continue; |
| 687 } | 687 } |
| 688 next = NodeTraversal::nextSkippingChildren(*node); | 688 next = NodeTraversal::nextSkippingChildren(*node); |
| 689 ASSERT(!node->contains(nodeAfterContext)); | 689 ASSERT(!node->contains(nodeAfterContext)); |
| 690 node->parentNode()->removeChild(node.get(), ASSERT_NO_EXCEPTION); | 690 node->parentNode()->removeChild(node.get(), ASSERT_NO_EXCEPTION); |
| 691 if (nodeBeforeContext == node) | 691 if (nodeBeforeContext == node) |
| 692 break; | 692 break; |
| 693 } | 693 } |
| 694 | 694 |
| 695 ASSERT(nodeAfterContext->parentNode()); | 695 ASSERT(nodeAfterContext->parentNode()); |
| 696 for (RefPtr<Node> node = nodeAfterContext; node; node = next) { | 696 for (RefPtrWillBeRawPtr<Node> node = nodeAfterContext; node; node = next) { |
| 697 next = NodeTraversal::nextSkippingChildren(*node); | 697 next = NodeTraversal::nextSkippingChildren(*node); |
| 698 node->parentNode()->removeChild(node.get(), ASSERT_NO_EXCEPTION); | 698 node->parentNode()->removeChild(node.get(), ASSERT_NO_EXCEPTION); |
| 699 } | 699 } |
| 700 } | 700 } |
| 701 | 701 |
| 702 PassRefPtrWillBeRawPtr<DocumentFragment> createFragmentFromMarkupWithContext(Doc
ument& document, const String& markup, unsigned fragmentStart, unsigned fragment
End, | 702 PassRefPtrWillBeRawPtr<DocumentFragment> createFragmentFromMarkupWithContext(Doc
ument& document, const String& markup, unsigned fragmentStart, unsigned fragment
End, |
| 703 const String& baseURL, ParserContentPolicy parserContentPolicy) | 703 const String& baseURL, ParserContentPolicy parserContentPolicy) |
| 704 { | 704 { |
| 705 // FIXME: Need to handle the case where the markup already contains these ma
rkers. | 705 // FIXME: Need to handle the case where the markup already contains these ma
rkers. |
| 706 | 706 |
| 707 StringBuilder taggedMarkup; | 707 StringBuilder taggedMarkup; |
| 708 taggedMarkup.append(markup.left(fragmentStart)); | 708 taggedMarkup.append(markup.left(fragmentStart)); |
| 709 MarkupAccumulator::appendComment(taggedMarkup, fragmentMarkerTag); | 709 MarkupAccumulator::appendComment(taggedMarkup, fragmentMarkerTag); |
| 710 taggedMarkup.append(markup.substring(fragmentStart, fragmentEnd - fragmentSt
art)); | 710 taggedMarkup.append(markup.substring(fragmentStart, fragmentEnd - fragmentSt
art)); |
| 711 MarkupAccumulator::appendComment(taggedMarkup, fragmentMarkerTag); | 711 MarkupAccumulator::appendComment(taggedMarkup, fragmentMarkerTag); |
| 712 taggedMarkup.append(markup.substring(fragmentEnd)); | 712 taggedMarkup.append(markup.substring(fragmentEnd)); |
| 713 | 713 |
| 714 RefPtrWillBeRawPtr<DocumentFragment> taggedFragment = createFragmentFromMark
up(document, taggedMarkup.toString(), baseURL, parserContentPolicy); | 714 RefPtrWillBeRawPtr<DocumentFragment> taggedFragment = createFragmentFromMark
up(document, taggedMarkup.toString(), baseURL, parserContentPolicy); |
| 715 RefPtrWillBeRawPtr<Document> taggedDocument = Document::create(); | 715 RefPtrWillBeRawPtr<Document> taggedDocument = Document::create(); |
| 716 taggedDocument->setContextFeatures(document.contextFeatures()); | 716 taggedDocument->setContextFeatures(document.contextFeatures()); |
| 717 | 717 |
| 718 // FIXME: It's not clear what this code is trying to do. It puts nodes as di
rect children of a | 718 // FIXME: It's not clear what this code is trying to do. It puts nodes as di
rect children of a |
| 719 // Document that are not normally allowed by using the parser machinery. | 719 // Document that are not normally allowed by using the parser machinery. |
| 720 taggedDocument->parserTakeAllChildrenFrom(*taggedFragment); | 720 taggedDocument->parserTakeAllChildrenFrom(*taggedFragment); |
| 721 | 721 |
| 722 RefPtr<Node> nodeBeforeContext; | 722 RefPtrWillBeRawPtr<Node> nodeBeforeContext = nullptr; |
| 723 RefPtr<Node> nodeAfterContext; | 723 RefPtrWillBeRawPtr<Node> nodeAfterContext = nullptr; |
| 724 if (!findNodesSurroundingContext(taggedDocument.get(), nodeBeforeContext, no
deAfterContext)) | 724 if (!findNodesSurroundingContext(taggedDocument.get(), nodeBeforeContext, no
deAfterContext)) |
| 725 return nullptr; | 725 return nullptr; |
| 726 | 726 |
| 727 RefPtrWillBeRawPtr<Range> range = Range::create(*taggedDocument.get(), | 727 RefPtrWillBeRawPtr<Range> range = Range::create(*taggedDocument.get(), |
| 728 positionAfterNode(nodeBeforeContext.get()).parentAnchoredEquivalent(), | 728 positionAfterNode(nodeBeforeContext.get()).parentAnchoredEquivalent(), |
| 729 positionBeforeNode(nodeAfterContext.get()).parentAnchoredEquivalent()); | 729 positionBeforeNode(nodeAfterContext.get()).parentAnchoredEquivalent()); |
| 730 | 730 |
| 731 Node* commonAncestor = range->commonAncestorContainer(); | 731 Node* commonAncestor = range->commonAncestorContainer(); |
| 732 Node* specialCommonAncestor = ancestorToRetainStructureAndAppearanceWithNoRe
nderer(commonAncestor); | 732 Node* specialCommonAncestor = ancestorToRetainStructureAndAppearanceWithNoRe
nderer(commonAncestor); |
| 733 | 733 |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 942 | 942 |
| 943 PassRefPtrWillBeRawPtr<DocumentFragment> createFragmentForTransformToFragment(co
nst String& sourceString, const String& sourceMIMEType, Document& outputDoc) | 943 PassRefPtrWillBeRawPtr<DocumentFragment> createFragmentForTransformToFragment(co
nst String& sourceString, const String& sourceMIMEType, Document& outputDoc) |
| 944 { | 944 { |
| 945 RefPtrWillBeRawPtr<DocumentFragment> fragment = outputDoc.createDocumentFrag
ment(); | 945 RefPtrWillBeRawPtr<DocumentFragment> fragment = outputDoc.createDocumentFrag
ment(); |
| 946 | 946 |
| 947 if (sourceMIMEType == "text/html") { | 947 if (sourceMIMEType == "text/html") { |
| 948 // As far as I can tell, there isn't a spec for how transformToFragment
is supposed to work. | 948 // As far as I can tell, there isn't a spec for how transformToFragment
is supposed to work. |
| 949 // Based on the documentation I can find, it looks like we want to start
parsing the fragment in the InBody insertion mode. | 949 // Based on the documentation I can find, it looks like we want to start
parsing the fragment in the InBody insertion mode. |
| 950 // Unfortunately, that's an implementation detail of the parser. | 950 // Unfortunately, that's an implementation detail of the parser. |
| 951 // We achieve that effect here by passing in a fake body element as cont
ext for the fragment. | 951 // We achieve that effect here by passing in a fake body element as cont
ext for the fragment. |
| 952 RefPtr<HTMLBodyElement> fakeBody = HTMLBodyElement::create(outputDoc); | 952 RefPtrWillBeRawPtr<HTMLBodyElement> fakeBody = HTMLBodyElement::create(o
utputDoc); |
| 953 fragment->parseHTML(sourceString, fakeBody.get()); | 953 fragment->parseHTML(sourceString, fakeBody.get()); |
| 954 } else if (sourceMIMEType == "text/plain") { | 954 } else if (sourceMIMEType == "text/plain") { |
| 955 fragment->parserAppendChild(Text::create(outputDoc, sourceString)); | 955 fragment->parserAppendChild(Text::create(outputDoc, sourceString)); |
| 956 } else { | 956 } else { |
| 957 bool successfulParse = fragment->parseXML(sourceString, 0); | 957 bool successfulParse = fragment->parseXML(sourceString, 0); |
| 958 if (!successfulParse) | 958 if (!successfulParse) |
| 959 return nullptr; | 959 return nullptr; |
| 960 } | 960 } |
| 961 | 961 |
| 962 // FIXME: Do we need to mess with URLs here? | 962 // FIXME: Do we need to mess with URLs here? |
| 963 | 963 |
| 964 return fragment.release(); | 964 return fragment.release(); |
| 965 } | 965 } |
| 966 | 966 |
| 967 static inline void removeElementPreservingChildren(PassRefPtrWillBeRawPtr<Docume
ntFragment> fragment, HTMLElement* element) | 967 static inline void removeElementPreservingChildren(PassRefPtrWillBeRawPtr<Docume
ntFragment> fragment, HTMLElement* element) |
| 968 { | 968 { |
| 969 RefPtr<Node> nextChild; | 969 RefPtrWillBeRawPtr<Node> nextChild = nullptr; |
| 970 for (RefPtr<Node> child = element->firstChild(); child; child = nextChild) { | 970 for (RefPtrWillBeRawPtr<Node> child = element->firstChild(); child; child =
nextChild) { |
| 971 nextChild = child->nextSibling(); | 971 nextChild = child->nextSibling(); |
| 972 element->removeChild(child.get()); | 972 element->removeChild(child.get()); |
| 973 fragment->insertBefore(child, element); | 973 fragment->insertBefore(child, element); |
| 974 } | 974 } |
| 975 fragment->removeChild(element); | 975 fragment->removeChild(element); |
| 976 } | 976 } |
| 977 | 977 |
| 978 PassRefPtrWillBeRawPtr<DocumentFragment> createContextualFragment(const String&
markup, HTMLElement* element, ParserContentPolicy parserContentPolicy, Exception
State& exceptionState) | 978 PassRefPtrWillBeRawPtr<DocumentFragment> createContextualFragment(const String&
markup, HTMLElement* element, ParserContentPolicy parserContentPolicy, Exception
State& exceptionState) |
| 979 { | 979 { |
| 980 ASSERT(element); | 980 ASSERT(element); |
| 981 if (element->ieForbidsInsertHTML() || element->hasLocalName(colTag) || eleme
nt->hasLocalName(colgroupTag) || element->hasLocalName(framesetTag) | 981 if (element->ieForbidsInsertHTML() || element->hasLocalName(colTag) || eleme
nt->hasLocalName(colgroupTag) || element->hasLocalName(framesetTag) |
| 982 || element->hasLocalName(headTag) || element->hasLocalName(styleTag) ||
element->hasLocalName(titleTag)) { | 982 || element->hasLocalName(headTag) || element->hasLocalName(styleTag) ||
element->hasLocalName(titleTag)) { |
| 983 exceptionState.throwDOMException(NotSupportedError, "The range's contain
er is '" + element->localName() + "', which is not supported."); | 983 exceptionState.throwDOMException(NotSupportedError, "The range's contain
er is '" + element->localName() + "', which is not supported."); |
| 984 return nullptr; | 984 return nullptr; |
| 985 } | 985 } |
| 986 | 986 |
| 987 RefPtrWillBeRawPtr<DocumentFragment> fragment = createFragmentForInnerOuterH
TML(markup, element, parserContentPolicy, "createContextualFragment", exceptionS
tate); | 987 RefPtrWillBeRawPtr<DocumentFragment> fragment = createFragmentForInnerOuterH
TML(markup, element, parserContentPolicy, "createContextualFragment", exceptionS
tate); |
| 988 if (!fragment) | 988 if (!fragment) |
| 989 return nullptr; | 989 return nullptr; |
| 990 | 990 |
| 991 // We need to pop <html> and <body> elements and remove <head> to | 991 // We need to pop <html> and <body> elements and remove <head> to |
| 992 // accommodate folks passing complete HTML documents to make the | 992 // accommodate folks passing complete HTML documents to make the |
| 993 // child of an element. | 993 // child of an element. |
| 994 | 994 |
| 995 RefPtr<Node> nextNode; | 995 RefPtrWillBeRawPtr<Node> nextNode = nullptr; |
| 996 for (RefPtr<Node> node = fragment->firstChild(); node; node = nextNode) { | 996 for (RefPtrWillBeRawPtr<Node> node = fragment->firstChild(); node; node = ne
xtNode) { |
| 997 nextNode = node->nextSibling(); | 997 nextNode = node->nextSibling(); |
| 998 if (isHTMLHtmlElement(*node) || isHTMLHeadElement(*node) || isHTMLBodyEl
ement(*node)) { | 998 if (isHTMLHtmlElement(*node) || isHTMLHeadElement(*node) || isHTMLBodyEl
ement(*node)) { |
| 999 HTMLElement* element = toHTMLElement(node); | 999 HTMLElement* element = toHTMLElement(node); |
| 1000 if (Node* firstChild = element->firstChild()) | 1000 if (Node* firstChild = element->firstChild()) |
| 1001 nextNode = firstChild; | 1001 nextNode = firstChild; |
| 1002 removeElementPreservingChildren(fragment, element); | 1002 removeElementPreservingChildren(fragment, element); |
| 1003 } | 1003 } |
| 1004 } | 1004 } |
| 1005 return fragment.release(); | 1005 return fragment.release(); |
| 1006 } | 1006 } |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1061 // FIXME: No need to replace the child it is a text node and its contents ar
e already == text. | 1061 // FIXME: No need to replace the child it is a text node and its contents ar
e already == text. |
| 1062 if (containerNode->hasOneChild()) { | 1062 if (containerNode->hasOneChild()) { |
| 1063 containerNode->replaceChild(textNode.release(), containerNode->firstChil
d(), exceptionState); | 1063 containerNode->replaceChild(textNode.release(), containerNode->firstChil
d(), exceptionState); |
| 1064 return; | 1064 return; |
| 1065 } | 1065 } |
| 1066 | 1066 |
| 1067 containerNode->removeChildren(); | 1067 containerNode->removeChildren(); |
| 1068 containerNode->appendChild(textNode.release(), exceptionState); | 1068 containerNode->appendChild(textNode.release(), exceptionState); |
| 1069 } | 1069 } |
| 1070 | 1070 |
| 1071 void mergeWithNextTextNode(PassRefPtr<Node> node, ExceptionState& exceptionState
) | 1071 void mergeWithNextTextNode(PassRefPtrWillBeRawPtr<Node> node, ExceptionState& ex
ceptionState) |
| 1072 { | 1072 { |
| 1073 ASSERT(node && node->isTextNode()); | 1073 ASSERT(node && node->isTextNode()); |
| 1074 Node* next = node->nextSibling(); | 1074 Node* next = node->nextSibling(); |
| 1075 if (!next || !next->isTextNode()) | 1075 if (!next || !next->isTextNode()) |
| 1076 return; | 1076 return; |
| 1077 | 1077 |
| 1078 RefPtrWillBeRawPtr<Text> textNode = toText(node.get()); | 1078 RefPtrWillBeRawPtr<Text> textNode = toText(node.get()); |
| 1079 RefPtrWillBeRawPtr<Text> textNext = toText(next); | 1079 RefPtrWillBeRawPtr<Text> textNext = toText(next); |
| 1080 textNode->appendData(textNext->data()); | 1080 textNode->appendData(textNext->data()); |
| 1081 if (textNext->parentNode()) // Might have been removed by mutation event. | 1081 if (textNext->parentNode()) // Might have been removed by mutation event. |
| 1082 textNext->remove(exceptionState); | 1082 textNext->remove(exceptionState); |
| 1083 } | 1083 } |
| 1084 | 1084 |
| 1085 } | 1085 } |
| OLD | NEW |