summaryrefslogtreecommitdiff
path: root/Source/WebCore/editing/markup.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-05-25 15:09:11 +0200
committerSimon Hausmann <simon.hausmann@nokia.com>2012-05-25 15:09:11 +0200
commita89b2ebb8e192c5e8cea21079bda2ee2c0c7dddd (patch)
treeb7abd9f49ae1d4d2e426a5883bfccd42b8e2ee12 /Source/WebCore/editing/markup.cpp
parent8d473cf9743f1d30a16a27114e93bd5af5648d23 (diff)
downloadqtwebkit-a89b2ebb8e192c5e8cea21079bda2ee2c0c7dddd.tar.gz
Imported WebKit commit eb5c1b8fe4d4b1b90b5137433fc58a91da0e6878 (http://svn.webkit.org/repository/webkit/trunk@118516)
Diffstat (limited to 'Source/WebCore/editing/markup.cpp')
-rw-r--r--Source/WebCore/editing/markup.cpp80
1 files changed, 78 insertions, 2 deletions
diff --git a/Source/WebCore/editing/markup.cpp b/Source/WebCore/editing/markup.cpp
index a1c5a3362..4983dcd4d 100644
--- a/Source/WebCore/editing/markup.cpp
+++ b/Source/WebCore/editing/markup.cpp
@@ -665,7 +665,7 @@ PassRefPtr<DocumentFragment> createFragmentFromMarkup(Document* document, const
{
// We use a fake body element here to trick the HTML parser to using the InBody insertion mode.
RefPtr<HTMLBodyElement> fakeBody = HTMLBodyElement::create(document);
- RefPtr<DocumentFragment> fragment = Range::createDocumentFragmentForElement(markup, fakeBody.get(), scriptingPermission);
+ RefPtr<DocumentFragment> fragment = createContextualFragment(markup, fakeBody.get(), scriptingPermission);
if (fragment && !baseURL.isEmpty() && baseURL != blankURL() && baseURL != document->baseURL())
completeURLs(fragment.get(), baseURL);
@@ -992,7 +992,7 @@ String urlToMarkup(const KURL& url, const String& title)
return markup.toString();
}
-PassRefPtr<DocumentFragment> createFragmentFromSource(const String& markup, Element* contextElement, ExceptionCode& ec)
+PassRefPtr<DocumentFragment> createFragmentForInnerOuterHTML(const String& markup, Element* contextElement, ExceptionCode& ec)
{
Document* document = contextElement->document();
RefPtr<DocumentFragment> fragment = DocumentFragment::create(document);
@@ -1010,6 +1010,82 @@ PassRefPtr<DocumentFragment> createFragmentFromSource(const String& markup, Elem
return fragment.release();
}
+PassRefPtr<DocumentFragment> createFragmentForTransformToFragment(const String& sourceString, const String& sourceMIMEType, Document* outputDoc)
+{
+ RefPtr<DocumentFragment> fragment = outputDoc->createDocumentFragment();
+
+ if (sourceMIMEType == "text/html") {
+ // As far as I can tell, there isn't a spec for how transformToFragment is supposed to work.
+ // Based on the documentation I can find, it looks like we want to start parsing the fragment in the InBody insertion mode.
+ // Unfortunately, that's an implementation detail of the parser.
+ // We achieve that effect here by passing in a fake body element as context for the fragment.
+ RefPtr<HTMLBodyElement> fakeBody = HTMLBodyElement::create(outputDoc);
+ fragment->parseHTML(sourceString, fakeBody.get());
+ } else if (sourceMIMEType == "text/plain")
+ fragment->parserAddChild(Text::create(outputDoc, sourceString));
+ else {
+ bool successfulParse = fragment->parseXML(sourceString, 0);
+ if (!successfulParse)
+ return 0;
+ }
+
+ // FIXME: Do we need to mess with URLs here?
+
+ return fragment.release();
+}
+
+static inline void removeElementPreservingChildren(PassRefPtr<DocumentFragment> fragment, HTMLElement* element)
+{
+ ExceptionCode ignoredExceptionCode;
+
+ RefPtr<Node> nextChild;
+ for (RefPtr<Node> child = element->firstChild(); child; child = nextChild) {
+ nextChild = child->nextSibling();
+ element->removeChild(child.get(), ignoredExceptionCode);
+ ASSERT(!ignoredExceptionCode);
+ fragment->insertBefore(child, element, ignoredExceptionCode);
+ ASSERT(!ignoredExceptionCode);
+ }
+ fragment->removeChild(element, ignoredExceptionCode);
+ ASSERT(!ignoredExceptionCode);
+}
+
+PassRefPtr<DocumentFragment> createContextualFragment(const String& markup, Element* element, FragmentScriptingPermission scriptingPermission)
+{
+ ASSERT(element);
+ HTMLElement* htmlElement = toHTMLElement(element);
+ if (htmlElement->ieForbidsInsertHTML())
+ return 0;
+
+ if (htmlElement->hasLocalName(colTag) || htmlElement->hasLocalName(colgroupTag) || htmlElement->hasLocalName(framesetTag)
+ || htmlElement->hasLocalName(headTag) || htmlElement->hasLocalName(styleTag) || htmlElement->hasLocalName(titleTag))
+ return 0;
+
+ // FIXME: This code is almost identical to createFragmentForInnerOuterHTML except this code doesn't handle exceptions.
+ RefPtr<DocumentFragment> fragment = element->document()->createDocumentFragment();
+
+ if (element->document()->isHTMLDocument())
+ fragment->parseHTML(markup, element, scriptingPermission);
+ else if (!fragment->parseXML(markup, element, scriptingPermission))
+ return 0; // FIXME: We should propagate a syntax error exception out here.
+
+ // We need to pop <html> and <body> elements and remove <head> to
+ // accommodate folks passing complete HTML documents to make the
+ // child of an element.
+
+ RefPtr<Node> nextNode;
+ for (RefPtr<Node> node = fragment->firstChild(); node; node = nextNode) {
+ nextNode = node->nextSibling();
+ if (node->hasTagName(htmlTag) || node->hasTagName(headTag) || node->hasTagName(bodyTag)) {
+ HTMLElement* element = toHTMLElement(node.get());
+ if (Node* firstChild = element->firstChild())
+ nextNode = firstChild;
+ removeElementPreservingChildren(fragment, element);
+ }
+ }
+ return fragment.release();
+}
+
static inline bool hasOneChild(ContainerNode* node)
{
Node* firstChild = node->firstChild();