Issue #2111 - Implement CSSStyleRule.selectorText setter

Unlike the original patch, this copies Chrome behavior: ignores invalid values of selectorText without any console log.

Partially based on https://bugzilla.mozilla.org/show_bug.cgi?id=37468
This commit is contained in:
FranklinDM 2023-02-20 11:20:23 +08:00 committed by roytam1
commit 6d3500bb48
4 changed files with 45 additions and 3 deletions

View file

@ -1618,6 +1618,12 @@ CSSStyleSheet::DidDirty()
ClearRuleCascades();
}
void
CSSStyleSheet::AssertHasUniqueInner()
{
MOZ_ASSERT(mInner->mSheets.Length() == 1, "expected unique inner");
}
nsresult
CSSStyleSheet::RegisterNamespaceRule(css::Rule* aRule)
{

View file

@ -217,6 +217,7 @@ public:
void WillDirty();
void DidDirty();
void AssertHasUniqueInner();
private:
CSSStyleSheet(const CSSStyleSheet& aCopy,

View file

@ -1571,9 +1571,43 @@ StyleRule::GetSelectorText(nsAString& aSelectorText)
void
StyleRule::SetSelectorText(const nsAString& aSelectorText)
{
// XXX TBI - get a parser and re-parse the selectors,
// XXX then need to re-compute the cascade
// XXX and dirty sheet
CSSStyleSheet* sheet = GetStyleSheet();
nsIDocument* doc = GetDocument();
RefPtr<css::Loader> loader;
if (doc) {
loader = doc->CSSLoader();
}
// NOTE: Passing a null loader means that the parser is always in
// standards mode and never in quirks mode.
nsCSSParser css(loader, sheet);
// StyleRule lives inside of the Inner, it is unsafe to call WillDirty
// if sheet does not already have a unique Inner.
sheet->AssertHasUniqueInner();
sheet->WillDirty();
nsCSSSelectorList* selectorList = nullptr;
nsresult result = css.ParseSelectorString(
aSelectorText, sheet->GetSheetURI(), 0, &selectorList);
if (NS_FAILED(result)) {
// Ignore parsing errors and continue to use the previous value.
return;
}
// Replace selector.
delete mSelector;
mSelector = selectorList;
sheet->DidDirty();
if (doc) {
mozAutoDocUpdate updateBatch(doc, UPDATE_STYLE, true);
doc->StyleRuleChanged(sheet, this);
}
}
/* virtual */ size_t

View file

@ -186,6 +186,7 @@ public:
// WillDirty and then make no change and skip the DidDirty call.
inline void WillDirty();
inline void DidDirty();
inline void AssertHasUniqueInner();
private:
// Get a handle to the various stylesheet bits which live on the 'inner' for