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