Skip to content
Permalink
Browse files
Fix form association behavior when a form and a control with form= ar…
…e removed from a document together

https://bugs.webkit.org/show_bug.cgi?id=247593

Reviewed by Darin Adler.

Fix the bug that a form associated element with form content attribute were not disassociated from
its form owner if both elements are removed together in a same subtree.

New behavior matches the spec as well as behaviors of Chrome and Firefox:
https://html.spec.whatwg.org/multipage/infrastructure.html#html-element-removing-steps
https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#reset-the-form-owner

* LayoutTests/fast/forms/form-associated-element-removal-with-form-attribute-expected.txt: Added.
* LayoutTests/fast/forms/form-associated-element-removal-with-form-attribute.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/shadow-dom/form-control-form-attribute-expected.txt: Rebaselined.

* Source/WebCore/html/FormAssociatedElement.cpp:
(WebCore::FormAssociatedElement::removedFromAncestor):

Canonical link: https://commits.webkit.org/256620@main
  • Loading branch information
rniwa committed Nov 13, 2022
1 parent 2429800 commit d16d7ec796839625be5b5a686c5c82b55ba620b3
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 3 deletions.
@@ -0,0 +1,12 @@
This tests removing an input element with form content attribute from the document.
The input element should be dissociated from the form element.

On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".


PASS input.form is null
PASS form.elements.length is 0
PASS successfullyParsed is true

TEST COMPLETE

@@ -0,0 +1,15 @@
<!DOCTYPE html>
<body>
<div><input form="formOwner"><form id="formOwner"></form></div>
<script src="../../resources/js-test.js"></script>
<script>
description(`This tests removing an input element with form content attribute from the document.<br>
The input element should be dissociated from the form element.`);
owner = document.getElementById('owner');
input = document.querySelector('input');
form = document.querySelector('form');
input.parentNode.remove();
shouldBeNull('input.form');
shouldBe('form.elements.length', '0');
</script>
</body>
@@ -2,6 +2,6 @@ form


PASS Form control's form attribute should point to the form element.
FAIL Shadow form control's form attribute should work also in shadow DOM. assert_equals: expected null but got Element node <form id="form">form</form>
PASS Shadow form control's form attribute should work also in shadow DOM.
PASS Form element as form control's ancestor should work also in shadow DOM.

@@ -89,15 +89,19 @@ void FormAssociatedElement::insertedIntoAncestor(Node::InsertionType insertionTy
resetFormAttributeTargetObserver();
}

void FormAssociatedElement::removedFromAncestor(Node::RemovalType, ContainerNode&)
void FormAssociatedElement::removedFromAncestor(Node::RemovalType removalType, ContainerNode&)
{
auto& element = asHTMLElement();
m_formAttributeTargetObserver = nullptr;

// If the form and element are both in the same tree, preserve the connection to the form.
// Otherwise, null out our form and remove ourselves from the form's list of elements.
// Do not rely on rootNode() because our IsInTreeScope is outdated.
if (m_form && &asHTMLElement().traverseToRootNode() != &m_form->traverseToRootNode())
if ((m_form && &element.traverseToRootNode() != &m_form->traverseToRootNode())
|| (removalType.disconnectedFromDocument && element.hasAttributeWithoutSynchronization(formAttr))) {
setForm(nullptr);
resetFormOwner();
}
}

HTMLFormElement* FormAssociatedElement::findAssociatedForm(const HTMLElement* element, HTMLFormElement* currentAssociatedForm)

0 comments on commit d16d7ec

Please sign in to comment.