Bug 1332353 - Make it clearer when a stylesheet is really owned by its mDocument

Tag #1375
This commit is contained in:
Matt A. Tobin 2020-04-17 05:46:23 -04:00 • committed by Roy Tam
commit 5d444ef68a
13 changed files with 83 additions and 38 deletions

View file

@ -694,7 +694,7 @@ nsMediaList::GetMediaText(nsAString& aMediaText)
// nsCOMPtr<nsIDocument>
#define BEGIN_MEDIA_CHANGE(sheet, doc) \
if (sheet) { \
doc = sheet->GetOwningDocument(); \
doc = sheet->GetAssociatedDocument(); \
} \
mozAutoDocUpdate updateBatch(doc, UPDATE_STYLE, true); \
if (sheet) { \
@ -864,7 +864,8 @@ struct ChildSheetListBuilder {
void SetParentLinks(CSSStyleSheet* aSheet) {
aSheet->mParent = parent;
aSheet->SetOwningDocument(parent->mDocument);
aSheet->SetAssociatedDocument(parent->mDocument,
parent->mDocumentAssociationMode);
}
static void ReparentChildList(CSSStyleSheet* aPrimarySheet,
@ -872,7 +873,8 @@ struct ChildSheetListBuilder {
{
for (CSSStyleSheet *child = aFirstChild; child; child = child->mNext) {
child->mParent = aPrimarySheet;
child->SetOwningDocument(aPrimarySheet->mDocument);
child->SetAssociatedDocument(aPrimarySheet->mDocument,
aPrimarySheet->mDocumentAssociationMode);
}
}
};
@ -1359,16 +1361,22 @@ CSSStyleSheet::GetParentSheet() const
}
void
CSSStyleSheet::SetOwningDocument(nsIDocument* aDocument)
{ // not ref counted
CSSStyleSheet::SetAssociatedDocument(nsIDocument* aDocument,
DocumentAssociationMode aAssociationMode)
{
MOZ_ASSERT_IF(!aDocument, aAssociationMode == NotOwnedByDocument);
// not ref counted
mDocument = aDocument;
mDocumentAssociationMode = aAssociationMode;
// Now set the same document on all our child sheets....
// XXXbz this is a little bogus; see the XXX comment where we
// declare mFirstChild.
for (CSSStyleSheet* child = mInner->mFirstChild;
child; child = child->mNext) {
if (child->mParent == this) {
child->SetOwningDocument(aDocument);
child->SetAssociatedDocument(aDocument, aAssociationMode);
}
}
}

View file

@ -129,7 +129,8 @@ public:
// style sheet owner info
CSSStyleSheet* GetParentSheet() const; // may be null
void SetOwningDocument(nsIDocument* aDocument);
void SetAssociatedDocument(nsIDocument* aDocument,
DocumentAssociationMode aAssociationMode);
// Find the ID of the owner inner window.
uint64_t FindOwningWindowInnerID() const;

View file

@ -2209,9 +2209,9 @@ Loader::LoadChildSheet(StyleSheet* aParentSheet,
nsCOMPtr<nsINode> owningNode;
// check for an owning document: if none, don't bother walking up the parent
// sheets
if (aParentSheet->GetOwningDocument()) {
// check for an associated document: if none, don't bother walking up the
// parent sheets
if (aParentSheet->GetAssociatedDocument()) {
StyleSheet* topSheet = aParentSheet;
while (StyleSheet* parent = topSheet->GetParentSheet()) {
topSheet = parent;

View file

@ -30,19 +30,23 @@ ServoStyleSheet::HasRules() const
}
void
ServoStyleSheet::SetOwningDocument(nsIDocument* aDocument)
ServoStyleSheet::SetAssociatedDocument(nsIDocument* aDocument,
DocumentAssociationMode aAssociationMode)
{
MOZ_ASSERT_IF(!aDocument, aAssociationMode == NotOwnedByDocument);
// XXXheycam: Traverse to child ServoStyleSheets to set this, like
// CSSStyleSheet::SetOwningDocument does.
// CSSStyleSheet::SetAssociatedDocument does.
mDocument = aDocument;
mDocumentAssociationMode = aAssociationMode;
}
ServoStyleSheet*
ServoStyleSheet::GetParentSheet() const
{
// XXXheycam: When we implement support for child sheets, we'll have
// to fix SetOwningDocument to propagate the owning document down
// to fix SetAssociatedDocument to propagate the associated document down
// to the children.
MOZ_CRASH("stylo: not implemented");
}

View file

@ -29,7 +29,8 @@ public:
bool HasRules() const;
void SetOwningDocument(nsIDocument* aDocument);
void SetAssociatedDocument(nsIDocument* aDocument,
DocumentAssociationMode aAssociationMode);
ServoStyleSheet* GetParentSheet() const;
void AppendStyleSheet(ServoStyleSheet* aSheet);

View file

@ -1209,13 +1209,13 @@ DOMCSSDeclarationImpl::SetCSSDeclaration(DeclarationBlock* aDecl)
NS_PRECONDITION(mRule,
"can only be called when |GetCSSDeclaration| returned a declaration");
nsCOMPtr<nsIDocument> owningDoc;
nsCOMPtr<nsIDocument> doc;
RefPtr<CSSStyleSheet> sheet = mRule->GetStyleSheet();
if (sheet) {
owningDoc = sheet->GetOwningDocument();
doc = sheet->GetAssociatedDocument();
}
mozAutoDocUpdate updateBatch(owningDoc, UPDATE_STYLE, true);
mozAutoDocUpdate updateBatch(doc, UPDATE_STYLE, true);
mRule->SetDeclaration(aDecl->AsGecko());
@ -1223,8 +1223,8 @@ DOMCSSDeclarationImpl::SetCSSDeclaration(DeclarationBlock* aDecl)
sheet->DidDirty();
}
if (owningDoc) {
owningDoc->StyleRuleChanged(sheet, mRule);
if (doc) {
doc->StyleRuleChanged(sheet, mRule);
}
return NS_OK;
}

View file

@ -24,6 +24,7 @@ StyleSheet::StyleSheet(StyleBackendType aType, css::SheetParsingMode aParsingMod
, mParsingMode(aParsingMode)
, mType(aType)
, mDisabled(false)
, mDocumentAssociationMode(NotOwnedByDocument)
{
}
@ -36,6 +37,9 @@ StyleSheet::StyleSheet(const StyleSheet& aCopy,
, mParsingMode(aCopy.mParsingMode)
, mType(aCopy.mType)
, mDisabled(aCopy.mDisabled)
// We only use this constructor during cloning. It's the cloner's
// responsibility to notify us if we end up being owned by a document.
, mDocumentAssociationMode(NotOwnedByDocument)
{
}

View file

@ -95,8 +95,22 @@ public:
inline bool HasRules() const;
// style sheet owner info
nsIDocument* GetOwningDocument() const { return mDocument; }
inline void SetOwningDocument(nsIDocument* aDocument);
enum DocumentAssociationMode {
// OwnedByDocument means mDocument owns us (possibly via a chain of other
// stylesheets).
OwnedByDocument,
// NotOwnedByDocument means we're owned by something that might have a
// different lifetime than mDocument.
NotOwnedByDocument
};
nsIDocument* GetAssociatedDocument() const { return mDocument; }
bool IsOwnedByDocument() const {
return mDocumentAssociationMode == OwnedByDocument;
}
// aDocument must not be null.
inline void SetAssociatedDocument(nsIDocument* aDocument,
DocumentAssociationMode aMode);
inline void ClearAssociatedDocument();
nsINode* GetOwnerNode() const { return mOwningNode; }
inline StyleSheet* GetParentSheet() const;
@ -206,6 +220,11 @@ protected:
const StyleBackendType mType;
bool mDisabled;
// mDocumentAssociationMode determines whether mDocument directly owns us (in
// the sense that if it's known-live then we're known-live). Always
// NotOwnedByDocument when mDocument is null.
DocumentAssociationMode mDocumentAssociationMode;
};
} // namespace mozilla

View file

@ -83,9 +83,17 @@ StyleSheet::HasRules() const
}
void
StyleSheet::SetOwningDocument(nsIDocument* aDocument)
StyleSheet::SetAssociatedDocument(nsIDocument* aDocument,
DocumentAssociationMode aAssociationMode)
{
MOZ_STYLO_FORWARD(SetOwningDocument, (aDocument))
MOZ_ASSERT(aDocument);
MOZ_STYLO_FORWARD(SetAssociatedDocument, (aDocument, aAssociationMode))
}
void
StyleSheet::ClearAssociatedDocument()
{
MOZ_STYLO_FORWARD(SetAssociatedDocument, (nullptr, NotOwnedByDocument));
}
StyleSheet*

View file

@ -267,7 +267,7 @@ nsDOMCSSDeclaration::GetCSSParsingEnvironmentForRule(css::Rule* aRule,
return;
}
nsIDocument* document = sheet->GetOwningDocument();
nsIDocument* document = sheet->GetAssociatedDocument();
aCSSParseEnv.mSheetURI = sheet->GetSheetURI();
aCSSParseEnv.mBaseURI = sheet->GetBaseURI();
aCSSParseEnv.mPrincipal = sheet->Principal();