diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /dom/xbl/nsXBLPrototypeResources.cpp | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | uxp-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz |
Add m-esr52 at 52.6.0
Diffstat (limited to 'dom/xbl/nsXBLPrototypeResources.cpp')
-rw-r--r-- | dom/xbl/nsXBLPrototypeResources.cpp | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/dom/xbl/nsXBLPrototypeResources.cpp b/dom/xbl/nsXBLPrototypeResources.cpp new file mode 100644 index 0000000000..a1ec426635 --- /dev/null +++ b/dom/xbl/nsXBLPrototypeResources.cpp @@ -0,0 +1,204 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsIStyleRuleProcessor.h" +#include "nsIDocument.h" +#include "nsIContent.h" +#include "nsIServiceManager.h" +#include "nsXBLResourceLoader.h" +#include "nsXBLPrototypeResources.h" +#include "nsXBLPrototypeBinding.h" +#include "nsIDocumentObserver.h" +#include "mozilla/css/Loader.h" +#include "nsIURI.h" +#include "nsLayoutCID.h" +#include "nsCSSRuleProcessor.h" +#include "nsStyleSet.h" +#include "mozilla/dom/URL.h" +#include "mozilla/DebugOnly.h" +#include "mozilla/StyleSheet.h" +#include "mozilla/StyleSheetInlines.h" + +using namespace mozilla; +using mozilla::dom::IsChromeURI; + +nsXBLPrototypeResources::nsXBLPrototypeResources(nsXBLPrototypeBinding* aBinding) +{ + MOZ_COUNT_CTOR(nsXBLPrototypeResources); + + mLoader = new nsXBLResourceLoader(aBinding, this); +} + +nsXBLPrototypeResources::~nsXBLPrototypeResources() +{ + MOZ_COUNT_DTOR(nsXBLPrototypeResources); + if (mLoader) { + mLoader->mResources = nullptr; + } +} + +void +nsXBLPrototypeResources::AddResource(nsIAtom* aResourceType, const nsAString& aSrc) +{ + if (mLoader) + mLoader->AddResource(aResourceType, aSrc); +} + +void +nsXBLPrototypeResources::LoadResources(bool* aResult) +{ + if (mLoader) + mLoader->LoadResources(aResult); + else + *aResult = true; // All resources loaded. +} + +void +nsXBLPrototypeResources::AddResourceListener(nsIContent* aBoundElement) +{ + if (mLoader) + mLoader->AddResourceListener(aBoundElement); +} + +nsresult +nsXBLPrototypeResources::FlushSkinSheets() +{ + if (mStyleSheetList.Length() == 0) + return NS_OK; + + nsCOMPtr<nsIDocument> doc = + mLoader->mBinding->XBLDocumentInfo()->GetDocument(); + + // If doc is null, we're in the process of tearing things down, so just + // return without rebuilding anything. + if (!doc) { + return NS_OK; + } + + // We have scoped stylesheets. Reload any chrome stylesheets we + // encounter. (If they aren't skin sheets, it doesn't matter, since + // they'll still be in the chrome cache. Skip inline sheets, which + // skin sheets can't be, and which in any case don't have a usable + // URL to reload.) + + nsTArray<RefPtr<StyleSheet>> oldSheets; + + oldSheets.SwapElements(mStyleSheetList); + + mozilla::css::Loader* cssLoader = doc->CSSLoader(); + + for (size_t i = 0, count = oldSheets.Length(); i < count; ++i) { + StyleSheet* oldSheet = oldSheets[i]; + + nsIURI* uri = oldSheet->GetSheetURI(); + + RefPtr<StyleSheet> newSheet; + if (!oldSheet->IsInline() && IsChromeURI(uri)) { + if (NS_FAILED(cssLoader->LoadSheetSync(uri, &newSheet))) + continue; + } + else { + newSheet = oldSheet; + } + + mStyleSheetList.AppendElement(newSheet); + } + + GatherRuleProcessor(); + + return NS_OK; +} + +nsresult +nsXBLPrototypeResources::Write(nsIObjectOutputStream* aStream) +{ + if (mLoader) + return mLoader->Write(aStream); + return NS_OK; +} + +void +nsXBLPrototypeResources::Traverse(nsCycleCollectionTraversalCallback &cb) +{ + NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "proto mResources mLoader"); + cb.NoteXPCOMChild(mLoader); + + CycleCollectionNoteChild(cb, mRuleProcessor.get(), "mRuleProcessor"); + ImplCycleCollectionTraverse(cb, mStyleSheetList, "mStyleSheetList"); +} + +void +nsXBLPrototypeResources::Unlink() +{ + mStyleSheetList.Clear(); + mRuleProcessor = nullptr; +} + +void +nsXBLPrototypeResources::ClearLoader() +{ + mLoader = nullptr; +} + +void +nsXBLPrototypeResources::GatherRuleProcessor() +{ + nsTArray<RefPtr<CSSStyleSheet>> sheets(mStyleSheetList.Length()); + for (StyleSheet* sheet : mStyleSheetList) { + MOZ_ASSERT(sheet->IsGecko(), + "GatherRuleProcessor must only be called for " + "nsXBLPrototypeResources objects with Gecko-flavored style " + "backends"); + sheets.AppendElement(sheet->AsGecko()); + } + mRuleProcessor = new nsCSSRuleProcessor(Move(sheets), + SheetType::Doc, + nullptr, + mRuleProcessor); +} + +void +nsXBLPrototypeResources::AppendStyleSheet(StyleSheet* aSheet) +{ + mStyleSheetList.AppendElement(aSheet); +} + +void +nsXBLPrototypeResources::RemoveStyleSheet(StyleSheet* aSheet) +{ + mStyleSheetList.RemoveElement(aSheet); +} + +void +nsXBLPrototypeResources::InsertStyleSheetAt(size_t aIndex, StyleSheet* aSheet) +{ + mStyleSheetList.InsertElementAt(aIndex, aSheet); +} + +StyleSheet* +nsXBLPrototypeResources::StyleSheetAt(size_t aIndex) const +{ + return mStyleSheetList[aIndex]; +} + +size_t +nsXBLPrototypeResources::SheetCount() const +{ + return mStyleSheetList.Length(); +} + +bool +nsXBLPrototypeResources::HasStyleSheets() const +{ + return !mStyleSheetList.IsEmpty(); +} + +void +nsXBLPrototypeResources::AppendStyleSheetsTo( + nsTArray<StyleSheet*>& aResult) const +{ + aResult.AppendElements(mStyleSheetList); +} |