diff options
author | Matt A. Tobin <email@mattatobin.com> | 2020-04-17 05:50:47 -0400 |
---|---|---|
committer | Matt A. Tobin <email@mattatobin.com> | 2020-04-17 05:50:47 -0400 |
commit | 4d1d777e706322cb9aca8ed2d5a6e50b805d3bd1 (patch) | |
tree | 1cea0ad854fb25e536caf93f240258eebfb3aea8 /dom/html | |
parent | 32e8155127126c187ce32f7368742057bcaf69da (diff) | |
download | uxp-4d1d777e706322cb9aca8ed2d5a6e50b805d3bd1.tar.gz |
Bug 1373798 - Move HTML dir attribute state into event state flags
* Stop calling SetHasDirAuto/ClearHasDirAuto in input element code
* Introduce event state flags that track the state of an element's dir attribute
* Rewrite our existing checks for the state of the dir attr on top of the new event state flags
* Add pseudo-classes for matching on the dir attribute states
* Use the new dir attribute pseudoclasses in html.css
Tag #1375
Diffstat (limited to 'dom/html')
-rw-r--r-- | dom/html/HTMLInputElement.cpp | 27 | ||||
-rw-r--r-- | dom/html/HTMLInputElement.h | 2 | ||||
-rw-r--r-- | dom/html/HTMLUnknownElement.h | 3 | ||||
-rw-r--r-- | dom/html/nsGenericHTMLElement.cpp | 37 |
4 files changed, 42 insertions, 27 deletions
diff --git a/dom/html/HTMLInputElement.cpp b/dom/html/HTMLInputElement.cpp index 7c2688b7ed..7708a60acf 100644 --- a/dom/html/HTMLInputElement.cpp +++ b/dom/html/HTMLInputElement.cpp @@ -1264,10 +1264,6 @@ HTMLInputElement::BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName, } } else if (aNotify && aName == nsGkAtoms::disabled) { mDisabledChanged = true; - } else if (aName == nsGkAtoms::dir && - AttrValueIs(kNameSpaceID_None, nsGkAtoms::dir, - nsGkAtoms::_auto, eIgnoreCase)) { - SetDirectionIfAuto(false, aNotify); } else if (mType == NS_FORM_INPUT_RADIO && aName == nsGkAtoms::required) { nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer(); @@ -1419,7 +1415,7 @@ HTMLInputElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, "HTML5 spec does not allow underflow for type=range"); } else if (aName == nsGkAtoms::dir && aValue && aValue->Equals(nsGkAtoms::_auto, eIgnoreCase)) { - SetDirectionIfAuto(true, aNotify); + SetDirectionFromValue(aNotify); } else if (aName == nsGkAtoms::lang) { if (mType == NS_FORM_INPUT_NUMBER) { // Update the value that is displayed to the user to the new locale: @@ -4975,7 +4971,9 @@ HTMLInputElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent, } // Set direction based on value if dir=auto - SetDirectionIfAuto(HasDirAuto(), false); + if (HasDirAuto()) { + SetDirectionFromValue(false); + } // An element can't suffer from value missing if it is not in a document. // We have to check if we suffer from that as we are now in a document. @@ -6693,17 +6691,12 @@ HTMLInputElement::SetDefaultValueAsValue() } void -HTMLInputElement::SetDirectionIfAuto(bool aAuto, bool aNotify) +HTMLInputElement::SetDirectionFromValue(bool aNotify) { - if (aAuto) { - SetHasDirAuto(); - if (IsSingleLineTextControl(true)) { - nsAutoString value; - GetValue(value); - SetDirectionalityFromValue(this, value, aNotify); - } - } else { - ClearHasDirAuto(); + if (IsSingleLineTextControl(true)) { + nsAutoString value; + GetValue(value); + SetDirectionalityFromValue(this, value, aNotify); } } @@ -8480,7 +8473,7 @@ HTMLInputElement::OnValueChanged(bool aNotify, bool aWasInteractiveUserChange) UpdateAllValidityStates(aNotify); if (HasDirAuto()) { - SetDirectionIfAuto(true, aNotify); + SetDirectionFromValue(aNotify); } // :placeholder-shown pseudo-class may change when the value changes. diff --git a/dom/html/HTMLInputElement.h b/dom/html/HTMLInputElement.h index 48807f7337..55bb59ec98 100644 --- a/dom/html/HTMLInputElement.h +++ b/dom/html/HTMLInputElement.h @@ -1122,7 +1122,7 @@ protected: */ nsresult SetDefaultValueAsValue(); - virtual void SetDirectionIfAuto(bool aAuto, bool aNotify); + void SetDirectionFromValue(bool aNotify); /** * Return if an element should have a specific validity UI diff --git a/dom/html/HTMLUnknownElement.h b/dom/html/HTMLUnknownElement.h index c77fba919e..6390cc5761 100644 --- a/dom/html/HTMLUnknownElement.h +++ b/dom/html/HTMLUnknownElement.h @@ -7,6 +7,7 @@ #define mozilla_dom_HTMLUnknownElement_h #include "mozilla/Attributes.h" +#include "mozilla/EventStates.h" #include "nsGenericHTMLElement.h" namespace mozilla { @@ -27,7 +28,7 @@ public: : nsGenericHTMLElement(aNodeInfo) { if (NodeInfo()->Equals(nsGkAtoms::bdi)) { - SetHasDirAuto(); + AddStatesSilently(NS_EVENT_STATE_DIR_ATTR_LIKE_AUTO); } } diff --git a/dom/html/nsGenericHTMLElement.cpp b/dom/html/nsGenericHTMLElement.cpp index be78dc1cf0..3cf19ea8f9 100644 --- a/dom/html/nsGenericHTMLElement.cpp +++ b/dom/html/nsGenericHTMLElement.cpp @@ -708,28 +708,49 @@ nsGenericHTMLElement::AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName, } else if (aName == nsGkAtoms::dir) { Directionality dir = eDir_LTR; + // A boolean tracking whether we need to recompute our directionality. + // This needs to happen after we update our internal "dir" attribute + // state but before we call SetDirectionalityOnDescendants. + bool recomputeDirectionality = false; + // We don't want to have to keep getting the "dir" attribute in + // IntrinsicState, so we manually recompute our dir-related event states + // here and send the relevant update notifications. + EventStates dirStates; if (aValue && aValue->Type() == nsAttrValue::eEnum) { SetHasValidDir(); + dirStates |= NS_EVENT_STATE_HAS_DIR_ATTR; Directionality dirValue = (Directionality)aValue->GetEnumValue(); if (dirValue == eDir_Auto) { - SetHasDirAuto(); - ClearHasFixedDir(); + dirStates |= NS_EVENT_STATE_DIR_ATTR_LIKE_AUTO; } else { dir = dirValue; SetDirectionality(dir, aNotify); - ClearHasDirAuto(); - SetHasFixedDir(); + if (dirValue == eDir_LTR) { + dirStates |= NS_EVENT_STATE_DIR_ATTR_LTR; + } else { + MOZ_ASSERT(dirValue == eDir_RTL); + dirStates |= NS_EVENT_STATE_DIR_ATTR_RTL; + } } } else { + if (aValue) { + // We have a value, just not a valid one. + dirStates |= NS_EVENT_STATE_HAS_DIR_ATTR; + } ClearHasValidDir(); - ClearHasFixedDir(); if (NodeInfo()->Equals(nsGkAtoms::bdi)) { - SetHasDirAuto(); + dirStates |= NS_EVENT_STATE_DIR_ATTR_LIKE_AUTO; } else { - ClearHasDirAuto(); - dir = RecomputeDirectionality(this, aNotify); + recomputeDirectionality = true; } } + // Now figure out what's changed about our dir states. + EventStates oldDirStates = State() & DIR_ATTR_STATES; + EventStates changedStates = dirStates ^ oldDirStates; + ToggleStates(changedStates, aNotify); + if (recomputeDirectionality) { + dir = RecomputeDirectionality(this, aNotify); + } SetDirectionalityOnDescendants(this, dir, aNotify); } else if (aName == nsGkAtoms::contenteditable) { int32_t editableCountDelta = 0; |