|
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/. */ |
|
5 |
|
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" |
|
15 #include "nsIURI.h" |
|
16 #include "nsLayoutCID.h" |
|
17 #include "nsCSSRuleProcessor.h" |
|
18 #include "nsStyleSet.h" |
|
19 #include "mozilla/dom/URL.h" |
|
20 |
|
21 using mozilla::dom::IsChromeURI; |
|
22 |
|
23 nsXBLPrototypeResources::nsXBLPrototypeResources(nsXBLPrototypeBinding* aBinding) |
|
24 { |
|
25 MOZ_COUNT_CTOR(nsXBLPrototypeResources); |
|
26 |
|
27 mLoader = new nsXBLResourceLoader(aBinding, this); |
|
28 } |
|
29 |
|
30 nsXBLPrototypeResources::~nsXBLPrototypeResources() |
|
31 { |
|
32 MOZ_COUNT_DTOR(nsXBLPrototypeResources); |
|
33 if (mLoader) { |
|
34 mLoader->mResources = nullptr; |
|
35 } |
|
36 } |
|
37 |
|
38 void |
|
39 nsXBLPrototypeResources::AddResource(nsIAtom* aResourceType, const nsAString& aSrc) |
|
40 { |
|
41 if (mLoader) |
|
42 mLoader->AddResource(aResourceType, aSrc); |
|
43 } |
|
44 |
|
45 void |
|
46 nsXBLPrototypeResources::LoadResources(bool* aResult) |
|
47 { |
|
48 if (mLoader) |
|
49 mLoader->LoadResources(aResult); |
|
50 else |
|
51 *aResult = true; // All resources loaded. |
|
52 } |
|
53 |
|
54 void |
|
55 nsXBLPrototypeResources::AddResourceListener(nsIContent* aBoundElement) |
|
56 { |
|
57 if (mLoader) |
|
58 mLoader->AddResourceListener(aBoundElement); |
|
59 } |
|
60 |
|
61 nsresult |
|
62 nsXBLPrototypeResources::FlushSkinSheets() |
|
63 { |
|
64 if (mStyleSheetList.Length() == 0) |
|
65 return NS_OK; |
|
66 |
|
67 nsCOMPtr<nsIDocument> doc = |
|
68 mLoader->mBinding->XBLDocumentInfo()->GetDocument(); |
|
69 |
|
70 // If doc is null, we're in the process of tearing things down, so just |
|
71 // return without rebuilding anything. |
|
72 if (!doc) { |
|
73 return NS_OK; |
|
74 } |
|
75 |
|
76 // We have scoped stylesheets. Reload any chrome stylesheets we |
|
77 // encounter. (If they aren't skin sheets, it doesn't matter, since |
|
78 // they'll still be in the chrome cache. |
|
79 mRuleProcessor = nullptr; |
|
80 |
|
81 sheet_array_type oldSheets(mStyleSheetList); |
|
82 mStyleSheetList.Clear(); |
|
83 |
|
84 mozilla::css::Loader* cssLoader = doc->CSSLoader(); |
|
85 |
|
86 for (sheet_array_type::size_type i = 0, count = oldSheets.Length(); |
|
87 i < count; ++i) { |
|
88 nsCSSStyleSheet* oldSheet = oldSheets[i]; |
|
89 |
|
90 nsIURI* uri = oldSheet->GetSheetURI(); |
|
91 |
|
92 nsRefPtr<nsCSSStyleSheet> newSheet; |
|
93 if (IsChromeURI(uri)) { |
|
94 if (NS_FAILED(cssLoader->LoadSheetSync(uri, getter_AddRefs(newSheet)))) |
|
95 continue; |
|
96 } |
|
97 else { |
|
98 newSheet = oldSheet; |
|
99 } |
|
100 |
|
101 mStyleSheetList.AppendElement(newSheet); |
|
102 } |
|
103 mRuleProcessor = new nsCSSRuleProcessor(mStyleSheetList, |
|
104 nsStyleSet::eDocSheet, |
|
105 nullptr); |
|
106 |
|
107 return NS_OK; |
|
108 } |
|
109 |
|
110 nsresult |
|
111 nsXBLPrototypeResources::Write(nsIObjectOutputStream* aStream) |
|
112 { |
|
113 if (mLoader) |
|
114 return mLoader->Write(aStream); |
|
115 return NS_OK; |
|
116 } |
|
117 |
|
118 void |
|
119 nsXBLPrototypeResources::Traverse(nsCycleCollectionTraversalCallback &cb) const |
|
120 { |
|
121 NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "proto mResources mLoader"); |
|
122 cb.NoteXPCOMChild(mLoader); |
|
123 } |
|
124 |
|
125 void |
|
126 nsXBLPrototypeResources::ClearLoader() |
|
127 { |
|
128 mLoader = nullptr; |
|
129 } |