michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "nsIStyleRuleProcessor.h" michael@0: #include "nsIDocument.h" michael@0: #include "nsIContent.h" michael@0: #include "nsIServiceManager.h" michael@0: #include "nsXBLResourceLoader.h" michael@0: #include "nsXBLPrototypeResources.h" michael@0: #include "nsXBLPrototypeBinding.h" michael@0: #include "nsIDocumentObserver.h" michael@0: #include "mozilla/css/Loader.h" michael@0: #include "nsIURI.h" michael@0: #include "nsLayoutCID.h" michael@0: #include "nsCSSRuleProcessor.h" michael@0: #include "nsStyleSet.h" michael@0: #include "mozilla/dom/URL.h" michael@0: michael@0: using mozilla::dom::IsChromeURI; michael@0: michael@0: nsXBLPrototypeResources::nsXBLPrototypeResources(nsXBLPrototypeBinding* aBinding) michael@0: { michael@0: MOZ_COUNT_CTOR(nsXBLPrototypeResources); michael@0: michael@0: mLoader = new nsXBLResourceLoader(aBinding, this); michael@0: } michael@0: michael@0: nsXBLPrototypeResources::~nsXBLPrototypeResources() michael@0: { michael@0: MOZ_COUNT_DTOR(nsXBLPrototypeResources); michael@0: if (mLoader) { michael@0: mLoader->mResources = nullptr; michael@0: } michael@0: } michael@0: michael@0: void michael@0: nsXBLPrototypeResources::AddResource(nsIAtom* aResourceType, const nsAString& aSrc) michael@0: { michael@0: if (mLoader) michael@0: mLoader->AddResource(aResourceType, aSrc); michael@0: } michael@0: michael@0: void michael@0: nsXBLPrototypeResources::LoadResources(bool* aResult) michael@0: { michael@0: if (mLoader) michael@0: mLoader->LoadResources(aResult); michael@0: else michael@0: *aResult = true; // All resources loaded. michael@0: } michael@0: michael@0: void michael@0: nsXBLPrototypeResources::AddResourceListener(nsIContent* aBoundElement) michael@0: { michael@0: if (mLoader) michael@0: mLoader->AddResourceListener(aBoundElement); michael@0: } michael@0: michael@0: nsresult michael@0: nsXBLPrototypeResources::FlushSkinSheets() michael@0: { michael@0: if (mStyleSheetList.Length() == 0) michael@0: return NS_OK; michael@0: michael@0: nsCOMPtr doc = michael@0: mLoader->mBinding->XBLDocumentInfo()->GetDocument(); michael@0: michael@0: // If doc is null, we're in the process of tearing things down, so just michael@0: // return without rebuilding anything. michael@0: if (!doc) { michael@0: return NS_OK; michael@0: } michael@0: michael@0: // We have scoped stylesheets. Reload any chrome stylesheets we michael@0: // encounter. (If they aren't skin sheets, it doesn't matter, since michael@0: // they'll still be in the chrome cache. michael@0: mRuleProcessor = nullptr; michael@0: michael@0: sheet_array_type oldSheets(mStyleSheetList); michael@0: mStyleSheetList.Clear(); michael@0: michael@0: mozilla::css::Loader* cssLoader = doc->CSSLoader(); michael@0: michael@0: for (sheet_array_type::size_type i = 0, count = oldSheets.Length(); michael@0: i < count; ++i) { michael@0: nsCSSStyleSheet* oldSheet = oldSheets[i]; michael@0: michael@0: nsIURI* uri = oldSheet->GetSheetURI(); michael@0: michael@0: nsRefPtr newSheet; michael@0: if (IsChromeURI(uri)) { michael@0: if (NS_FAILED(cssLoader->LoadSheetSync(uri, getter_AddRefs(newSheet)))) michael@0: continue; michael@0: } michael@0: else { michael@0: newSheet = oldSheet; michael@0: } michael@0: michael@0: mStyleSheetList.AppendElement(newSheet); michael@0: } michael@0: mRuleProcessor = new nsCSSRuleProcessor(mStyleSheetList, michael@0: nsStyleSet::eDocSheet, michael@0: nullptr); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult michael@0: nsXBLPrototypeResources::Write(nsIObjectOutputStream* aStream) michael@0: { michael@0: if (mLoader) michael@0: return mLoader->Write(aStream); michael@0: return NS_OK; michael@0: } michael@0: michael@0: void michael@0: nsXBLPrototypeResources::Traverse(nsCycleCollectionTraversalCallback &cb) const michael@0: { michael@0: NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "proto mResources mLoader"); michael@0: cb.NoteXPCOMChild(mLoader); michael@0: } michael@0: michael@0: void michael@0: nsXBLPrototypeResources::ClearLoader() michael@0: { michael@0: mLoader = nullptr; michael@0: }