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
This commit is contained in:
Emilio Cobos Álvarez 2018-02-16 11:34:12 +01:00
parent d39c5388fc
commit 37e9a4f2a2
4 changed files with 50 additions and 30 deletions

View File

@ -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,

View File

@ -1270,23 +1270,41 @@ ServoStyleSet::ComputeAnimationValue(
bool
ServoStyleSet::EnsureUniqueInnerOnCSSSheets()
{
AutoTArray<StyleSheet*, 32> queue;
using SheetOwner = Variant<ServoStyleSet*, nsXBLPrototypeBinding*>;
AutoTArray<Pair<StyleSheet*, SheetOwner>, 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<StyleSheet*, 3> 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<nsXBLPrototypeBinding*>()) {
if (auto* styles = owner.as<nsXBLPrototypeBinding*>()->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<StyleSheet*, 3> children;
sheet->AppendAllChildSheets(children);
for (auto* sheet : children) {
queue.AppendElement(MakePair(sheet, owner));
}
}
if (anyXBLSheetChanged) {
SetStylistXBLStyleSheetsDirty();
}
if (mNeedsRestyleAfterEnsureUniqueInner) {

View File

@ -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 <link>, 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);

View File

@ -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();