mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-19 00:05:36 +00:00
Backed out 2 changesets (bug 1617746) assertion failures on ShadowRoot.cpp.
CLOSED TREE Backed out changeset 6cb30e866b95 (bug 1617746) Backed out changeset 3543162b815b (bug 1617746)
This commit is contained in:
parent
a4cb1b1fae
commit
3497aa8314
@ -2705,35 +2705,70 @@ size_t Document::FindDocStyleSheetInsertionPoint(const StyleSheet& aSheet) {
|
||||
return index;
|
||||
}
|
||||
|
||||
void Document::AppendAdoptedStyleSheet(StyleSheet& aSheet) {
|
||||
DocumentOrShadowRoot::InsertAdoptedSheetAt(mAdoptedStyleSheets.Length(),
|
||||
aSheet);
|
||||
if (aSheet.IsApplicable()) {
|
||||
AddStyleSheetToStyleSets(&aSheet);
|
||||
}
|
||||
}
|
||||
|
||||
void Document::RemoveDocStyleSheetsFromStyleSets() {
|
||||
MOZ_ASSERT(mStyleSetFilled);
|
||||
// The stylesheets should forget us
|
||||
for (StyleSheet* sheet : Reversed(mStyleSheets)) {
|
||||
sheet->ClearAssociatedDocumentOrShadowRoot();
|
||||
if (sheet->IsApplicable()) {
|
||||
mStyleSet->RemoveDocStyleSheet(sheet);
|
||||
}
|
||||
// XXX Tell observers?
|
||||
}
|
||||
}
|
||||
|
||||
void Document::RemoveStyleSheetsFromStyleSets(
|
||||
const nsTArray<RefPtr<StyleSheet>>& aSheets, StyleOrigin aType) {
|
||||
// The stylesheets should forget us
|
||||
for (StyleSheet* sheet : Reversed(aSheets)) {
|
||||
sheet->ClearAssociatedDocumentOrShadowRoot();
|
||||
if (mStyleSetFilled && sheet->IsApplicable()) {
|
||||
mStyleSet->RemoveStyleSheet(aType, sheet);
|
||||
}
|
||||
// XXX Tell observers?
|
||||
}
|
||||
}
|
||||
|
||||
void Document::ResetStylesheetsToURI(nsIURI* aURI) {
|
||||
MOZ_ASSERT(aURI);
|
||||
|
||||
ClearAdoptedStyleSheets();
|
||||
|
||||
auto ClearSheetList = [&](nsTArray<RefPtr<StyleSheet>>& aSheetList) {
|
||||
for (auto& sheet : Reversed(aSheetList)) {
|
||||
sheet->ClearAssociatedDocumentOrShadowRoot();
|
||||
if (mStyleSetFilled) {
|
||||
mStyleSet->RemoveStyleSheet(*sheet);
|
||||
}
|
||||
}
|
||||
aSheetList.Clear();
|
||||
};
|
||||
ClearSheetList(mStyleSheets);
|
||||
for (auto& sheets : mAdditionalSheets) {
|
||||
ClearSheetList(sheets);
|
||||
}
|
||||
if (mStyleSetFilled) {
|
||||
if (auto* ss = nsStyleSheetService::GetInstance()) {
|
||||
for (auto& sheet : Reversed(*ss->AuthorStyleSheets())) {
|
||||
MOZ_ASSERT(!sheet->GetAssociatedDocumentOrShadowRoot());
|
||||
if (sheet->IsApplicable()) {
|
||||
mStyleSet->RemoveStyleSheet(*sheet);
|
||||
}
|
||||
}
|
||||
// Skip removing style sheets from the style set if we know we haven't
|
||||
// filled the style set. (This allows us to avoid calling
|
||||
// GetStyleBackendType() too early.)
|
||||
RemoveDocStyleSheetsFromStyleSets();
|
||||
RemoveStyleSheetsFromStyleSets(mAdditionalSheets[eAgentSheet],
|
||||
StyleOrigin::UserAgent);
|
||||
RemoveStyleSheetsFromStyleSets(mAdditionalSheets[eUserSheet],
|
||||
StyleOrigin::User);
|
||||
RemoveStyleSheetsFromStyleSets(mAdditionalSheets[eAuthorSheet],
|
||||
StyleOrigin::Author);
|
||||
|
||||
if (nsStyleSheetService* sheetService =
|
||||
nsStyleSheetService::GetInstance()) {
|
||||
RemoveStyleSheetsFromStyleSets(*sheetService->AuthorStyleSheets(),
|
||||
StyleOrigin::Author);
|
||||
}
|
||||
}
|
||||
|
||||
// Release all the sheets
|
||||
mStyleSheets.Clear();
|
||||
for (auto& sheets : mAdditionalSheets) {
|
||||
sheets.Clear();
|
||||
}
|
||||
|
||||
// NOTE: We don't release the catalog sheets. It doesn't really matter
|
||||
// now, but it could in the future -- in which case not releasing them
|
||||
// is probably the right thing to do.
|
||||
|
||||
// Now reset our inline style and attribute sheets.
|
||||
if (mAttrStyleSheet) {
|
||||
mAttrStyleSheet->Reset();
|
||||
@ -2755,10 +2790,11 @@ void Document::ResetStylesheetsToURI(nsIURI* aURI) {
|
||||
}
|
||||
}
|
||||
|
||||
static void AppendSheetsToStyleSet(
|
||||
ServoStyleSet* aStyleSet, const nsTArray<RefPtr<StyleSheet>>& aSheets) {
|
||||
static void AppendSheetsToStyleSet(ServoStyleSet* aStyleSet,
|
||||
const nsTArray<RefPtr<StyleSheet>>& aSheets,
|
||||
StyleOrigin aOrigin) {
|
||||
for (StyleSheet* sheet : Reversed(aSheets)) {
|
||||
aStyleSet->AppendStyleSheet(*sheet);
|
||||
aStyleSet->AppendStyleSheet(aOrigin, sheet);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2775,57 +2811,59 @@ void Document::FillStyleSetUserAndUASheets() {
|
||||
"service has gone");
|
||||
|
||||
for (StyleSheet* sheet : *sheetService->UserStyleSheets()) {
|
||||
mStyleSet->AppendStyleSheet(*sheet);
|
||||
mStyleSet->AppendStyleSheet(StyleOrigin::User, sheet);
|
||||
}
|
||||
|
||||
StyleSheet* sheet = IsInChromeDocShell() ? cache->GetUserChromeSheet()
|
||||
: cache->GetUserContentSheet();
|
||||
if (sheet) {
|
||||
mStyleSet->AppendStyleSheet(*sheet);
|
||||
mStyleSet->AppendStyleSheet(StyleOrigin::User, sheet);
|
||||
}
|
||||
|
||||
mStyleSet->AppendStyleSheet(*cache->UASheet());
|
||||
mStyleSet->AppendStyleSheet(StyleOrigin::UserAgent, cache->UASheet());
|
||||
|
||||
if (MOZ_LIKELY(NodeInfoManager()->MathMLEnabled())) {
|
||||
mStyleSet->AppendStyleSheet(*cache->MathMLSheet());
|
||||
mStyleSet->AppendStyleSheet(StyleOrigin::UserAgent, cache->MathMLSheet());
|
||||
}
|
||||
|
||||
if (MOZ_LIKELY(NodeInfoManager()->SVGEnabled())) {
|
||||
mStyleSet->AppendStyleSheet(*cache->SVGSheet());
|
||||
mStyleSet->AppendStyleSheet(StyleOrigin::UserAgent, cache->SVGSheet());
|
||||
}
|
||||
|
||||
mStyleSet->AppendStyleSheet(*cache->HTMLSheet());
|
||||
mStyleSet->AppendStyleSheet(StyleOrigin::UserAgent, cache->HTMLSheet());
|
||||
|
||||
if (nsLayoutUtils::ShouldUseNoFramesSheet(this)) {
|
||||
mStyleSet->AppendStyleSheet(*cache->NoFramesSheet());
|
||||
mStyleSet->AppendStyleSheet(StyleOrigin::UserAgent, cache->NoFramesSheet());
|
||||
}
|
||||
|
||||
if (nsLayoutUtils::ShouldUseNoScriptSheet(this)) {
|
||||
mStyleSet->AppendStyleSheet(*cache->NoScriptSheet());
|
||||
mStyleSet->AppendStyleSheet(StyleOrigin::UserAgent, cache->NoScriptSheet());
|
||||
}
|
||||
|
||||
mStyleSet->AppendStyleSheet(*cache->CounterStylesSheet());
|
||||
mStyleSet->AppendStyleSheet(StyleOrigin::UserAgent,
|
||||
cache->CounterStylesSheet());
|
||||
|
||||
// Load the minimal XUL rules for scrollbars and a few other XUL things
|
||||
// that non-XUL (typically HTML) documents commonly use.
|
||||
mStyleSet->AppendStyleSheet(*cache->MinimalXULSheet());
|
||||
mStyleSet->AppendStyleSheet(StyleOrigin::UserAgent, cache->MinimalXULSheet());
|
||||
|
||||
// Only load the full XUL sheet if we'll need it.
|
||||
if (LoadsFullXULStyleSheetUpFront()) {
|
||||
mStyleSet->AppendStyleSheet(*cache->XULSheet());
|
||||
mStyleSet->AppendStyleSheet(StyleOrigin::UserAgent, cache->XULSheet());
|
||||
}
|
||||
|
||||
mStyleSet->AppendStyleSheet(*cache->FormsSheet());
|
||||
mStyleSet->AppendStyleSheet(*cache->ScrollbarsSheet());
|
||||
mStyleSet->AppendStyleSheet(*cache->PluginProblemSheet());
|
||||
mStyleSet->AppendStyleSheet(StyleOrigin::UserAgent, cache->FormsSheet());
|
||||
mStyleSet->AppendStyleSheet(StyleOrigin::UserAgent, cache->ScrollbarsSheet());
|
||||
mStyleSet->AppendStyleSheet(StyleOrigin::UserAgent,
|
||||
cache->PluginProblemSheet());
|
||||
|
||||
for (StyleSheet* sheet : *sheetService->AgentStyleSheets()) {
|
||||
mStyleSet->AppendStyleSheet(*sheet);
|
||||
mStyleSet->AppendStyleSheet(StyleOrigin::UserAgent, sheet);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!mQuirkSheetAdded);
|
||||
if (NeedsQuirksSheet()) {
|
||||
mStyleSet->AppendStyleSheet(*cache->QuirkSheet());
|
||||
mStyleSet->AppendStyleSheet(StyleOrigin::UserAgent, cache->QuirkSheet());
|
||||
mQuirkSheetAdded = true;
|
||||
}
|
||||
}
|
||||
@ -2843,12 +2881,14 @@ void Document::RemoveContentEditableStyleSheets() {
|
||||
auto* cache = GlobalStyleSheetCache::Singleton();
|
||||
bool changed = false;
|
||||
if (mDesignModeSheetAdded) {
|
||||
mStyleSet->RemoveStyleSheet(*cache->DesignModeSheet());
|
||||
mStyleSet->RemoveStyleSheet(StyleOrigin::UserAgent,
|
||||
cache->DesignModeSheet());
|
||||
mDesignModeSheetAdded = false;
|
||||
changed = true;
|
||||
}
|
||||
if (mContentEditableSheetAdded) {
|
||||
mStyleSet->RemoveStyleSheet(*cache->ContentEditableSheet());
|
||||
mStyleSet->RemoveStyleSheet(StyleOrigin::UserAgent,
|
||||
cache->ContentEditableSheet());
|
||||
mContentEditableSheetAdded = false;
|
||||
changed = true;
|
||||
}
|
||||
@ -2866,15 +2906,18 @@ void Document::AddContentEditableStyleSheetsToStyleSet(bool aDesignMode) {
|
||||
auto* cache = GlobalStyleSheetCache::Singleton();
|
||||
bool changed = false;
|
||||
if (!mContentEditableSheetAdded) {
|
||||
mStyleSet->AppendStyleSheet(*cache->ContentEditableSheet());
|
||||
mStyleSet->AppendStyleSheet(StyleOrigin::UserAgent,
|
||||
cache->ContentEditableSheet());
|
||||
mContentEditableSheetAdded = true;
|
||||
changed = true;
|
||||
}
|
||||
if (mDesignModeSheetAdded != aDesignMode) {
|
||||
if (mDesignModeSheetAdded) {
|
||||
mStyleSet->RemoveStyleSheet(*cache->DesignModeSheet());
|
||||
mStyleSet->RemoveStyleSheet(StyleOrigin::UserAgent,
|
||||
cache->DesignModeSheet());
|
||||
} else {
|
||||
mStyleSet->AppendStyleSheet(*cache->DesignModeSheet());
|
||||
mStyleSet->AppendStyleSheet(StyleOrigin::UserAgent,
|
||||
cache->DesignModeSheet());
|
||||
}
|
||||
mDesignModeSheetAdded = !mDesignModeSheetAdded;
|
||||
changed = true;
|
||||
@ -2888,32 +2931,31 @@ void Document::FillStyleSetDocumentSheets() {
|
||||
MOZ_ASSERT(mStyleSet->SheetCount(StyleOrigin::Author) == 0,
|
||||
"Style set already has document sheets?");
|
||||
|
||||
// Sheets are added in reverse order to avoid worst-case time complexity when
|
||||
// looking up the index of a sheet.
|
||||
//
|
||||
// Note that usually appending is faster (rebuilds less stuff in the
|
||||
// styleset), but in this case it doesn't matter since we're filling the
|
||||
// styleset from scratch anyway.
|
||||
// Sheets are added in reverse order to avoid worst-case
|
||||
// time complexity when looking up the index of a sheet
|
||||
for (StyleSheet* sheet : Reversed(mStyleSheets)) {
|
||||
if (sheet->IsApplicable()) {
|
||||
mStyleSet->AddDocStyleSheet(*sheet);
|
||||
mStyleSet->AddDocStyleSheet(sheet);
|
||||
}
|
||||
}
|
||||
|
||||
EnumerateUniqueAdoptedStyleSheetsBackToFront([&](StyleSheet& aSheet) {
|
||||
if (aSheet.IsApplicable()) {
|
||||
mStyleSet->AddDocStyleSheet(aSheet);
|
||||
for (StyleSheet* sheet : Reversed(mAdoptedStyleSheets)) {
|
||||
if (sheet->IsApplicable()) {
|
||||
mStyleSet->AddDocStyleSheet(sheet);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
nsStyleSheetService* sheetService = nsStyleSheetService::GetInstance();
|
||||
for (StyleSheet* sheet : *sheetService->AuthorStyleSheets()) {
|
||||
mStyleSet->AppendStyleSheet(*sheet);
|
||||
mStyleSet->AppendStyleSheet(StyleOrigin::Author, sheet);
|
||||
}
|
||||
|
||||
AppendSheetsToStyleSet(mStyleSet.get(), mAdditionalSheets[eAgentSheet]);
|
||||
AppendSheetsToStyleSet(mStyleSet.get(), mAdditionalSheets[eUserSheet]);
|
||||
AppendSheetsToStyleSet(mStyleSet.get(), mAdditionalSheets[eAuthorSheet]);
|
||||
AppendSheetsToStyleSet(mStyleSet.get(), mAdditionalSheets[eAgentSheet],
|
||||
StyleOrigin::UserAgent);
|
||||
AppendSheetsToStyleSet(mStyleSet.get(), mAdditionalSheets[eUserSheet],
|
||||
StyleOrigin::User);
|
||||
AppendSheetsToStyleSet(mStyleSet.get(), mAdditionalSheets[eAuthorSheet],
|
||||
StyleOrigin::Author);
|
||||
}
|
||||
|
||||
void Document::CompatibilityModeChanged() {
|
||||
@ -2935,9 +2977,9 @@ void Document::CompatibilityModeChanged() {
|
||||
auto* cache = GlobalStyleSheetCache::Singleton();
|
||||
StyleSheet* sheet = cache->QuirkSheet();
|
||||
if (mQuirkSheetAdded) {
|
||||
mStyleSet->RemoveStyleSheet(*sheet);
|
||||
mStyleSet->RemoveStyleSheet(StyleOrigin::UserAgent, sheet);
|
||||
} else {
|
||||
mStyleSet->AppendStyleSheet(*sheet);
|
||||
mStyleSet->AppendStyleSheet(StyleOrigin::UserAgent, sheet);
|
||||
}
|
||||
mQuirkSheetAdded = !mQuirkSheetAdded;
|
||||
ApplicableStylesChanged();
|
||||
@ -6501,7 +6543,7 @@ void Document::RemoveChildNode(nsIContent* aKid, bool aNotify) {
|
||||
"(maybe somebody called GetRootElement() too early?)");
|
||||
}
|
||||
|
||||
void Document::AddStyleSheetToStyleSets(StyleSheet& aSheet) {
|
||||
void Document::AddStyleSheetToStyleSets(StyleSheet* aSheet) {
|
||||
if (mStyleSetFilled) {
|
||||
mStyleSet->AddDocStyleSheet(aSheet);
|
||||
ApplicableStylesChanged();
|
||||
@ -6537,9 +6579,9 @@ void Document::ApplicableStylesChanged() {
|
||||
pc->RestyleManager()->NextRestyleIsForCSSRuleChanges();
|
||||
}
|
||||
|
||||
void Document::RemoveStyleSheetFromStyleSets(StyleSheet& aSheet) {
|
||||
void Document::RemoveStyleSheetFromStyleSets(StyleSheet* aSheet) {
|
||||
if (mStyleSetFilled) {
|
||||
mStyleSet->RemoveStyleSheet(aSheet);
|
||||
mStyleSet->RemoveDocStyleSheet(aSheet);
|
||||
ApplicableStylesChanged();
|
||||
}
|
||||
}
|
||||
@ -6553,7 +6595,7 @@ void Document::RemoveStyleSheet(StyleSheet& aSheet) {
|
||||
}
|
||||
|
||||
if (!mIsGoingAway && sheet->IsApplicable()) {
|
||||
RemoveStyleSheetFromStyleSets(*sheet);
|
||||
RemoveStyleSheetFromStyleSets(sheet);
|
||||
}
|
||||
|
||||
sheet->ClearAssociatedDocumentOrShadowRoot();
|
||||
@ -6563,7 +6605,7 @@ void Document::InsertSheetAt(size_t aIndex, StyleSheet& aSheet) {
|
||||
DocumentOrShadowRoot::InsertSheetAt(aIndex, aSheet);
|
||||
|
||||
if (aSheet.IsApplicable()) {
|
||||
AddStyleSheetToStyleSets(aSheet);
|
||||
AddStyleSheetToStyleSets(&aSheet);
|
||||
}
|
||||
}
|
||||
|
||||
@ -6572,9 +6614,9 @@ void Document::StyleSheetApplicableStateChanged(StyleSheet& aSheet) {
|
||||
// If we're actually in the document style sheet list
|
||||
if (StyleOrderIndexOfSheet(aSheet) >= 0) {
|
||||
if (applicable) {
|
||||
AddStyleSheetToStyleSets(aSheet);
|
||||
AddStyleSheetToStyleSets(&aSheet);
|
||||
} else {
|
||||
RemoveStyleSheetFromStyleSets(aSheet);
|
||||
RemoveStyleSheetFromStyleSets(&aSheet);
|
||||
}
|
||||
}
|
||||
|
||||
@ -6616,6 +6658,20 @@ void Document::NotifyStyleSheetApplicableStateChanged() {
|
||||
}
|
||||
}
|
||||
|
||||
static StyleOrigin ConvertAdditionalSheetType(
|
||||
Document::additionalSheetType aType) {
|
||||
switch (aType) {
|
||||
case Document::eAgentSheet:
|
||||
return StyleOrigin::UserAgent;
|
||||
case Document::eUserSheet:
|
||||
return StyleOrigin::User;
|
||||
case Document::eAuthorSheet:
|
||||
return StyleOrigin::Author;
|
||||
default:
|
||||
MOZ_CRASH("Wrong sheet type");
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t FindSheet(const nsTArray<RefPtr<StyleSheet>>& aSheets,
|
||||
nsIURI* aSheetURI) {
|
||||
for (int32_t i = aSheets.Length() - 1; i >= 0; i--) {
|
||||
@ -6686,7 +6742,7 @@ nsresult Document::AddAdditionalStyleSheet(additionalSheetType aType,
|
||||
mAdditionalSheets[aType].AppendElement(aSheet);
|
||||
|
||||
if (mStyleSetFilled) {
|
||||
mStyleSet->AppendStyleSheet(*aSheet);
|
||||
mStyleSet->AppendStyleSheet(ConvertAdditionalSheetType(aType), aSheet);
|
||||
ApplicableStylesChanged();
|
||||
}
|
||||
return NS_OK;
|
||||
@ -6700,13 +6756,14 @@ void Document::RemoveAdditionalStyleSheet(additionalSheetType aType,
|
||||
|
||||
int32_t i = FindSheet(mAdditionalSheets[aType], aSheetURI);
|
||||
if (i >= 0) {
|
||||
RefPtr<StyleSheet> sheetRef = std::move(sheets[i]);
|
||||
RefPtr<StyleSheet> sheetRef = sheets[i];
|
||||
sheets.RemoveElementAt(i);
|
||||
|
||||
if (!mIsGoingAway) {
|
||||
MOZ_ASSERT(sheetRef->IsApplicable());
|
||||
if (mStyleSetFilled) {
|
||||
mStyleSet->RemoveStyleSheet(*sheetRef);
|
||||
mStyleSet->RemoveStyleSheet(ConvertAdditionalSheetType(aType),
|
||||
sheetRef);
|
||||
ApplicableStylesChanged();
|
||||
}
|
||||
}
|
||||
@ -16113,5 +16170,34 @@ Document::RecomputeContentBlockingAllowListPrincipal(
|
||||
return copy.forget();
|
||||
}
|
||||
|
||||
// https://wicg.github.io/construct-stylesheets/#dom-documentorshadowroot-adoptedstylesheets
|
||||
void Document::SetAdoptedStyleSheets(
|
||||
const Sequence<OwningNonNull<StyleSheet>>& aAdoptedStyleSheets,
|
||||
ErrorResult& aRv) {
|
||||
// Step 1 is a variable declaration
|
||||
|
||||
// 2.1 Check if all sheets are constructed, else throw NotAllowedError
|
||||
// 2.2 Check if all sheets' constructor documents match the
|
||||
// DocumentOrShadowRoot's node document, else throw NotAlloweError
|
||||
EnsureAdoptedSheetsAreValid(aAdoptedStyleSheets, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. Set the adopted style sheets to the new sheets
|
||||
for (const RefPtr<StyleSheet>& sheet : mAdoptedStyleSheets) {
|
||||
if (sheet->IsApplicable()) {
|
||||
RemoveStyleSheetFromStyleSets(sheet);
|
||||
}
|
||||
sheet->RemoveAdopter(*this);
|
||||
}
|
||||
mAdoptedStyleSheets.ClearAndRetainStorage();
|
||||
mAdoptedStyleSheets.SetCapacity(aAdoptedStyleSheets.Length());
|
||||
for (const OwningNonNull<StyleSheet>& sheet : aAdoptedStyleSheets) {
|
||||
sheet->AddAdopter(*this);
|
||||
AppendAdoptedStyleSheet(*sheet);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -475,8 +475,6 @@ class Document : public nsINode,
|
||||
public nsStubMutationObserver,
|
||||
public DispatcherTrait,
|
||||
public SupportsWeakPtr<Document> {
|
||||
friend class DocumentOrShadowRoot;
|
||||
|
||||
protected:
|
||||
explicit Document(const char* aContentType);
|
||||
virtual ~Document();
|
||||
@ -1728,6 +1726,8 @@ class Document : public nsINode,
|
||||
return mAdditionalSheets[eAuthorSheet].SafeElementAt(0);
|
||||
}
|
||||
|
||||
void AppendAdoptedStyleSheet(StyleSheet& aSheet);
|
||||
|
||||
/**
|
||||
* Returns the index that aSheet should be inserted at to maintain document
|
||||
* ordering.
|
||||
@ -3882,6 +3882,10 @@ class Document : public nsINode,
|
||||
|
||||
already_AddRefed<Promise> AddCertException(bool aIsTemporary);
|
||||
|
||||
void SetAdoptedStyleSheets(
|
||||
const Sequence<OwningNonNull<StyleSheet>>& aAdoptedStyleSheets,
|
||||
ErrorResult& aRv);
|
||||
|
||||
protected:
|
||||
void DoUpdateSVGUseElementShadowTrees();
|
||||
|
||||
@ -3936,6 +3940,8 @@ class Document : public nsINode,
|
||||
}
|
||||
|
||||
void RemoveDocStyleSheetsFromStyleSets();
|
||||
void RemoveStyleSheetsFromStyleSets(
|
||||
const nsTArray<RefPtr<StyleSheet>>& aSheets, StyleOrigin);
|
||||
void ResetStylesheetsToURI(nsIURI* aURI);
|
||||
void FillStyleSet();
|
||||
void FillStyleSetUserAndUASheets();
|
||||
@ -3948,8 +3954,8 @@ class Document : public nsINode,
|
||||
}
|
||||
void AddContentEditableStyleSheetsToStyleSet(bool aDesignMode);
|
||||
void RemoveContentEditableStyleSheets();
|
||||
void AddStyleSheetToStyleSets(StyleSheet&);
|
||||
void RemoveStyleSheetFromStyleSets(StyleSheet&);
|
||||
void AddStyleSheetToStyleSets(StyleSheet* aSheet);
|
||||
void RemoveStyleSheetFromStyleSets(StyleSheet* aSheet);
|
||||
void NotifyStyleSheetApplicableStateChanged();
|
||||
// Just like EnableStyleSheetsForSet, but doesn't check whether
|
||||
// aSheetSet is null and allows the caller to control whether to set
|
||||
|
@ -78,6 +78,11 @@ void DocumentOrShadowRoot::InsertSheetAt(size_t aIndex, StyleSheet& aSheet) {
|
||||
mStyleSheets.InsertElementAt(aIndex, &aSheet);
|
||||
}
|
||||
|
||||
void DocumentOrShadowRoot::InsertAdoptedSheetAt(size_t aIndex,
|
||||
StyleSheet& aSheet) {
|
||||
mAdoptedStyleSheets.InsertElementAt(aIndex, &aSheet);
|
||||
}
|
||||
|
||||
already_AddRefed<StyleSheet> DocumentOrShadowRoot::RemoveSheet(
|
||||
StyleSheet& aSheet) {
|
||||
auto index = mStyleSheets.IndexOf(&aSheet);
|
||||
@ -90,24 +95,13 @@ already_AddRefed<StyleSheet> DocumentOrShadowRoot::RemoveSheet(
|
||||
return sheet.forget();
|
||||
}
|
||||
|
||||
void DocumentOrShadowRoot::RemoveSheetFromStylesIfApplicable(
|
||||
StyleSheet& aSheet) {
|
||||
if (!aSheet.IsApplicable()) {
|
||||
return;
|
||||
}
|
||||
if (mKind == Kind::Document) {
|
||||
AsNode().AsDocument()->RemoveStyleSheetFromStyleSets(aSheet);
|
||||
} else {
|
||||
MOZ_ASSERT(AsNode().IsShadowRoot());
|
||||
static_cast<ShadowRoot&>(AsNode()).RemoveSheetFromStyles(aSheet);
|
||||
}
|
||||
}
|
||||
|
||||
// https://wicg.github.io/construct-stylesheets/#dom-documentorshadowroot-adoptedstylesheets
|
||||
void DocumentOrShadowRoot::SetAdoptedStyleSheets(
|
||||
void DocumentOrShadowRoot::EnsureAdoptedSheetsAreValid(
|
||||
const Sequence<OwningNonNull<StyleSheet>>& aAdoptedStyleSheets,
|
||||
ErrorResult& aRv) {
|
||||
Document& doc = *AsNode().OwnerDoc();
|
||||
nsTHashtable<nsPtrHashKey<const StyleSheet>> set(
|
||||
aAdoptedStyleSheets.Length());
|
||||
|
||||
for (const OwningNonNull<StyleSheet>& sheet : aAdoptedStyleSheets) {
|
||||
// 2.1 Check if all sheets are constructed, else throw NotAllowedError
|
||||
if (!sheet->IsConstructed()) {
|
||||
@ -117,51 +111,23 @@ void DocumentOrShadowRoot::SetAdoptedStyleSheets(
|
||||
}
|
||||
// 2.2 Check if all sheets' constructor documents match the
|
||||
// DocumentOrShadowRoot's node document, else throw NotAlloweError
|
||||
if (!sheet->ConstructorDocumentMatches(doc)) {
|
||||
if (!sheet->ConstructorDocumentMatches(AsNode().OwnerDoc())) {
|
||||
return aRv.ThrowNotAllowedError(
|
||||
"Each adopted style sheet's constructor document must match the "
|
||||
"document or shadow root's node document");
|
||||
}
|
||||
}
|
||||
|
||||
auto* shadow = ShadowRoot::FromNode(AsNode());
|
||||
MOZ_ASSERT((mKind == Kind::ShadowRoot) == !!shadow);
|
||||
|
||||
ClearAdoptedStyleSheets();
|
||||
|
||||
// 3. Set the adopted style sheets to the new sheets
|
||||
mAdoptedStyleSheets.SetCapacity(aAdoptedStyleSheets.Length());
|
||||
|
||||
AdoptedStyleSheetSet set(aAdoptedStyleSheets.Length());
|
||||
for (const OwningNonNull<StyleSheet>& sheet : aAdoptedStyleSheets) {
|
||||
if (MOZ_UNLIKELY(!set.EnsureInserted(sheet.get()))) {
|
||||
// The idea is that this case is rare, so we pay the price of removing the
|
||||
// old sheet from the styles and append it later rather than the other way
|
||||
// around.
|
||||
RemoveSheetFromStylesIfApplicable(*sheet);
|
||||
} else {
|
||||
sheet->AddAdopter(*this);
|
||||
}
|
||||
mAdoptedStyleSheets.AppendElement(sheet);
|
||||
if (sheet->IsApplicable()) {
|
||||
if (mKind == Kind::Document) {
|
||||
doc.AddStyleSheetToStyleSets(*sheet);
|
||||
} else {
|
||||
shadow->InsertSheetIntoAuthorData(mAdoptedStyleSheets.Length() - 1,
|
||||
*sheet, mAdoptedStyleSheets);
|
||||
}
|
||||
// FIXME(nordzilla): This is temporary code to disallow duplicate sheets.
|
||||
// This exists to ensure that the fuzzers aren't blocked.
|
||||
// This code will eventually be removed.
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1617302
|
||||
if (!set.EnsureInserted(sheet.get())) {
|
||||
return aRv.ThrowNotAllowedError(
|
||||
"Temporarily disallowing duplicate stylesheets.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DocumentOrShadowRoot::ClearAdoptedStyleSheets() {
|
||||
EnumerateUniqueAdoptedStyleSheetsBackToFront([&](StyleSheet& aSheet) {
|
||||
RemoveSheetFromStylesIfApplicable(aSheet);
|
||||
aSheet.RemoveAdopter(*this);
|
||||
});
|
||||
mAdoptedStyleSheets.Clear();
|
||||
}
|
||||
|
||||
Element* DocumentOrShadowRoot::GetElementById(const nsAString& aElementId) {
|
||||
if (MOZ_UNLIKELY(aElementId.IsEmpty())) {
|
||||
nsContentUtils::ReportEmptyGetElementByIdArg(AsNode().OwnerDoc());
|
||||
@ -696,9 +662,7 @@ nsRadioGroupStruct* DocumentOrShadowRoot::GetOrCreateRadioGroup(
|
||||
int32_t DocumentOrShadowRoot::StyleOrderIndexOfSheet(
|
||||
const StyleSheet& aSheet) const {
|
||||
if (aSheet.IsConstructed()) {
|
||||
// NOTE: constructable sheets can have duplicates, so we need to start
|
||||
// looking from behind.
|
||||
int32_t index = mAdoptedStyleSheets.LastIndexOf(&aSheet);
|
||||
int32_t index = mAdoptedStyleSheets.IndexOf(&aSheet);
|
||||
return (index < 0) ? index : index + SheetCount();
|
||||
}
|
||||
return mStyleSheets.IndexOf(&aSheet);
|
||||
@ -715,27 +679,26 @@ void DocumentOrShadowRoot::Traverse(DocumentOrShadowRoot* tmp,
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDOMStyleSheets)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAdoptedStyleSheets)
|
||||
|
||||
auto NoteSheetIfApplicable = [&](StyleSheet& aSheet) {
|
||||
if (!aSheet.IsApplicable()) {
|
||||
return;
|
||||
}
|
||||
// The style set or mServoStyles keep more references to it if the sheet
|
||||
// is applicable.
|
||||
if (tmp->mKind == Kind::ShadowRoot) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mServoStyles->sheets[i]");
|
||||
cb.NoteXPCOMChild(&aSheet);
|
||||
} else if (tmp->AsNode().AsDocument()->StyleSetFilled()) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(
|
||||
cb, "mStyleSet->mRawSet.stylist.stylesheets.author[i]");
|
||||
cb.NoteXPCOMChild(&aSheet);
|
||||
auto NoteSheets = [tmp, &cb = cb](nsTArray<RefPtr<StyleSheet>>& sheetList) {
|
||||
for (StyleSheet* sheet : sheetList) {
|
||||
if (!sheet->IsApplicable()) {
|
||||
continue;
|
||||
}
|
||||
// The style set or mServoStyles keep more references to it if the sheet
|
||||
// is applicable.
|
||||
if (tmp->mKind == Kind::ShadowRoot) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mServoStyles->sheets[i]");
|
||||
cb.NoteXPCOMChild(sheet);
|
||||
} else if (tmp->AsNode().AsDocument()->StyleSetFilled()) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(
|
||||
cb, "mStyleSet->mRawSet.stylist.stylesheets.author[i]");
|
||||
cb.NoteXPCOMChild(sheet);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
for (auto& sheet : tmp->mStyleSheets) {
|
||||
NoteSheetIfApplicable(*sheet);
|
||||
}
|
||||
|
||||
tmp->EnumerateUniqueAdoptedStyleSheetsBackToFront(NoteSheetIfApplicable);
|
||||
NoteSheets(tmp->mStyleSheets);
|
||||
NoteSheets(tmp->mAdoptedStyleSheets);
|
||||
|
||||
for (auto iter = tmp->mIdentifierMap.ConstIter(); !iter.Done(); iter.Next()) {
|
||||
iter.Get()->Traverse(&cb);
|
||||
|
@ -221,33 +221,15 @@ class DocumentOrShadowRoot {
|
||||
|
||||
nsIContent* Retarget(nsIContent* aContent) const;
|
||||
|
||||
void SetAdoptedStyleSheets(
|
||||
const Sequence<OwningNonNull<StyleSheet>>& aAdoptedStyleSheets,
|
||||
ErrorResult& aRv);
|
||||
|
||||
// This is needed because ServoStyleSet / ServoAuthorData don't deal with
|
||||
// duplicate stylesheets (and it's unclear we'd want to support that as it'd
|
||||
// be a bunch of duplicate work), while adopted stylesheets do need to deal
|
||||
// with them.
|
||||
template <typename Callback>
|
||||
void EnumerateUniqueAdoptedStyleSheetsBackToFront(Callback aCallback) {
|
||||
AdoptedStyleSheetSet set(mAdoptedStyleSheets.Length());
|
||||
for (StyleSheet* sheet : Reversed(mAdoptedStyleSheets)) {
|
||||
if (MOZ_UNLIKELY(!set.EnsureInserted(sheet))) {
|
||||
continue;
|
||||
}
|
||||
aCallback(*sheet);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
using AdoptedStyleSheetSet = nsTHashtable<nsPtrHashKey<const StyleSheet>>;
|
||||
void RemoveSheetFromStylesIfApplicable(StyleSheet&);
|
||||
void ClearAdoptedStyleSheets();
|
||||
|
||||
// Returns the reference to the sheet, if found in mStyleSheets.
|
||||
already_AddRefed<StyleSheet> RemoveSheet(StyleSheet& aSheet);
|
||||
void InsertSheetAt(size_t aIndex, StyleSheet& aSheet);
|
||||
void InsertAdoptedSheetAt(size_t aIndex, StyleSheet& aSheet);
|
||||
|
||||
void EnsureAdoptedSheetsAreValid(
|
||||
const Sequence<OwningNonNull<StyleSheet>>& aAdoptedStyleSheets,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void AddSizeOfExcludingThis(nsWindowSizes&) const;
|
||||
void AddSizeOfOwnedSheetArrayExcludingThis(
|
||||
|
@ -376,17 +376,11 @@ void ShadowRoot::InsertSheetAt(size_t aIndex, StyleSheet& aSheet) {
|
||||
}
|
||||
}
|
||||
|
||||
StyleSheet* FirstApplicableAdoptedStyleSheet(
|
||||
const nsTArray<RefPtr<StyleSheet>>& aList) {
|
||||
size_t i = 0;
|
||||
for (StyleSheet* sheet : aList) {
|
||||
// Deal with duplicate sheets by only considering the last one.
|
||||
if (sheet->IsApplicable() && MOZ_LIKELY(aList.LastIndexOf(sheet) == i)) {
|
||||
return sheet;
|
||||
}
|
||||
i++;
|
||||
void ShadowRoot::InsertAdoptedSheetAt(size_t aIndex, StyleSheet& aSheet) {
|
||||
DocumentOrShadowRoot::InsertAdoptedSheetAt(aIndex, aSheet);
|
||||
if (aSheet.IsApplicable()) {
|
||||
InsertSheetIntoAuthorData(aIndex, aSheet, mAdoptedStyleSheets);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ShadowRoot::InsertSheetIntoAuthorData(
|
||||
@ -394,7 +388,6 @@ void ShadowRoot::InsertSheetIntoAuthorData(
|
||||
const nsTArray<RefPtr<StyleSheet>>& aList) {
|
||||
MOZ_ASSERT(aSheet.IsApplicable());
|
||||
MOZ_ASSERT(aList[aIndex] == &aSheet);
|
||||
MOZ_ASSERT(aList.LastIndexOf(&aSheet) == aIndex);
|
||||
MOZ_ASSERT(&aList == &mAdoptedStyleSheets || &aList == &mStyleSheets);
|
||||
|
||||
if (!mServoStyles) {
|
||||
@ -405,38 +398,25 @@ void ShadowRoot::InsertSheetIntoAuthorData(
|
||||
mStyleRuleMap->SheetAdded(aSheet);
|
||||
}
|
||||
|
||||
auto changedOnExit =
|
||||
mozilla::MakeScopeExit([&] { ApplicableRulesChanged(); });
|
||||
|
||||
for (size_t i = aIndex + 1; i < aList.Length(); ++i) {
|
||||
StyleSheet* beforeSheet = aList.ElementAt(i);
|
||||
if (!beforeSheet->IsApplicable()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If this is a duplicate adopted stylesheet that is not in the right
|
||||
// position (the last one) then we skip over it. Otherwise we're done.
|
||||
if (&aList == &mAdoptedStyleSheets &&
|
||||
MOZ_UNLIKELY(aList.LastIndexOf(beforeSheet) != i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Servo_AuthorStyles_InsertStyleSheetBefore(mServoStyles.get(), &aSheet,
|
||||
beforeSheet);
|
||||
ApplicableRulesChanged();
|
||||
return;
|
||||
}
|
||||
|
||||
if (mAdoptedStyleSheets.IsEmpty() || &aList == &mAdoptedStyleSheets) {
|
||||
Servo_AuthorStyles_AppendStyleSheet(mServoStyles.get(), &aSheet);
|
||||
return;
|
||||
}
|
||||
|
||||
if (auto* before = FirstApplicableAdoptedStyleSheet(mAdoptedStyleSheets)) {
|
||||
Servo_AuthorStyles_InsertStyleSheetBefore(mServoStyles.get(), &aSheet,
|
||||
before);
|
||||
} else {
|
||||
Servo_AuthorStyles_AppendStyleSheet(mServoStyles.get(), &aSheet);
|
||||
Servo_AuthorStyles_InsertStyleSheetBefore(mServoStyles.get(), &aSheet,
|
||||
mAdoptedStyleSheets.ElementAt(0));
|
||||
}
|
||||
ApplicableRulesChanged();
|
||||
}
|
||||
|
||||
// FIXME(emilio): This needs to notify document observers and such,
|
||||
@ -466,22 +446,29 @@ void ShadowRoot::StyleSheetApplicableStateChanged(StyleSheet& aSheet) {
|
||||
}
|
||||
}
|
||||
|
||||
void ShadowRoot::RemoveSheetFromStyles(StyleSheet& aSheet) {
|
||||
MOZ_ASSERT(aSheet.IsApplicable());
|
||||
MOZ_ASSERT(mServoStyles);
|
||||
if (mStyleRuleMap) {
|
||||
mStyleRuleMap->SheetRemoved(aSheet);
|
||||
void ShadowRoot::ClearAdoptedStyleSheets() {
|
||||
for (const RefPtr<StyleSheet>& sheet : mAdoptedStyleSheets) {
|
||||
RemoveSheetFromStyles(*sheet);
|
||||
sheet->RemoveAdopter(*this);
|
||||
}
|
||||
mAdoptedStyleSheets.Clear();
|
||||
}
|
||||
|
||||
void ShadowRoot::RemoveSheetFromStyles(StyleSheet& aSheet) {
|
||||
if (aSheet.IsApplicable()) {
|
||||
MOZ_ASSERT(mServoStyles);
|
||||
if (mStyleRuleMap) {
|
||||
mStyleRuleMap->SheetRemoved(aSheet);
|
||||
}
|
||||
Servo_AuthorStyles_RemoveStyleSheet(mServoStyles.get(), &aSheet);
|
||||
ApplicableRulesChanged();
|
||||
}
|
||||
Servo_AuthorStyles_RemoveStyleSheet(mServoStyles.get(), &aSheet);
|
||||
ApplicableRulesChanged();
|
||||
}
|
||||
|
||||
void ShadowRoot::RemoveSheet(StyleSheet& aSheet) {
|
||||
RefPtr<StyleSheet> sheet = DocumentOrShadowRoot::RemoveSheet(aSheet);
|
||||
MOZ_ASSERT(sheet);
|
||||
if (sheet->IsApplicable()) {
|
||||
RemoveSheetFromStyles(*sheet);
|
||||
}
|
||||
RemoveSheetFromStyles(*sheet);
|
||||
}
|
||||
|
||||
void ShadowRoot::AddToIdTable(Element* aElement, nsAtom* aId) {
|
||||
@ -727,3 +714,29 @@ nsresult ShadowRoot::Clone(dom::NodeInfo* aNodeInfo, nsINode** aResult) const {
|
||||
*aResult = nullptr;
|
||||
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
|
||||
}
|
||||
|
||||
// https://wicg.github.io/construct-stylesheets/#dom-documentorshadowroot-adoptedstylesheets
|
||||
void ShadowRoot::SetAdoptedStyleSheets(
|
||||
const Sequence<OwningNonNull<StyleSheet>>& aAdoptedStyleSheets,
|
||||
ErrorResult& aRv) {
|
||||
// Step 1 is a variable declaration
|
||||
|
||||
// 2.1 Check if all sheets are constructed, else throw NotAllowedError
|
||||
// 2.2 Check if all sheets' constructor documents match the
|
||||
// DocumentOrShadowRoot's node document, else throw NotAlloweError
|
||||
EnsureAdoptedSheetsAreValid(aAdoptedStyleSheets, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. Set the adopted style sheets to the new sheets
|
||||
// TODO(nordzilla): There are optimizations that can be made here
|
||||
// in the case of only appending new sheets.
|
||||
// See https://bugzilla.mozilla.org/show_bug.cgi?id=1611236
|
||||
ClearAdoptedStyleSheets();
|
||||
mAdoptedStyleSheets.SetCapacity(aAdoptedStyleSheets.Length());
|
||||
for (const OwningNonNull<StyleSheet>& sheet : aAdoptedStyleSheets) {
|
||||
sheet->AddAdopter(*this);
|
||||
AppendAdoptedStyleSheet(*sheet);
|
||||
}
|
||||
}
|
||||
|
@ -41,8 +41,6 @@ class HTMLInputElement;
|
||||
class ShadowRoot final : public DocumentFragment,
|
||||
public DocumentOrShadowRoot,
|
||||
public nsIRadioGroupContainer {
|
||||
friend class DocumentOrShadowRoot;
|
||||
|
||||
public:
|
||||
NS_IMPL_FROMNODE_HELPER(ShadowRoot, IsShadowRoot());
|
||||
|
||||
@ -88,6 +86,7 @@ class ShadowRoot final : public DocumentFragment,
|
||||
*/
|
||||
void CloneInternalDataFrom(ShadowRoot* aOther);
|
||||
void InsertSheetAt(size_t aIndex, StyleSheet&);
|
||||
void InsertAdoptedSheetAt(size_t aIndex, StyleSheet&);
|
||||
|
||||
// Calls UnbindFromTree for each of our kids, and also flags us as no longer
|
||||
// being connected.
|
||||
@ -111,6 +110,10 @@ class ShadowRoot final : public DocumentFragment,
|
||||
InsertSheetAt(SheetCount(), aSheet);
|
||||
}
|
||||
|
||||
void AppendAdoptedStyleSheet(StyleSheet& aSheet) {
|
||||
InsertAdoptedSheetAt(AdoptedSheetCount(), aSheet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the insertion point in a slot for a given node.
|
||||
*/
|
||||
@ -253,6 +256,12 @@ class ShadowRoot final : public DocumentFragment,
|
||||
return DocumentOrShadowRoot::SetValueMissingState(aName, aValue);
|
||||
}
|
||||
|
||||
void SetAdoptedStyleSheets(
|
||||
const Sequence<OwningNonNull<StyleSheet>>& aAdoptedStyleSheets,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void ClearAdoptedStyleSheets();
|
||||
|
||||
protected:
|
||||
// FIXME(emilio): This will need to become more fine-grained.
|
||||
void ApplicableRulesChanged();
|
||||
|
@ -1477,13 +1477,13 @@ void PresShell::UpdatePreferenceStyles() {
|
||||
// it to be modifiable from devtools and similar, see bugs 1239336 and
|
||||
// 1436782. I think it conceptually should be a user sheet, and could be
|
||||
// without too much trouble I'd think.
|
||||
StyleSet()->AppendStyleSheet(*newPrefSheet);
|
||||
StyleSet()->AppendStyleSheet(StyleOrigin::UserAgent, newPrefSheet);
|
||||
mPrefStyleSheet = newPrefSheet;
|
||||
}
|
||||
|
||||
void PresShell::RemovePreferenceStyles() {
|
||||
if (mPrefStyleSheet) {
|
||||
StyleSet()->RemoveStyleSheet(*mPrefStyleSheet);
|
||||
StyleSet()->RemoveStyleSheet(StyleOrigin::UserAgent, mPrefStyleSheet);
|
||||
mPrefStyleSheet = nullptr;
|
||||
}
|
||||
}
|
||||
@ -1514,10 +1514,10 @@ void PresShell::AddUserSheet(StyleSheet* aSheet) {
|
||||
}
|
||||
|
||||
if (index == static_cast<size_t>(StyleSet()->SheetCount(StyleOrigin::User))) {
|
||||
StyleSet()->AppendStyleSheet(*aSheet);
|
||||
StyleSet()->AppendStyleSheet(StyleOrigin::User, aSheet);
|
||||
} else {
|
||||
StyleSheet* ref = StyleSet()->SheetAt(StyleOrigin::User, index);
|
||||
StyleSet()->InsertStyleSheetBefore(*aSheet, *ref);
|
||||
StyleSet()->InsertStyleSheetBefore(StyleOrigin::User, aSheet, ref);
|
||||
}
|
||||
|
||||
mDocument->ApplicableStylesChanged();
|
||||
@ -1526,7 +1526,7 @@ void PresShell::AddUserSheet(StyleSheet* aSheet) {
|
||||
void PresShell::AddAgentSheet(StyleSheet* aSheet) {
|
||||
// Make sure this does what nsDocumentViewer::CreateStyleSet does
|
||||
// wrt ordering.
|
||||
StyleSet()->AppendStyleSheet(*aSheet);
|
||||
StyleSet()->AppendStyleSheet(StyleOrigin::UserAgent, aSheet);
|
||||
mDocument->ApplicableStylesChanged();
|
||||
}
|
||||
|
||||
@ -1535,14 +1535,20 @@ void PresShell::AddAuthorSheet(StyleSheet* aSheet) {
|
||||
// ones added with the StyleSheetService.
|
||||
StyleSheet* firstAuthorSheet = mDocument->GetFirstAdditionalAuthorSheet();
|
||||
if (firstAuthorSheet) {
|
||||
StyleSet()->InsertStyleSheetBefore(*aSheet, *firstAuthorSheet);
|
||||
StyleSet()->InsertStyleSheetBefore(StyleOrigin::Author, aSheet,
|
||||
firstAuthorSheet);
|
||||
} else {
|
||||
StyleSet()->AppendStyleSheet(*aSheet);
|
||||
StyleSet()->AppendStyleSheet(StyleOrigin::Author, aSheet);
|
||||
}
|
||||
|
||||
mDocument->ApplicableStylesChanged();
|
||||
}
|
||||
|
||||
void PresShell::RemoveSheet(StyleOrigin aOrigin, StyleSheet* aSheet) {
|
||||
StyleSet()->RemoveStyleSheet(aOrigin, aSheet);
|
||||
mDocument->ApplicableStylesChanged();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresShell::SetDisplaySelection(int16_t aToggle) {
|
||||
RefPtr<nsFrameSelection> frameSelection = mSelection;
|
||||
@ -8871,12 +8877,12 @@ bool PresShell::IsDisplayportSuppressed() {
|
||||
}
|
||||
|
||||
nsresult PresShell::AddOverrideStyleSheet(StyleSheet* aSheet) {
|
||||
StyleSet()->AppendStyleSheet(*aSheet);
|
||||
StyleSet()->AppendStyleSheet(aSheet->GetOrigin(), aSheet);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult PresShell::RemoveOverrideStyleSheet(StyleSheet* aSheet) {
|
||||
StyleSet()->RemoveStyleSheet(*aSheet);
|
||||
StyleSet()->RemoveStyleSheet(aSheet->GetOrigin(), aSheet);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -10920,6 +10926,21 @@ void PresShell::SyncWindowProperties(nsView* aView) {
|
||||
}
|
||||
}
|
||||
|
||||
static StyleOrigin ToOrigin(uint32_t aServiceSheetType) {
|
||||
switch (aServiceSheetType) {
|
||||
case nsIStyleSheetService::AGENT_SHEET:
|
||||
return StyleOrigin::UserAgent;
|
||||
break;
|
||||
case nsIStyleSheetService::USER_SHEET:
|
||||
return StyleOrigin::User;
|
||||
break;
|
||||
default:
|
||||
MOZ_FALLTHROUGH_ASSERT("unexpected aSheetType value");
|
||||
case nsIStyleSheetService::AUTHOR_SHEET:
|
||||
return StyleOrigin::Author;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult PresShell::HasRuleProcessorUsedByMultipleStyleSets(uint32_t aSheetType,
|
||||
bool* aRetVal) {
|
||||
*aRetVal = false;
|
||||
@ -10946,8 +10967,7 @@ void PresShell::NotifyStyleSheetServiceSheetAdded(StyleSheet* aSheet,
|
||||
|
||||
void PresShell::NotifyStyleSheetServiceSheetRemoved(StyleSheet* aSheet,
|
||||
uint32_t aSheetType) {
|
||||
StyleSet()->RemoveStyleSheet(*aSheet);
|
||||
mDocument->ApplicableStylesChanged();
|
||||
RemoveSheet(ToOrigin(aSheetType), aSheet);
|
||||
}
|
||||
|
||||
void PresShell::SetIsUnderHiddenEmbedderElement(
|
||||
|
@ -1826,6 +1826,7 @@ class PresShell final : public nsStubDocumentObserver,
|
||||
void AddUserSheet(StyleSheet*);
|
||||
void AddAgentSheet(StyleSheet*);
|
||||
void AddAuthorSheet(StyleSheet*);
|
||||
void RemoveSheet(StyleOrigin, StyleSheet*);
|
||||
void RemovePreferenceStyles();
|
||||
|
||||
/**
|
||||
|
@ -90,9 +90,6 @@ void InspectorUtils::GetAllStyleSheets(GlobalObject& aGlobalObject,
|
||||
for (size_t i = 0; i < aDocument.SheetCount(); i++) {
|
||||
aResult.AppendElement(aDocument.SheetAt(i));
|
||||
}
|
||||
|
||||
// FIXME(emilio, bug 1617948): This doesn't deal with adopted stylesheets, and
|
||||
// it should. It should also handle duplicates correctly when it does.
|
||||
}
|
||||
|
||||
bool InspectorUtils::IsIgnorableWhitespace(CharacterData& aDataNode) {
|
||||
|
@ -134,7 +134,7 @@ void ServoStyleSet::ShellDetachedFromDocument() {
|
||||
// Remove all our stylesheets...
|
||||
for (auto origin : kOrigins) {
|
||||
for (size_t count = SheetCount(origin); count--;) {
|
||||
RemoveStyleSheet(*SheetAt(origin, count));
|
||||
RemoveStyleSheet(origin, SheetAt(origin, count));
|
||||
}
|
||||
}
|
||||
|
||||
@ -563,60 +563,66 @@ already_AddRefed<ComputedStyle> ServoStyleSet::ResolveXULTreePseudoStyle(
|
||||
#endif
|
||||
|
||||
// manage the set of style sheets in the style set
|
||||
void ServoStyleSet::AppendStyleSheet(StyleSheet& aSheet) {
|
||||
MOZ_ASSERT(aSheet.IsApplicable());
|
||||
MOZ_ASSERT(aSheet.RawContents(),
|
||||
void ServoStyleSet::AppendStyleSheet(StyleOrigin aOrigin, StyleSheet* aSheet) {
|
||||
MOZ_ASSERT(aSheet);
|
||||
MOZ_ASSERT(aSheet->IsApplicable());
|
||||
MOZ_ASSERT(aSheet->RawContents(),
|
||||
"Raw sheet should be in place before insertion.");
|
||||
|
||||
aSheet.AddStyleSet(this);
|
||||
aSheet->AddStyleSet(this);
|
||||
|
||||
// Maintain a mirrored list of sheets on the servo side.
|
||||
// Servo will remove aSheet from its original position as part of the call
|
||||
// to Servo_StyleSet_AppendStyleSheet.
|
||||
Servo_StyleSet_AppendStyleSheet(mRawSet.get(), &aSheet);
|
||||
Servo_StyleSet_AppendStyleSheet(mRawSet.get(), aSheet);
|
||||
SetStylistStyleSheetsDirty();
|
||||
|
||||
if (mStyleRuleMap) {
|
||||
mStyleRuleMap->SheetAdded(aSheet);
|
||||
mStyleRuleMap->SheetAdded(*aSheet);
|
||||
}
|
||||
}
|
||||
|
||||
void ServoStyleSet::RemoveStyleSheet(StyleSheet& aSheet) {
|
||||
aSheet.DropStyleSet(this);
|
||||
void ServoStyleSet::RemoveStyleSheet(StyleOrigin aOrigin, StyleSheet* aSheet) {
|
||||
MOZ_ASSERT(aSheet);
|
||||
|
||||
aSheet->DropStyleSet(this);
|
||||
|
||||
// Maintain a mirrored list of sheets on the servo side.
|
||||
Servo_StyleSet_RemoveStyleSheet(mRawSet.get(), &aSheet);
|
||||
Servo_StyleSet_RemoveStyleSheet(mRawSet.get(), aSheet);
|
||||
SetStylistStyleSheetsDirty();
|
||||
|
||||
if (mStyleRuleMap) {
|
||||
mStyleRuleMap->SheetRemoved(aSheet);
|
||||
mStyleRuleMap->SheetRemoved(*aSheet);
|
||||
}
|
||||
}
|
||||
|
||||
void ServoStyleSet::InsertStyleSheetBefore(StyleSheet& aNewSheet,
|
||||
StyleSheet& aReferenceSheet) {
|
||||
MOZ_ASSERT(aNewSheet.IsApplicable());
|
||||
MOZ_ASSERT(aReferenceSheet.IsApplicable());
|
||||
MOZ_ASSERT(&aNewSheet != &aReferenceSheet,
|
||||
"Can't place sheet before itself.");
|
||||
MOZ_ASSERT(aNewSheet.GetOrigin() == aReferenceSheet.GetOrigin(),
|
||||
"Sheets should be in the same origin");
|
||||
MOZ_ASSERT(aNewSheet.RawContents(),
|
||||
void ServoStyleSet::RemoveDocStyleSheet(StyleSheet* aSheet) {
|
||||
RemoveStyleSheet(Origin::Author, aSheet);
|
||||
}
|
||||
|
||||
void ServoStyleSet::InsertStyleSheetBefore(Origin aOrigin,
|
||||
StyleSheet* aNewSheet,
|
||||
StyleSheet* aReferenceSheet) {
|
||||
MOZ_ASSERT(aNewSheet);
|
||||
MOZ_ASSERT(aReferenceSheet);
|
||||
MOZ_ASSERT(aNewSheet->IsApplicable());
|
||||
MOZ_ASSERT(aNewSheet != aReferenceSheet, "Can't place sheet before itself.");
|
||||
MOZ_ASSERT(aNewSheet->RawContents(),
|
||||
"Raw sheet should be in place before insertion.");
|
||||
MOZ_ASSERT(aReferenceSheet.RawContents(),
|
||||
MOZ_ASSERT(aReferenceSheet->RawContents(),
|
||||
"Reference sheet should have a raw sheet.");
|
||||
|
||||
// Servo will remove aNewSheet from its original position as part of the
|
||||
// call to Servo_StyleSet_InsertStyleSheetBefore.
|
||||
aNewSheet.AddStyleSet(this);
|
||||
aNewSheet->AddStyleSet(this);
|
||||
|
||||
// Maintain a mirrored list of sheets on the servo side.
|
||||
Servo_StyleSet_InsertStyleSheetBefore(mRawSet.get(), &aNewSheet,
|
||||
&aReferenceSheet);
|
||||
Servo_StyleSet_InsertStyleSheetBefore(mRawSet.get(), aNewSheet,
|
||||
aReferenceSheet);
|
||||
SetStylistStyleSheetsDirty();
|
||||
|
||||
if (mStyleRuleMap) {
|
||||
mStyleRuleMap->SheetAdded(aNewSheet);
|
||||
mStyleRuleMap->SheetAdded(*aNewSheet);
|
||||
}
|
||||
}
|
||||
|
||||
@ -638,29 +644,31 @@ void ServoStyleSet::AppendAllNonDocumentAuthorSheets(
|
||||
});
|
||||
}
|
||||
|
||||
void ServoStyleSet::AddDocStyleSheet(StyleSheet& aSheet) {
|
||||
MOZ_ASSERT(aSheet.IsApplicable());
|
||||
MOZ_ASSERT(aSheet.RawContents(),
|
||||
void ServoStyleSet::AddDocStyleSheet(StyleSheet* aSheet) {
|
||||
MOZ_ASSERT(aSheet->IsApplicable());
|
||||
MOZ_ASSERT(aSheet->RawContents(),
|
||||
"Raw sheet should be in place by this point.");
|
||||
|
||||
size_t index = mDocument->FindDocStyleSheetInsertionPoint(aSheet);
|
||||
aSheet.AddStyleSet(this);
|
||||
RefPtr<StyleSheet> strong(aSheet);
|
||||
|
||||
size_t index = mDocument->FindDocStyleSheetInsertionPoint(*aSheet);
|
||||
aSheet->AddStyleSet(this);
|
||||
|
||||
if (index < SheetCount(Origin::Author)) {
|
||||
// This case is insert before.
|
||||
StyleSheet* beforeSheet = SheetAt(Origin::Author, index);
|
||||
|
||||
// Maintain a mirrored list of sheets on the servo side.
|
||||
Servo_StyleSet_InsertStyleSheetBefore(mRawSet.get(), &aSheet, beforeSheet);
|
||||
Servo_StyleSet_InsertStyleSheetBefore(mRawSet.get(), aSheet, beforeSheet);
|
||||
SetStylistStyleSheetsDirty();
|
||||
} else {
|
||||
// Maintain a mirrored list of sheets on the servo side.
|
||||
Servo_StyleSet_AppendStyleSheet(mRawSet.get(), &aSheet);
|
||||
Servo_StyleSet_AppendStyleSheet(mRawSet.get(), aSheet);
|
||||
SetStylistStyleSheetsDirty();
|
||||
}
|
||||
|
||||
if (mStyleRuleMap) {
|
||||
mStyleRuleMap->SheetAdded(aSheet);
|
||||
mStyleRuleMap->SheetAdded(*aSheet);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -231,16 +231,19 @@ class ServoStyleSet {
|
||||
ComputedStyle* aParentStyle, const AtomArray& aInputWord);
|
||||
#endif
|
||||
|
||||
// manage the set of style sheets in the style set
|
||||
void AppendStyleSheet(Origin, StyleSheet*);
|
||||
void RemoveStyleSheet(Origin, StyleSheet*);
|
||||
void InsertStyleSheetBefore(Origin, StyleSheet*, StyleSheet* aReferenceSheet);
|
||||
|
||||
size_t SheetCount(Origin) const;
|
||||
StyleSheet* SheetAt(Origin, size_t aIndex) const;
|
||||
|
||||
void AppendAllNonDocumentAuthorSheets(nsTArray<StyleSheet*>& aArray) const;
|
||||
|
||||
// Manage the set of style sheets in the style set
|
||||
void AppendStyleSheet(StyleSheet&);
|
||||
void InsertStyleSheetBefore(StyleSheet&, StyleSheet& aReferenceSheet);
|
||||
void RemoveStyleSheet(StyleSheet&);
|
||||
void AddDocStyleSheet(StyleSheet&);
|
||||
void RemoveDocStyleSheet(StyleSheet* aSheet);
|
||||
|
||||
void AddDocStyleSheet(StyleSheet* aSheet);
|
||||
|
||||
/**
|
||||
* Performs a Servo traversal to compute style for all dirty nodes in the
|
||||
|
@ -394,15 +394,14 @@ class StyleSheet final : public nsICSSLoaderObserver, public nsWrapperCache {
|
||||
bool IsConstructed() const { return !!mConstructorDocument; }
|
||||
|
||||
// Ture if the sheet's constructor document matches the given document
|
||||
bool ConstructorDocumentMatches(dom::Document& aDocument) const {
|
||||
return mConstructorDocument == &aDocument;
|
||||
bool ConstructorDocumentMatches(dom::Document* aDocument) const {
|
||||
return mConstructorDocument == aDocument;
|
||||
}
|
||||
|
||||
// Add a document or shadow root to the list of adopters.
|
||||
// Adopters will be notified when styles are changed.
|
||||
void AddAdopter(dom::DocumentOrShadowRoot& aAdopter) {
|
||||
MOZ_ASSERT(IsConstructed());
|
||||
MOZ_ASSERT(!mAdopters.Contains(&aAdopter));
|
||||
mAdopters.AppendElement(&aAdopter);
|
||||
}
|
||||
|
||||
|
@ -294,9 +294,7 @@ where
|
||||
// Removing sheets makes us tear down the whole cascade and invalidation
|
||||
// data, but only if the sheet has been involved in at least one flush.
|
||||
// Checking whether the sheet has been committed allows us to avoid
|
||||
// rebuilding the world when sites quickly append and remove a
|
||||
// stylesheet.
|
||||
//
|
||||
// rebuilding the world when sites quickly append and remove a stylesheet.
|
||||
// See bug 1434756.
|
||||
if sheet.committed {
|
||||
self.set_data_validity_at_least(DataValidity::FullyInvalid);
|
||||
|
@ -1,2 +0,0 @@
|
||||
[CSSStyleSheet-constructable-disabled-regular-sheet-insertion.html]
|
||||
prefs: [layout.css.constructable-stylesheets.enabled:true]
|
@ -1,2 +0,0 @@
|
||||
[CSSStyleSheet-constructable-duplicate.html]
|
||||
prefs: [layout.css.constructable-stylesheets.enabled:true]
|
@ -1,22 +0,0 @@
|
||||
<!doctype html>
|
||||
<title>Shouldn't crash / assert when inserting a stylesheet after there are disabled constructable sheets</title>
|
||||
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
|
||||
<link rel="help" href="https://wicg.github.io/construct-stylesheets/">
|
||||
<script src = '/resources/testharness.js'></script>
|
||||
<script src = '/resources/testharnessreport.js'></script>
|
||||
<div id="host"></div>
|
||||
<script>
|
||||
test(function() {
|
||||
let sheet = new CSSStyleSheet({ disabled: true });
|
||||
sheet.replaceSync("div { color: red }");
|
||||
|
||||
let root = document.getElementById("host").attachShadow({ mode: "open" });
|
||||
root.adoptedStyleSheets = [sheet];
|
||||
let style = document.createElement("style");
|
||||
root.innerHTML = `
|
||||
<style>div { color: green }</style>
|
||||
<div>Should be green</div>
|
||||
`;
|
||||
assert_equals(getComputedStyle(root.querySelector("div")).color, "rgb(0, 128, 0)", "Should insert the sheet at the right position and not crash");
|
||||
});
|
||||
</script>
|
@ -1,20 +0,0 @@
|
||||
<!doctype html>
|
||||
<title>Cascade order of a stylesheet for duplicate sheets.</title>
|
||||
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
|
||||
<link rel="help" href="https://wicg.github.io/construct-stylesheets/">
|
||||
<script src = '/resources/testharness.js'></script>
|
||||
<script src = '/resources/testharnessreport.js'></script>
|
||||
<div></div>
|
||||
<script>
|
||||
test(function() {
|
||||
let sheets = [];
|
||||
|
||||
for (let i = 0; i < 2; ++i) {
|
||||
sheets.push(new CSSStyleSheet());
|
||||
sheets[i].replaceSync("div { z-index: " + i + " }");
|
||||
}
|
||||
|
||||
document.adoptedStyleSheets = [sheets[1], sheets[0], sheets[1]];
|
||||
assert_equals(getComputedStyle(document.querySelector("div")).zIndex, "1", "duplicate stylesheet should take right position in the cascade");
|
||||
});
|
||||
</script>
|
Loading…
Reference in New Issue
Block a user