Fix theme switching bugs related to insufficient change handling when entry points to themes are stylesheet links (processing instructions or XBL stylesheet elements) or xul:image src attributes by giving the chrome: protocol its own URL implementation that remembers the URL to which the chrome: URL was resolved and uses that resolved URL as part of equality testing. Fix various fastload issues arising from this change. b=252703 r=darin sr=bzbarsky

This commit is contained in:
dbaron%dbaron.org 2004-12-01 22:39:17 +00:00
Родитель 670fb87360
Коммит 21dccaeace
30 изменённых файлов: 1377 добавлений и 290 удалений

Просмотреть файл

@ -79,6 +79,7 @@ CPPSRCS = \
nsChromeRegistry.cpp \
nsChromeUIDataSource.cpp \
nsChromeProtocolHandler.cpp \
nsChromeURL.cpp \
$(NULL)
EXTRA_DSO_LDOPTS = \

Просмотреть файл

@ -46,8 +46,10 @@
#include "rdf.h"
#include "nsChromeProtocolHandler.h"
#include "nsChromeRegistry.h"
#include "nsChromeURL.h"
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsChromeRegistry, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsChromeURL)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsChromeProtocolHandler)
// The list of components we register
@ -63,6 +65,12 @@ static const nsModuleComponentInfo components[] =
NS_CHROMEPROTOCOLHANDLER_CID,
NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "chrome",
nsChromeProtocolHandlerConstructor
},
{ "Chrome URL", // needed only for fastload
NS_CHROMEURL_CID,
nsnull,
nsChromeURLConstructor
}
};

Просмотреть файл

@ -44,11 +44,13 @@
#include "nsChromeProtocolHandler.h"
#include "nsCOMPtr.h"
#include "nsAutoPtr.h"
#include "nsContentCID.h"
#include "nsCRT.h"
#include "nsEventQueueUtils.h"
#include "nsIChannel.h"
#include "nsIChromeRegistry.h"
#include "nsChromeURL.h"
#include "nsIComponentManager.h"
#include "nsIEventQueue.h"
#include "nsIEventQueueService.h"
@ -63,7 +65,6 @@
#include "nsIObjectOutputStream.h"
#include "nsIScriptSecurityManager.h"
#include "nsIServiceManager.h"
#include "nsIStandardURL.h"
#include "nsIStreamListener.h"
#ifdef MOZ_XUL
#include "nsIXULPrototypeCache.h"
@ -465,49 +466,17 @@ nsChromeProtocolHandler::NewURI(const nsACString &aSpec,
nsIURI **result)
{
NS_PRECONDITION(result, "Null out param");
nsresult rv;
*result = nsnull;
// Chrome: URLs (currently) have no additional structure beyond that provided
// by standard URLs, so there is no "outer" given to CreateInstance
nsRefPtr<nsChromeURL> url = new nsChromeURL();
if (!url)
return NS_ERROR_OUT_OF_MEMORY;
nsCOMPtr<nsIStandardURL> url(do_CreateInstance(NS_STANDARDURL_CONTRACTID, &rv));
nsresult rv = url->Init(aSpec, aCharset, aBaseURI);
if (NS_FAILED(rv))
return rv;
rv = url->Init(nsIStandardURL::URLTYPE_STANDARD, -1, aSpec, aCharset, aBaseURI);
if (NS_FAILED(rv))
return rv;
nsCOMPtr<nsIURI> uri(do_QueryInterface(url, &rv));
if (NS_FAILED(rv))
return rv;
// Canonify the "chrome:" URL; e.g., so that we collapse
// "chrome://navigator/content/" and "chrome://navigator/content"
// and "chrome://navigator/content/navigator.xul".
// Try the global cache first.
nsCOMPtr<nsIChromeRegistry> reg = gChromeRegistry;
// If that fails, the service has not been instantiated yet; let's
// do that now.
if (!reg) {
reg = do_GetService(NS_CHROMEREGISTRY_CONTRACTID, &rv);
if (NS_FAILED(rv))
return rv;
}
NS_ASSERTION(reg, "Must have a chrome registry by now");
rv = reg->Canonify(uri);
if (NS_FAILED(rv))
return rv;
*result = uri;
NS_ADDREF(*result);
NS_ADDREF(*result = url);
return NS_OK;
}
@ -517,29 +486,11 @@ nsChromeProtocolHandler::NewChannel(nsIURI* aURI,
{
NS_ENSURE_ARG_POINTER(aURI);
NS_PRECONDITION(aResult, "Null out param");
#ifdef DEBUG
// Check that the uri we got is already canonified
nsresult debug_rv;
nsCOMPtr<nsIChromeRegistry> debugReg(do_GetService(NS_CHROMEREGISTRY_CONTRACTID, &debug_rv));
if (NS_SUCCEEDED(debug_rv)) {
nsCOMPtr<nsIURI> debugClone;
debug_rv = aURI->Clone(getter_AddRefs(debugClone));
if (NS_SUCCEEDED(debug_rv)) {
debug_rv = debugReg->Canonify(debugClone);
if (NS_SUCCEEDED(debug_rv)) {
PRBool same;
debug_rv = aURI->Equals(debugClone, &same);
if (NS_SUCCEEDED(debug_rv)) {
NS_ASSERTION(same, "Non-canonified chrome uri passed to nsChromeProtocolHandler::NewChannel!");
}
}
}
}
#endif
nsresult rv;
nsCOMPtr<nsIChromeURL> chromeURL = do_QueryInterface(aURI, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIChannel> result;
#ifdef MOZ_XUL
@ -578,36 +529,14 @@ nsChromeProtocolHandler::NewChannel(nsIURI* aURI,
else
#endif
{
// Miss. Resolve the chrome URL using the registry and do a
// normal necko load.
//nsXPIDLCString oldSpec;
//aURI->GetSpec(getter_Copies(oldSpec));
//printf("*************************** %s\n", (const char*)oldSpec);
nsCOMPtr<nsIChromeRegistry> reg = gChromeRegistry;
if (!reg) {
reg = do_GetService(NS_CHROMEREGISTRY_CONTRACTID, &rv);
if (NS_FAILED(rv)) return rv;
}
nsCAutoString spec;
rv = reg->ConvertChromeURL(aURI, spec);
if (NS_FAILED(rv)) {
#ifdef DEBUG
aURI->GetSpec(spec);
printf("Couldn't convert chrome URL: %s\n", spec.get());
#endif
return rv;
}
// Miss. Get the converted URL and do a normal necko load.
nsCOMPtr<nsIURI> convertedURI;
chromeURL->GetConvertedURI(getter_AddRefs(convertedURI));
nsCOMPtr<nsIIOService> ioServ(do_GetIOService(&rv));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIURI> chromeURI;
rv = ioServ->NewURI(spec, nsnull, nsnull, getter_AddRefs(chromeURI));
if (NS_FAILED(rv)) return rv;
rv = ioServ->NewChannelFromURI(chromeURI, getter_AddRefs(result));
rv = ioServ->NewChannelFromURI(convertedURI, getter_AddRefs(result));
if (NS_FAILED(rv)) return rv;
// XXX Will be removed someday when we handle remote chrome.

Просмотреть файл

@ -96,6 +96,7 @@
#include "nsNetCID.h"
#include "nsIJARURI.h"
#include "nsIFileURL.h"
#include "nsIChromeURL.h"
#include "nsILocaleService.h"
#include "nsICmdLineService.h"
#include "nsILookAndFeel.h"
@ -1260,14 +1261,6 @@ nsChromeRegistry::FlushSkinCaches()
NS_CHROME_FLUSH_SKINS_TOPIC, nsnull);
}
static PRBool IsChromeURI(nsIURI* aURI)
{
PRBool isChrome=PR_FALSE;
if (NS_SUCCEEDED(aURI->SchemeIs("chrome", &isChrome)) && isChrome)
return PR_TRUE;
return PR_FALSE;
}
// XXXbsmedberg: move this to windowmediator
nsresult nsChromeRegistry::RefreshWindow(nsIDOMWindowInternal* aWindow)
{
@ -1295,6 +1288,8 @@ nsresult nsChromeRegistry::RefreshWindow(nsIDOMWindowInternal* aWindow)
if (!document)
return NS_OK;
mozAutoDocUpdate update(document, UPDATE_STYLE, PR_TRUE);
// Deal with the agent sheets first. Have to do all the style sets by hand.
PRUint32 shellCount = document->GetNumberOfShells();
for (PRUint32 k = 0; k < shellCount; k++) {
@ -1313,10 +1308,15 @@ nsresult nsChromeRegistry::RefreshWindow(nsIDOMWindowInternal* aWindow)
rv = sheet->GetSheetURI(getter_AddRefs(uri));
if (NS_FAILED(rv)) return rv;
if (IsChromeURI(uri)) {
// Reload the sheet.
nsCOMPtr<nsIChromeURL> chromeURL = do_QueryInterface(uri);
if (chromeURL) {
// Reload the sheet. Recreate the URI since the chrome URL
// caches its resolved form.
nsCOMPtr<nsIChromeURL> newURL;
chromeURL->ReConvert(getter_AddRefs(newURL));
nsCOMPtr<nsICSSStyleSheet> newSheet;
rv = LoadStyleSheetWithURL(uri, getter_AddRefs(newSheet));
rv = LoadStyleSheetWithURL(newURL, getter_AddRefs(newSheet));
if (NS_FAILED(rv)) return rv;
if (newSheet) {
rv = newAgentSheets.AppendObject(newSheet) ? NS_OK : NS_ERROR_FAILURE;
@ -1358,17 +1358,20 @@ nsresult nsChromeRegistry::RefreshWindow(nsIDOMWindowInternal* aWindow)
rv = sheet->GetSheetURI(getter_AddRefs(uri));
if (NS_FAILED(rv)) return rv;
if (IsChromeURI(uri)) {
nsCOMPtr<nsIChromeURL> chromeURL = do_QueryInterface(uri);
if (chromeURL) {
// Reload the sheet.
#ifdef DEBUG
nsCOMPtr<nsICSSStyleSheet> oldCSSSheet = do_QueryInterface(sheet);
NS_ASSERTION(oldCSSSheet, "Don't know how to reload a non-CSS sheet");
#endif
nsCOMPtr<nsIChromeURL> newURL;
chromeURL->ReConvert(getter_AddRefs(newURL));
nsCOMPtr<nsICSSStyleSheet> newSheet;
// XXX what about chrome sheets that have a title or are disabled? This
// only works by sheer dumb luck.
// XXXbz this should really use the document's CSSLoader!
LoadStyleSheetWithURL(uri, getter_AddRefs(newSheet));
LoadStyleSheetWithURL(newURL, getter_AddRefs(newSheet));
// Even if it's null, we put in in there.
newSheets.AppendObject(newSheet);
}

399
chrome/src/nsChromeURL.cpp Normal file
Просмотреть файл

@ -0,0 +1,399 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
// vim:cindent:ts=4:et:sw=4:
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is nsChromeURL.
*
* The Initial Developer of the Original Code is the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2004
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* L. David Baron <dbaron@dbaron.org> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsChromeURL.h"
#include "nsIStandardURL.h"
#include "nsNetUtil.h"
#include "nsIChromeRegistry.h"
#include "nsNetCID.h"
#include "nsMemory.h"
#include "nsComponentManagerUtils.h"
#include "nsString.h"
#include "nsIObjectInputStream.h"
#include "nsIObjectOutputStream.h"
#include "nsAutoPtr.h"
// This comes from nsChromeRegistry.cpp
extern nsIChromeRegistry* gChromeRegistry;
static NS_DEFINE_CID(kChromeURLCID, NS_CHROMEURL_CID);
nsresult
nsChromeURL::Init(const nsACString &aSpec, const char *aCharset,
nsIURI *aBaseURI)
{
nsresult rv;
nsCOMPtr<nsIStandardURL> url =
do_CreateInstance(NS_STANDARDURL_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = url->Init(nsIStandardURL::URLTYPE_STANDARD, -1, aSpec, aCharset,
aBaseURI);
NS_ENSURE_SUCCESS(rv, rv);
mChromeURL = do_QueryInterface(url, &rv);
NS_ENSURE_SUCCESS(rv, rv);
// Canonify the "chrome:" URL; e.g., so that we collapse
// "chrome://navigator/content/" and "chrome://navigator/content"
// and "chrome://navigator/content/navigator.xul".
// Try the global cache first.
if (!gChromeRegistry) {
// The service has not been instantiated yet; let's do that now.
nsCOMPtr<nsIChromeRegistry> reg =
do_GetService(NS_CHROMEREGISTRY_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
NS_ASSERTION(gChromeRegistry, "yikes, gChromeRegistry not set");
}
return gChromeRegistry->Canonify(mChromeURL);
// Construction of |mConvertedURI| must happen lazily since this
// method can be called during nsChromeRegistry::Init, when
// nsChromeRegistry::ConvertChromeURL will fail.
}
// interface nsISupports
NS_IMPL_ADDREF(nsChromeURL)
NS_IMPL_RELEASE(nsChromeURL)
NS_INTERFACE_MAP_BEGIN(nsChromeURL)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStandardURL)
NS_INTERFACE_MAP_ENTRY(nsIURI)
NS_INTERFACE_MAP_ENTRY(nsIURL)
NS_INTERFACE_MAP_ENTRY(nsIChromeURL)
NS_INTERFACE_MAP_ENTRY(nsIStandardURL)
NS_INTERFACE_MAP_ENTRY(nsISerializable)
NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
if (aIID.Equals(nsChromeURL::GetIID())) // NS_CHROMEURL_IMPL_IID
foundInterface = NS_REINTERPRET_CAST(nsISupports*, this);
else
NS_INTERFACE_MAP_END
#define FORWARD_METHOD(method_, params_, args_) \
NS_IMETHODIMP nsChromeURL::method_ params_ \
{ \
return mChromeURL->method_ args_; \
}
// interface nsIURI
FORWARD_METHOD(GetSpec, (nsACString & aSpec), (aSpec))
FORWARD_METHOD(SetSpec, (const nsACString & aSpec), (aSpec))
FORWARD_METHOD(GetPrePath, (nsACString & aPrePath), (aPrePath))
FORWARD_METHOD(GetScheme, (nsACString & aScheme), (aScheme))
FORWARD_METHOD(SetScheme, (const nsACString & aScheme), (aScheme))
FORWARD_METHOD(GetUserPass, (nsACString & aUserPass), (aUserPass))
FORWARD_METHOD(SetUserPass, (const nsACString & aUserPass), (aUserPass))
FORWARD_METHOD(GetUsername, (nsACString & aUsername), (aUsername))
FORWARD_METHOD(SetUsername, (const nsACString & aUsername), (aUsername))
FORWARD_METHOD(GetPassword, (nsACString & aPassword), (aPassword))
FORWARD_METHOD(SetPassword, (const nsACString & aPassword), (aPassword))
FORWARD_METHOD(GetHostPort, (nsACString & aHostPort), (aHostPort))
FORWARD_METHOD(SetHostPort, (const nsACString & aHostPort), (aHostPort))
FORWARD_METHOD(GetHost, (nsACString & aHost), (aHost))
FORWARD_METHOD(SetHost, (const nsACString & aHost), (aHost))
FORWARD_METHOD(GetPort, (PRInt32 *aPort), (aPort))
FORWARD_METHOD(SetPort, (PRInt32 aPort), (aPort))
FORWARD_METHOD(GetPath, (nsACString & aPath), (aPath))
FORWARD_METHOD(SetPath, (const nsACString & aPath), (aPath))
/*
* Overriding Equals is the main point of nsChromeURL's existence. But
* be careful because nsStandardURL equals QIs its |other| argument to
* nsStandardURL, which we don't implement.
*/
NS_IMETHODIMP nsChromeURL::Equals(nsIURI *other, PRBool *_retval)
{
NS_ENSURE_ARG_POINTER(other);
NS_PRECONDITION(_retval, "null out param");
*_retval = PR_FALSE;
nsRefPtr<nsChromeURL> otherChrome;
CallQueryInterface(other,
NS_STATIC_CAST(nsChromeURL**, getter_AddRefs(otherChrome)));
if (!otherChrome) {
return NS_OK; // false
}
PRBool equal;
nsresult rv = mChromeURL->Equals(otherChrome->mChromeURL, &equal);
NS_ENSURE_SUCCESS(rv, rv);
if (!equal) {
return NS_OK; // false
}
if (!mConvertedURI) {
nsCOMPtr<nsIURI> tmp;
rv = GetConvertedURI(getter_AddRefs(tmp));
NS_ENSURE_SUCCESS(rv, rv);
}
if (!otherChrome->mConvertedURI) {
nsCOMPtr<nsIURI> tmp;
rv = otherChrome->GetConvertedURI(getter_AddRefs(tmp));
NS_ENSURE_SUCCESS(rv, rv);
}
return mConvertedURI->Equals(otherChrome->mConvertedURI, _retval);
}
FORWARD_METHOD(SchemeIs, (const char *scheme, PRBool *_retval), (scheme, _retval))
NS_IMETHODIMP nsChromeURL::Clone(nsIURI **_retval)
{
nsIChromeURL *cloneI;
nsresult rv = nsChromeURL::ReConvert(&cloneI);
NS_ENSURE_SUCCESS(rv, rv);
nsChromeURL *clone = NS_STATIC_CAST(nsChromeURL*, cloneI);
if (mConvertedURI)
rv = mConvertedURI->Clone(getter_AddRefs(clone->mConvertedURI));
if (NS_FAILED(rv)) {
NS_RELEASE(clone);
return rv;
}
*_retval = clone;
return NS_OK;
}
FORWARD_METHOD(Resolve, (const nsACString & relativePath, nsACString & _retval), (relativePath, _retval))
FORWARD_METHOD(GetAsciiSpec, (nsACString & aAsciiSpec), (aAsciiSpec))
FORWARD_METHOD(GetAsciiHost, (nsACString & aAsciiHost), (aAsciiHost))
FORWARD_METHOD(GetOriginCharset, (nsACString & aOriginCharset), (aOriginCharset))
// interface nsIURL
FORWARD_METHOD(GetFilePath, (nsACString & aFilePath), (aFilePath))
FORWARD_METHOD(SetFilePath, (const nsACString & aFilePath), (aFilePath))
FORWARD_METHOD(GetParam, (nsACString & aParam), (aParam))
FORWARD_METHOD(SetParam, (const nsACString & aParam), (aParam))
FORWARD_METHOD(GetQuery, (nsACString & aQuery), (aQuery))
FORWARD_METHOD(SetQuery, (const nsACString & aQuery), (aQuery))
FORWARD_METHOD(GetRef, (nsACString & aRef), (aRef))
FORWARD_METHOD(SetRef, (const nsACString & aRef), (aRef))
FORWARD_METHOD(GetDirectory, (nsACString & aDirectory), (aDirectory))
FORWARD_METHOD(SetDirectory, (const nsACString & aDirectory), (aDirectory))
FORWARD_METHOD(GetFileName, (nsACString & aFileName), (aFileName))
FORWARD_METHOD(SetFileName, (const nsACString & aFileName), (aFileName))
FORWARD_METHOD(GetFileBaseName, (nsACString & aFileBaseName), (aFileBaseName))
FORWARD_METHOD(SetFileBaseName, (const nsACString & aFileBaseName), (aFileBaseName))
FORWARD_METHOD(GetFileExtension, (nsACString & aFileExtension), (aFileExtension))
FORWARD_METHOD(SetFileExtension, (const nsACString & aFileExtension), (aFileExtension))
/*
* override because nsStandardURL QIs aURIToCompare to nsStandardURL,
* which we don't implement.
*/
NS_IMETHODIMP nsChromeURL::GetCommonBaseSpec(nsIURI *aURIToCompare, nsACString & _retval)
{
NS_ENSURE_ARG_POINTER(aURIToCompare);
nsChromeURL *otherChromeURL;
nsresult rv;
if (NS_SUCCEEDED(CallQueryInterface(aURIToCompare, &otherChromeURL))) {
rv = mChromeURL->GetCommonBaseSpec(otherChromeURL->mChromeURL, _retval);
NS_RELEASE(otherChromeURL);
} else {
rv = mChromeURL->GetCommonBaseSpec(aURIToCompare, _retval);
}
return rv;
}
/*
* override because nsStandardURL QIs aURIToCompare to nsStandardURL,
* which we don't implement.
*/
NS_IMETHODIMP nsChromeURL::GetRelativeSpec(nsIURI *aURIToCompare, nsACString & _retval)
{
NS_ENSURE_ARG_POINTER(aURIToCompare);
nsChromeURL *otherChromeURL;
nsresult rv;
if (NS_SUCCEEDED(CallQueryInterface(aURIToCompare, &otherChromeURL))) {
rv = mChromeURL->GetRelativeSpec(otherChromeURL->mChromeURL, _retval);
NS_RELEASE(otherChromeURL);
} else {
rv = mChromeURL->GetRelativeSpec(aURIToCompare, _retval);
}
return rv;
}
// interface nsIChromeURL
NS_IMETHODIMP nsChromeURL::GetConvertedURI(nsIURI **aConvertedURI)
{
if (!mConvertedURI) {
NS_ENSURE_TRUE(gChromeRegistry, NS_ERROR_UNEXPECTED);
// From now on, mutation is forbidden, since it wouldn't be
// reflected in mConvertedURI, and the whole point of nsChromeURL
// is to keep track of when mConvertedURI changes.
nsCOMPtr<nsIStandardURL> standardURL = do_QueryInterface(mChromeURL);
standardURL->SetMutable(PR_FALSE);
// Resolve the "chrome:" URL to a URL with a different scheme.
nsCAutoString spec;
nsresult rv = gChromeRegistry->ConvertChromeURL(mChromeURL, spec);
NS_ENSURE_SUCCESS(rv, rv);
rv = NS_NewURI(getter_AddRefs(mConvertedURI), spec);
NS_ENSURE_SUCCESS(rv, rv);
}
NS_ADDREF(*aConvertedURI = mConvertedURI);
return NS_OK;
}
// NOTE: This function is used to implement Clone.
NS_IMETHODIMP nsChromeURL::ReConvert(nsIChromeURL **aResult)
{
*aResult = nsnull;
nsRefPtr<nsChromeURL> result = new nsChromeURL;
if (!result)
return NS_ERROR_OUT_OF_MEMORY;
nsresult rv = mChromeURL->Clone(NS_REINTERPRET_CAST(nsIURI**,
NS_STATIC_CAST(nsIURL**,
getter_AddRefs(result->mChromeURL))));
NS_ASSERTION(nsCOMPtr<nsIURL>(do_QueryInterface(
NS_STATIC_CAST(nsISupports*, result->mChromeURL)))
== result->mChromeURL, "invalid cast");
NS_ENSURE_SUCCESS(rv, rv);
NS_ADDREF(*aResult = result);
return NS_OK;
}
// interface nsIStandardURL
NS_IMETHODIMP nsChromeURL::Init(PRUint32 aUrlType, PRInt32 aDefaultPort, const nsACString & aSpec, const char *aOriginCharset, nsIURI *aBaseURI)
{
NS_NOTREACHED("nsChromeURL::Init");
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP nsChromeURL::GetMutable(PRBool *aMutable)
{
nsCOMPtr<nsIStandardURL> url = do_QueryInterface(mChromeURL);
return url->GetMutable(aMutable);
}
NS_IMETHODIMP nsChromeURL::SetMutable(PRBool aMutable)
{
nsCOMPtr<nsIStandardURL> url = do_QueryInterface(mChromeURL);
return url->SetMutable(aMutable);
}
// interface nsISerializable
NS_IMETHODIMP nsChromeURL::Read(nsIObjectInputStream *aInputStream)
{
nsresult rv =
aInputStream->ReadObject(PR_TRUE, getter_AddRefs(mChromeURL));
NS_ENSURE_SUCCESS(rv, rv);
return NS_ReadOptionalObject(aInputStream, PR_TRUE,
getter_AddRefs(mConvertedURI));
}
NS_IMETHODIMP nsChromeURL::Write(nsIObjectOutputStream *aOutputStream)
{
nsresult rv = aOutputStream->WriteCompoundObject(mChromeURL,
NS_GET_IID(nsIURL),
PR_TRUE);
NS_ENSURE_SUCCESS(rv, rv);
// XXX Should this be optional, or should we resolve before writing?
return NS_WriteOptionalCompoundObject(aOutputStream, mConvertedURI,
NS_GET_IID(nsIURI), PR_TRUE);
}
// interface nsIClassInfo
NS_IMETHODIMP nsChromeURL::GetInterfaces(PRUint32 *count, nsIID * **array)
{
*count = 0;
*array = nsnull;
return NS_OK;
}
NS_IMETHODIMP nsChromeURL::GetHelperForLanguage(PRUint32 language, nsISupports **_retval)
{
*_retval = nsnull;
return NS_OK;
}
NS_IMETHODIMP nsChromeURL::GetContractID(char * *aContractID)
{
*aContractID = nsnull;
return NS_OK;
}
NS_IMETHODIMP nsChromeURL::GetClassDescription(char * *aClassDescription)
{
*aClassDescription = nsnull;
return NS_OK;
}
NS_IMETHODIMP nsChromeURL::GetClassID(nsCID * *aClassID)
{
*aClassID = (nsCID*) nsMemory::Alloc(sizeof(nsCID));
if (!*aClassID)
return NS_ERROR_OUT_OF_MEMORY;
return GetClassIDNoAlloc(*aClassID);
}
NS_IMETHODIMP nsChromeURL::GetImplementationLanguage(PRUint32 *aImplementationLanguage)
{
*aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS;
return NS_OK;
}
NS_IMETHODIMP nsChromeURL::GetFlags(PRUint32 *aFlags)
{
*aFlags = nsIClassInfo::MAIN_THREAD_ONLY;
return NS_OK;
}
NS_IMETHODIMP nsChromeURL::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
{
*aClassIDNoAlloc = kChromeURLCID;
return NS_OK;
}

96
chrome/src/nsChromeURL.h Normal file
Просмотреть файл

@ -0,0 +1,96 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
// vim:cindent:ts=4:et:sw=4:
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is nsChromeURL.
*
* The Initial Developer of the Original Code is the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2004
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* L. David Baron <dbaron@dbaron.org> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsChromeURL_h_
#define nsChromeURL_h_
#include "nsIURL.h"
#include "nsIStandardURL.h"
#include "nsISerializable.h"
#include "nsIClassInfo.h"
#include "nsIChromeURL.h"
#include "nsCOMPtr.h"
// 5f0dbeb4-6dde-4219-b516-f160a1639064
#define NS_CHROMEURL_CID \
{ 0x5f0dbeb4, 0x6dde, 0x4219, \
{ 0xb5, 0x16, 0xf1, 0x60, 0xa1, 0x63, 0x90, 0x64 } }
// 5f4b99a7-7217-4307-91b9-a3ea6c7c369b
#define NS_CHROMEURL_IMPL_IID \
{ 0x5f4b99a7, 0x7217, 0x4307, \
{ 0x91, 0xb9, 0xa3, 0xea, 0x6c, 0x7c, 0x36, 0x9b } }
/**
* nsChromeURL is a wrapper for nsStandardURL that implements all the
* interfaces that nsStandardURL does just to override the Equals method
* and provide a mechanism for getting at the resolved URL.
*/
class nsChromeURL : public nsIChromeURL,
public nsIStandardURL,
public nsISerializable,
public nsIClassInfo
{
public:
// The constructor doesn't do anything; callers are required to call
// either |Init| or |Read| and ensure it succeeds before doing
// anything else.
nsChromeURL() {}
nsresult Init(const nsACString &aSpec, const char *aCharset,
nsIURI *aBaseURI);
NS_DEFINE_STATIC_IID_ACCESSOR(NS_CHROMEURL_IMPL_IID);
NS_DECL_ISUPPORTS
NS_DECL_NSIURI
NS_DECL_NSIURL
NS_DECL_NSICHROMEURL
NS_DECL_NSISTANDARDURL
NS_DECL_NSISERIALIZABLE
NS_DECL_NSICLASSINFO
protected:
// Canonical, but still in the "chrome" scheme. Most methods
// forwarded here.
nsCOMPtr<nsIURL> mChromeURL;
// Converted to some other scheme (e.g., "jar").
nsCOMPtr<nsIURI> mConvertedURI;
};
#endif /* nsChromeURL_h_ */

Просмотреть файл

@ -87,6 +87,7 @@ SDK_XPIDLSRCS = \
XPIDLSRCS = \
nsIChromeRegistry.idl \
nsIChromeURL.idl \
nsIContentPolicy.idl \
nsISelectionController.idl \
nsISelectionDisplay.idl \

Просмотреть файл

@ -0,0 +1,53 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is nsIChromeURL.
*
* The Initial Developer of the Original Code is the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2004
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* L. David Baron <dbaron@dbaron.org> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsIURI.idl"
#include "nsIURL.idl"
[scriptable, uuid(90f4030e-a6b1-4e58-8ac4-059a76918e96)]
interface nsIChromeURL : nsIURL {
/*
* The URI, in some other protocol, that this chrome: URL resolves to.
*/
readonly attribute nsIURI convertedURI;
/*
* create a new chrome URL, based on the current one, but that does not
* remember the URI to which this one was resolved.
*/
nsIChromeURL reConvert();
};

Просмотреть файл

@ -596,9 +596,7 @@ nsSyncLoadService::LoadLocalXBLDocument(nsIChannel* aChannel,
nsCOMPtr<nsIInputStream> in;
nsresult rv = aChannel->Open(getter_AddRefs(in));
if (NS_FAILED(rv)) {
return rv;
}
NS_ENSURE_SUCCESS(rv, rv);
// Get uri and loadgroup
nsCOMPtr<nsIURI> docURI;

Просмотреть файл

@ -49,6 +49,7 @@
#include "nsICSSLoader.h"
#include "nsIURI.h"
#include "nsLayoutCID.h"
#include "nsIChromeURL.h"
#include "nsCSSRuleProcessor.h"
static NS_DEFINE_CID(kCSSLoaderCID, NS_CSS_LOADER_CID);
@ -95,14 +96,6 @@ nsXBLPrototypeResources::AddResourceListener(nsIContent* aBoundElement)
mLoader->AddResourceListener(aBoundElement);
}
static PRBool IsChromeURI(nsIURI* aURI)
{
PRBool isChrome=PR_FALSE;
if (NS_SUCCEEDED(aURI->SchemeIs("chrome", &isChrome)) && isChrome)
return PR_TRUE;
return PR_FALSE;
}
nsresult
nsXBLPrototypeResources::FlushSkinSheets()
{
@ -131,8 +124,12 @@ nsXBLPrototypeResources::FlushSkinSheets()
oldSheet->GetSheetURI(getter_AddRefs(uri));
nsCOMPtr<nsICSSStyleSheet> newSheet;
if (IsChromeURI(uri)) {
if (NS_FAILED(loader->LoadAgentSheet(uri, getter_AddRefs(newSheet))))
nsCOMPtr<nsIChromeURL> chromeURL = do_QueryInterface(uri);
if (chromeURL) {
nsCOMPtr<nsIChromeURL> newURL;
rv = chromeURL->ReConvert(getter_AddRefs(newURL));
NS_ENSURE_SUCCESS(rv, rv);
if (NS_FAILED(loader->LoadAgentSheet(newURL, getter_AddRefs(newSheet))))
continue;
}
else {

Просмотреть файл

@ -128,7 +128,7 @@ const char XUL_FASTLOAD_FILE_BASENAME[] = "XUL";
// Increase the subtractor when changing version, say when changing the
// (opaque to FastLoad code) format of JS script, function, regexp, etc.
// XDR serializations.
#define XUL_FASTLOAD_FILE_VERSION (0xfeedbeef - 9)
#define XUL_FASTLOAD_FILE_VERSION (0xfeedbeef - 10)
#define XUL_SERIALIZATION_BUFFER_SIZE (64 * 1024)
#define XUL_DESERIALIZATION_BUFFER_SIZE (8 * 1024)

Просмотреть файл

@ -116,6 +116,7 @@
#include "nsContentUtils.h"
#include "nsIParser.h"
#include "nsICSSStyleSheet.h"
#include "nsIChromeURL.h"
#include "nsIScriptError.h"
//----------------------------------------------------------------------
@ -3504,25 +3505,13 @@ nsXULDocument::AddPrototypeSheets()
PRUint32 count;
sheets->Count(&count);
for (PRUint32 i = 0; i < count; ++i) {
nsISupports* isupports = sheets->ElementAt(i);
nsCOMPtr<nsIURI> uri = do_QueryInterface(isupports);
NS_IF_RELEASE(isupports);
NS_ASSERTION(uri, "not a URI!!!");
if (! uri)
return NS_ERROR_UNEXPECTED;
nsCAutoString spec;
uri->GetAsciiSpec(spec);
if (!IsChromeURI(uri)) {
nsCOMPtr<nsIChromeURL> uri = do_QueryElementAt(sheets, i);
if (!uri) {
// These don't get to be in the prototype cache anyway...
// and we can't load non-chrome sheets synchronously
continue;
}
nsCOMPtr<nsICSSStyleSheet> sheet;
// If the sheet is a chrome URL, then we can refetch the sheet
// synchronously, since we know the sheet is local. It's not
// too late! :) If we're lucky, the loader will just pull it
@ -3535,7 +3524,13 @@ nsXULDocument::AddPrototypeSheets()
//XXXbz we hit this code from fastload all the time. Bug 183505.
nsICSSLoader* loader = GetCSSLoader();
NS_ENSURE_TRUE(loader, NS_ERROR_OUT_OF_MEMORY);
rv = loader->LoadAgentSheet(uri, getter_AddRefs(sheet));
nsCOMPtr<nsIChromeURL> newURL;
rv = uri->ReConvert(getter_AddRefs(newURL));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsICSSStyleSheet> sheet;
rv = loader->LoadAgentSheet(newURL, getter_AddRefs(sheet));
// XXXldb We need to prevent bogus sheets from being held in the
// prototype's list, but until then, don't propagate the failure
// from LoadAgentSheet (and thus exit the loop).

Просмотреть файл

@ -182,6 +182,7 @@
#endif
#include "nsIXBLBinding.h"
#include "nsPlaceholderFrame.h"
#include "nsIDOMMutationEvent.h"
// Dummy layout request
#include "nsDummyLayoutRequest.h"
@ -1378,9 +1379,7 @@ protected:
nsresult GetSelectionForCopy(nsISelection** outSelection);
nsICSSStyleSheet* mPrefStyleSheet; // mStyleSet owns it but we maintain a ref, may be null
#ifdef DEBUG
PRUint32 mUpdateCount;
#endif
// normal reflow commands
nsVoidArray mReflowCommands;
PLDHashTable mReflowCommandTable;
@ -3422,26 +3421,21 @@ PresShell::GetPageSequenceFrame(nsIPageSequenceFrame** aResult) const
void
PresShell::BeginUpdate(nsIDocument *aDocument, nsUpdateType aUpdateType)
{
#ifdef DEBUG
mUpdateCount++;
#endif
mFrameConstructor->BeginUpdate();
if (aUpdateType & UPDATE_STYLE)
if (aUpdateType & UPDATE_STYLE) {
++mUpdateCount;
mStyleSet->BeginUpdate();
}
}
void
PresShell::EndUpdate(nsIDocument *aDocument, nsUpdateType aUpdateType)
{
#ifdef DEBUG
NS_PRECONDITION(0 != mUpdateCount, "too many EndUpdate's");
--mUpdateCount;
#endif
if (aUpdateType & UPDATE_STYLE) {
mStyleSet->EndUpdate();
if (mStylesHaveChanged)
NS_ASSERTION(0 != mUpdateCount, "too many EndUpdate's");
if (--mUpdateCount == 0 && mStylesHaveChanged)
ReconstructStyleData();
}
@ -6033,6 +6027,7 @@ PresShell::GetAgentStyleSheets(nsCOMArray<nsIStyleSheet>& aSheets)
nsresult
PresShell::SetAgentStyleSheets(const nsCOMArray<nsIStyleSheet>& aSheets)
{
mStylesHaveChanged = PR_TRUE;
return mStyleSet->ReplaceSheets(nsStyleSet::eAgentSheet, aSheets);
}
@ -6479,13 +6474,23 @@ ReResolveMenusAndTrees(nsIFrame *aFrame, void *aClosure)
}
PR_STATIC_CALLBACK(PRBool)
ReframeImageBoxes(nsIFrame *aFrame, void *aClosure)
UpdateImageBoxSrcs(nsIFrame *aFrame, void *aClosure)
{
nsStyleChangeList *list = NS_STATIC_CAST(nsStyleChangeList*, aClosure);
if (aFrame->GetType() == nsLayoutAtoms::imageBoxFrame) {
list->AppendChange(aFrame, aFrame->GetContent(),
NS_STYLE_HINT_FRAMECHANGE);
return PR_FALSE; // don't walk descendants
nsPresContext *presContext = NS_STATIC_CAST(nsPresContext*, aClosure);
nsIContent *content = aFrame->GetContent();
if (aFrame->GetType() == nsLayoutAtoms::imageBoxFrame &&
content->HasAttr(kNameSpaceID_None, nsHTMLAtoms::src)) {
// If it's a chrome URL containing "/skin/", we want the frame to
// reload its image.
nsAutoString attr;
content->GetAttr(kNameSpaceID_None, nsHTMLAtoms::src, attr);
if (StringBeginsWith(attr, NS_LITERAL_STRING("chrome:")) &&
attr.Find("/skin/") != -1) {
aFrame->AttributeChanged(presContext, content,
kNameSpaceID_None, nsHTMLAtoms::src,
nsIDOMMutationEvent::MODIFICATION);
}
}
return PR_TRUE; // walk descendants
}
@ -6542,12 +6547,10 @@ PresShell::Observe(nsISupports* aSubject,
WalkFramesThroughPlaceholders(mPresContext, rootFrame,
&ReResolveMenusAndTrees, nsnull);
// Because "chrome:" URL equality is messy, reframe image box
// frames (hack!).
nsStyleChangeList changeList;
// Allow <xul:image src="" /> to be an additional (to stylesheet
// links) entry point into themes, for convenience.
WalkFramesThroughPlaceholders(mPresContext, rootFrame,
ReframeImageBoxes, &changeList);
mFrameConstructor->ProcessRestyledFrames(changeList, mPresContext);
UpdateImageBoxSrcs, mPresContext);
mViewManager->EndUpdateViewBatch(NS_VMREFRESH_NO_SYNC);
}

Просмотреть файл

@ -182,6 +182,7 @@
#endif
#include "nsIXBLBinding.h"
#include "nsPlaceholderFrame.h"
#include "nsIDOMMutationEvent.h"
// Dummy layout request
#include "nsDummyLayoutRequest.h"
@ -1378,9 +1379,7 @@ protected:
nsresult GetSelectionForCopy(nsISelection** outSelection);
nsICSSStyleSheet* mPrefStyleSheet; // mStyleSet owns it but we maintain a ref, may be null
#ifdef DEBUG
PRUint32 mUpdateCount;
#endif
// normal reflow commands
nsVoidArray mReflowCommands;
PLDHashTable mReflowCommandTable;
@ -3422,26 +3421,21 @@ PresShell::GetPageSequenceFrame(nsIPageSequenceFrame** aResult) const
void
PresShell::BeginUpdate(nsIDocument *aDocument, nsUpdateType aUpdateType)
{
#ifdef DEBUG
mUpdateCount++;
#endif
mFrameConstructor->BeginUpdate();
if (aUpdateType & UPDATE_STYLE)
if (aUpdateType & UPDATE_STYLE) {
++mUpdateCount;
mStyleSet->BeginUpdate();
}
}
void
PresShell::EndUpdate(nsIDocument *aDocument, nsUpdateType aUpdateType)
{
#ifdef DEBUG
NS_PRECONDITION(0 != mUpdateCount, "too many EndUpdate's");
--mUpdateCount;
#endif
if (aUpdateType & UPDATE_STYLE) {
mStyleSet->EndUpdate();
if (mStylesHaveChanged)
NS_ASSERTION(0 != mUpdateCount, "too many EndUpdate's");
if (--mUpdateCount == 0 && mStylesHaveChanged)
ReconstructStyleData();
}
@ -6033,6 +6027,7 @@ PresShell::GetAgentStyleSheets(nsCOMArray<nsIStyleSheet>& aSheets)
nsresult
PresShell::SetAgentStyleSheets(const nsCOMArray<nsIStyleSheet>& aSheets)
{
mStylesHaveChanged = PR_TRUE;
return mStyleSet->ReplaceSheets(nsStyleSet::eAgentSheet, aSheets);
}
@ -6479,13 +6474,23 @@ ReResolveMenusAndTrees(nsIFrame *aFrame, void *aClosure)
}
PR_STATIC_CALLBACK(PRBool)
ReframeImageBoxes(nsIFrame *aFrame, void *aClosure)
UpdateImageBoxSrcs(nsIFrame *aFrame, void *aClosure)
{
nsStyleChangeList *list = NS_STATIC_CAST(nsStyleChangeList*, aClosure);
if (aFrame->GetType() == nsLayoutAtoms::imageBoxFrame) {
list->AppendChange(aFrame, aFrame->GetContent(),
NS_STYLE_HINT_FRAMECHANGE);
return PR_FALSE; // don't walk descendants
nsPresContext *presContext = NS_STATIC_CAST(nsPresContext*, aClosure);
nsIContent *content = aFrame->GetContent();
if (aFrame->GetType() == nsLayoutAtoms::imageBoxFrame &&
content->HasAttr(kNameSpaceID_None, nsHTMLAtoms::src)) {
// If it's a chrome URL containing "/skin/", we want the frame to
// reload its image.
nsAutoString attr;
content->GetAttr(kNameSpaceID_None, nsHTMLAtoms::src, attr);
if (StringBeginsWith(attr, NS_LITERAL_STRING("chrome:")) &&
attr.Find("/skin/") != -1) {
aFrame->AttributeChanged(presContext, content,
kNameSpaceID_None, nsHTMLAtoms::src,
nsIDOMMutationEvent::MODIFICATION);
}
}
return PR_TRUE; // walk descendants
}
@ -6542,12 +6547,10 @@ PresShell::Observe(nsISupports* aSubject,
WalkFramesThroughPlaceholders(mPresContext, rootFrame,
&ReResolveMenusAndTrees, nsnull);
// Because "chrome:" URL equality is messy, reframe image box
// frames (hack!).
nsStyleChangeList changeList;
// Allow <xul:image src="" /> to be an additional (to stylesheet
// links) entry point into themes, for convenience.
WalkFramesThroughPlaceholders(mPresContext, rootFrame,
ReframeImageBoxes, &changeList);
mFrameConstructor->ProcessRestyledFrames(changeList, mPresContext);
UpdateImageBoxSrcs, mPresContext);
mViewManager->EndUpdateViewBatch(NS_VMREFRESH_NO_SYNC);
}

Просмотреть файл

@ -56,6 +56,7 @@
#include "nsRecyclingAllocator.h"
#include "nsXPTZipLoader.h"
#include "nsJARProtocolHandler.h"
#include "nsJARURI.h"
extern nsRecyclingAllocator *gZlibAllocator;
@ -63,6 +64,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsXPTZipLoader)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsJAR)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsZipReaderCache)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsJARProtocolHandler, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsJARURI)
// The list of components we register
static const nsModuleComponentInfo components[] =
@ -86,6 +88,11 @@ static const nsModuleComponentInfo components[] =
NS_JARPROTOCOLHANDLER_CID,
NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "jar",
nsJARProtocolHandlerConstructor
},
{ NS_JARURI_CLASSNAME, // needed only for fastload
NS_JARURI_CID,
nsnull,
nsJARURIConstructor
}
};

Просмотреть файл

@ -46,6 +46,11 @@
#include "nsIZipReader.h"
#include "nsReadableUtils.h"
#include "nsAutoPtr.h"
#include "nsNetCID.h"
#include "nsIObjectInputStream.h"
#include "nsIObjectOutputStream.h"
static NS_DEFINE_CID(kJARURICID, NS_JARURI_CID);
static NS_DEFINE_CID(kThisImplCID, NS_THIS_JARURI_IMPL_CID);
@ -59,6 +64,7 @@ nsJARURI::~nsJARURI()
{
}
// XXX Why is this threadsafe?
NS_IMPL_THREADSAFE_ADDREF(nsJARURI)
NS_IMPL_THREADSAFE_RELEASE(nsJARURI)
NS_INTERFACE_MAP_BEGIN(nsJARURI)
@ -67,6 +73,7 @@ NS_INTERFACE_MAP_BEGIN(nsJARURI)
NS_INTERFACE_MAP_ENTRY(nsIURL)
NS_INTERFACE_MAP_ENTRY(nsIJARURI)
NS_INTERFACE_MAP_ENTRY(nsISerializable)
NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
// see nsJARURI::Equals
if (aIID.Equals(kThisImplCID))
foundInterface = NS_STATIC_CAST(nsIJARURI *, this);
@ -135,17 +142,98 @@ nsJARURI::CreateEntryURL(const nsACString& entryFilename,
// nsISerializable methods:
NS_IMETHODIMP
nsJARURI::Read(nsIObjectInputStream* aStream)
nsJARURI::Read(nsIObjectInputStream* aInputStream)
{
NS_NOTREACHED("nsJARURI::Read");
return NS_ERROR_NOT_IMPLEMENTED;
nsresult rv;
rv = aInputStream->ReadObject(PR_TRUE, getter_AddRefs(mJARFile));
NS_ENSURE_SUCCESS(rv, rv);
rv = aInputStream->ReadObject(PR_TRUE, getter_AddRefs(mJAREntry));
NS_ENSURE_SUCCESS(rv, rv);
rv = aInputStream->ReadCString(mCharsetHint);
return rv;
}
NS_IMETHODIMP
nsJARURI::Write(nsIObjectOutputStream* aStream)
nsJARURI::Write(nsIObjectOutputStream* aOutputStream)
{
NS_NOTREACHED("nsJARURI::Write");
return NS_ERROR_NOT_IMPLEMENTED;
nsresult rv;
rv = aOutputStream->WriteCompoundObject(mJARFile, NS_GET_IID(nsIURI),
PR_TRUE);
NS_ENSURE_SUCCESS(rv, rv);
rv = aOutputStream->WriteCompoundObject(mJAREntry, NS_GET_IID(nsIURL),
PR_TRUE);
NS_ENSURE_SUCCESS(rv, rv);
rv = aOutputStream->WriteStringZ(mCharsetHint.get());
return rv;
}
////////////////////////////////////////////////////////////////////////////////
// nsIClassInfo methods:
NS_IMETHODIMP
nsJARURI::GetInterfaces(PRUint32 *count, nsIID * **array)
{
*count = 0;
*array = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsJARURI::GetHelperForLanguage(PRUint32 language, nsISupports **_retval)
{
*_retval = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsJARURI::GetContractID(char * *aContractID)
{
*aContractID = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsJARURI::GetClassDescription(char * *aClassDescription)
{
*aClassDescription = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsJARURI::GetClassID(nsCID * *aClassID)
{
*aClassID = (nsCID*) nsMemory::Alloc(sizeof(nsCID));
if (!*aClassID)
return NS_ERROR_OUT_OF_MEMORY;
return GetClassIDNoAlloc(*aClassID);
}
NS_IMETHODIMP
nsJARURI::GetImplementationLanguage(PRUint32 *aImplementationLanguage)
{
*aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS;
return NS_OK;
}
NS_IMETHODIMP
nsJARURI::GetFlags(PRUint32 *aFlags)
{
// XXX We implement THREADSAFE addref/release, but probably shouldn't.
*aFlags = nsIClassInfo::MAIN_THREAD_ONLY;
return NS_OK;
}
NS_IMETHODIMP
nsJARURI::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
{
*aClassIDNoAlloc = kJARURICID;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////

Просмотреть файл

@ -41,6 +41,7 @@
#include "nsIJARURI.h"
#include "nsISerializable.h"
#include "nsIClassInfo.h"
#include "nsCOMPtr.h"
#include "nsString.h"
@ -52,7 +53,18 @@
{0xb7, 0x5b, 0xfa, 0x7d, 0x95, 0x70, 0xa6, 0x91} \
}
class nsJARURI : public nsIJARURI, nsISerializable
#define NS_JARURI_CLASSNAME \
"nsJARURI"
#define NS_JARURI_CID \
{ /* 245abae2-b947-4ded-a46d-9829d3cca462 */ \
0x245abae2, \
0xb947, \
0x4ded, \
{0xa4, 0x6d, 0x98, 0x29, 0xd3, 0xcc, 0xa4, 0x62} \
}
class nsJARURI : public nsIJARURI, nsISerializable, nsIClassInfo
{
public:
NS_DECL_ISUPPORTS
@ -60,6 +72,7 @@ public:
NS_DECL_NSIURL
NS_DECL_NSIJARURI
NS_DECL_NSISERIALIZABLE
NS_DECL_NSICLASSINFO
// nsJARURI
nsJARURI();

Просмотреть файл

@ -1511,11 +1511,18 @@ nsStandardURL::SchemeIs(const char *scheme, PRBool *result)
return NS_OK;
}
NS_IMETHODIMP
nsStandardURL::Clone(nsIURI **result)
/* virtual */ nsStandardURL*
nsStandardURL::StartClone()
{
nsStandardURL *clone;
NS_NEWXPCOM(clone, nsStandardURL);
return clone;
}
NS_IMETHODIMP
nsStandardURL::Clone(nsIURI **result)
{
nsStandardURL *clone = StartClone();
if (!clone)
return NS_ERROR_OUT_OF_MEMORY;

Просмотреть файл

@ -140,6 +140,9 @@ public: /* internal -- HPUX compiler can't handle this being private */
};
friend class nsSegmentEncoder;
protected:
virtual nsStandardURL* StartClone();
private:
PRInt32 Port() { return mPort == -1 ? mDefaultPort : mPort; }

Просмотреть файл

@ -537,6 +537,17 @@
{0x8c, 0xda, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
#define NS_RESURL_CLASSNAME \
"nsResURL"
#define NS_RESURL_CID \
{ /* ff8fe7ec-2f74-4408-b742-6b7a546029a8 */ \
0xff8fe7ec, \
0x2f74, \
0x4408, \
{0xb7, 0x42, 0x6b, 0x7a, 0x54, 0x60, 0x29, 0xa8} \
}
/******************************************************************************
* netwerk/protocol/file/ classes
*/

Просмотреть файл

@ -195,6 +195,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsHttpDigestAuth)
// resource
#include "nsResProtocolHandler.h"
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsResProtocolHandler, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsResURL)
#endif
///////////////////////////////////////////////////////////////////////////////
@ -927,6 +928,11 @@ static const nsModuleComponentInfo gNetModuleInfo[] = {
NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "resource",
nsResProtocolHandlerConstructor
},
{ NS_RESURL_CLASSNAME, // needed only for fastload
NS_RESURL_CID,
nsnull,
nsResURLConstructor
},
#endif
// from netwerk/protocol/about (about:blank is mandatory):

Просмотреть файл

@ -52,6 +52,8 @@
#include "nsNetUtil.h"
#include "nsURLHelper.h"
static NS_DEFINE_CID(kResURLCID, NS_RESURL_CID);
static nsResProtocolHandler *gResHandler = nsnull;
#if defined(PR_LOGGING)
@ -74,15 +76,6 @@ static PRLogModuleInfo *gResLog;
// nsResURL : overrides nsStandardURL::GetFile to provide nsIFile resolution
//----------------------------------------------------------------------------
#include "nsStandardURL.h"
class nsResURL : public nsStandardURL
{
public:
nsResURL() : nsStandardURL(PR_TRUE) {}
NS_IMETHOD GetFile(nsIFile **);
};
NS_IMETHODIMP
nsResURL::GetFile(nsIFile **result)
{
@ -108,6 +101,21 @@ nsResURL::GetFile(nsIFile **result)
return rv;
}
/* virtual */ nsStandardURL*
nsResURL::StartClone()
{
nsResURL *clone;
NS_NEWXPCOM(clone, nsResURL);
return clone;
}
NS_IMETHODIMP
nsResURL::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
{
*aClassIDNoAlloc = kResURLCID;
return NS_OK;
}
//----------------------------------------------------------------------------
// nsResProtocolHandler <public>
//----------------------------------------------------------------------------

Просмотреть файл

@ -45,6 +45,17 @@
#include "nsISupportsArray.h"
#include "nsIIOService.h"
#include "nsWeakReference.h"
#include "nsStandardURL.h"
// nsResURL : overrides nsStandardURL::GetFile to provide nsIFile resolution
class nsResURL : public nsStandardURL
{
public:
nsResURL() : nsStandardURL(PR_TRUE) {}
NS_IMETHOD GetFile(nsIFile **);
virtual nsStandardURL* StartClone();
NS_IMETHOD GetClassIDNoAlloc(nsCID *aCID);
};
class nsResProtocolHandler : public nsIResProtocolHandler, public nsSupportsWeakReference
{

Просмотреть файл

@ -46,8 +46,10 @@
#include "rdf.h"
#include "nsChromeProtocolHandler.h"
#include "nsChromeRegistry.h"
#include "nsChromeURL.h"
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsChromeRegistry, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsChromeURL)
// The list of components we register
static const nsModuleComponentInfo components[] =
@ -62,6 +64,12 @@ static const nsModuleComponentInfo components[] =
NS_CHROMEPROTOCOLHANDLER_CID,
NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "chrome",
nsChromeProtocolHandler::Create
},
{ "Chrome URL", // needed only for fastload
NS_CHROMEURL_CID,
nsnull,
nsChromeURLConstructor
}
};

Просмотреть файл

@ -66,6 +66,7 @@ REQUIRES = xpcom \
CPPSRCS = \
nsChromeRegistry.cpp \
nsChromeURL.cpp \
nsChromeUIDataSource.cpp \
nsChromeProtocolHandler.cpp \
$(NULL)

Просмотреть файл

@ -43,10 +43,12 @@
#include "nsChromeProtocolHandler.h"
#include "nsCOMPtr.h"
#include "nsAutoPtr.h"
#include "nsContentCID.h"
#include "nsCRT.h"
#include "nsIChannel.h"
#include "nsIChromeRegistry.h"
#include "nsChromeURL.h"
#include "nsIComponentManager.h"
#include "nsIEventQueue.h"
#include "nsIEventQueueService.h"
@ -61,7 +63,6 @@
#include "nsIObjectOutputStream.h"
#include "nsIScriptSecurityManager.h"
#include "nsIServiceManager.h"
#include "nsIStandardURL.h"
#include "nsIStreamListener.h"
#ifdef MOZ_XUL
#include "nsIXULPrototypeCache.h"
@ -76,7 +77,6 @@
static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
static NS_DEFINE_CID(kStandardURLCID, NS_STANDARDURL_CID);
#ifdef MOZ_XUL
static NS_DEFINE_CID(kXULPrototypeCacheCID, NS_XULPROTOTYPECACHE_CID);
#endif
@ -571,49 +571,17 @@ nsChromeProtocolHandler::NewURI(const nsACString &aSpec,
nsIURI **result)
{
NS_PRECONDITION(result, "Null out param");
nsresult rv;
*result = nsnull;
// Chrome: URLs (currently) have no additional structure beyond that provided
// by standard URLs, so there is no "outer" given to CreateInstance
nsRefPtr<nsChromeURL> url = new nsChromeURL();
if (!url)
return NS_ERROR_OUT_OF_MEMORY;
nsCOMPtr<nsIStandardURL> url(do_CreateInstance(kStandardURLCID, &rv));
nsresult rv = url->Init(aSpec, aCharset, aBaseURI);
if (NS_FAILED(rv))
return rv;
rv = url->Init(nsIStandardURL::URLTYPE_STANDARD, -1, aSpec, aCharset, aBaseURI);
if (NS_FAILED(rv))
return rv;
nsCOMPtr<nsIURI> uri(do_QueryInterface(url, &rv));
if (NS_FAILED(rv))
return rv;
// Canonify the "chrome:" URL; e.g., so that we collapse
// "chrome://navigator/content/" and "chrome://navigator/content"
// and "chrome://navigator/content/navigator.xul".
// Try the global cache first.
nsCOMPtr<nsIChromeRegistry> reg = gChromeRegistry;
// If that fails, the service has not been instantiated yet; let's
// do that now.
if (!reg) {
reg = do_GetService(NS_CHROMEREGISTRY_CONTRACTID, &rv);
if (NS_FAILED(rv))
return rv;
}
NS_ASSERTION(reg, "Must have a chrome registry by now");
rv = reg->Canonify(uri);
if (NS_FAILED(rv))
return rv;
*result = uri;
NS_ADDREF(*result);
NS_ADDREF(*result = url);
return NS_OK;
}
@ -623,29 +591,11 @@ nsChromeProtocolHandler::NewChannel(nsIURI* aURI,
{
NS_ENSURE_ARG_POINTER(aURI);
NS_PRECONDITION(aResult, "Null out param");
#ifdef DEBUG
// Check that the uri we got is already canonified
nsresult debug_rv;
nsCOMPtr<nsIChromeRegistry> debugReg(do_GetService(NS_CHROMEREGISTRY_CONTRACTID, &debug_rv));
if (NS_SUCCEEDED(debug_rv)) {
nsCOMPtr<nsIURI> debugClone;
debug_rv = aURI->Clone(getter_AddRefs(debugClone));
if (NS_SUCCEEDED(debug_rv)) {
debug_rv = debugReg->Canonify(debugClone);
if (NS_SUCCEEDED(debug_rv)) {
PRBool same;
debug_rv = aURI->Equals(debugClone, &same);
if (NS_SUCCEEDED(debug_rv)) {
NS_ASSERTION(same, "Non-canonified chrome uri passed to nsChromeProtocolHandler::NewChannel!");
}
}
}
}
#endif
nsresult rv;
nsCOMPtr<nsIChromeURL> chromeURL = do_QueryInterface(aURI, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIChannel> result;
#ifdef MOZ_XUL
@ -683,30 +633,14 @@ nsChromeProtocolHandler::NewChannel(nsIURI* aURI,
else
#endif
{
// Miss. Resolve the chrome URL using the registry and do a
// normal necko load.
//nsXPIDLCString oldSpec;
//aURI->GetSpec(getter_Copies(oldSpec));
//printf("*************************** %s\n", (const char*)oldSpec);
// Miss. Get the converted URL and do a normal necko load.
nsCOMPtr<nsIURI> convertedURI;
chromeURL->GetConvertedURI(getter_AddRefs(convertedURI));
nsCOMPtr<nsIChromeRegistry> reg = gChromeRegistry;
if (!reg) {
reg = do_GetService(NS_CHROMEREGISTRY_CONTRACTID, &rv);
if (NS_FAILED(rv)) return rv;
}
nsCAutoString spec;
rv = reg->ConvertChromeURL(aURI, spec);
nsCOMPtr<nsIIOService> ioServ = do_GetService(kIOServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIIOService> ioServ(do_GetService(kIOServiceCID, &rv));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIURI> chromeURI;
rv = ioServ->NewURI(spec, nsnull, nsnull, getter_AddRefs(chromeURI));
if (NS_FAILED(rv)) return rv;
rv = ioServ->NewChannelFromURI(chromeURI, getter_AddRefs(result));
rv = ioServ->NewChannelFromURI(convertedURI, getter_AddRefs(result));
if (NS_FAILED(rv)) return rv;
// XXX Will be removed someday when we handle remote chrome.

Просмотреть файл

@ -95,6 +95,7 @@
#include "nsNetCID.h"
#include "nsIJARURI.h"
#include "nsIFileURL.h"
#include "nsIChromeURL.h"
static char kChromePrefix[] = "chrome://";
nsIAtom* nsChromeRegistry::sCPrefix; // atom for "c"
@ -1353,14 +1354,6 @@ nsChromeRegistry::FlushSkinCaches()
NS_CHROME_FLUSH_SKINS_TOPIC, nsnull);
}
static PRBool IsChromeURI(nsIURI* aURI)
{
PRBool isChrome=PR_FALSE;
if (NS_SUCCEEDED(aURI->SchemeIs("chrome", &isChrome)) && isChrome)
return PR_TRUE;
return PR_FALSE;
}
// XXXbsmedberg: move this to windowmediator
nsresult nsChromeRegistry::RefreshWindow(nsIDOMWindowInternal* aWindow)
{
@ -1388,6 +1381,8 @@ nsresult nsChromeRegistry::RefreshWindow(nsIDOMWindowInternal* aWindow)
if (!document)
return NS_OK;
mozAutoDocUpdate update(document, UPDATE_STYLE, PR_TRUE);
// Deal with the agent sheets first. Have to do all the style sets by hand.
PRUint32 shellCount = document->GetNumberOfShells();
for (PRUint32 k = 0; k < shellCount; k++) {
@ -1406,10 +1401,15 @@ nsresult nsChromeRegistry::RefreshWindow(nsIDOMWindowInternal* aWindow)
rv = sheet->GetSheetURI(getter_AddRefs(uri));
if (NS_FAILED(rv)) return rv;
if (IsChromeURI(uri)) {
// Reload the sheet.
nsCOMPtr<nsIChromeURL> chromeURL = do_QueryInterface(uri);
if (chromeURL) {
// Reload the sheet. Recreate the URI since the chrome URL
// caches its resolved form.
nsCOMPtr<nsIChromeURL> newURL;
chromeURL->ReConvert(getter_AddRefs(newURL));
nsCOMPtr<nsICSSStyleSheet> newSheet;
rv = LoadStyleSheetWithURL(uri, getter_AddRefs(newSheet));
rv = LoadStyleSheetWithURL(newURL, getter_AddRefs(newSheet));
if (NS_FAILED(rv)) return rv;
if (newSheet) {
rv = newAgentSheets.AppendObject(newSheet) ? NS_OK : NS_ERROR_FAILURE;
@ -1451,17 +1451,20 @@ nsresult nsChromeRegistry::RefreshWindow(nsIDOMWindowInternal* aWindow)
rv = sheet->GetSheetURI(getter_AddRefs(uri));
if (NS_FAILED(rv)) return rv;
if (IsChromeURI(uri)) {
nsCOMPtr<nsIChromeURL> chromeURL = do_QueryInterface(uri);
if (chromeURL) {
// Reload the sheet.
#ifdef DEBUG
nsCOMPtr<nsICSSStyleSheet> oldCSSSheet = do_QueryInterface(sheet);
NS_ASSERTION(oldCSSSheet, "Don't know how to reload a non-CSS sheet");
#endif
nsCOMPtr<nsIChromeURL> newURL;
chromeURL->ReConvert(getter_AddRefs(newURL));
nsCOMPtr<nsICSSStyleSheet> newSheet;
// XXX what about chrome sheets that have a title or are disabled? This
// only works by sheer dumb luck.
// XXXbz this should really use the document's CSSLoader!
LoadStyleSheetWithURL(uri, getter_AddRefs(newSheet));
LoadStyleSheetWithURL(newURL, getter_AddRefs(newSheet));
// Even if it's null, we put in in there.
newSheets.AppendObject(newSheet);
}

Просмотреть файл

@ -0,0 +1,399 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
// vim:cindent:ts=4:et:sw=4:
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is nsChromeURL.
*
* The Initial Developer of the Original Code is the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2004
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* L. David Baron <dbaron@dbaron.org> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsChromeURL.h"
#include "nsIStandardURL.h"
#include "nsNetUtil.h"
#include "nsIChromeRegistry.h"
#include "nsNetCID.h"
#include "nsMemory.h"
#include "nsComponentManagerUtils.h"
#include "nsString.h"
#include "nsIObjectInputStream.h"
#include "nsIObjectOutputStream.h"
#include "nsAutoPtr.h"
// This comes from nsChromeRegistry.cpp
extern nsIChromeRegistry* gChromeRegistry;
static NS_DEFINE_CID(kChromeURLCID, NS_CHROMEURL_CID);
nsresult
nsChromeURL::Init(const nsACString &aSpec, const char *aCharset,
nsIURI *aBaseURI)
{
nsresult rv;
nsCOMPtr<nsIStandardURL> url =
do_CreateInstance(NS_STANDARDURL_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = url->Init(nsIStandardURL::URLTYPE_STANDARD, -1, aSpec, aCharset,
aBaseURI);
NS_ENSURE_SUCCESS(rv, rv);
mChromeURL = do_QueryInterface(url, &rv);
NS_ENSURE_SUCCESS(rv, rv);
// Canonify the "chrome:" URL; e.g., so that we collapse
// "chrome://navigator/content/" and "chrome://navigator/content"
// and "chrome://navigator/content/navigator.xul".
// Try the global cache first.
if (!gChromeRegistry) {
// The service has not been instantiated yet; let's do that now.
nsCOMPtr<nsIChromeRegistry> reg =
do_GetService(NS_CHROMEREGISTRY_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
NS_ASSERTION(gChromeRegistry, "yikes, gChromeRegistry not set");
}
return gChromeRegistry->Canonify(mChromeURL);
// Construction of |mConvertedURI| must happen lazily since this
// method can be called during nsChromeRegistry::Init, when
// nsChromeRegistry::ConvertChromeURL will fail.
}
// interface nsISupports
NS_IMPL_ADDREF(nsChromeURL)
NS_IMPL_RELEASE(nsChromeURL)
NS_INTERFACE_MAP_BEGIN(nsChromeURL)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStandardURL)
NS_INTERFACE_MAP_ENTRY(nsIURI)
NS_INTERFACE_MAP_ENTRY(nsIURL)
NS_INTERFACE_MAP_ENTRY(nsIChromeURL)
NS_INTERFACE_MAP_ENTRY(nsIStandardURL)
NS_INTERFACE_MAP_ENTRY(nsISerializable)
NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
if (aIID.Equals(nsChromeURL::GetIID())) // NS_CHROMEURL_IMPL_IID
foundInterface = NS_REINTERPRET_CAST(nsISupports*, this);
else
NS_INTERFACE_MAP_END
#define FORWARD_METHOD(method_, params_, args_) \
NS_IMETHODIMP nsChromeURL::method_ params_ \
{ \
return mChromeURL->method_ args_; \
}
// interface nsIURI
FORWARD_METHOD(GetSpec, (nsACString & aSpec), (aSpec))
FORWARD_METHOD(SetSpec, (const nsACString & aSpec), (aSpec))
FORWARD_METHOD(GetPrePath, (nsACString & aPrePath), (aPrePath))
FORWARD_METHOD(GetScheme, (nsACString & aScheme), (aScheme))
FORWARD_METHOD(SetScheme, (const nsACString & aScheme), (aScheme))
FORWARD_METHOD(GetUserPass, (nsACString & aUserPass), (aUserPass))
FORWARD_METHOD(SetUserPass, (const nsACString & aUserPass), (aUserPass))
FORWARD_METHOD(GetUsername, (nsACString & aUsername), (aUsername))
FORWARD_METHOD(SetUsername, (const nsACString & aUsername), (aUsername))
FORWARD_METHOD(GetPassword, (nsACString & aPassword), (aPassword))
FORWARD_METHOD(SetPassword, (const nsACString & aPassword), (aPassword))
FORWARD_METHOD(GetHostPort, (nsACString & aHostPort), (aHostPort))
FORWARD_METHOD(SetHostPort, (const nsACString & aHostPort), (aHostPort))
FORWARD_METHOD(GetHost, (nsACString & aHost), (aHost))
FORWARD_METHOD(SetHost, (const nsACString & aHost), (aHost))
FORWARD_METHOD(GetPort, (PRInt32 *aPort), (aPort))
FORWARD_METHOD(SetPort, (PRInt32 aPort), (aPort))
FORWARD_METHOD(GetPath, (nsACString & aPath), (aPath))
FORWARD_METHOD(SetPath, (const nsACString & aPath), (aPath))
/*
* Overriding Equals is the main point of nsChromeURL's existence. But
* be careful because nsStandardURL equals QIs its |other| argument to
* nsStandardURL, which we don't implement.
*/
NS_IMETHODIMP nsChromeURL::Equals(nsIURI *other, PRBool *_retval)
{
NS_ENSURE_ARG_POINTER(other);
NS_PRECONDITION(_retval, "null out param");
*_retval = PR_FALSE;
nsRefPtr<nsChromeURL> otherChrome;
CallQueryInterface(other,
NS_STATIC_CAST(nsChromeURL**, getter_AddRefs(otherChrome)));
if (!otherChrome) {
return NS_OK; // false
}
PRBool equal;
nsresult rv = mChromeURL->Equals(otherChrome->mChromeURL, &equal);
NS_ENSURE_SUCCESS(rv, rv);
if (!equal) {
return NS_OK; // false
}
if (!mConvertedURI) {
nsCOMPtr<nsIURI> tmp;
rv = GetConvertedURI(getter_AddRefs(tmp));
NS_ENSURE_SUCCESS(rv, rv);
}
if (!otherChrome->mConvertedURI) {
nsCOMPtr<nsIURI> tmp;
rv = otherChrome->GetConvertedURI(getter_AddRefs(tmp));
NS_ENSURE_SUCCESS(rv, rv);
}
return mConvertedURI->Equals(otherChrome->mConvertedURI, _retval);
}
FORWARD_METHOD(SchemeIs, (const char *scheme, PRBool *_retval), (scheme, _retval))
NS_IMETHODIMP nsChromeURL::Clone(nsIURI **_retval)
{
nsIChromeURL *cloneI;
nsresult rv = nsChromeURL::ReConvert(&cloneI);
NS_ENSURE_SUCCESS(rv, rv);
nsChromeURL *clone = NS_STATIC_CAST(nsChromeURL*, cloneI);
if (mConvertedURI)
rv = mConvertedURI->Clone(getter_AddRefs(clone->mConvertedURI));
if (NS_FAILED(rv)) {
NS_RELEASE(clone);
return rv;
}
*_retval = clone;
return NS_OK;
}
FORWARD_METHOD(Resolve, (const nsACString & relativePath, nsACString & _retval), (relativePath, _retval))
FORWARD_METHOD(GetAsciiSpec, (nsACString & aAsciiSpec), (aAsciiSpec))
FORWARD_METHOD(GetAsciiHost, (nsACString & aAsciiHost), (aAsciiHost))
FORWARD_METHOD(GetOriginCharset, (nsACString & aOriginCharset), (aOriginCharset))
// interface nsIURL
FORWARD_METHOD(GetFilePath, (nsACString & aFilePath), (aFilePath))
FORWARD_METHOD(SetFilePath, (const nsACString & aFilePath), (aFilePath))
FORWARD_METHOD(GetParam, (nsACString & aParam), (aParam))
FORWARD_METHOD(SetParam, (const nsACString & aParam), (aParam))
FORWARD_METHOD(GetQuery, (nsACString & aQuery), (aQuery))
FORWARD_METHOD(SetQuery, (const nsACString & aQuery), (aQuery))
FORWARD_METHOD(GetRef, (nsACString & aRef), (aRef))
FORWARD_METHOD(SetRef, (const nsACString & aRef), (aRef))
FORWARD_METHOD(GetDirectory, (nsACString & aDirectory), (aDirectory))
FORWARD_METHOD(SetDirectory, (const nsACString & aDirectory), (aDirectory))
FORWARD_METHOD(GetFileName, (nsACString & aFileName), (aFileName))
FORWARD_METHOD(SetFileName, (const nsACString & aFileName), (aFileName))
FORWARD_METHOD(GetFileBaseName, (nsACString & aFileBaseName), (aFileBaseName))
FORWARD_METHOD(SetFileBaseName, (const nsACString & aFileBaseName), (aFileBaseName))
FORWARD_METHOD(GetFileExtension, (nsACString & aFileExtension), (aFileExtension))
FORWARD_METHOD(SetFileExtension, (const nsACString & aFileExtension), (aFileExtension))
/*
* override because nsStandardURL QIs aURIToCompare to nsStandardURL,
* which we don't implement.
*/
NS_IMETHODIMP nsChromeURL::GetCommonBaseSpec(nsIURI *aURIToCompare, nsACString & _retval)
{
NS_ENSURE_ARG_POINTER(aURIToCompare);
nsChromeURL *otherChromeURL;
nsresult rv;
if (NS_SUCCEEDED(CallQueryInterface(aURIToCompare, &otherChromeURL))) {
rv = mChromeURL->GetCommonBaseSpec(otherChromeURL->mChromeURL, _retval);
NS_RELEASE(otherChromeURL);
} else {
rv = mChromeURL->GetCommonBaseSpec(aURIToCompare, _retval);
}
return rv;
}
/*
* override because nsStandardURL QIs aURIToCompare to nsStandardURL,
* which we don't implement.
*/
NS_IMETHODIMP nsChromeURL::GetRelativeSpec(nsIURI *aURIToCompare, nsACString & _retval)
{
NS_ENSURE_ARG_POINTER(aURIToCompare);
nsChromeURL *otherChromeURL;
nsresult rv;
if (NS_SUCCEEDED(CallQueryInterface(aURIToCompare, &otherChromeURL))) {
rv = mChromeURL->GetRelativeSpec(otherChromeURL->mChromeURL, _retval);
NS_RELEASE(otherChromeURL);
} else {
rv = mChromeURL->GetRelativeSpec(aURIToCompare, _retval);
}
return rv;
}
// interface nsIChromeURL
NS_IMETHODIMP nsChromeURL::GetConvertedURI(nsIURI **aConvertedURI)
{
if (!mConvertedURI) {
NS_ENSURE_TRUE(gChromeRegistry, NS_ERROR_UNEXPECTED);
// From now on, mutation is forbidden, since it wouldn't be
// reflected in mConvertedURI, and the whole point of nsChromeURL
// is to keep track of when mConvertedURI changes.
nsCOMPtr<nsIStandardURL> standardURL = do_QueryInterface(mChromeURL);
standardURL->SetMutable(PR_FALSE);
// Resolve the "chrome:" URL to a URL with a different scheme.
nsCAutoString spec;
nsresult rv = gChromeRegistry->ConvertChromeURL(mChromeURL, spec);
NS_ENSURE_SUCCESS(rv, rv);
rv = NS_NewURI(getter_AddRefs(mConvertedURI), spec);
NS_ENSURE_SUCCESS(rv, rv);
}
NS_ADDREF(*aConvertedURI = mConvertedURI);
return NS_OK;
}
// NOTE: This function is used to implement Clone.
NS_IMETHODIMP nsChromeURL::ReConvert(nsIChromeURL **aResult)
{
*aResult = nsnull;
nsRefPtr<nsChromeURL> result = new nsChromeURL;
if (!result)
return NS_ERROR_OUT_OF_MEMORY;
nsresult rv = mChromeURL->Clone(NS_REINTERPRET_CAST(nsIURI**,
NS_STATIC_CAST(nsIURL**,
getter_AddRefs(result->mChromeURL))));
NS_ASSERTION(nsCOMPtr<nsIURL>(do_QueryInterface(
NS_STATIC_CAST(nsISupports*, result->mChromeURL)))
== result->mChromeURL, "invalid cast");
NS_ENSURE_SUCCESS(rv, rv);
NS_ADDREF(*aResult = result);
return NS_OK;
}
// interface nsIStandardURL
NS_IMETHODIMP nsChromeURL::Init(PRUint32 aUrlType, PRInt32 aDefaultPort, const nsACString & aSpec, const char *aOriginCharset, nsIURI *aBaseURI)
{
NS_NOTREACHED("nsChromeURL::Init");
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP nsChromeURL::GetMutable(PRBool *aMutable)
{
nsCOMPtr<nsIStandardURL> url = do_QueryInterface(mChromeURL);
return url->GetMutable(aMutable);
}
NS_IMETHODIMP nsChromeURL::SetMutable(PRBool aMutable)
{
nsCOMPtr<nsIStandardURL> url = do_QueryInterface(mChromeURL);
return url->SetMutable(aMutable);
}
// interface nsISerializable
NS_IMETHODIMP nsChromeURL::Read(nsIObjectInputStream *aInputStream)
{
nsresult rv =
aInputStream->ReadObject(PR_TRUE, getter_AddRefs(mChromeURL));
NS_ENSURE_SUCCESS(rv, rv);
return NS_ReadOptionalObject(aInputStream, PR_TRUE,
getter_AddRefs(mConvertedURI));
}
NS_IMETHODIMP nsChromeURL::Write(nsIObjectOutputStream *aOutputStream)
{
nsresult rv = aOutputStream->WriteCompoundObject(mChromeURL,
NS_GET_IID(nsIURL),
PR_TRUE);
NS_ENSURE_SUCCESS(rv, rv);
// XXX Should this be optional, or should we resolve before writing?
return NS_WriteOptionalCompoundObject(aOutputStream, mConvertedURI,
NS_GET_IID(nsIURI), PR_TRUE);
}
// interface nsIClassInfo
NS_IMETHODIMP nsChromeURL::GetInterfaces(PRUint32 *count, nsIID * **array)
{
*count = 0;
*array = nsnull;
return NS_OK;
}
NS_IMETHODIMP nsChromeURL::GetHelperForLanguage(PRUint32 language, nsISupports **_retval)
{
*_retval = nsnull;
return NS_OK;
}
NS_IMETHODIMP nsChromeURL::GetContractID(char * *aContractID)
{
*aContractID = nsnull;
return NS_OK;
}
NS_IMETHODIMP nsChromeURL::GetClassDescription(char * *aClassDescription)
{
*aClassDescription = nsnull;
return NS_OK;
}
NS_IMETHODIMP nsChromeURL::GetClassID(nsCID * *aClassID)
{
*aClassID = (nsCID*) nsMemory::Alloc(sizeof(nsCID));
if (!*aClassID)
return NS_ERROR_OUT_OF_MEMORY;
return GetClassIDNoAlloc(*aClassID);
}
NS_IMETHODIMP nsChromeURL::GetImplementationLanguage(PRUint32 *aImplementationLanguage)
{
*aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS;
return NS_OK;
}
NS_IMETHODIMP nsChromeURL::GetFlags(PRUint32 *aFlags)
{
*aFlags = nsIClassInfo::MAIN_THREAD_ONLY;
return NS_OK;
}
NS_IMETHODIMP nsChromeURL::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
{
*aClassIDNoAlloc = kChromeURLCID;
return NS_OK;
}

Просмотреть файл

@ -0,0 +1,96 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
// vim:cindent:ts=4:et:sw=4:
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is nsChromeURL.
*
* The Initial Developer of the Original Code is the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2004
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* L. David Baron <dbaron@dbaron.org> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsChromeURL_h_
#define nsChromeURL_h_
#include "nsIURL.h"
#include "nsIStandardURL.h"
#include "nsISerializable.h"
#include "nsIClassInfo.h"
#include "nsIChromeURL.h"
#include "nsCOMPtr.h"
// 5f0dbeb4-6dde-4219-b516-f160a1639064
#define NS_CHROMEURL_CID \
{ 0x5f0dbeb4, 0x6dde, 0x4219, \
{ 0xb5, 0x16, 0xf1, 0x60, 0xa1, 0x63, 0x90, 0x64 } }
// 5f4b99a7-7217-4307-91b9-a3ea6c7c369b
#define NS_CHROMEURL_IMPL_IID \
{ 0x5f4b99a7, 0x7217, 0x4307, \
{ 0x91, 0xb9, 0xa3, 0xea, 0x6c, 0x7c, 0x36, 0x9b } }
/**
* nsChromeURL is a wrapper for nsStandardURL that implements all the
* interfaces that nsStandardURL does just to override the Equals method
* and provide a mechanism for getting at the resolved URL.
*/
class nsChromeURL : public nsIChromeURL,
public nsIStandardURL,
public nsISerializable,
public nsIClassInfo
{
public:
// The constructor doesn't do anything; callers are required to call
// either |Init| or |Read| and ensure it succeeds before doing
// anything else.
nsChromeURL() {}
nsresult Init(const nsACString &aSpec, const char *aCharset,
nsIURI *aBaseURI);
NS_DEFINE_STATIC_IID_ACCESSOR(NS_CHROMEURL_IMPL_IID);
NS_DECL_ISUPPORTS
NS_DECL_NSIURI
NS_DECL_NSIURL
NS_DECL_NSICHROMEURL
NS_DECL_NSISTANDARDURL
NS_DECL_NSISERIALIZABLE
NS_DECL_NSICLASSINFO
protected:
// Canonical, but still in the "chrome" scheme. Most methods
// forwarded here.
nsCOMPtr<nsIURL> mChromeURL;
// Converted to some other scheme (e.g., "jar").
nsCOMPtr<nsIURI> mConvertedURI;
};
#endif /* nsChromeURL_h_ */

Просмотреть файл

@ -2140,8 +2140,10 @@ nsFastLoadFileWriter::WriteObjectCommon(nsISupports* aObject,
// updating after reading.
oid |= MFL_OBJECT_DEF_TAG;
classInfo = do_QueryInterface(aObject);
if (!classInfo)
if (!classInfo) {
NS_NOTREACHED("aObject must implement nsIClassInfo");
return NS_ERROR_FAILURE;
}
PRUint32 flags;
if (NS_SUCCEEDED(classInfo->GetFlags(&flags)) &&
@ -2175,8 +2177,10 @@ nsFastLoadFileWriter::WriteObjectCommon(nsISupports* aObject,
if (oid & MFL_OBJECT_DEF_TAG) {
nsCOMPtr<nsISerializable> serializable(do_QueryInterface(aObject));
if (!serializable)
if (!serializable) {
NS_NOTREACHED("aObject must implement nsISerializable");
return NS_ERROR_FAILURE;
}
nsCID slowCID;
rv = classInfo->GetClassIDNoAlloc(&slowCID);
@ -2233,13 +2237,15 @@ nsFastLoadFileWriter::WriteCompoundObject(nsISupports* aObject,
{
nsresult rv;
nsCOMPtr<nsISupports> rootObject(do_QueryInterface(aObject));
// We could assert that |rootObject != aObject|, but that would prevent
// callers who don't know whether they're dealing with the primary
// nsISupports pointer (e.g., they don't know which implementation of
// nsIURI they have) from using this function.
#ifdef NS_DEBUG
nsCOMPtr<nsISupports> roundtrip;
rootObject->QueryInterface(aIID, getter_AddRefs(roundtrip));
NS_ASSERTION(rootObject.get() != aObject,
"wasteful call to WriteCompoundObject -- call WriteObject!");
NS_ASSERTION(roundtrip.get() == aObject,
"bad aggregation or multiple inheritance detected by call to "
"WriteCompoundObject!");