Bug 1897194 - Form-associated custom elements shouldn't have special handling for :read-write, r=edgar

Differential Revision: https://phabricator.services.mozilla.com/D210868
This commit is contained in:
Olli Pettay 2024-05-21 12:53:14 +00:00
parent 9b4a7fecb7
commit c10f141eb1
6 changed files with 33 additions and 13 deletions

View file

@ -381,10 +381,6 @@ HTMLFieldSetElement* HTMLElement::GetFieldSetInternal() const {
bool HTMLElement::CanBeDisabled() const { return IsFormAssociatedElement(); }
bool HTMLElement::DoesReadOnlyApply() const {
return IsFormAssociatedElement();
}
void HTMLElement::UpdateDisabledState(bool aNotify) {
bool oldState = IsDisabled();
nsGenericHTMLFormElement::UpdateDisabledState(aNotify);

View file

@ -75,7 +75,6 @@ class HTMLElement final : public nsGenericHTMLFormElement {
void SetFieldSetInternal(HTMLFieldSetElement* aFieldset) override;
HTMLFieldSetElement* GetFieldSetInternal() const override;
bool CanBeDisabled() const override;
bool DoesReadOnlyApply() const override;
void UpdateDisabledState(bool aNotify) override;
void UpdateFormOwner(bool aBindToTree, Element* aFormIdElement) override;

View file

@ -6553,7 +6553,7 @@ HTMLInputElement::ValueModeType HTMLInputElement::GetValueMode() const {
bool HTMLInputElement::IsMutable() const {
return !IsDisabled() &&
!(DoesReadOnlyApply() && State().HasState(ElementState::READONLY));
!(DoesReadWriteApply() && State().HasState(ElementState::READONLY));
}
bool HTMLInputElement::DoesRequiredApply() const {

View file

@ -2233,7 +2233,7 @@ void nsGenericHTMLFormElement::UpdateDisabledState(bool aNotify) {
if (!changedStates.IsEmpty()) {
ToggleStates(changedStates, aNotify);
if (DoesReadOnlyApply()) {
if (DoesReadWriteApply()) {
// :disabled influences :read-only / :read-write.
UpdateReadOnlyState(aNotify);
}
@ -2241,7 +2241,7 @@ void nsGenericHTMLFormElement::UpdateDisabledState(bool aNotify) {
}
bool nsGenericHTMLFormElement::IsReadOnlyInternal() const {
if (DoesReadOnlyApply()) {
if (DoesReadWriteApply()) {
return IsDisabled() || GetBoolAttr(nsGkAtoms::readonly);
}
return nsGenericHTMLElement::IsReadOnlyInternal();
@ -2682,7 +2682,7 @@ bool nsGenericHTMLFormControlElement::CanBeDisabled() const {
return type != FormControlType::Object && type != FormControlType::Output;
}
bool nsGenericHTMLFormControlElement::DoesReadOnlyApply() const {
bool nsGenericHTMLFormControlElement::DoesReadWriteApply() const {
auto type = ControlType();
if (!IsInputElement(type) && type != FormControlType::Textarea) {
return false;
@ -2716,7 +2716,7 @@ bool nsGenericHTMLFormControlElement::DoesReadOnlyApply() const {
case FormControlType::InputDatetimeLocal:
return true;
default:
MOZ_ASSERT_UNREACHABLE("Unexpected input type in DoesReadOnlyApply()");
MOZ_ASSERT_UNREACHABLE("Unexpected input type in DoesReadWriteApply()");
return true;
#else // DEBUG
default:

View file

@ -1140,9 +1140,10 @@ class nsGenericHTMLFormElement : public nsGenericHTMLElement {
virtual bool CanBeDisabled() const { return false; }
/**
* Returns if the readonly attribute applies.
* Returns true if :read-write pseudo class may match the element even if the
* element isn't part of designMode or contenteditable.
*/
virtual bool DoesReadOnlyApply() const { return false; }
virtual bool DoesReadWriteApply() const { return false; }
/**
* Returns true if the element is a form associated element.
@ -1200,7 +1201,7 @@ class nsGenericHTMLFormControlElement : public nsGenericHTMLFormElement,
// nsGenericHTMLFormElement
bool CanBeDisabled() const override;
bool DoesReadOnlyApply() const override;
bool DoesReadWriteApply() const override;
void SetFormInternal(mozilla::dom::HTMLFormElement* aForm,
bool aBindToTree) override;
mozilla::dom::HTMLFormElement* GetFormInternal() const override;

View file

@ -5,6 +5,17 @@
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="utils.js"></script>
<script>
class CustomElement extends HTMLElement {
static formAssociated = true;
constructor() {
super();
}
}
window.customElements.define("custom-element", CustomElement);
</script>
<div id="log"></div>
<div id=set0>
@ -58,6 +69,14 @@
</div>
</div>
<div id=set6>
<custom-element id=ce1>content</custom-element>
<custom-element id=ce2 contenteditable>content</custom-element>
<custom-element id=ce3 contenteditable readonly>content</custom-element>
<custom-element id=ce4 contenteditable disabled>content</custom-element>
<custom-element id=ce5 contenteditable readonly disabled>content</custom-element>
</div>
<script>
testSelectorIdsMatch("#set0 :read-write", [], "The :read-write pseudo-class must not match input elements to which the readonly attribute does not apply");
@ -115,4 +134,9 @@
testSelectorIdsMatch("#set5 :read-write", ["cd1", "p3", "ci3", "ci4", "ct3", "ct4"], "The :read-write pseudo-class must match elements that are inside editing hosts, but not match inputs and textareas inside that aren't");
testSelectorIdsMatch("#set6 :read-only", ["ce1"], "The :read-only pseudo-class must match form-associated custom elements");
testSelectorIdsMatch("#set6 :read-write", ["ce2", "ce3", "ce4", "ce5"], "The :read-write pseudo-class must match form-associated contenteditable custom elements");
</script>