|
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* vim: set ts=2 sw=2 et tw=78: */ |
|
3 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
4 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
6 |
|
7 #include "nsChromeRegistry.h" |
|
8 #include "nsChromeRegistryChrome.h" |
|
9 #include "nsChromeRegistryContent.h" |
|
10 |
|
11 #include "prprf.h" |
|
12 |
|
13 #include "nsCOMPtr.h" |
|
14 #include "nsError.h" |
|
15 #include "nsEscape.h" |
|
16 #include "nsNetUtil.h" |
|
17 #include "nsString.h" |
|
18 |
|
19 #include "nsCSSStyleSheet.h" |
|
20 #include "nsIConsoleService.h" |
|
21 #include "nsIDocument.h" |
|
22 #include "nsIDOMDocument.h" |
|
23 #include "nsIDOMLocation.h" |
|
24 #include "nsIDOMWindowCollection.h" |
|
25 #include "nsIDOMWindow.h" |
|
26 #include "nsIObserverService.h" |
|
27 #include "nsIPresShell.h" |
|
28 #include "nsIScriptError.h" |
|
29 #include "nsIWindowMediator.h" |
|
30 #include "mozilla/dom/URL.h" |
|
31 |
|
32 nsChromeRegistry* nsChromeRegistry::gChromeRegistry; |
|
33 using mozilla::dom::IsChromeURI; |
|
34 |
|
35 //////////////////////////////////////////////////////////////////////////////// |
|
36 |
|
37 void |
|
38 nsChromeRegistry::LogMessage(const char* aMsg, ...) |
|
39 { |
|
40 nsCOMPtr<nsIConsoleService> console |
|
41 (do_GetService(NS_CONSOLESERVICE_CONTRACTID)); |
|
42 if (!console) |
|
43 return; |
|
44 |
|
45 va_list args; |
|
46 va_start(args, aMsg); |
|
47 char* formatted = PR_vsmprintf(aMsg, args); |
|
48 va_end(args); |
|
49 if (!formatted) |
|
50 return; |
|
51 |
|
52 console->LogStringMessage(NS_ConvertUTF8toUTF16(formatted).get()); |
|
53 PR_smprintf_free(formatted); |
|
54 } |
|
55 |
|
56 void |
|
57 nsChromeRegistry::LogMessageWithContext(nsIURI* aURL, uint32_t aLineNumber, uint32_t flags, |
|
58 const char* aMsg, ...) |
|
59 { |
|
60 nsresult rv; |
|
61 |
|
62 nsCOMPtr<nsIConsoleService> console |
|
63 (do_GetService(NS_CONSOLESERVICE_CONTRACTID)); |
|
64 |
|
65 nsCOMPtr<nsIScriptError> error |
|
66 (do_CreateInstance(NS_SCRIPTERROR_CONTRACTID)); |
|
67 if (!console || !error) |
|
68 return; |
|
69 |
|
70 va_list args; |
|
71 va_start(args, aMsg); |
|
72 char* formatted = PR_vsmprintf(aMsg, args); |
|
73 va_end(args); |
|
74 if (!formatted) |
|
75 return; |
|
76 |
|
77 nsCString spec; |
|
78 if (aURL) |
|
79 aURL->GetSpec(spec); |
|
80 |
|
81 rv = error->Init(NS_ConvertUTF8toUTF16(formatted), |
|
82 NS_ConvertUTF8toUTF16(spec), |
|
83 EmptyString(), |
|
84 aLineNumber, 0, flags, "chrome registration"); |
|
85 PR_smprintf_free(formatted); |
|
86 |
|
87 if (NS_FAILED(rv)) |
|
88 return; |
|
89 |
|
90 console->LogMessage(error); |
|
91 } |
|
92 |
|
93 nsChromeRegistry::~nsChromeRegistry() |
|
94 { |
|
95 gChromeRegistry = nullptr; |
|
96 } |
|
97 |
|
98 NS_INTERFACE_MAP_BEGIN(nsChromeRegistry) |
|
99 NS_INTERFACE_MAP_ENTRY(nsIChromeRegistry) |
|
100 NS_INTERFACE_MAP_ENTRY(nsIXULChromeRegistry) |
|
101 NS_INTERFACE_MAP_ENTRY(nsIToolkitChromeRegistry) |
|
102 #ifdef MOZ_XUL |
|
103 NS_INTERFACE_MAP_ENTRY(nsIXULOverlayProvider) |
|
104 #endif |
|
105 NS_INTERFACE_MAP_ENTRY(nsIObserver) |
|
106 NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) |
|
107 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIChromeRegistry) |
|
108 NS_INTERFACE_MAP_END |
|
109 |
|
110 NS_IMPL_ADDREF(nsChromeRegistry) |
|
111 NS_IMPL_RELEASE(nsChromeRegistry) |
|
112 |
|
113 //////////////////////////////////////////////////////////////////////////////// |
|
114 // nsIChromeRegistry methods: |
|
115 |
|
116 already_AddRefed<nsIChromeRegistry> |
|
117 nsChromeRegistry::GetService() |
|
118 { |
|
119 if (!gChromeRegistry) |
|
120 { |
|
121 // We don't actually want this ref, we just want the service to |
|
122 // initialize if it hasn't already. |
|
123 nsCOMPtr<nsIChromeRegistry> reg( |
|
124 do_GetService(NS_CHROMEREGISTRY_CONTRACTID)); |
|
125 if (!gChromeRegistry) |
|
126 return nullptr; |
|
127 } |
|
128 nsCOMPtr<nsIChromeRegistry> registry = gChromeRegistry; |
|
129 return registry.forget(); |
|
130 } |
|
131 |
|
132 nsresult |
|
133 nsChromeRegistry::Init() |
|
134 { |
|
135 // This initialization process is fairly complicated and may cause reentrant |
|
136 // getservice calls to resolve chrome URIs (especially locale files). We |
|
137 // don't want that, so we inform the protocol handler about our existence |
|
138 // before we are actually fully initialized. |
|
139 gChromeRegistry = this; |
|
140 |
|
141 mInitialized = true; |
|
142 |
|
143 return NS_OK; |
|
144 } |
|
145 |
|
146 nsresult |
|
147 nsChromeRegistry::GetProviderAndPath(nsIURL* aChromeURL, |
|
148 nsACString& aProvider, nsACString& aPath) |
|
149 { |
|
150 nsresult rv; |
|
151 |
|
152 #ifdef DEBUG |
|
153 bool isChrome; |
|
154 aChromeURL->SchemeIs("chrome", &isChrome); |
|
155 NS_ASSERTION(isChrome, "Non-chrome URI?"); |
|
156 #endif |
|
157 |
|
158 nsAutoCString path; |
|
159 rv = aChromeURL->GetPath(path); |
|
160 NS_ENSURE_SUCCESS(rv, rv); |
|
161 |
|
162 if (path.Length() < 3) { |
|
163 LogMessage("Invalid chrome URI: %s", path.get()); |
|
164 return NS_ERROR_FAILURE; |
|
165 } |
|
166 |
|
167 path.SetLength(nsUnescapeCount(path.BeginWriting())); |
|
168 NS_ASSERTION(path.First() == '/', "Path should always begin with a slash!"); |
|
169 |
|
170 int32_t slash = path.FindChar('/', 1); |
|
171 if (slash == 1) { |
|
172 LogMessage("Invalid chrome URI: %s", path.get()); |
|
173 return NS_ERROR_FAILURE; |
|
174 } |
|
175 |
|
176 if (slash == -1) { |
|
177 aPath.Truncate(); |
|
178 } |
|
179 else { |
|
180 if (slash == (int32_t) path.Length() - 1) |
|
181 aPath.Truncate(); |
|
182 else |
|
183 aPath.Assign(path.get() + slash + 1, path.Length() - slash - 1); |
|
184 |
|
185 --slash; |
|
186 } |
|
187 |
|
188 aProvider.Assign(path.get() + 1, slash); |
|
189 return NS_OK; |
|
190 } |
|
191 |
|
192 |
|
193 nsresult |
|
194 nsChromeRegistry::Canonify(nsIURL* aChromeURL) |
|
195 { |
|
196 NS_NAMED_LITERAL_CSTRING(kSlash, "/"); |
|
197 |
|
198 nsresult rv; |
|
199 |
|
200 nsAutoCString provider, path; |
|
201 rv = GetProviderAndPath(aChromeURL, provider, path); |
|
202 NS_ENSURE_SUCCESS(rv, rv); |
|
203 |
|
204 if (path.IsEmpty()) { |
|
205 nsAutoCString package; |
|
206 rv = aChromeURL->GetHost(package); |
|
207 NS_ENSURE_SUCCESS(rv, rv); |
|
208 |
|
209 // we re-use the "path" local string to build a new URL path |
|
210 path.Assign(kSlash + provider + kSlash + package); |
|
211 if (provider.EqualsLiteral("content")) { |
|
212 path.AppendLiteral(".xul"); |
|
213 } |
|
214 else if (provider.EqualsLiteral("locale")) { |
|
215 path.AppendLiteral(".dtd"); |
|
216 } |
|
217 else if (provider.EqualsLiteral("skin")) { |
|
218 path.AppendLiteral(".css"); |
|
219 } |
|
220 else { |
|
221 return NS_ERROR_INVALID_ARG; |
|
222 } |
|
223 aChromeURL->SetPath(path); |
|
224 } |
|
225 else { |
|
226 // prevent directory traversals ("..") |
|
227 // path is already unescaped once, but uris can get unescaped twice |
|
228 const char* pos = path.BeginReading(); |
|
229 const char* end = path.EndReading(); |
|
230 while (pos < end) { |
|
231 switch (*pos) { |
|
232 case ':': |
|
233 return NS_ERROR_DOM_BAD_URI; |
|
234 case '.': |
|
235 if (pos[1] == '.') |
|
236 return NS_ERROR_DOM_BAD_URI; |
|
237 break; |
|
238 case '%': |
|
239 // chrome: URIs with double-escapes are trying to trick us. |
|
240 // watch for %2e, and %25 in case someone triple unescapes |
|
241 if (pos[1] == '2' && |
|
242 ( pos[2] == 'e' || pos[2] == 'E' || |
|
243 pos[2] == '5' )) |
|
244 return NS_ERROR_DOM_BAD_URI; |
|
245 break; |
|
246 case '?': |
|
247 case '#': |
|
248 pos = end; |
|
249 continue; |
|
250 } |
|
251 ++pos; |
|
252 } |
|
253 } |
|
254 |
|
255 return NS_OK; |
|
256 } |
|
257 |
|
258 NS_IMETHODIMP |
|
259 nsChromeRegistry::ConvertChromeURL(nsIURI* aChromeURI, nsIURI* *aResult) |
|
260 { |
|
261 nsresult rv; |
|
262 NS_ASSERTION(aChromeURI, "null url!"); |
|
263 |
|
264 if (mOverrideTable.Get(aChromeURI, aResult)) |
|
265 return NS_OK; |
|
266 |
|
267 nsCOMPtr<nsIURL> chromeURL (do_QueryInterface(aChromeURI)); |
|
268 NS_ENSURE_TRUE(chromeURL, NS_NOINTERFACE); |
|
269 |
|
270 nsAutoCString package, provider, path; |
|
271 rv = chromeURL->GetHostPort(package); |
|
272 NS_ENSURE_SUCCESS(rv, rv); |
|
273 |
|
274 rv = GetProviderAndPath(chromeURL, provider, path); |
|
275 NS_ENSURE_SUCCESS(rv, rv); |
|
276 |
|
277 nsIURI* baseURI = GetBaseURIFromPackage(package, provider, path); |
|
278 |
|
279 uint32_t flags; |
|
280 rv = GetFlagsFromPackage(package, &flags); |
|
281 if (NS_FAILED(rv)) |
|
282 return rv; |
|
283 |
|
284 if (flags & PLATFORM_PACKAGE) { |
|
285 #if defined(XP_WIN) |
|
286 path.Insert("win/", 0); |
|
287 #elif defined(XP_MACOSX) |
|
288 path.Insert("mac/", 0); |
|
289 #else |
|
290 path.Insert("unix/", 0); |
|
291 #endif |
|
292 } |
|
293 |
|
294 if (!baseURI) { |
|
295 LogMessage("No chrome package registered for chrome://%s/%s/%s", |
|
296 package.get(), provider.get(), path.get()); |
|
297 return NS_ERROR_FAILURE; |
|
298 } |
|
299 |
|
300 return NS_NewURI(aResult, path, nullptr, baseURI); |
|
301 } |
|
302 |
|
303 //////////////////////////////////////////////////////////////////////// |
|
304 |
|
305 // theme stuff |
|
306 |
|
307 |
|
308 static void FlushSkinBindingsForWindow(nsIDOMWindow* aWindow) |
|
309 { |
|
310 // Get the DOM document. |
|
311 nsCOMPtr<nsIDOMDocument> domDocument; |
|
312 aWindow->GetDocument(getter_AddRefs(domDocument)); |
|
313 if (!domDocument) |
|
314 return; |
|
315 |
|
316 nsCOMPtr<nsIDocument> document = do_QueryInterface(domDocument); |
|
317 if (!document) |
|
318 return; |
|
319 |
|
320 // Annihilate all XBL bindings. |
|
321 document->FlushSkinBindings(); |
|
322 } |
|
323 |
|
324 // XXXbsmedberg: move this to nsIWindowMediator |
|
325 NS_IMETHODIMP nsChromeRegistry::RefreshSkins() |
|
326 { |
|
327 nsCOMPtr<nsIWindowMediator> windowMediator |
|
328 (do_GetService(NS_WINDOWMEDIATOR_CONTRACTID)); |
|
329 if (!windowMediator) |
|
330 return NS_OK; |
|
331 |
|
332 nsCOMPtr<nsISimpleEnumerator> windowEnumerator; |
|
333 windowMediator->GetEnumerator(nullptr, getter_AddRefs(windowEnumerator)); |
|
334 bool more; |
|
335 windowEnumerator->HasMoreElements(&more); |
|
336 while (more) { |
|
337 nsCOMPtr<nsISupports> protoWindow; |
|
338 windowEnumerator->GetNext(getter_AddRefs(protoWindow)); |
|
339 if (protoWindow) { |
|
340 nsCOMPtr<nsIDOMWindow> domWindow = do_QueryInterface(protoWindow); |
|
341 if (domWindow) |
|
342 FlushSkinBindingsForWindow(domWindow); |
|
343 } |
|
344 windowEnumerator->HasMoreElements(&more); |
|
345 } |
|
346 |
|
347 FlushSkinCaches(); |
|
348 |
|
349 windowMediator->GetEnumerator(nullptr, getter_AddRefs(windowEnumerator)); |
|
350 windowEnumerator->HasMoreElements(&more); |
|
351 while (more) { |
|
352 nsCOMPtr<nsISupports> protoWindow; |
|
353 windowEnumerator->GetNext(getter_AddRefs(protoWindow)); |
|
354 if (protoWindow) { |
|
355 nsCOMPtr<nsIDOMWindow> domWindow = do_QueryInterface(protoWindow); |
|
356 if (domWindow) |
|
357 RefreshWindow(domWindow); |
|
358 } |
|
359 windowEnumerator->HasMoreElements(&more); |
|
360 } |
|
361 |
|
362 return NS_OK; |
|
363 } |
|
364 |
|
365 void |
|
366 nsChromeRegistry::FlushSkinCaches() |
|
367 { |
|
368 nsCOMPtr<nsIObserverService> obsSvc = |
|
369 mozilla::services::GetObserverService(); |
|
370 NS_ASSERTION(obsSvc, "Couldn't get observer service."); |
|
371 |
|
372 obsSvc->NotifyObservers(static_cast<nsIChromeRegistry*>(this), |
|
373 NS_CHROME_FLUSH_SKINS_TOPIC, nullptr); |
|
374 } |
|
375 |
|
376 // XXXbsmedberg: move this to windowmediator |
|
377 nsresult nsChromeRegistry::RefreshWindow(nsIDOMWindow* aWindow) |
|
378 { |
|
379 // Deal with our subframes first. |
|
380 nsCOMPtr<nsIDOMWindowCollection> frames; |
|
381 aWindow->GetFrames(getter_AddRefs(frames)); |
|
382 uint32_t length; |
|
383 frames->GetLength(&length); |
|
384 uint32_t j; |
|
385 for (j = 0; j < length; j++) { |
|
386 nsCOMPtr<nsIDOMWindow> childWin; |
|
387 frames->Item(j, getter_AddRefs(childWin)); |
|
388 RefreshWindow(childWin); |
|
389 } |
|
390 |
|
391 nsresult rv; |
|
392 // Get the DOM document. |
|
393 nsCOMPtr<nsIDOMDocument> domDocument; |
|
394 aWindow->GetDocument(getter_AddRefs(domDocument)); |
|
395 if (!domDocument) |
|
396 return NS_OK; |
|
397 |
|
398 nsCOMPtr<nsIDocument> document = do_QueryInterface(domDocument); |
|
399 if (!document) |
|
400 return NS_OK; |
|
401 |
|
402 // Deal with the agent sheets first. Have to do all the style sets by hand. |
|
403 nsCOMPtr<nsIPresShell> shell = document->GetShell(); |
|
404 if (shell) { |
|
405 // Reload only the chrome URL agent style sheets. |
|
406 nsCOMArray<nsIStyleSheet> agentSheets; |
|
407 rv = shell->GetAgentStyleSheets(agentSheets); |
|
408 NS_ENSURE_SUCCESS(rv, rv); |
|
409 |
|
410 nsCOMArray<nsIStyleSheet> newAgentSheets; |
|
411 for (int32_t l = 0; l < agentSheets.Count(); ++l) { |
|
412 nsIStyleSheet *sheet = agentSheets[l]; |
|
413 |
|
414 nsIURI* uri = sheet->GetSheetURI(); |
|
415 |
|
416 if (IsChromeURI(uri)) { |
|
417 // Reload the sheet. |
|
418 nsRefPtr<nsCSSStyleSheet> newSheet; |
|
419 rv = document->LoadChromeSheetSync(uri, true, |
|
420 getter_AddRefs(newSheet)); |
|
421 if (NS_FAILED(rv)) return rv; |
|
422 if (newSheet) { |
|
423 rv = newAgentSheets.AppendObject(newSheet) ? NS_OK : NS_ERROR_FAILURE; |
|
424 if (NS_FAILED(rv)) return rv; |
|
425 } |
|
426 } |
|
427 else { // Just use the same sheet. |
|
428 rv = newAgentSheets.AppendObject(sheet) ? NS_OK : NS_ERROR_FAILURE; |
|
429 if (NS_FAILED(rv)) return rv; |
|
430 } |
|
431 } |
|
432 |
|
433 rv = shell->SetAgentStyleSheets(newAgentSheets); |
|
434 NS_ENSURE_SUCCESS(rv, rv); |
|
435 } |
|
436 |
|
437 // Build an array of nsIURIs of style sheets we need to load. |
|
438 nsCOMArray<nsIStyleSheet> oldSheets; |
|
439 nsCOMArray<nsIStyleSheet> newSheets; |
|
440 |
|
441 int32_t count = document->GetNumberOfStyleSheets(); |
|
442 |
|
443 // Iterate over the style sheets. |
|
444 int32_t i; |
|
445 for (i = 0; i < count; i++) { |
|
446 // Get the style sheet |
|
447 nsIStyleSheet *styleSheet = document->GetStyleSheetAt(i); |
|
448 |
|
449 if (!oldSheets.AppendObject(styleSheet)) { |
|
450 return NS_ERROR_OUT_OF_MEMORY; |
|
451 } |
|
452 } |
|
453 |
|
454 // Iterate over our old sheets and kick off a sync load of the new |
|
455 // sheet if and only if it's a chrome URL. |
|
456 for (i = 0; i < count; i++) { |
|
457 nsRefPtr<nsCSSStyleSheet> sheet = do_QueryObject(oldSheets[i]); |
|
458 nsIURI* uri = sheet ? sheet->GetOriginalURI() : nullptr; |
|
459 |
|
460 if (uri && IsChromeURI(uri)) { |
|
461 // Reload the sheet. |
|
462 nsRefPtr<nsCSSStyleSheet> newSheet; |
|
463 // XXX what about chrome sheets that have a title or are disabled? This |
|
464 // only works by sheer dumb luck. |
|
465 document->LoadChromeSheetSync(uri, false, getter_AddRefs(newSheet)); |
|
466 // Even if it's null, we put in in there. |
|
467 newSheets.AppendObject(newSheet); |
|
468 } |
|
469 else { |
|
470 // Just use the same sheet. |
|
471 newSheets.AppendObject(sheet); |
|
472 } |
|
473 } |
|
474 |
|
475 // Now notify the document that multiple sheets have been added and removed. |
|
476 document->UpdateStyleSheets(oldSheets, newSheets); |
|
477 return NS_OK; |
|
478 } |
|
479 |
|
480 void |
|
481 nsChromeRegistry::FlushAllCaches() |
|
482 { |
|
483 nsCOMPtr<nsIObserverService> obsSvc = |
|
484 mozilla::services::GetObserverService(); |
|
485 NS_ASSERTION(obsSvc, "Couldn't get observer service."); |
|
486 |
|
487 obsSvc->NotifyObservers((nsIChromeRegistry*) this, |
|
488 NS_CHROME_FLUSH_TOPIC, nullptr); |
|
489 } |
|
490 |
|
491 // xxxbsmedberg Move me to nsIWindowMediator |
|
492 NS_IMETHODIMP |
|
493 nsChromeRegistry::ReloadChrome() |
|
494 { |
|
495 UpdateSelectedLocale(); |
|
496 FlushAllCaches(); |
|
497 // Do a reload of all top level windows. |
|
498 nsresult rv = NS_OK; |
|
499 |
|
500 // Get the window mediator |
|
501 nsCOMPtr<nsIWindowMediator> windowMediator |
|
502 (do_GetService(NS_WINDOWMEDIATOR_CONTRACTID)); |
|
503 if (windowMediator) { |
|
504 nsCOMPtr<nsISimpleEnumerator> windowEnumerator; |
|
505 |
|
506 rv = windowMediator->GetEnumerator(nullptr, getter_AddRefs(windowEnumerator)); |
|
507 if (NS_SUCCEEDED(rv)) { |
|
508 // Get each dom window |
|
509 bool more; |
|
510 rv = windowEnumerator->HasMoreElements(&more); |
|
511 if (NS_FAILED(rv)) return rv; |
|
512 while (more) { |
|
513 nsCOMPtr<nsISupports> protoWindow; |
|
514 rv = windowEnumerator->GetNext(getter_AddRefs(protoWindow)); |
|
515 if (NS_SUCCEEDED(rv)) { |
|
516 nsCOMPtr<nsIDOMWindow> domWindow = do_QueryInterface(protoWindow); |
|
517 if (domWindow) { |
|
518 nsCOMPtr<nsIDOMLocation> location; |
|
519 domWindow->GetLocation(getter_AddRefs(location)); |
|
520 if (location) { |
|
521 rv = location->Reload(false); |
|
522 if (NS_FAILED(rv)) return rv; |
|
523 } |
|
524 } |
|
525 } |
|
526 rv = windowEnumerator->HasMoreElements(&more); |
|
527 if (NS_FAILED(rv)) return rv; |
|
528 } |
|
529 } |
|
530 } |
|
531 return rv; |
|
532 } |
|
533 |
|
534 NS_IMETHODIMP |
|
535 nsChromeRegistry::AllowScriptsForPackage(nsIURI* aChromeURI, bool *aResult) |
|
536 { |
|
537 nsresult rv; |
|
538 *aResult = false; |
|
539 |
|
540 #ifdef DEBUG |
|
541 bool isChrome; |
|
542 aChromeURI->SchemeIs("chrome", &isChrome); |
|
543 NS_ASSERTION(isChrome, "Non-chrome URI passed to AllowScriptsForPackage!"); |
|
544 #endif |
|
545 |
|
546 nsCOMPtr<nsIURL> url (do_QueryInterface(aChromeURI)); |
|
547 NS_ENSURE_TRUE(url, NS_NOINTERFACE); |
|
548 |
|
549 nsAutoCString provider, file; |
|
550 rv = GetProviderAndPath(url, provider, file); |
|
551 NS_ENSURE_SUCCESS(rv, rv); |
|
552 |
|
553 if (!provider.EqualsLiteral("skin")) |
|
554 *aResult = true; |
|
555 |
|
556 return NS_OK; |
|
557 } |
|
558 |
|
559 NS_IMETHODIMP |
|
560 nsChromeRegistry::AllowContentToAccess(nsIURI *aURI, bool *aResult) |
|
561 { |
|
562 nsresult rv; |
|
563 |
|
564 *aResult = false; |
|
565 |
|
566 #ifdef DEBUG |
|
567 bool isChrome; |
|
568 aURI->SchemeIs("chrome", &isChrome); |
|
569 NS_ASSERTION(isChrome, "Non-chrome URI passed to AllowContentToAccess!"); |
|
570 #endif |
|
571 |
|
572 nsCOMPtr<nsIURL> url = do_QueryInterface(aURI); |
|
573 if (!url) { |
|
574 NS_ERROR("Chrome URL doesn't implement nsIURL."); |
|
575 return NS_ERROR_UNEXPECTED; |
|
576 } |
|
577 |
|
578 nsAutoCString package; |
|
579 rv = url->GetHostPort(package); |
|
580 NS_ENSURE_SUCCESS(rv, rv); |
|
581 |
|
582 uint32_t flags; |
|
583 rv = GetFlagsFromPackage(package, &flags); |
|
584 |
|
585 if (NS_SUCCEEDED(rv)) { |
|
586 *aResult = !!(flags & CONTENT_ACCESSIBLE); |
|
587 } |
|
588 return NS_OK; |
|
589 } |
|
590 |
|
591 NS_IMETHODIMP_(bool) |
|
592 nsChromeRegistry::WrappersEnabled(nsIURI *aURI) |
|
593 { |
|
594 nsCOMPtr<nsIURL> chromeURL (do_QueryInterface(aURI)); |
|
595 if (!chromeURL) |
|
596 return false; |
|
597 |
|
598 bool isChrome = false; |
|
599 nsresult rv = chromeURL->SchemeIs("chrome", &isChrome); |
|
600 if (NS_FAILED(rv) || !isChrome) |
|
601 return false; |
|
602 |
|
603 nsAutoCString package; |
|
604 rv = chromeURL->GetHostPort(package); |
|
605 if (NS_FAILED(rv)) |
|
606 return false; |
|
607 |
|
608 uint32_t flags; |
|
609 rv = GetFlagsFromPackage(package, &flags); |
|
610 return NS_SUCCEEDED(rv) && (flags & XPCNATIVEWRAPPERS); |
|
611 } |
|
612 |
|
613 already_AddRefed<nsChromeRegistry> |
|
614 nsChromeRegistry::GetSingleton() |
|
615 { |
|
616 if (gChromeRegistry) { |
|
617 nsRefPtr<nsChromeRegistry> registry = gChromeRegistry; |
|
618 return registry.forget(); |
|
619 } |
|
620 |
|
621 nsRefPtr<nsChromeRegistry> cr; |
|
622 if (GeckoProcessType_Content == XRE_GetProcessType()) |
|
623 cr = new nsChromeRegistryContent(); |
|
624 else |
|
625 cr = new nsChromeRegistryChrome(); |
|
626 |
|
627 if (NS_FAILED(cr->Init())) |
|
628 return nullptr; |
|
629 |
|
630 return cr.forget(); |
|
631 } |