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 |