зеркало из https://github.com/mozilla/gecko-dev.git
Bug 541079 - Make app cache selection happen before speculative loads in the HTML5 parser. r=bnewman.
This commit is contained in:
Родитель
287034c014
Коммит
6b8df8aef8
|
@ -1087,11 +1087,22 @@ nsContentSink::ProcessOfflineManifest(nsIContent *aElement)
|
|||
return;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
|
||||
// Check for a manifest= attribute.
|
||||
nsAutoString manifestSpec;
|
||||
aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::manifest, manifestSpec);
|
||||
ProcessOfflineManifest(manifestSpec);
|
||||
}
|
||||
|
||||
void
|
||||
nsContentSink::ProcessOfflineManifest(const nsAString& aManifestSpec)
|
||||
{
|
||||
// Don't bother processing offline manifest for documents
|
||||
// without a docshell
|
||||
if (!mDocShell) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
|
||||
// Grab the application cache the document was loaded from, if any.
|
||||
nsCOMPtr<nsIApplicationCache> applicationCache;
|
||||
|
@ -1115,7 +1126,7 @@ nsContentSink::ProcessOfflineManifest(nsIContent *aElement)
|
|||
}
|
||||
}
|
||||
|
||||
if (manifestSpec.IsEmpty() && !applicationCache) {
|
||||
if (aManifestSpec.IsEmpty() && !applicationCache) {
|
||||
// Not loaded from an application cache, and no manifest
|
||||
// attribute. Nothing to do here.
|
||||
return;
|
||||
|
@ -1124,12 +1135,12 @@ nsContentSink::ProcessOfflineManifest(nsIContent *aElement)
|
|||
CacheSelectionAction action = CACHE_SELECTION_NONE;
|
||||
nsCOMPtr<nsIURI> manifestURI;
|
||||
|
||||
if (manifestSpec.IsEmpty()) {
|
||||
if (aManifestSpec.IsEmpty()) {
|
||||
action = CACHE_SELECTION_RESELECT_WITHOUT_MANIFEST;
|
||||
}
|
||||
else {
|
||||
nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(manifestURI),
|
||||
manifestSpec, mDocument,
|
||||
aManifestSpec, mDocument,
|
||||
mDocumentURI);
|
||||
if (!manifestURI) {
|
||||
return;
|
||||
|
|
|
@ -247,6 +247,10 @@ public:
|
|||
// of the above defined methods to select the document's application
|
||||
// cache, let it be associated with the document and eventually
|
||||
// schedule the cache update process.
|
||||
void ProcessOfflineManifest(const nsAString& aManifestSpec);
|
||||
|
||||
// Extracts the manifest attribute from the element if it is the root
|
||||
// element and calls the above method.
|
||||
void ProcessOfflineManifest(nsIContent *aElement);
|
||||
|
||||
protected:
|
||||
|
|
|
@ -85,7 +85,7 @@ nsHtml5Parser::nsHtml5Parser()
|
|||
: mFirstBuffer(new nsHtml5UTF16Buffer(0))
|
||||
, mLastBuffer(mFirstBuffer)
|
||||
, mExecutor(new nsHtml5TreeOpExecutor())
|
||||
, mTreeBuilder(new nsHtml5TreeBuilder(mExecutor))
|
||||
, mTreeBuilder(new nsHtml5TreeBuilder(mExecutor, nsnull))
|
||||
, mTokenizer(new nsHtml5Tokenizer(mTreeBuilder))
|
||||
, mRootContextLineNumber(1)
|
||||
{
|
||||
|
@ -662,9 +662,6 @@ nsHtml5Parser::Initialize(nsIDocument* aDoc,
|
|||
nsISupports* aContainer,
|
||||
nsIChannel* aChannel)
|
||||
{
|
||||
if (mStreamParser && aDoc) {
|
||||
mStreamParser->SetSpeculativeLoaderWithDocument(aDoc);
|
||||
}
|
||||
return mExecutor->Init(aDoc, aURI, aContainer, aChannel);
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "nsNetUtil.h"
|
||||
#include "nsScriptLoader.h"
|
||||
#include "nsICSSLoaderObserver.h"
|
||||
#include "nsIDocument.h"
|
||||
|
||||
/**
|
||||
* Used if we need to pass an nsICSSLoaderObserver as parameter,
|
||||
|
@ -59,8 +60,8 @@ public:
|
|||
|
||||
NS_IMPL_ISUPPORTS1(nsHtml5DummyCSSLoaderObserver, nsICSSLoaderObserver)
|
||||
|
||||
nsHtml5SpeculativeLoader::nsHtml5SpeculativeLoader(nsIDocument* aDocument)
|
||||
: mDocument(aDocument)
|
||||
nsHtml5SpeculativeLoader::nsHtml5SpeculativeLoader(nsHtml5TreeOpExecutor* aExecutor)
|
||||
: mExecutor(aExecutor)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsHtml5SpeculativeLoader);
|
||||
mPreloadedURLs.Init(23); // Mean # of preloadable resources per page on dmoz
|
||||
|
@ -78,8 +79,12 @@ NS_IMPL_THREADSAFE_RELEASE(nsHtml5SpeculativeLoader)
|
|||
already_AddRefed<nsIURI>
|
||||
nsHtml5SpeculativeLoader::ConvertIfNotPreloadedYet(const nsAString& aURL)
|
||||
{
|
||||
nsIURI* base = mDocument->GetBaseURI();
|
||||
const nsCString& charset = mDocument->GetDocumentCharacterSet();
|
||||
nsIDocument* doc = mExecutor->GetDocument();
|
||||
if (!doc) {
|
||||
return nsnull;
|
||||
}
|
||||
nsIURI* base = doc->GetBaseURI();
|
||||
const nsCString& charset = doc->GetDocumentCharacterSet();
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(uri), aURL, charset.get(), base);
|
||||
if (NS_FAILED(rv)) {
|
||||
|
@ -106,7 +111,10 @@ nsHtml5SpeculativeLoader::PreloadScript(const nsAString& aURL,
|
|||
if (!uri) {
|
||||
return;
|
||||
}
|
||||
mDocument->ScriptLoader()->PreloadURI(uri, aCharset, aType);
|
||||
nsIDocument* doc = mExecutor->GetDocument();
|
||||
if (doc) {
|
||||
doc->ScriptLoader()->PreloadURI(uri, aCharset, aType);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -118,9 +126,13 @@ nsHtml5SpeculativeLoader::PreloadStyle(const nsAString& aURL,
|
|||
return;
|
||||
}
|
||||
nsCOMPtr<nsICSSLoaderObserver> obs = new nsHtml5DummyCSSLoaderObserver();
|
||||
mDocument->CSSLoader()->LoadSheet(uri, mDocument->NodePrincipal(),
|
||||
NS_LossyConvertUTF16toASCII(aCharset),
|
||||
obs);
|
||||
nsIDocument* doc = mExecutor->GetDocument();
|
||||
if (doc) {
|
||||
doc->CSSLoader()->LoadSheet(uri,
|
||||
doc->NodePrincipal(),
|
||||
NS_LossyConvertUTF16toASCII(aCharset),
|
||||
obs);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -130,5 +142,14 @@ nsHtml5SpeculativeLoader::PreloadImage(const nsAString& aURL)
|
|||
if (!uri) {
|
||||
return;
|
||||
}
|
||||
mDocument->MaybePreLoadImage(uri);
|
||||
nsIDocument* doc = mExecutor->GetDocument();
|
||||
if (doc) {
|
||||
doc->MaybePreLoadImage(uri);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5SpeculativeLoader::ProcessManifest(const nsAString& aURL)
|
||||
{
|
||||
mExecutor->ProcessOfflineManifest(aURL);
|
||||
}
|
||||
|
|
|
@ -42,13 +42,13 @@
|
|||
#include "nsIURI.h"
|
||||
#include "nsString.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsHtml5TreeOpExecutor.h"
|
||||
#include "nsHashSets.h"
|
||||
|
||||
class nsHtml5SpeculativeLoader
|
||||
{
|
||||
public:
|
||||
nsHtml5SpeculativeLoader(nsIDocument* aDocument);
|
||||
nsHtml5SpeculativeLoader(nsHtml5TreeOpExecutor* aExecutor);
|
||||
~nsHtml5SpeculativeLoader();
|
||||
|
||||
NS_IMETHOD_(nsrefcnt) AddRef(void);
|
||||
|
@ -62,6 +62,8 @@ class nsHtml5SpeculativeLoader
|
|||
|
||||
void PreloadImage(const nsAString& aURL);
|
||||
|
||||
void ProcessManifest(const nsAString& aURL);
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
|
@ -72,9 +74,9 @@ class nsHtml5SpeculativeLoader
|
|||
nsAutoRefCnt mRefCnt;
|
||||
|
||||
/**
|
||||
* The document to use as the context for preloading.
|
||||
* The executor to use as the context for preloading.
|
||||
*/
|
||||
nsCOMPtr<nsIDocument> mDocument;
|
||||
nsRefPtr<nsHtml5TreeOpExecutor> mExecutor;
|
||||
|
||||
/**
|
||||
* URLs already preloaded/preloading.
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include "nsHtml5AtomTable.h"
|
||||
#include "nsHtml5Module.h"
|
||||
#include "nsHtml5RefPtr.h"
|
||||
#include "nsHtml5SpeculativeLoader.h"
|
||||
|
||||
static NS_DEFINE_CID(kCharsetAliasCID, NS_CHARSETALIAS_CID);
|
||||
|
||||
|
@ -91,7 +92,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsHtml5StreamParser)
|
|||
tmp->mOwner = nsnull;
|
||||
tmp->mExecutorFlusher = nsnull;
|
||||
tmp->mExecutor = nsnull;
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDocument)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mChardet)
|
||||
tmp->mTreeBuilder->DropSpeculativeLoader();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
@ -108,7 +108,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsHtml5StreamParser)
|
|||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExecutorFlusher->mExecutor");
|
||||
cb.NoteXPCOMChild(static_cast<nsIContentSink*> (tmp->mExecutor));
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDocument)
|
||||
// hack: count self if held by mChardet
|
||||
if (tmp->mChardet) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb,
|
||||
|
@ -116,10 +115,10 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsHtml5StreamParser)
|
|||
cb.NoteXPCOMChild(static_cast<nsIStreamListener*>(tmp));
|
||||
}
|
||||
// hack: count the strongly owned edge wrapped in the speculative loader
|
||||
if (tmp->mDocument) {
|
||||
if (tmp->mTreeBuilder->HasSpeculativeLoader()) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb,
|
||||
"mTreeBuilder->mSpeculativeLoader->mDocument");
|
||||
cb.NoteXPCOMChild(tmp->mDocument);
|
||||
"mTreeBuilder->mSpeculativeLoader->mExecutor");
|
||||
cb.NoteXPCOMChild(static_cast<nsIContentSink*> (tmp->mExecutor));
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
|
@ -143,7 +142,8 @@ nsHtml5StreamParser::nsHtml5StreamParser(nsHtml5TreeOpExecutor* aExecutor,
|
|||
: mFirstBuffer(new nsHtml5UTF16Buffer(NS_HTML5_STREAM_PARSER_READ_BUFFER_SIZE))
|
||||
, mLastBuffer(mFirstBuffer)
|
||||
, mExecutor(aExecutor)
|
||||
, mTreeBuilder(new nsHtml5TreeBuilder(mExecutor->GetStage()))
|
||||
, mTreeBuilder(new nsHtml5TreeBuilder(mExecutor->GetStage(),
|
||||
new nsHtml5SpeculativeLoader(mExecutor)))
|
||||
, mTokenizer(new nsHtml5Tokenizer(mTreeBuilder))
|
||||
, mTokenizerMutex("nsHtml5StreamParser mTokenizerMutex")
|
||||
, mOwner(aOwner)
|
||||
|
@ -199,13 +199,6 @@ nsHtml5StreamParser::~nsHtml5StreamParser()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5StreamParser::SetSpeculativeLoaderWithDocument(nsIDocument* aDocument) {
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
mDocument = aDocument;
|
||||
mTreeBuilder->SetSpeculativeLoaderWithDocument(aDocument);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHtml5StreamParser::GetChannel(nsIChannel** aChannel)
|
||||
{
|
||||
|
@ -1039,7 +1032,7 @@ nsHtml5StreamParser::PostTimerFlush()
|
|||
sTimerInterval,
|
||||
nsITimer::TYPE_ONE_SHOT);
|
||||
|
||||
// TODO: (If mDocument isn't in the frontmost tab or If the user isn't
|
||||
// TODO: (If the document isn't in the frontmost tab or If the user isn't
|
||||
// interacting with the browser) and this isn't every nth timer flush, return
|
||||
|
||||
nsCOMPtr<nsIRunnable> event = new nsHtml5StreamParserTimerFlusher(this);
|
||||
|
|
|
@ -161,8 +161,6 @@ class nsHtml5StreamParser : public nsIStreamListener,
|
|||
mObserver = aObserver;
|
||||
}
|
||||
|
||||
void SetSpeculativeLoaderWithDocument(nsIDocument* aDocument);
|
||||
|
||||
nsresult GetChannel(nsIChannel** aChannel);
|
||||
|
||||
/**
|
||||
|
@ -453,11 +451,6 @@ class nsHtml5StreamParser : public nsIStreamListener,
|
|||
|
||||
nsCOMPtr<nsIRunnable> mExecutorFlusher;
|
||||
|
||||
/**
|
||||
* The document wrapped by the speculative loader.
|
||||
*/
|
||||
nsCOMPtr<nsIDocument> mDocument;
|
||||
|
||||
/**
|
||||
* The chardet instance if chardet is enabled.
|
||||
*/
|
||||
|
|
|
@ -50,7 +50,8 @@
|
|||
|
||||
// this really should be autogenerated...
|
||||
jArray<PRUnichar,PRInt32> nsHtml5TreeBuilder::ISINDEX_PROMPT = jArray<PRUnichar,PRInt32>();
|
||||
nsHtml5TreeBuilder::nsHtml5TreeBuilder(nsAHtml5TreeOpSink* aOpSink)
|
||||
nsHtml5TreeBuilder::nsHtml5TreeBuilder(nsAHtml5TreeOpSink* aOpSink,
|
||||
nsHtml5SpeculativeLoader* aSpeculativeLoader)
|
||||
: scriptingEnabled(PR_FALSE)
|
||||
, fragment(PR_FALSE)
|
||||
, contextNode(nsnull)
|
||||
|
@ -59,6 +60,7 @@ nsHtml5TreeBuilder::nsHtml5TreeBuilder(nsAHtml5TreeOpSink* aOpSink)
|
|||
, mOpSink(aOpSink)
|
||||
, mHandles(new nsIContent*[NS_HTML5_TREE_BUILDER_HANDLE_ARRAY_LENGTH])
|
||||
, mHandlesUsed(0)
|
||||
, mSpeculativeLoader(aSpeculativeLoader)
|
||||
, mCurrentHtmlScriptIsAsyncOrDefer(PR_FALSE)
|
||||
#ifdef DEBUG
|
||||
, mActive(PR_FALSE)
|
||||
|
@ -137,6 +139,24 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class nsHtml5SpeculativeManifest : public nsRunnable
|
||||
{
|
||||
private:
|
||||
nsRefPtr<nsHtml5SpeculativeLoader> mSpeculativeLoader;
|
||||
nsString mURL;
|
||||
public:
|
||||
nsHtml5SpeculativeManifest(nsHtml5SpeculativeLoader* aSpeculativeLoader,
|
||||
const nsAString& aURL)
|
||||
: mSpeculativeLoader(aSpeculativeLoader)
|
||||
, mURL(aURL)
|
||||
{}
|
||||
NS_IMETHODIMP Run()
|
||||
{
|
||||
mSpeculativeLoader->ProcessManifest(mURL);
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
nsIContent**
|
||||
nsHtml5TreeBuilder::createElement(PRInt32 aNamespace, nsIAtom* aName, nsHtml5HtmlAttributes* aAttributes)
|
||||
{
|
||||
|
@ -201,6 +221,11 @@ nsHtml5TreeBuilder::createElement(PRInt32 aNamespace, nsIAtom* aName, nsHtml5Htm
|
|||
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
|
||||
NS_ASSERTION(treeOp, "Tree op allocation failed.");
|
||||
treeOp->Init(eTreeOpSetStyleLineNumber, content, tokenizer->getLineNumber());
|
||||
} else if (nsHtml5Atoms::html == aName) {
|
||||
nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_MANIFEST);
|
||||
if (url) {
|
||||
Dispatch(new nsHtml5SpeculativeManifest(mSpeculativeLoader, *url));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case kNameSpaceID_SVG:
|
||||
|
@ -252,6 +277,13 @@ nsHtml5TreeBuilder::createElement(PRInt32 aNamespace, nsIAtom* aName, nsHtml5Htm
|
|||
(aAttributes->contains(nsHtml5AttributeName::ATTR_ASYNC) ||
|
||||
aAttributes->contains(nsHtml5AttributeName::ATTR_DEFER));
|
||||
}
|
||||
} else if (aNamespace == kNameSpaceID_XHTML && nsHtml5Atoms::html == aName) {
|
||||
nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_MANIFEST);
|
||||
if (url) {
|
||||
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
|
||||
NS_ASSERTION(treeOp, "Tree op allocation failed.");
|
||||
treeOp->Init(eTreeOpProcessOfflineManifest, *url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -439,18 +471,6 @@ nsHtml5TreeBuilder::appendDoctypeToDocument(nsIAtom* aName, nsString* aPublicId,
|
|||
void
|
||||
nsHtml5TreeBuilder::elementPushed(PRInt32 aNamespace, nsIAtom* aName, nsIContent** aElement)
|
||||
{
|
||||
NS_ASSERTION(aNamespace == kNameSpaceID_XHTML || aNamespace == kNameSpaceID_SVG || aNamespace == kNameSpaceID_MathML, "Element isn't HTML, SVG or MathML!");
|
||||
NS_ASSERTION(aName, "Element doesn't have local name!");
|
||||
NS_ASSERTION(aElement, "No element!");
|
||||
// Give autoloading links a chance to fire
|
||||
if (aNamespace == kNameSpaceID_XHTML) {
|
||||
if (aName == nsHtml5Atoms::html) {
|
||||
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
|
||||
NS_ASSERTION(treeOp, "Tree op allocation failed.");
|
||||
treeOp->Init(eTreeOpProcessOfflineManifest, aElement);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -664,12 +684,6 @@ nsHtml5TreeBuilder::AddSnapshotToScript(nsAHtml5TreeBuilderState* aSnapshot, PRI
|
|||
mOpQueue.ElementAt(mOpQueue.Length() - 1).SetSnapshot(aSnapshot, aLine);
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::SetSpeculativeLoaderWithDocument(nsIDocument* aDocument) {
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
mSpeculativeLoader = new nsHtml5SpeculativeLoader(aDocument);
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::DropSpeculativeLoader() {
|
||||
mSpeculativeLoader = nsnull;
|
||||
|
|
|
@ -60,7 +60,8 @@
|
|||
|
||||
public:
|
||||
|
||||
nsHtml5TreeBuilder(nsAHtml5TreeOpSink* aOpSink);
|
||||
nsHtml5TreeBuilder(nsAHtml5TreeOpSink* aOpSink,
|
||||
nsHtml5SpeculativeLoader* aSpeculativeLoader);
|
||||
|
||||
~nsHtml5TreeBuilder();
|
||||
|
||||
|
@ -76,8 +77,10 @@
|
|||
mOpQueue.Clear();
|
||||
}
|
||||
|
||||
void SetSpeculativeLoaderWithDocument(nsIDocument* aDocument);
|
||||
|
||||
PRBool HasSpeculativeLoader() {
|
||||
return !!mSpeculativeLoader;
|
||||
}
|
||||
|
||||
void DropSpeculativeLoader();
|
||||
|
||||
PRBool Flush();
|
||||
|
|
|
@ -119,6 +119,9 @@ nsHtml5TreeOperation::~nsHtml5TreeOperation()
|
|||
case eTreeOpNeedsCharsetSwitchTo:
|
||||
delete[] mOne.charPtr;
|
||||
break;
|
||||
case eTreeOpProcessOfflineManifest:
|
||||
nsMemory::Free(mOne.unicharPtr);
|
||||
break;
|
||||
default: // keep the compiler happy
|
||||
break;
|
||||
}
|
||||
|
@ -554,8 +557,9 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
|
|||
return rv;
|
||||
}
|
||||
case eTreeOpProcessOfflineManifest: {
|
||||
nsIContent* node = *(mOne.node);
|
||||
aBuilder->ProcessOfflineManifest(node);
|
||||
PRUnichar* str = mOne.unicharPtr;
|
||||
nsDependentString dependentString(str);
|
||||
aBuilder->ProcessOfflineManifest(dependentString);
|
||||
return rv;
|
||||
}
|
||||
case eTreeOpMarkMalformedIfScript: {
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "nsIContent.h"
|
||||
#include "nsHtml5DocumentMode.h"
|
||||
#include "nsHtml5HtmlAttributes.h"
|
||||
#include "nsXPCOMStrings.h"
|
||||
|
||||
class nsHtml5TreeOpExecutor;
|
||||
class nsHtml5StateSnapshot;
|
||||
|
@ -263,6 +264,15 @@ class nsHtml5TreeOperation {
|
|||
mOne.charPtr = str;
|
||||
}
|
||||
|
||||
inline void Init(eHtml5TreeOperation aOpCode, const nsAString& aString) {
|
||||
NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
|
||||
"Op code must be uninitialized when initializing.");
|
||||
|
||||
PRUnichar* str = NS_StringCloneData(aString);
|
||||
mOpCode = aOpCode;
|
||||
mOne.unicharPtr = str;
|
||||
}
|
||||
|
||||
inline void Init(eHtml5TreeOperation aOpCode,
|
||||
nsIContent** aNode,
|
||||
PRInt32 aInt) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче