зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1600624 - Fix import rules to properly unlink their stylesheet from its parent. r=heycam
Test is hopefully self-explanatory. The children setup here is a bit bogus as noted here and other comments, will file a followup to clean it up. Differential Revision: https://phabricator.services.mozilla.com/D55550 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
5ccf884103
Коммит
912559b8d2
|
@ -76,6 +76,13 @@ dom::MediaList* CSSImportRule::GetMedia() const {
|
|||
return mChildSheet ? mChildSheet->Media() : nullptr;
|
||||
}
|
||||
|
||||
void CSSImportRule::DropSheetReference() {
|
||||
if (mChildSheet) {
|
||||
mChildSheet->RemoveFromParent();
|
||||
}
|
||||
Rule::DropSheetReference();
|
||||
}
|
||||
|
||||
void CSSImportRule::GetHref(nsAString& aHref) const {
|
||||
Servo_ImportRule_GetHref(mRawRule, &aHref);
|
||||
}
|
||||
|
|
|
@ -38,6 +38,9 @@ class CSSImportRule final : public css::Rule {
|
|||
dom::MediaList* GetMedia() const;
|
||||
StyleSheet* GetStyleSheet() const { return mChildSheet; }
|
||||
|
||||
// Clear the mSheet pointer on this rule and descendants.
|
||||
void DropSheetReference() final;
|
||||
|
||||
JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
|
|
|
@ -664,6 +664,36 @@ uint64_t StyleSheet::FindOwningWindowInnerID() const {
|
|||
return windowID;
|
||||
}
|
||||
|
||||
void StyleSheet::RemoveFromParent() {
|
||||
if (!mParent) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO(emilio): It seems we should actually use mozilla::LinkedList or such
|
||||
// for this.
|
||||
//
|
||||
// Also this is still pretty bogus, see where we declare mFirstChild in
|
||||
// StyleSheetInfo.
|
||||
bool found = false;
|
||||
for (auto* child = mParent->GetFirstChild(); child; child = child->mNext) {
|
||||
if (child == this) {
|
||||
// We can only get here if we're the first.
|
||||
found = true;
|
||||
mParent->Inner().mFirstChild = mNext;
|
||||
break;
|
||||
}
|
||||
if (child->mNext == this) {
|
||||
found = true;
|
||||
child->mNext = mNext;
|
||||
break;
|
||||
}
|
||||
}
|
||||
MOZ_DIAGNOSTIC_ASSERT(found, "Should find the rule in the child list.");
|
||||
mParent = nullptr;
|
||||
ClearAssociatedDocumentOrShadowRoot();
|
||||
mNext = nullptr;
|
||||
}
|
||||
|
||||
void StyleSheet::UnparentChildren() {
|
||||
// XXXbz this is a little bogus; see the XXX comment where we
|
||||
// declare mFirstChild in StyleSheetInfo.
|
||||
|
|
|
@ -396,6 +396,9 @@ class StyleSheet final : public nsICSSLoaderObserver, public nsWrapperCache {
|
|||
// This is true for any User Agent sheets once they are complete.
|
||||
bool IsReadOnly() const;
|
||||
|
||||
// Removes a stylesheet from its parent sheet child list, if any.
|
||||
void RemoveFromParent();
|
||||
|
||||
private:
|
||||
// Returns the ShadowRoot that contains this stylesheet or our ancestor
|
||||
// stylesheet, if any.
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
<!doctype html>
|
||||
<title>CSSImportRule correctly unlinks its child stylesheet from its parent</title>
|
||||
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<link rel="help" href="https://drafts.csswg.org/cssom/#the-cssimportrule-interface">
|
||||
<style>
|
||||
@import "data:text/css,:root{background:red}";
|
||||
</style>
|
||||
<script>
|
||||
let t = async_test("@import stylesheet is properly unlinked from parent after removal");
|
||||
window.onload = t.step_func_done(function() {
|
||||
let sheet = document.styleSheets[0];
|
||||
let childSheet = sheet.cssRules[0].styleSheet;
|
||||
assert_not_equals(childSheet, null, "@import rule should have a stylesheet");
|
||||
assert_equals(childSheet.parentStyleSheet, sheet, "@import rule should the correct parent");
|
||||
sheet.deleteRule(0);
|
||||
assert_equals(childSheet.parentStyleSheet, null, "@import rule should be correctly unlinked");
|
||||
});
|
||||
</script>
|
Загрузка…
Ссылка в новой задаче