зеркало из https://github.com/mozilla/pjs.git
Bug 404386 - nsScanner construction is 5% of setting innerHTML. r=mrbkap,smontagu. sr=jst. a=blocking1.9.
This commit is contained in:
Родитель
cee5fb2864
Коммит
e21c0e91c9
|
@ -63,6 +63,16 @@ nsCharsetAlias2::~nsCharsetAlias2()
|
|||
if(mDelegate)
|
||||
delete mDelegate;
|
||||
}
|
||||
|
||||
//
|
||||
static const char* kAliases[][3] = {
|
||||
// Triple with { lower-case test string, out string, length of out string }
|
||||
{ "iso-8859-1", "ISO-8859-1", (const char*)10 },
|
||||
{ "utf-8", "UTF-8", (const char*)5 },
|
||||
{ "x-sjis", "Shift_JIS", (const char*)9 },
|
||||
{ "shift_jis", "Shift_JIS", (const char*)9 }
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------
|
||||
NS_IMETHODIMP nsCharsetAlias2::GetPreferred(const nsACString& aAlias,
|
||||
nsACString& oResult)
|
||||
|
@ -70,35 +80,26 @@ NS_IMETHODIMP nsCharsetAlias2::GetPreferred(const nsACString& aAlias,
|
|||
if (aAlias.IsEmpty()) return NS_ERROR_NULL_POINTER;
|
||||
NS_TIMELINE_START_TIMER("nsCharsetAlias2:GetPreferred");
|
||||
|
||||
nsCAutoString aKey(aAlias);
|
||||
ToLowerCase(aKey);
|
||||
oResult.Truncate();
|
||||
|
||||
// Delay loading charsetalias.properties by hardcoding the most
|
||||
// frequent aliases. Note that it's possible to recur in to this
|
||||
// function *while loading* charsetalias.properties (see bug 190951),
|
||||
// so we might have an |mDelegate| already that isn't valid yet, but
|
||||
// the load is guaranteed to be "UTF-8" so things will be OK.
|
||||
if(aKey.EqualsLiteral("utf-8")) {
|
||||
oResult.AssignLiteral("UTF-8");
|
||||
NS_TIMELINE_STOP_TIMER("nsCharsetAlias2:GetPreferred");
|
||||
return NS_OK;
|
||||
}
|
||||
if(aKey.EqualsLiteral("iso-8859-1")) {
|
||||
oResult.AssignLiteral("ISO-8859-1");
|
||||
NS_TIMELINE_STOP_TIMER("nsCharsetAlias2:GetPreferred");
|
||||
return NS_OK;
|
||||
}
|
||||
if(aKey.EqualsLiteral("x-sjis") ||
|
||||
aKey.EqualsLiteral("shift_jis")) {
|
||||
oResult.AssignLiteral("Shift_JIS");
|
||||
NS_TIMELINE_STOP_TIMER("nsCharsetAlias2:GetPreferred");
|
||||
return NS_OK;
|
||||
}
|
||||
for (PRUint32 index = 0; index < NS_ARRAY_LENGTH(kAliases); index++) {
|
||||
if (aAlias.LowerCaseEqualsASCII(kAliases[index][0])) {
|
||||
oResult.Assign(nsDependentCString(kAliases[index][1],
|
||||
(PRUint32)kAliases[index][2]));
|
||||
NS_TIMELINE_STOP_TIMER("nsCharsetAlias2:GetPreferred");
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
oResult.Truncate();
|
||||
|
||||
if(!mDelegate) {
|
||||
//load charsetalias.properties string bundle with all remaining aliases
|
||||
// we may need to protect the following section with a lock so we won't call the
|
||||
// we may need to protect the following section with a lock so we won't call the
|
||||
// 'new nsGREResProperties' from two different threads
|
||||
mDelegate = new nsGREResProperties( NS_LITERAL_CSTRING("charsetalias.properties") );
|
||||
NS_ASSERTION(mDelegate, "cannot create nsGREResProperties");
|
||||
|
@ -109,10 +110,13 @@ NS_IMETHODIMP nsCharsetAlias2::GetPreferred(const nsACString& aAlias,
|
|||
NS_TIMELINE_STOP_TIMER("nsCharsetAlias2:GetPreferred");
|
||||
NS_TIMELINE_MARK_TIMER("nsCharsetAlias2:GetPreferred");
|
||||
|
||||
nsCAutoString key(aAlias);
|
||||
ToLowerCase(key);
|
||||
|
||||
// hack for now, have to fix nsGREResProperties, but we can't until
|
||||
// string bundles use UTF8 keys
|
||||
nsAutoString result;
|
||||
nsresult rv = mDelegate->Get(NS_ConvertASCIItoUTF16(aKey), result);
|
||||
nsresult rv = mDelegate->Get(NS_ConvertASCIItoUTF16(key), result);
|
||||
LossyAppendUTF16toASCII(result, oResult);
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -86,6 +86,12 @@ nsCharsetConverterManager::~nsCharsetConverterManager()
|
|||
NS_IF_RELEASE(mTitleBundle);
|
||||
}
|
||||
|
||||
nsresult nsCharsetConverterManager::Init()
|
||||
{
|
||||
if (!mDecoderHash.Init())
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsCharsetConverterManager::RegisterConverterManagerData()
|
||||
{
|
||||
|
@ -254,30 +260,28 @@ nsCharsetConverterManager::GetUnicodeDecoderRaw(const char * aSrc,
|
|||
#endif
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
NS_NAMED_LITERAL_CSTRING(kUnicodeDecoderContractIDBase,
|
||||
NS_UNICODEDECODER_CONTRACTID_BASE);
|
||||
|
||||
nsCAutoString contractid(kUnicodeDecoderContractIDBase +
|
||||
nsDependentCString(aSrc));
|
||||
|
||||
if (!strncmp(aSrc,
|
||||
NS_1BYTE_CODER_PATTERN,
|
||||
NS_1BYTE_CODER_PATTERN_LEN))
|
||||
NS_NAMED_LITERAL_CSTRING(contractbase, NS_UNICODEDECODER_CONTRACTID_BASE);
|
||||
nsDependentCString src(aSrc);
|
||||
|
||||
if (!strncmp(aSrc, NS_1BYTE_CODER_PATTERN, NS_1BYTE_CODER_PATTERN_LEN))
|
||||
{
|
||||
// Single byte decoders dont hold state. Optimize by using a service.
|
||||
decoder = do_GetService(contractid.get(), &rv);
|
||||
// Single byte decoders don't hold state. Optimize by using a service, and
|
||||
// cache it in our hash to avoid repeated trips through the service manager.
|
||||
if (!mDecoderHash.Get(aSrc, getter_AddRefs(decoder))) {
|
||||
decoder = do_GetService(PromiseFlatCString(contractbase + src).get(),
|
||||
&rv);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
mDecoderHash.Put(aSrc, decoder);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
decoder = do_CreateInstance(contractid.get(), &rv);
|
||||
}
|
||||
if(NS_FAILED(rv))
|
||||
rv = NS_ERROR_UCONV_NOCONV;
|
||||
else
|
||||
{
|
||||
*aResult = decoder.get();
|
||||
NS_ADDREF(*aResult);
|
||||
decoder = do_CreateInstance(PromiseFlatCString(contractbase + src).get(),
|
||||
&rv);
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_UCONV_NOCONV);
|
||||
|
||||
decoder.forget(aResult);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "nsISupports.h"
|
||||
#include "nsICharsetConverterManager.h"
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsInterfaceHashtable.h"
|
||||
|
||||
#ifdef MOZ_USE_NATIVE_UCONV
|
||||
#include "nsINativeUConvService.h"
|
||||
|
@ -55,6 +56,8 @@ public:
|
|||
nsCharsetConverterManager();
|
||||
virtual ~nsCharsetConverterManager();
|
||||
|
||||
nsresult Init();
|
||||
|
||||
private:
|
||||
|
||||
nsIStringBundle * mDataBundle;
|
||||
|
@ -64,6 +67,8 @@ private:
|
|||
nsCOMPtr<nsINativeUConvService> mNativeUC;
|
||||
#endif
|
||||
|
||||
nsInterfaceHashtable<nsCharPtrHashKey, nsIUnicodeDecoder> mDecoderHash;
|
||||
|
||||
nsresult LoadExtensibleBundle(const char * aRegistryKey,
|
||||
nsIStringBundle ** aResult);
|
||||
|
||||
|
|
|
@ -610,7 +610,7 @@ nsConverterManagerDataRegister(nsIComponentManager* aCompMgr,
|
|||
return nsCharsetConverterManager::RegisterConverterManagerData();
|
||||
}
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsCharsetConverterManager)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsCharsetConverterManager, Init)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsTextToSubURI)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsUTF8ConverterService)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsCharsetAlias2)
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "nsICachingChannel.h"
|
||||
#include "nsICacheEntryDescriptor.h"
|
||||
#include "nsICharsetAlias.h"
|
||||
#include "nsICharsetConverterManager.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "CNavDTD.h"
|
||||
#include "prenv.h"
|
||||
|
@ -154,6 +155,9 @@ public:
|
|||
|
||||
//-------------- End ParseContinue Event Definition ------------------------
|
||||
|
||||
nsICharsetAlias* nsParser::sCharsetAliasService = nsnull;
|
||||
nsICharsetConverterManager* nsParser::sCharsetConverterManager = nsnull;
|
||||
|
||||
/**
|
||||
* This gets called when the htmlparser module is initialized.
|
||||
*/
|
||||
|
@ -204,6 +208,17 @@ nsParser::Init()
|
|||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsICharsetAlias> charsetAlias =
|
||||
do_GetService(NS_CHARSETALIAS_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsICharsetConverterManager> charsetConverter =
|
||||
do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
charsetAlias.swap(sCharsetAliasService);
|
||||
charsetConverter.swap(sCharsetConverterManager);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -216,9 +231,11 @@ void nsParser::Shutdown()
|
|||
{
|
||||
delete sParserDataListeners;
|
||||
sParserDataListeners = nsnull;
|
||||
|
||||
NS_IF_RELEASE(sCharsetAliasService);
|
||||
NS_IF_RELEASE(sCharsetConverterManager);
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
static PRBool gDumpContent=PR_FALSE;
|
||||
#endif
|
||||
|
|
|
@ -90,6 +90,8 @@
|
|||
#include "nsIUnicharStreamListener.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
|
||||
class nsICharsetConverterManager;
|
||||
class nsICharsetAlias;
|
||||
class nsIDTD;
|
||||
class nsScanner;
|
||||
class nsIProgressEventSink;
|
||||
|
@ -124,7 +126,6 @@ class nsParser : public nsIParser,
|
|||
*/
|
||||
nsParser();
|
||||
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
* @update gess5/11/98
|
||||
|
@ -372,6 +373,14 @@ class nsParser : public nsIParser,
|
|||
|
||||
static nsCOMArray<nsIUnicharStreamListener> *sParserDataListeners;
|
||||
|
||||
static nsICharsetAlias* GetCharsetAliasService() {
|
||||
return sCharsetAliasService;
|
||||
}
|
||||
|
||||
static nsICharsetConverterManager* GetCharsetConverterManager() {
|
||||
return sCharsetConverterManager;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
|
@ -455,7 +464,8 @@ protected:
|
|||
nsCString mCharset;
|
||||
nsCString mCommandStr;
|
||||
|
||||
|
||||
static nsICharsetAlias* sCharsetAliasService;
|
||||
static nsICharsetConverterManager* sCharsetConverterManager;
|
||||
|
||||
public:
|
||||
|
||||
|
|
|
@ -103,7 +103,6 @@ nsScanner::nsScanner(const nsAString& anHTMLString, const nsACString& aCharset,
|
|||
mIncremental = PR_FALSE;
|
||||
mUnicodeDecoder = 0;
|
||||
mCharsetSource = kCharsetUninitialized;
|
||||
SetDocumentCharset(aCharset, aSource);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -149,42 +148,48 @@ nsresult nsScanner::SetDocumentCharset(const nsACString& aCharset , PRInt32 aSou
|
|||
if( aSource < mCharsetSource) // priority is lower the the current one , just
|
||||
return res;
|
||||
|
||||
nsCOMPtr<nsICharsetAlias> calias(do_GetService(NS_CHARSETALIAS_CONTRACTID, &res));
|
||||
NS_ASSERTION( nsnull != calias, "cannot find charset alias");
|
||||
if( NS_SUCCEEDED(res) && (nsnull != calias))
|
||||
nsICharsetAlias* calias = nsParser::GetCharsetAliasService();
|
||||
NS_ASSERTION(calias, "Must have the charset alias service!");
|
||||
|
||||
if (!mCharset.IsEmpty())
|
||||
{
|
||||
PRBool same = PR_FALSE;
|
||||
PRBool same;
|
||||
res = calias->Equals(aCharset, mCharset, &same);
|
||||
if(NS_SUCCEEDED(res) && same)
|
||||
{
|
||||
return NS_OK; // no difference, don't change it
|
||||
}
|
||||
// different, need to change it
|
||||
nsCAutoString charsetName;
|
||||
res = calias->GetPreferred(aCharset, charsetName);
|
||||
|
||||
if(NS_FAILED(res) && (kCharsetUninitialized == mCharsetSource) )
|
||||
{
|
||||
// failed - unknown alias , fallback to ISO-8859-1
|
||||
charsetName.AssignLiteral("ISO-8859-1");
|
||||
}
|
||||
mCharset = charsetName;
|
||||
mCharsetSource = aSource;
|
||||
|
||||
nsCOMPtr<nsICharsetConverterManager> ccm =
|
||||
do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &res);
|
||||
if(NS_SUCCEEDED(res) && (nsnull != ccm))
|
||||
{
|
||||
nsIUnicodeDecoder * decoder = nsnull;
|
||||
res = ccm->GetUnicodeDecoderRaw(mCharset.get(), &decoder);
|
||||
if(NS_SUCCEEDED(res) && (nsnull != decoder))
|
||||
{
|
||||
NS_IF_RELEASE(mUnicodeDecoder);
|
||||
|
||||
mUnicodeDecoder = decoder;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// different, need to change it
|
||||
nsCString charsetName;
|
||||
res = calias->GetPreferred(aCharset, charsetName);
|
||||
|
||||
if(NS_FAILED(res) && (mCharsetSource == kCharsetUninitialized))
|
||||
{
|
||||
// failed - unknown alias , fallback to ISO-8859-1
|
||||
mCharset.AssignLiteral("ISO-8859-1");
|
||||
}
|
||||
else
|
||||
{
|
||||
mCharset.Assign(charsetName);
|
||||
}
|
||||
|
||||
mCharsetSource = aSource;
|
||||
|
||||
NS_ASSERTION(nsParser::GetCharsetConverterManager(),
|
||||
"Must have the charset converter manager!");
|
||||
|
||||
nsIUnicodeDecoder * decoder = nsnull;
|
||||
res = nsParser::GetCharsetConverterManager()->
|
||||
GetUnicodeDecoderRaw(mCharset.get(), &decoder);
|
||||
if(NS_SUCCEEDED(res) && (nsnull != decoder))
|
||||
{
|
||||
NS_IF_RELEASE(mUnicodeDecoder);
|
||||
|
||||
mUnicodeDecoder = decoder;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче