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
This commit is contained in:
Matt A. Tobin 2020-04-17 05:50:47 -04:00 committed by Roy Tam
commit 3b2a22f085
11 changed files with 139 additions and 72 deletions

View file

@ -708,27 +708,48 @@ 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 {
ClearHasValidDir();
ClearHasFixedDir();
if (NodeInfo()->Equals(nsGkAtoms::bdi)) {
SetHasDirAuto();
} else {
ClearHasDirAuto();
dir = RecomputeDirectionality(this, aNotify);
if (aValue) {
// We have a value, just not a valid one.
dirStates |= NS_EVENT_STATE_HAS_DIR_ATTR;
}
ClearHasValidDir();
if (NodeInfo()->Equals(nsGkAtoms::bdi)) {
dirStates |= NS_EVENT_STATE_DIR_ATTR_LIKE_AUTO;
} else {
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) {