From 37e9a4f2a27060703b670af330f6a0a2569294b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Fri, 16 Feb 2018 11:34:12 +0100 Subject: [PATCH] Bug 1436059: Fix inspector. r=xidorn This removes a hack, but adds slightly more complex code in inspector-only code. I'm not excited about this code, but this fixes ServoStyleRuleMap for XBL. MozReview-Commit-ID: 6h0dCsiIWKU --- layout/style/ServoBindingList.h | 2 ++ layout/style/ServoStyleSet.cpp | 42 ++++++++++++++++++++++++++------- layout/style/StyleSheet.cpp | 17 ------------- layout/style/StyleSheet.h | 19 +++++++++++---- 4 files changed, 50 insertions(+), 30 deletions(-) diff --git a/layout/style/ServoBindingList.h b/layout/style/ServoBindingList.h index f41fb632d7d1..03c891558ad9 100644 --- a/layout/style/ServoBindingList.h +++ b/layout/style/ServoBindingList.h @@ -183,6 +183,8 @@ SERVO_BINDING_FUNC(Servo_AuthorStyles_Create, RawServoAuthorStyles*) SERVO_BINDING_FUNC(Servo_AuthorStyles_AppendStyleSheet, void, RawServoAuthorStylesBorrowedMut self, const mozilla::ServoStyleSheet* gecko_sheet) +SERVO_BINDING_FUNC(Servo_AuthorStyles_ForceDirty, void, + RawServoAuthorStylesBorrowedMut self) // TODO(emilio): This will need to take an element to implement invalidation for // Shadow DOM. SERVO_BINDING_FUNC(Servo_AuthorStyles_Flush, void, diff --git a/layout/style/ServoStyleSet.cpp b/layout/style/ServoStyleSet.cpp index f11253bd686a..2937a90d7497 100644 --- a/layout/style/ServoStyleSet.cpp +++ b/layout/style/ServoStyleSet.cpp @@ -1270,23 +1270,41 @@ ServoStyleSet::ComputeAnimationValue( bool ServoStyleSet::EnsureUniqueInnerOnCSSSheets() { - AutoTArray queue; + using SheetOwner = Variant; + + AutoTArray, 32> queue; for (auto& entryArray : mSheets) { for (auto& sheet : entryArray) { - queue.AppendElement(sheet); + StyleSheet* downcasted = sheet; + queue.AppendElement(MakePair(downcasted, SheetOwner { this })); } } - // This is a stub until more of the functionality of nsStyleSet is - // replicated for Servo here. - // Bug 1290276 will replicate the nsStyleSet work of checking - // a nsBindingManager + mDocument->BindingManager()->EnumerateBoundContentBindings( + [&](nsXBLBinding* aBinding) { + AutoTArray sheets; + aBinding->PrototypeBinding()->AppendStyleSheetsTo(sheets); + for (auto* sheet : sheets) { + queue.AppendElement(MakePair(sheet, SheetOwner { aBinding->PrototypeBinding() })); + } + return true; + }); + bool anyXBLSheetChanged = false; while (!queue.IsEmpty()) { uint32_t idx = queue.Length() - 1; - StyleSheet* sheet = queue[idx]; + auto* sheet = queue[idx].first(); + SheetOwner owner = queue[idx].second(); queue.RemoveElementAt(idx); + if (!sheet->HasUniqueInner() && owner.is()) { + if (auto* styles = owner.as()->GetServoStyles()) { + Servo_AuthorStyles_ForceDirty(styles); + mNeedsRestyleAfterEnsureUniqueInner = true; + anyXBLSheetChanged = true; + } + } + // Only call EnsureUniqueInner for complete sheets. If we do call it on // incomplete sheets, we'll cause problems when the sheet is actually // loaded. We don't care about incomplete sheets here anyway, because this @@ -1298,7 +1316,15 @@ ServoStyleSet::EnsureUniqueInnerOnCSSSheets() } // Enqueue all the sheet's children. - sheet->AppendAllChildSheets(queue); + AutoTArray children; + sheet->AppendAllChildSheets(children); + for (auto* sheet : children) { + queue.AppendElement(MakePair(sheet, owner)); + } + } + + if (anyXBLSheetChanged) { + SetStylistXBLStyleSheetsDirty(); } if (mNeedsRestyleAfterEnsureUniqueInner) { diff --git a/layout/style/StyleSheet.cpp b/layout/style/StyleSheet.cpp index 07c8011b7110..89ef8cae1a01 100644 --- a/layout/style/StyleSheet.cpp +++ b/layout/style/StyleSheet.cpp @@ -401,23 +401,6 @@ StyleSheet::EnsureUniqueInner() return; } - // If this stylesheet is for XBL with Servo, don't bother cloning - // it, as it may break ServoStyleRuleMap. XBL stylesheets are not - // supposed to change anyway. - // - // The mDocument check is used as a fast reject path because no - // XBL stylesheets would have associated document, but in normal - // cases, content stylesheets should usually have one. - // - // FIXME(emilio): Shadow DOM definitely modifies stylesheets! Right now all of - // them are unique anyway because we don't support , but that needs to - // change. - if (!mDocument && IsServo() && - mStyleSets.Length() == 1 && - mStyleSets[0]->AsServo()->IsForXBL()) { - return; - } - StyleSheetInfo* clone = mInner->CloneFor(this); MOZ_ASSERT(clone); mInner->RemoveSheet(this); diff --git a/layout/style/StyleSheet.h b/layout/style/StyleSheet.h index 5e517a19e03b..b21f667eaaed 100644 --- a/layout/style/StyleSheet.h +++ b/layout/style/StyleSheet.h @@ -132,11 +132,20 @@ public: nsIDocument* aCloneDocument, nsINode* aCloneOwningNode) const = 0; - bool HasForcedUniqueInner() const { return mDirtyFlags & - FORCED_UNIQUE_INNER; } - bool HasModifiedRules() const { return mDirtyFlags & - MODIFIED_RULES; } - void ClearModifiedRules() { mDirtyFlags &= ~MODIFIED_RULES; } + bool HasForcedUniqueInner() const + { + return mDirtyFlags & FORCED_UNIQUE_INNER; + } + + bool HasModifiedRules() const + { + return mDirtyFlags & MODIFIED_RULES; + } + + void ClearModifiedRules() + { + mDirtyFlags &= ~MODIFIED_RULES; + } inline bool HasUniqueInner() const; void EnsureUniqueInner();