From 0aecc2c0de8b761dbbce67abf4a6899570df59e6 Mon Sep 17 00:00:00 2001 From: "mrbkap%gmail.com" Date: Tue, 7 Jun 2005 19:21:05 +0000 Subject: [PATCH] bug 271184: The output of nested document.write()s can get reversed (where later document.write()s are seen before previous document.write()s). This makes nsHTMLDocument use good parser keys. r=sicking sr=jst a=asa git-svn-id: svn://10.0.0.236/trunk@174220 18797224-902f-48f8-a5cc-f745e15eee43 --- .../content/base/public/nsIScriptLoader.idl | 8 ++++++- mozilla/content/base/src/nsScriptLoader.cpp | 18 +++++++++++++++ mozilla/content/base/src/nsScriptLoader.h | 1 + .../html/document/src/nsHTMLDocument.cpp | 22 ++++++++++++++----- .../html/document/src/nsHTMLDocument.h | 2 ++ 5 files changed, 44 insertions(+), 7 deletions(-) diff --git a/mozilla/content/base/public/nsIScriptLoader.idl b/mozilla/content/base/public/nsIScriptLoader.idl index ecdb7ace771..9ca1281288a 100644 --- a/mozilla/content/base/public/nsIScriptLoader.idl +++ b/mozilla/content/base/public/nsIScriptLoader.idl @@ -42,7 +42,7 @@ interface nsIDocument; interface nsIScriptElement; interface nsIScriptLoaderObserver; -[scriptable, uuid(501209d3-7edf-437d-9948-3c6d1c08ef7a)] +[scriptable, uuid(339a4eb5-dac6-4034-8c43-f4f8c645ce57)] interface nsIScriptLoader : nsISupports { /** * Initialize loader with a document. The container of this document @@ -89,6 +89,12 @@ interface nsIScriptLoader : nsISupports { void processScriptElement(in nsIScriptElement aElement, in nsIScriptLoaderObserver aObserver); + /** + * Gets the currently executing script. This is useful if you want to + * generate a unique key based on the currently executing script. + */ + nsIScriptElement getCurrentScript(); + /** * Whether the loader is enabled or not. * When disabled, processing of new script elements is disabled. diff --git a/mozilla/content/base/src/nsScriptLoader.cpp b/mozilla/content/base/src/nsScriptLoader.cpp index d1af7bfac3f..58f2dfef9d7 100644 --- a/mozilla/content/base/src/nsScriptLoader.cpp +++ b/mozilla/content/base/src/nsScriptLoader.cpp @@ -579,6 +579,17 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement, return rv; } +nsresult +nsScriptLoader::GetCurrentScript(nsIScriptElement **aElement) +{ + NS_ENSURE_ARG_POINTER(aElement); + *aElement = mCurrentScript; + + NS_IF_ADDREF(*aElement); + + return NS_OK; +} + nsresult nsScriptLoader::FireErrorNotification(nsresult aResult, nsIScriptElement* aElement, @@ -715,11 +726,18 @@ nsScriptLoader::EvaluateScript(nsScriptLoadRequest* aRequest, ::JS_SetOptions(cx, options | JSOPTION_XML); } + // Update our current script. + nsCOMPtr oldCurrent = mCurrentScript; + mCurrentScript = aRequest->mElement; + PRBool isUndefined; context->EvaluateString(aScript, nsnull, principal, url.get(), aRequest->mLineNo, aRequest->mJSVersion, nsnull, &isUndefined); + // Put the old script back in case it wants to do anything else. + mCurrentScript = oldCurrent; + ::JS_ReportPendingException(cx); if (needE4X) { ::JS_SetOptions(cx, options); diff --git a/mozilla/content/base/src/nsScriptLoader.h b/mozilla/content/base/src/nsScriptLoader.h index 425b7efc168..89c70192d4d 100644 --- a/mozilla/content/base/src/nsScriptLoader.h +++ b/mozilla/content/base/src/nsScriptLoader.h @@ -84,6 +84,7 @@ protected: nsIDocument* mDocument; // [WEAK] nsCOMArray mObservers; nsCOMArray mPendingRequests; + nsCOMPtr mCurrentScript; PRBool mEnabled; }; diff --git a/mozilla/content/html/document/src/nsHTMLDocument.cpp b/mozilla/content/html/document/src/nsHTMLDocument.cpp index 4d332065ec2..f6228236607 100644 --- a/mozilla/content/html/document/src/nsHTMLDocument.cpp +++ b/mozilla/content/html/document/src/nsHTMLDocument.cpp @@ -1,4 +1,5 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set sw=2 ts=2 et tw=80: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -2088,8 +2089,6 @@ nsHTMLDocument::Open(const nsACString& aContentType, PRBool aReplace, return CallQueryInterface(this, aReturn); } -#define NS_GENERATE_PARSER_KEY() NS_INT32_TO_PTR((mIsWriting << 31) | (mWriteLevel & 0x7fffffff)) - NS_IMETHODIMP nsHTMLDocument::Clear() { @@ -2106,11 +2105,11 @@ nsHTMLDocument::Close() ++mWriteLevel; if (mContentType.EqualsLiteral("text/html")) { rv = mParser->Parse(NS_LITERAL_STRING(""), - NS_GENERATE_PARSER_KEY(), + GenerateParserKey(), mContentType, PR_FALSE, PR_TRUE); } else { - rv = mParser->Parse(EmptyString(), NS_GENERATE_PARSER_KEY(), + rv = mParser->Parse(EmptyString(), GenerateParserKey(), mContentType, PR_FALSE, PR_TRUE); } --mWriteLevel; @@ -2191,12 +2190,12 @@ nsHTMLDocument::WriteCommon(const nsAString& aText, // why pay that price when we don't need to? if (aNewlineTerminate) { rv = mParser->Parse(aText + new_line, - NS_GENERATE_PARSER_KEY(), + GenerateParserKey(), mContentType, PR_FALSE, (!mIsWriting || (mWriteLevel > 1))); } else { rv = mParser->Parse(aText, - NS_GENERATE_PARSER_KEY(), + GenerateParserKey(), mContentType, PR_FALSE, (!mIsWriting || (mWriteLevel > 1))); } @@ -3477,6 +3476,17 @@ nsHTMLDocument::RemoveWyciwygChannel(void) return rv; } +void * +nsHTMLDocument::GenerateParserKey(void) +{ + // The script loader provides us with the currently executing script element, + // which is guaranteed to be unique per script. + nsCOMPtr key; + mScriptLoader->GetCurrentScript(getter_AddRefs(key)); + + return key; +} + /* attribute DOMString designMode; */ NS_IMETHODIMP nsHTMLDocument::GetDesignMode(nsAString & aDesignMode) diff --git a/mozilla/content/html/document/src/nsHTMLDocument.h b/mozilla/content/html/document/src/nsHTMLDocument.h index fc8574832a8..4d70dfca015 100644 --- a/mozilla/content/html/document/src/nsHTMLDocument.h +++ b/mozilla/content/html/document/src/nsHTMLDocument.h @@ -246,6 +246,8 @@ protected: nsresult CreateAndAddWyciwygChannel(void); nsresult RemoveWyciwygChannel(void); + void *GenerateParserKey(void); + PRInt32 GetDefaultNamespaceID() const { return mDefaultNamespaceID;