Bug 1359217 part 5 - Force all style rules to be constructed when failed to get style rule list. r?heycam
MozReview-Commit-ID: 6e1uSnRKbA1
--- a/layout/inspector/inDOMUtils.cpp
+++ b/layout/inspector/inDOMUtils.cpp
@@ -266,17 +266,31 @@ inDOMUtils::GetCSSStyleRules(nsIDOMEleme
rules->AppendElement(owningRule, /*weak =*/ false);
}
}
}
} else {
// It's a Servo source, so use some servo methods on the element to get
// the rule list.
nsTArray<const ServoStyleRule*> ruleList;
- Servo_Element_GetStyleRuleList(element, &ruleList);
+ auto getRuleList = [&ruleList, element]() {
+ return Servo_Element_GetStyleRuleList(element, &ruleList);
+ };
+ if (!getRuleList()) {
+ nsIDocument* doc = element->GetOwnerDocument();
+ nsIPresShell* shell = doc->GetShell();
+ if (!shell) {
+ return NS_OK;
+ }
+ ServoStyleSet* styleSet = shell->StyleSet()->AsServo();
+ styleSet->EnsureAllStyleRulesConstructed();
+ DebugOnly<bool> success = getRuleList();
+ MOZ_ASSERT(success, "Still fail to get rules "
+ "after forcing style rule construction?");
+ }
for (auto servoRule : Reversed(ruleList)) {
auto rule = const_cast<ServoStyleRule*>(servoRule);
rules->AppendElement(static_cast<css::Rule*>(rule), false);
}
}
rules.forget(_retval);
--- a/layout/style/ServoCSSRuleList.cpp
+++ b/layout/style/ServoCSSRuleList.cpp
@@ -305,33 +305,34 @@ ServoCSSRuleList::GetRuleType(uint32_t a
uintptr_t rule = mRules[aIndex];
if (rule <= kMaxRuleType) {
return rule;
}
return CastToPtr(rule)->Type();
}
void
-ServoCSSRuleList::FillStyleRuleHashtable(StyleRuleHashtable& aTable)
+ServoCSSRuleList::EnsureAllStyleRulesConstructed()
{
for (uint32_t i = 0; i < mRules.Length(); i++) {
uint16_t type = GetRuleType(i);
if (type == nsIDOMCSSRule::STYLE_RULE) {
- ServoStyleRule* castedRule = static_cast<ServoStyleRule*>(GetRule(i));
- RawServoStyleRule* rawRule = castedRule->Raw();
- aTable.Put(rawRule, castedRule);
+ GetRule(i);
} else if (type == nsIDOMCSSRule::MEDIA_RULE ||
type == nsIDOMCSSRule::SUPPORTS_RULE ||
type == nsIDOMCSSRule::DOCUMENT_RULE) {
- auto castedRule = static_cast<css::GroupRule*>(GetRule(i));
-
+ auto rule = static_cast<css::GroupRule*>(GetRule(i));
// Call this method recursively on the ServoCSSRuleList in the rule.
- ServoCSSRuleList* castedRuleList = static_cast<ServoCSSRuleList*>(
- castedRule->CssRules());
- castedRuleList->FillStyleRuleHashtable(aTable);
+ auto ruleList =
+ static_cast<ServoCSSRuleList*>(rule->CssRules());
+ ruleList->EnsureAllStyleRulesConstructed();
+ } else if (type == nsIDOMCSSRule::IMPORT_RULE) {
+ auto rule = static_cast<ServoImportRule*>(GetRule(i));
+ ServoStyleSheet* sheet = rule->GetStyleSheet()->AsServo();
+ sheet->EnsureAllStyleRulesConstructed();
}
}
}
ServoCSSRuleList::~ServoCSSRuleList()
{
DropAllRules();
}
--- a/layout/style/ServoCSSRuleList.h
+++ b/layout/style/ServoCSSRuleList.h
@@ -46,19 +46,17 @@ public:
void DropReference();
css::Rule* GetRule(uint32_t aIndex);
nsresult InsertRule(const nsAString& aRule, uint32_t aIndex);
nsresult DeleteRule(uint32_t aIndex);
uint16_t GetRuleType(uint32_t aIndex) const;
- typedef nsDataHashtable<nsPtrHashKey<const RawServoStyleRule>,
- ServoStyleRule*> StyleRuleHashtable;
- void FillStyleRuleHashtable(StyleRuleHashtable& aTable);
+ void EnsureAllStyleRulesConstructed();
private:
virtual ~ServoCSSRuleList();
// XXX Is it possible to have an address lower than or equal to 255?
// Is it possible to have more than 255 CSS rule types?
static const uintptr_t kMaxRuleType = UINT8_MAX;
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -1105,16 +1105,26 @@ ServoStyleSet::EnsureUniqueInnerOnCSSShe
}
bool res = mNeedsRestyleAfterEnsureUniqueInner;
mNeedsRestyleAfterEnsureUniqueInner = false;
return res;
}
void
+ServoStyleSet::EnsureAllStyleRulesConstructed()
+{
+ for (auto& sheetArray : mSheets) {
+ for (auto& sheet : sheetArray) {
+ sheet->EnsureAllStyleRulesConstructed();
+ }
+ }
+}
+
+void
ServoStyleSet::RebuildData()
{
ClearNonInheritingStyleContexts();
Servo_StyleSet_RebuildData(mRawSet.get());
}
void
ServoStyleSet::ClearDataAndMarkDeviceDirty()
--- a/layout/style/ServoStyleSet.h
+++ b/layout/style/ServoStyleSet.h
@@ -413,16 +413,20 @@ public:
bool EnsureUniqueInnerOnCSSSheets();
// Called by StyleSheet::EnsureUniqueInner to let us know it cloned
// its inner.
void SetNeedsRestyleAfterEnsureUniqueInner() {
mNeedsRestyleAfterEnsureUniqueInner = true;
}
+ // Ensure CSSOM object for all style rules in this style set has been
+ // constructed.
+ void EnsureAllStyleRulesConstructed();
+
private:
// On construction, sets sInServoTraversal to the given ServoStyleSet.
// On destruction, clears sInServoTraversal and calls RunPostTraversalTasks.
class MOZ_STACK_CLASS AutoSetInServoTraversal
{
public:
explicit AutoSetInServoTraversal(ServoStyleSet* aSet)
: mSet(aSet)
--- a/layout/style/ServoStyleSheet.cpp
+++ b/layout/style/ServoStyleSheet.cpp
@@ -275,16 +275,22 @@ ServoStyleSheet::Clone(StyleSheet* aClon
RefPtr<StyleSheet> clone = new ServoStyleSheet(*this,
static_cast<ServoStyleSheet*>(aCloneParent),
aCloneOwnerRule,
aCloneDocument,
aCloneOwningNode);
return clone.forget();
}
+void
+ServoStyleSheet::EnsureAllStyleRulesConstructed()
+{
+ GetCssRulesInternal()->EnsureAllStyleRulesConstructed();
+}
+
ServoCSSRuleList*
ServoStyleSheet::GetCssRulesInternal()
{
if (!mRuleList) {
EnsureUniqueInner();
RefPtr<ServoCssRules> rawRules =
Servo_StyleSheet_GetRules(Inner()->mSheet).Consume();
--- a/layout/style/ServoStyleSheet.h
+++ b/layout/style/ServoStyleSheet.h
@@ -109,16 +109,18 @@ public:
void DidDirty() override {}
already_AddRefed<StyleSheet> Clone(StyleSheet* aCloneParent,
dom::CSSImportRule* aCloneOwnerRule,
nsIDocument* aCloneDocument,
nsINode* aCloneOwningNode) const final;
+ void EnsureAllStyleRulesConstructed();
+
// nsICSSLoaderObserver interface
NS_IMETHOD StyleSheetLoaded(StyleSheet* aSheet, bool aWasAlternate,
nsresult aStatus) final;
protected:
virtual ~ServoStyleSheet();
ServoStyleSheetInner* Inner() const