Commit 5995f121 authored by rniwa@webkit.org's avatar rniwa@webkit.org

Change how the form element pointer affects parsing template elements, to...

Change how the form element pointer affects parsing template elements, to reduce weirdness in templates
https://bugs.webkit.org/show_bug.cgi?id=125279

Reviewed by Antti Koivisto.

Source/WebCore: 

Faithfully update the HTML5 parser after http://html5.org/tools/web-apps-tracker?from=8330&to=8331.

Test: fast/dom/HTMLTemplateElement/no-form-association-2.html

* html/parser/HTMLConstructionSite.cpp:
(WebCore::HTMLConstructionSite::insertHTMLFormElement): Don't the form element pointer if the context
element or its ancestor is a template element.
(WebCore::HTMLConstructionSite::insideTemplateElement): Added.
(WebCore::HTMLConstructionSite::createHTMLElement): Renamed openElementsContainTemplateElement to
insideTemplateElement to reflect the true semantics of the boolean.

* html/parser/HTMLConstructionSite.h:

* html/parser/HTMLTreeBuilder.cpp:
(WebCore::HTMLTreeBuilder::processIsindexStartTagForInBody): Ignore the form element pointer if there
is a template element on the stack of open elements. This faithfully reflects what's being said in the
specification. We should probably make isParsingTemplateContents more efficient by storing a boolean
and then wrap from() in some helper function but that should probbaly happen in a separate patch.
(WebCore::HTMLTreeBuilder::processStartTagForInBody): Ditto.
(WebCore::HTMLTreeBuilder::processStartTagForInTable): Ditto.
(WebCore::HTMLTreeBuilder::processEndTagForInBody): Don't unset or rely on the form element pointer
when there is a template element on the stack of open elements.

* html/parser/HTMLTreeBuilder.h:
(WebCore::HTMLTreeBuilder::isParsingTemplateContents): Added a trivial implementation for when
TEMPLATE_ELEMENT is disabled.
(WebCore::HTMLTreeBuilder::isParsingFragmentOrTemplateContents): Merged two implementations.

LayoutTests: 

Added a regression test. Someone should port this test into web-platform-tests once the latest spec.
change has been refelcted to a working draft version of the HTML5 specification.

* fast/dom/HTMLTemplateElement/no-form-association-2-expected.txt: Added.
* fast/dom/HTMLTemplateElement/no-form-association-2.html: Added.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@160182 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent c0b63ec5
2013-12-04 Ryosuke Niwa <rniwa@webkit.org>
Change how the form element pointer affects parsing template elements, to reduce weirdness in templates
https://bugs.webkit.org/show_bug.cgi?id=125279
Reviewed by Antti Koivisto.
Added a regression test. Someone should port this test into web-platform-tests once the latest spec.
change has been refelcted to a working draft version of the HTML5 specification.
* fast/dom/HTMLTemplateElement/no-form-association-2-expected.txt: Added.
* fast/dom/HTMLTemplateElement/no-form-association-2.html: Added.
2013-12-05 Thiago de Barros Lacerda <thiago.lacerda@openbossa.org>
[MediaStream] Firing negotiationneeded event upon track add/remove on MediaStream
PASS templateWithIsindex.innerHTML is containerWithIsindex.innerHTML
PASS templateWithFormInsideForm.innerHTML is '<form><input></form>'
PASS formInsideTemplate = templateWithFormInsideForm.content.firstChild; formInsideTemplate.localName is 'form'
PASS inputInsideTemplate = templateWithFormInsideForm.content.querySelector('input'); inputInsideTemplate.form is formInsideTemplate
PASS formInsideTemplate.elements[0] is inputInsideTemplate
PASS templateWithNestedForms.innerHTML is '<form><form></form></form>'
PASS templateWithIsindexInsideForm.innerHTML is '<form>' + containerWithIsindex.innerHTML + '</form>'
PASS successfullyParsed is true
TEST COMPLETE
<!DOCTYPE html>
<html>
<body>
<div id="containerWithIsindex" style="display:none"><isindex></div>
<form><template id="templateWithIsindex"><isindex></template></form>
<form><template id="templateWithFormInsideForm"><form><input></form></template></form>
<template id="templateWithNestedForms"><form><form></form></form></template>
<template id="templateWithIsindexInsideForm"><form><isindex></form></template>
<script src="../../../resources/js-test-pre.js"></script>
<script>
shouldBe("templateWithIsindex.innerHTML", "containerWithIsindex.innerHTML");
shouldBe("templateWithFormInsideForm.innerHTML", "'<form><input></form>'");
shouldBe("formInsideTemplate = templateWithFormInsideForm.content.firstChild; formInsideTemplate.localName", "'form'");
shouldBe("inputInsideTemplate = templateWithFormInsideForm.content.querySelector('input'); inputInsideTemplate.form", "formInsideTemplate");
shouldBe("formInsideTemplate.elements[0]", "inputInsideTemplate");
shouldBe("templateWithNestedForms.innerHTML", "'<form><form></form></form>'")
shouldBe("templateWithIsindexInsideForm.innerHTML", "'<form>' + containerWithIsindex.innerHTML + '</form>'")
</script>
<script src="../../../resources/js-test-post.js"></script>
</body>
</html>
2013-12-04 Ryosuke Niwa <rniwa@webkit.org>
Change how the form element pointer affects parsing template elements, to reduce weirdness in templates
https://bugs.webkit.org/show_bug.cgi?id=125279
Reviewed by Antti Koivisto.
Faithfully update the HTML5 parser after http://html5.org/tools/web-apps-tracker?from=8330&to=8331.
Test: fast/dom/HTMLTemplateElement/no-form-association-2.html
* html/parser/HTMLConstructionSite.cpp:
(WebCore::HTMLConstructionSite::insertHTMLFormElement): Don't the form element pointer if the context
element or its ancestor is a template element.
(WebCore::HTMLConstructionSite::insideTemplateElement): Added.
(WebCore::HTMLConstructionSite::createHTMLElement): Renamed openElementsContainTemplateElement to
insideTemplateElement to reflect the true semantics of the boolean.
* html/parser/HTMLConstructionSite.h:
* html/parser/HTMLTreeBuilder.cpp:
(WebCore::HTMLTreeBuilder::processIsindexStartTagForInBody): Ignore the form element pointer if there
is a template element on the stack of open elements. This faithfully reflects what's being said in the
specification. We should probably make isParsingTemplateContents more efficient by storing a boolean
and then wrap from() in some helper function but that should probbaly happen in a separate patch.
(WebCore::HTMLTreeBuilder::processStartTagForInBody): Ditto.
(WebCore::HTMLTreeBuilder::processStartTagForInTable): Ditto.
(WebCore::HTMLTreeBuilder::processEndTagForInBody): Don't unset or rely on the form element pointer
when there is a template element on the stack of open elements.
* html/parser/HTMLTreeBuilder.h:
(WebCore::HTMLTreeBuilder::isParsingTemplateContents): Added a trivial implementation for when
TEMPLATE_ELEMENT is disabled.
(WebCore::HTMLTreeBuilder::isParsingFragmentOrTemplateContents): Merged two implementations.
2013-12-05 Thiago de Barros Lacerda <thiago.lacerda@openbossa.org>
[MediaStream] Firing negotiationneeded event upon track add/remove on MediaStream
......@@ -411,10 +411,12 @@ void HTMLConstructionSite::insertHTMLFormElement(AtomicHTMLToken* token, bool is
{
RefPtr<Element> element = createHTMLElement(token);
ASSERT(isHTMLFormElement(element.get()));
m_form = static_pointer_cast<HTMLFormElement>(element.release());
m_form->setDemoted(isDemoted);
attachLater(currentNode(), m_form);
m_openElements.push(HTMLStackItem::create(m_form, token));
RefPtr<HTMLFormElement> form = static_pointer_cast<HTMLFormElement>(element.release());
if (!insideTemplateElement())
m_form = form;
form->setDemoted(isDemoted);
attachLater(currentNode(), form);
m_openElements.push(HTMLStackItem::create(form.release(), token));
}
void HTMLConstructionSite::insertHTMLElement(AtomicHTMLToken* token)
......@@ -537,6 +539,11 @@ inline Document& HTMLConstructionSite::ownerDocumentForCurrentNode()
return currentNode()->document();
}
inline bool HTMLConstructionSite::insideTemplateElement()
{
return !ownerDocumentForCurrentNode().frame();
}
PassRefPtr<Element> HTMLConstructionSite::createHTMLElement(AtomicHTMLToken* token)
{
QualifiedName tagName(nullAtom, token->name(), xhtmlNamespaceURI);
......@@ -545,8 +552,8 @@ PassRefPtr<Element> HTMLConstructionSite::createHTMLElement(AtomicHTMLToken* tok
// to occur after construction to allow better code sharing here.
// http://www.whatwg.org/specs/web-apps/current-work/multipage/tree-construction.html#create-an-element-for-the-token
Document& ownerDocument = ownerDocumentForCurrentNode();
bool openElementsContainTemplateElement = !ownerDocument.frame();
RefPtr<Element> element = HTMLElementFactory::createElement(tagName, ownerDocument, openElementsContainTemplateElement ? nullptr : form(), true);
bool insideTemplateElement = !ownerDocument.frame();
RefPtr<Element> element = HTMLElementFactory::createElement(tagName, ownerDocument, insideTemplateElement ? nullptr : form(), true);
setAttributes(element.get(), token, m_parserContentPolicy);
ASSERT(element->isHTMLElement());
return element.release();
......
......@@ -119,6 +119,7 @@ public:
HTMLStackItem* currentStackItem() const { return m_openElements.topStackItem(); }
HTMLStackItem* oneBelowTop() const { return m_openElements.oneBelowTop(); }
Document& ownerDocumentForCurrentNode();
bool insideTemplateElement();
HTMLElementStack* openElements() const { return &m_openElements; }
HTMLFormattingElementList* activeFormattingElements() const { return &m_activeFormattingElements; }
bool currentIsRootNode() { return m_openElements.topNode() == m_openElements.rootNode(); }
......
......@@ -462,7 +462,7 @@ void HTMLTreeBuilder::processIsindexStartTagForInBody(AtomicHTMLToken* token)
ASSERT(token->type() == HTMLToken::StartTag);
ASSERT(token->name() == isindexTag);
parseError(token);
if (m_tree.form())
if (m_tree.form() && !isParsingTemplateContents())
return;
notImplemented(); // Acknowledge self-closing flag
processFakeStartTag(formTag);
......@@ -700,7 +700,7 @@ void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken* token)
return;
}
if (token->name() == formTag) {
if (m_tree.form()) {
if (m_tree.form() && !isParsingTemplateContents()) {
parseError(token);
return;
}
......@@ -1051,7 +1051,7 @@ void HTMLTreeBuilder::processStartTagForInTable(AtomicHTMLToken* token)
}
if (token->name() == formTag) {
parseError(token);
if (m_tree.form())
if (m_tree.form() && !isParsingTemplateContents())
return;
m_tree.insertHTMLFormElement(token, true);
m_tree.openElements()->pop();
......@@ -1864,15 +1864,26 @@ void HTMLTreeBuilder::processEndTagForInBody(AtomicHTMLToken* token)
return;
}
if (token->name() == formTag) {
RefPtr<Element> node = m_tree.takeForm();
if (!node || !m_tree.openElements()->inScope(node.get())) {
parseError(token);
return;
if (!isParsingTemplateContents()) {
RefPtr<Element> node = m_tree.takeForm();
if (!node || !m_tree.openElements()->inScope(node.get())) {
parseError(token);
return;
}
m_tree.generateImpliedEndTags();
if (m_tree.currentNode() != node.get())
parseError(token);
m_tree.openElements()->remove(node.get());
} else {
if (!m_tree.openElements()->inScope(token->name())) {
parseError(token);
return;
}
m_tree.generateImpliedEndTags();
if (!m_tree.currentNode()->hasTagName(formTag))
parseError(token);
m_tree.openElements()->popUntilPopped(token->name());
}
m_tree.generateImpliedEndTags();
if (m_tree.currentElement() != node.get())
parseError(token);
m_tree.openElements()->remove(node.get());
}
if (token->name() == pTag) {
if (!m_tree.openElements()->inButtonScope(token->name())) {
......
......@@ -72,10 +72,10 @@ public:
bool isParsingFragment() const { return !!m_fragmentContext.fragment(); }
#if ENABLE(TEMPLATE_ELEMENT)
bool isParsingTemplateContents() const { return m_tree.openElements()->hasTemplateInHTMLScope(); }
bool isParsingFragmentOrTemplateContents() const { return isParsingFragment() || isParsingTemplateContents(); }
#else
bool isParsingFragmentOrTemplateContents() const { return isParsingFragment(); }
bool isParsingTemplateContents() const { return false; }
#endif
bool isParsingFragmentOrTemplateContents() const { return isParsingFragment() || isParsingTemplateContents(); }
void detach();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment