1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "nsIStyleRuleProcessor.h"
7 #include "nsIDocument.h"
8 #include "nsIContent.h"
9 #include "nsIServiceManager.h"
10 #include "nsXBLResourceLoader.h"
11 #include "nsXBLPrototypeResources.h"
12 #include "nsXBLPrototypeBinding.h"
13 #include "nsIDocumentObserver.h"
14 #include "mozilla/css/Loader.h"
16 #include "nsLayoutCID.h"
17 #include "nsCSSRuleProcessor.h"
18 #include "nsStyleSet.h"
19 #include "mozilla/dom/URL.h"
20 #include "mozilla/DebugOnly.h"
22 using namespace mozilla
;
23 using mozilla::dom::IsChromeURI
;
25 nsXBLPrototypeResources::nsXBLPrototypeResources(nsXBLPrototypeBinding
* aBinding
)
27 MOZ_COUNT_CTOR(nsXBLPrototypeResources
);
29 mLoader
= new nsXBLResourceLoader(aBinding
, this);
32 nsXBLPrototypeResources::~nsXBLPrototypeResources()
34 MOZ_COUNT_DTOR(nsXBLPrototypeResources
);
36 mLoader
->mResources
= nullptr;
41 nsXBLPrototypeResources::AddResource(nsIAtom
* aResourceType
, const nsAString
& aSrc
)
44 mLoader
->AddResource(aResourceType
, aSrc
);
48 nsXBLPrototypeResources::LoadResources(bool* aResult
)
51 mLoader
->LoadResources(aResult
);
53 *aResult
= true; // All resources loaded.
57 nsXBLPrototypeResources::AddResourceListener(nsIContent
* aBoundElement
)
60 mLoader
->AddResourceListener(aBoundElement
);
64 nsXBLPrototypeResources::FlushSkinSheets()
66 if (mStyleSheetList
.Length() == 0)
69 nsCOMPtr
<nsIDocument
> doc
=
70 mLoader
->mBinding
->XBLDocumentInfo()->GetDocument();
72 // If doc is null, we're in the process of tearing things down, so just
73 // return without rebuilding anything.
78 // We have scoped stylesheets. Reload any chrome stylesheets we
79 // encounter. (If they aren't skin sheets, it doesn't matter, since
80 // they'll still be in the chrome cache.
82 nsTArray
<nsRefPtr
<CSSStyleSheet
>> oldSheets
;
84 oldSheets
.SwapElements(mStyleSheetList
);
86 mozilla::css::Loader
* cssLoader
= doc
->CSSLoader();
88 for (size_t i
= 0, count
= oldSheets
.Length(); i
< count
; ++i
) {
89 CSSStyleSheet
* oldSheet
= oldSheets
[i
];
91 nsIURI
* uri
= oldSheet
->GetSheetURI();
93 nsRefPtr
<CSSStyleSheet
> newSheet
;
94 if (IsChromeURI(uri
)) {
95 if (NS_FAILED(cssLoader
->LoadSheetSync(uri
, getter_AddRefs(newSheet
))))
102 mStyleSheetList
.AppendElement(newSheet
);
105 GatherRuleProcessor();
111 nsXBLPrototypeResources::Write(nsIObjectOutputStream
* aStream
)
114 return mLoader
->Write(aStream
);
119 nsXBLPrototypeResources::Traverse(nsCycleCollectionTraversalCallback
&cb
)
121 NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb
, "proto mResources mLoader");
122 cb
.NoteXPCOMChild(mLoader
);
124 CycleCollectionNoteChild(cb
, mRuleProcessor
.get(), "mRuleProcessor");
125 ImplCycleCollectionTraverse(cb
, mStyleSheetList
, "mStyleSheetList");
129 nsXBLPrototypeResources::Unlink()
131 mStyleSheetList
.Clear();
132 mRuleProcessor
= nullptr;
136 nsXBLPrototypeResources::ClearLoader()
142 nsXBLPrototypeResources::GatherRuleProcessor()
144 mRuleProcessor
= new nsCSSRuleProcessor(mStyleSheetList
,
145 nsStyleSet::eDocSheet
,
151 nsXBLPrototypeResources::AppendStyleSheet(CSSStyleSheet
* aSheet
)
153 mStyleSheetList
.AppendElement(aSheet
);
157 nsXBLPrototypeResources::RemoveStyleSheet(CSSStyleSheet
* aSheet
)
159 mStyleSheetList
.RemoveElement(aSheet
);
163 nsXBLPrototypeResources::InsertStyleSheetAt(size_t aIndex
, CSSStyleSheet
* aSheet
)
165 mStyleSheetList
.InsertElementAt(aIndex
, aSheet
);
169 nsXBLPrototypeResources::StyleSheetAt(size_t aIndex
) const
171 return mStyleSheetList
[aIndex
];
175 nsXBLPrototypeResources::SheetCount() const
177 return mStyleSheetList
.Length();
181 nsXBLPrototypeResources::HasStyleSheets() const
183 return !mStyleSheetList
.IsEmpty();
187 nsXBLPrototypeResources::AppendStyleSheetsTo(
188 nsTArray
<CSSStyleSheet
*>& aResult
) const
190 aResult
.AppendElements(mStyleSheetList
);