summaryrefslogtreecommitdiffstats
path: root/WebCore/html/HTMLElement.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/html/HTMLElement.cpp')
-rw-r--r--WebCore/html/HTMLElement.cpp94
1 files changed, 70 insertions, 24 deletions
diff --git a/WebCore/html/HTMLElement.cpp b/WebCore/html/HTMLElement.cpp
index 6fc53a2..ff25e62 100644
--- a/WebCore/html/HTMLElement.cpp
+++ b/WebCore/html/HTMLElement.cpp
@@ -275,18 +275,23 @@ String HTMLElement::outerHTML() const
return createMarkup(this);
}
-// FIXME: This method is unecessary with the new HTMLDocumentParser.
-PassRefPtr<DocumentFragment> HTMLElement::createContextualFragment(const String& markup, FragmentScriptingPermission scriptingPermission)
+static bool useLegacyTreeBuilder(Document* document)
+{
+ return !document || !document->settings() || !document->settings()->html5TreeBuilderEnabled();
+}
+
+// FIXME: This logic should move into Range::createContextualFragment
+PassRefPtr<DocumentFragment> HTMLElement::deprecatedCreateContextualFragment(const String& markup, FragmentScriptingPermission scriptingPermission)
{
// The following is in accordance with the definition as used by IE.
if (endTagRequirement() == TagStatusForbidden)
return 0;
- if (hasLocalName(colTag) || hasLocalName(colgroupTag) || hasLocalName(framesetTag) ||
- hasLocalName(headTag) || hasLocalName(styleTag) || hasLocalName(titleTag))
+ if (hasLocalName(colTag) || hasLocalName(colgroupTag) || hasLocalName(framesetTag)
+ || hasLocalName(headTag) || hasLocalName(styleTag) || hasLocalName(titleTag))
return 0;
- return Element::createContextualFragment(markup, scriptingPermission);
+ return Element::deprecatedCreateContextualFragment(markup, scriptingPermission);
}
static inline bool hasOneChild(ContainerNode* node)
@@ -339,23 +344,46 @@ static void replaceChildrenWithText(HTMLElement* element, const String& text, Ex
element->appendChild(textNode.release(), ec);
}
+// We may want to move a version of this function into DocumentFragment.h/cpp
+static PassRefPtr<DocumentFragment> createFragmentFromSource(const String& markup, Element* contextElement, ExceptionCode& ec)
+{
+ Document* document = contextElement->document();
+ RefPtr<DocumentFragment> fragment;
+
+ if (useLegacyTreeBuilder(document)) {
+ fragment = contextElement->deprecatedCreateContextualFragment(markup);
+ if (!fragment)
+ ec = NO_MODIFICATION_ALLOWED_ERR;
+ return fragment;
+ }
+
+ fragment = DocumentFragment::create(document);
+ if (document->isHTMLDocument()) {
+ fragment->parseHTML(markup, contextElement);
+ return fragment;
+ }
+
+ bool wasValid = fragment->parseXML(markup, contextElement);
+ if (!wasValid) {
+ ec = INVALID_STATE_ERR;
+ return 0;
+ }
+ return fragment;
+}
+
void HTMLElement::setInnerHTML(const String& html, ExceptionCode& ec)
{
// FIXME: This code can be removed, it's handled by the HTMLDocumentParser correctly.
- if (hasLocalName(scriptTag) || hasLocalName(styleTag)) {
+ if (useLegacyTreeBuilder(document()) && (hasLocalName(scriptTag) || hasLocalName(styleTag))) {
// Script and CSS source shouldn't be parsed as HTML.
removeChildren();
appendChild(document()->createTextNode(html), ec);
return;
}
- RefPtr<DocumentFragment> fragment = createContextualFragment(html);
- if (!fragment) {
- ec = NO_MODIFICATION_ALLOWED_ERR;
- return;
- }
-
- replaceChildrenWithFragment(this, fragment.release(), ec);
+ RefPtr<DocumentFragment> fragment = createFragmentFromSource(html, this, ec);
+ if (fragment)
+ replaceChildrenWithFragment(this, fragment.release(), ec);
}
void HTMLElement::setOuterHTML(const String& html, ExceptionCode& ec)
@@ -365,17 +393,13 @@ void HTMLElement::setOuterHTML(const String& html, ExceptionCode& ec)
ec = NO_MODIFICATION_ALLOWED_ERR;
return;
}
-
HTMLElement* parent = static_cast<HTMLElement*>(p);
- RefPtr<DocumentFragment> fragment = parent->createContextualFragment(html);
- if (!fragment) {
- ec = NO_MODIFICATION_ALLOWED_ERR;
- return;
- }
- // FIXME: Why doesn't this have code to merge neighboring text nodes the way setOuterText does?
-
- parent->replaceChild(fragment.release(), this, ec);
+ RefPtr<DocumentFragment> fragment = createFragmentFromSource(html, parent, ec);
+ if (fragment) {
+ // FIXME: Why doesn't this have code to merge neighboring text nodes the way setOuterText does?
+ parent->replaceChild(fragment.release(), this, ec);
+ }
}
void HTMLElement::setInnerText(const String& text, ExceptionCode& ec)
@@ -549,13 +573,35 @@ Element* HTMLElement::insertAdjacentElement(const String& where, Element* newChi
return static_cast<Element*>(returnValue);
}
+// Step 3 of http://www.whatwg.org/specs/web-apps/current-work/multipage/apis-in-html-documents.html#insertadjacenthtml()
+static Element* contextElementForInsertion(const String& where, Element* element, ExceptionCode& ec)
+{
+ if (equalIgnoringCase(where, "beforeBegin") || equalIgnoringCase(where, "afterEnd")) {
+ Node* parent = element->parentNode();
+ if (parent && parent->isDocumentNode()) {
+ ec = NO_MODIFICATION_ALLOWED_ERR;
+ return 0;
+ }
+ ASSERT(!parent || parent->isElementNode());
+ return static_cast<Element*>(parent);
+ }
+ if (equalIgnoringCase(where, "afterBegin") || equalIgnoringCase(where, "beforeEnd"))
+ return element;
+ ec = SYNTAX_ERR;
+ return 0;
+}
+
void HTMLElement::insertAdjacentHTML(const String& where, const String& markup, ExceptionCode& ec)
{
RefPtr<DocumentFragment> fragment = document()->createDocumentFragment();
+ Element* contextElement = contextElementForInsertion(where, this, ec);
+ if (!contextElement)
+ return;
+
if (document()->isHTMLDocument())
- fragment->parseHTML(markup, this);
+ fragment->parseHTML(markup, contextElement);
else {
- if (!fragment->parseXML(markup, this))
+ if (!fragment->parseXML(markup, contextElement))
// FIXME: We should propagate a syntax error exception out here.
return;
}