Bug 1887338 - guard CustomStateSet from inserting multiple states in internal set r=emilio

This can cause an issue where removing a state looks as though it didn't
invalidate, because the internal representation contains multiple copies
of the same state ident.

Differential Revision: https://phabricator.services.mozilla.com/D205518
This commit is contained in:
keithamus
2024-03-24 08:54:48 +00:00
parent 7babaf9519
commit e6722a1708
2 changed files with 19 additions and 1 deletions

View File

@@ -81,14 +81,19 @@ void CustomStateSet::Add(const nsAString& aState, ErrorResult& aRv) {
return; return;
} }
nsTArray<RefPtr<nsAtom>>& states = mTarget->EnsureCustomStates();
RefPtr<nsAtom> atom = NS_AtomizeMainThread(aState); RefPtr<nsAtom> atom = NS_AtomizeMainThread(aState);
if (states.Contains(atom)) {
return;
}
Document* doc = mTarget->GetComposedDoc(); Document* doc = mTarget->GetComposedDoc();
PresShell* presShell = doc ? doc->GetPresShell() : nullptr; PresShell* presShell = doc ? doc->GetPresShell() : nullptr;
if (presShell) { if (presShell) {
presShell->CustomStatesWillChange(*mTarget); presShell->CustomStatesWillChange(*mTarget);
} }
mTarget->EnsureCustomStates().AppendElement(atom); states.AppendElement(atom);
if (presShell) { if (presShell) {
presShell->CustomStateChanged(*mTarget, atom); presShell->CustomStateChanged(*mTarget, atom);

View File

@@ -99,6 +99,19 @@
assert_equals(getComputedStyle(mySibling).getPropertyValue('color'), 'rgb(255, 0, 0)'); assert_equals(getComputedStyle(mySibling).getPropertyValue('color'), 'rgb(255, 0, 0)');
}, "state selector only applies to has() on given ident"); }, "state selector only applies to has() on given ident");
test(function(t) {
myCE.elementInternals.states.add('--green');
myCE.elementInternals.states.add('--green');
myCE.elementInternals.states.add('--green');
t.add_cleanup(() => { myCE.elementInternals.states.delete('--green') });
assert_true(myCE.elementInternals.states.has('--green'));
assert_equals(getComputedStyle(myCE).getPropertyValue('color'), 'rgb(0, 255, 0)');
assert_true(myCE.elementInternals.states.delete('--green'));
assert_false(myCE.elementInternals.states.has('--green'));
assert_equals(getComputedStyle(myCE).getPropertyValue('color'), 'rgb(255, 0, 0)');
assert_false(myCE.elementInternals.states.delete('--green'));
}, "states added multiple times counts as one");
test(function(t) { test(function(t) {
myCE.elementInternals.states.add('--green'); myCE.elementInternals.states.add('--green');
myCE.elementInternals.states.add('--foo'); myCE.elementInternals.states.add('--foo');