--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -85,17 +85,16 @@ class nsIConsoleService;
class nsIStringBundleService;
class nsIStringBundle;
class nsIContentPolicy;
class nsILineBreaker;
class nsIWordBreaker;
class nsIJSRuntimeService;
class nsIEventListenerManager;
class nsIScriptContext;
-class nsIRunnable;
template<class E> class nsCOMArray;
class nsIPref;
class nsVoidArray;
struct JSRuntime;
class nsICaseConversion;
class nsIWidget;
class nsPIDOMWindow;
#ifdef MOZ_XTF
@@ -1173,55 +1172,16 @@ public:
*/
static void GetOfflineAppManifest(nsIDOMWindow *aWindow, nsIURI **aURI);
/**
* Check whether an application should be allowed to use offline APIs.
*/
static PRBool OfflineAppAllowed(nsIURI *aURI);
- /**
- * Increases the count of blockers preventing scripts from running.
- * NOTE: You might want to use nsAutoScriptBlocker rather than calling
- * this directly
- */
- static void AddScriptBlocker();
-
- /**
- * Decreases the count of blockers preventing scripts from running.
- * NOTE: You might want to use nsAutoScriptBlocker rather than calling
- * this directly
- *
- * WARNING! Calling this function could synchronously execute scripts.
- */
- static void RemoveScriptBlocker();
-
- /**
- * Add a runnable that is to be executed as soon as it's safe to execute
- * scripts.
- * NOTE: If it's currently safe to execute scripts, aRunnable will be run
- * synchronously before the function returns.
- *
- * @param aRunnable The nsIRunnable to run as soon as it's safe to execute
- * scripts. Passing null is allowed and results in nothing
- * happening. It is also allowed to pass an object that
- * has not yet been AddRefed.
- */
- static PRBool AddScriptRunner(nsIRunnable* aRunnable);
-
- /**
- * Returns true if it's safe to execute content script and false otherwise.
- *
- * The only known case where this lies is mutation events. They run, and can
- * run anything else, when this function returns false, but this is ok.
- */
- static PRBool IsSafeToRunScript() {
- return sScriptBlockerCount == 0;
- }
-
private:
static PRBool InitializeEventTable();
static nsresult doReparentContentWrapper(nsIContent *aChild,
JSContext *cx,
JSObject *aOldGlobal,
JSObject *aNewGlobal,
@@ -1284,19 +1244,16 @@ private:
static PRInt32 sScriptRootCount[NS_STID_ARRAY_UBOUND];
static PRUint32 sJSGCThingRootCount;
#ifdef IBMBIDI
static nsIBidiKeyboard* sBidiKeyboard;
#endif
static PRBool sInitialized;
- static PRUint32 sScriptBlockerCount;
- static nsCOMArray<nsIRunnable>* sBlockedScriptRunners;
- static PRUint32 sRunnersCountAtFirstBlocker;
};
#define NS_HOLD_JS_OBJECTS(obj, clazz) \
nsContentUtils::HoldJSObjects(NS_CYCLE_COLLECTION_UPCAST(obj, clazz), \
&NS_CYCLE_COLLECTION_NAME(clazz))
#define NS_DROP_JS_OBJECTS(obj, clazz) \
nsContentUtils::DropJSObjects(NS_CYCLE_COLLECTION_UPCAST(obj, clazz))
@@ -1305,17 +1262,16 @@ private:
class nsCxPusher
{
public:
nsCxPusher();
~nsCxPusher(); // Calls Pop();
// Returns PR_FALSE if something erroneous happened.
PRBool Push(nsISupports *aCurrentTarget);
- PRBool Push(JSContext *cx);
void Pop();
private:
nsCOMPtr<nsIJSContextStack> mStack;
nsCOMPtr<nsIScriptContext> mScx;
PRBool mScriptIsRunning;
};
@@ -1356,26 +1312,16 @@ private:
static nsIJSRuntimeService* sJSRuntimeService;
static JSRuntime* sJSScriptRuntime;
void* mPtr;
nsresult mResult;
};
-class nsAutoScriptBlocker {
-public:
- nsAutoScriptBlocker() {
- nsContentUtils::AddScriptBlocker();
- }
- ~nsAutoScriptBlocker() {
- nsContentUtils::RemoveScriptBlocker();
- }
-};
-
#define NS_AUTO_GCROOT_PASTE2(tok,line) tok##line
#define NS_AUTO_GCROOT_PASTE(tok,line) \
NS_AUTO_GCROOT_PASTE2(tok,line)
#define NS_AUTO_GCROOT(ptr, result) \ \
nsAutoGCRoot NS_AUTO_GCROOT_PASTE(_autoGCRoot_, __LINE__) \
(ptr, result)
#define NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(_class) \
--- a/content/base/public/nsIObjectLoadingContent.idl
+++ b/content/base/public/nsIObjectLoadingContent.idl
@@ -38,17 +38,17 @@
#include "nsISupports.idl"
interface nsIObjectFrame;
interface nsIPluginInstance;
/**
* This interface represents a content node that loads objects.
*/
-[scriptable, uuid(90ab443e-3e99-405e-88c9-9c42adaa3217)]
+[scriptable, uuid(42f9358e-300f-4a44-afd7-7830b750e955)]
interface nsIObjectLoadingContent : nsISupports
{
const unsigned long TYPE_LOADING = 0;
const unsigned long TYPE_IMAGE = 1;
const unsigned long TYPE_PLUGIN = 2;
const unsigned long TYPE_DOCUMENT = 3;
const unsigned long TYPE_NULL = 4;
@@ -66,23 +66,16 @@ interface nsIObjectLoadingContent : nsIS
/**
* Gets the content type that corresponds to the give MIME type. See the
* constants above for the list of possible values. If nothing else fits,
* TYPE_NULL will be returned.
*/
unsigned long getContentTypeForMIMEType(in AUTF8String aMimeType);
- /**
- * Returns the plugin instance if it has already been instantiated. This
- * will never instantiate the plugin and so is safe to call even when
- * content script must not execute.
- */
- [noscript] readonly attribute nsIPluginInstance pluginInstance;
-
/**
* Makes sure that a frame for this object exists, and that the plugin is
* instantiated. This method does nothing if the type is not #TYPE_PLUGIN.
* There is no guarantee that there will be a frame after this method is
* called; for example, the node may have a display:none style. If plugin
* instantiation is possible, it will be done synchronously by this method,
* and the plugin instance will be returned. A success return value does not
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -144,18 +144,16 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_
#include "nsCompressedCharMap.h"
#include "nsINativeKeyBindings.h"
#include "nsIDOMNSUIEvent.h"
#include "nsIDOMNSEvent.h"
#include "nsIPrivateDOMEvent.h"
#include "nsXULPopupManager.h"
#include "nsIPermissionManager.h"
#include "nsIScriptObjectPrincipal.h"
-#include "nsIRunnable.h"
-#include "nsDOMJSUtils.h"
#ifdef IBMBIDI
#include "nsIBidiKeyboard.h"
#endif
#include "nsCycleCollectionParticipant.h"
// for ReportToConsole
#include "nsIStringBundle.h"
@@ -192,19 +190,16 @@ nsIWordBreaker *nsContentUtils::sWordBre
nsICaseConversion *nsContentUtils::sCaseConv;
nsVoidArray *nsContentUtils::sPtrsToPtrsToRelease;
nsIScriptRuntime *nsContentUtils::sScriptRuntimes[NS_STID_ARRAY_UBOUND];
PRInt32 nsContentUtils::sScriptRootCount[NS_STID_ARRAY_UBOUND];
PRUint32 nsContentUtils::sJSGCThingRootCount;
#ifdef IBMBIDI
nsIBidiKeyboard *nsContentUtils::sBidiKeyboard = nsnull;
#endif
-PRUint32 nsContentUtils::sScriptBlockerCount = 0;
-nsCOMArray<nsIRunnable>* nsContentUtils::sBlockedScriptRunners = nsnull;
-PRUint32 nsContentUtils::sRunnersCountAtFirstBlocker = 0;
nsIJSRuntimeService *nsAutoGCRoot::sJSRuntimeService;
JSRuntime *nsAutoGCRoot::sJSScriptRuntime;
PRBool nsContentUtils::sInitialized = PR_FALSE;
static PLDHashTable sEventListenerManagersHash;
@@ -323,19 +318,16 @@ nsContentUtils::Init()
if (!PL_DHashTableInit(&sEventListenerManagersHash, &hash_table_ops,
nsnull, sizeof(EventListenerManagerMapEntry), 16)) {
sEventListenerManagersHash.ops = nsnull;
return NS_ERROR_OUT_OF_MEMORY;
}
}
- sBlockedScriptRunners = new nsCOMArray<nsIRunnable>;
- NS_ENSURE_TRUE(sBlockedScriptRunners, NS_ERROR_OUT_OF_MEMORY);
-
sInitialized = PR_TRUE;
return NS_OK;
}
PRBool
nsContentUtils::InitializeEventTable() {
NS_ASSERTION(!sEventTable, "EventTable already initialized!");
@@ -824,22 +816,16 @@ nsContentUtils::Shutdown()
// wrapper table.
if (sEventListenerManagersHash.entryCount == 0) {
PL_DHashTableFinish(&sEventListenerManagersHash);
sEventListenerManagersHash.ops = nsnull;
}
}
- NS_ASSERTION(!sBlockedScriptRunners ||
- sBlockedScriptRunners->Count() == 0,
- "How'd this happen?");
- delete sBlockedScriptRunners;
- sBlockedScriptRunners = nsnull;
-
nsAutoGCRoot::Shutdown();
}
// static
PRBool
nsContentUtils::IsCallerTrustedForCapability(const char* aCapability)
{
// The secman really should handle UniversalXPConnect case, since that
@@ -2597,64 +2583,47 @@ nsCxPusher::Push(nsISupports *aCurrentTa
NS_ENSURE_TRUE(sgo || !hasHadScriptObject, PR_FALSE);
}
} else {
sgo = do_QueryInterface(aCurrentTarget);
}
JSContext *cx = nsnull;
- nsCOMPtr<nsIScriptContext> scx;
-
if (sgo) {
- scx = sgo->GetContext();
-
- if (scx) {
- cx = (JSContext *)scx->GetNativeContext();
+ mScx = sgo->GetContext();
+
+ if (mScx) {
+ cx = (JSContext *)mScx->GetNativeContext();
}
// Bad, no JSContext from script global object!
NS_ENSURE_TRUE(cx, PR_FALSE);
}
- // If there's no native context in the script context it must be
- // in the process or being torn down. We don't want to notify the
- // script context about scripts having been evaluated in such a
- // case, calling with a null cx is fine in that case.
- return Push(cx);
-}
-
-PRBool
-nsCxPusher::Push(JSContext *cx)
-{
- if (mScx) {
- NS_ERROR("Whaaa! No double pushing with nsCxPusher::Push()!");
-
- return PR_FALSE;
- }
-
if (cx) {
- mScx = GetScriptContextFromJSContext(cx);
- if (!mScx) {
- // Should probably return PR_FALSE. See bug 416916.
- return PR_TRUE;
- }
-
if (!mStack) {
mStack = do_GetService(kJSStackContractID);
}
if (mStack) {
if (IsContextOnStack(mStack, cx)) {
// If the context is on the stack, that means that a script
// is running at the moment in the context.
mScriptIsRunning = PR_TRUE;
}
mStack->Push(cx);
}
+ } else {
+ // If there's no native context in the script context it must be
+ // in the process or being torn down. We don't want to notify the
+ // script context about scripts having been evaluated in such a
+ // case, so null out mScx.
+
+ mScx = nsnull;
}
return PR_TRUE;
}
void
nsCxPusher::Pop()
{
if (!mScx || !mStack) {
@@ -3988,75 +3957,16 @@ nsContentUtils::DOMEventToNativeKeyEvent
aNativeEvent->nativeEvent = GetNativeEvent(aDOMEvent);
return PR_TRUE;
}
/* static */
void
-nsContentUtils::AddScriptBlocker()
-{
- if (!sScriptBlockerCount) {
- NS_ASSERTION(sRunnersCountAtFirstBlocker == 0,
- "Should not already have a count");
- sRunnersCountAtFirstBlocker = sBlockedScriptRunners->Count();
- }
- ++sScriptBlockerCount;
-}
-
-/* static */
-void
-nsContentUtils::RemoveScriptBlocker()
-{
- --sScriptBlockerCount;
- if (sScriptBlockerCount) {
- return;
- }
-
- PRUint32 firstBlocker = sRunnersCountAtFirstBlocker;
- PRUint32 lastBlocker = sBlockedScriptRunners->Count();
- sRunnersCountAtFirstBlocker = 0;
- NS_ASSERTION(firstBlocker <= lastBlocker,
- "bad sRunnersCountAtFirstBlocker");
-
- while (firstBlocker < lastBlocker) {
- nsCOMPtr<nsIRunnable> runnable = (*sBlockedScriptRunners)[firstBlocker];
- sBlockedScriptRunners->RemoveObjectAt(firstBlocker);
- --lastBlocker;
-
- runnable->Run();
- NS_ASSERTION(lastBlocker == sBlockedScriptRunners->Count() &&
- sRunnersCountAtFirstBlocker == 0,
- "Bad count");
- NS_ASSERTION(!sScriptBlockerCount, "This is really bad");
- }
-}
-
-
-/* static */
-PRBool
-nsContentUtils::AddScriptRunner(nsIRunnable* aRunnable)
-{
- if (!aRunnable) {
- return PR_FALSE;
- }
-
- if (sScriptBlockerCount) {
- return sBlockedScriptRunners->AppendObject(aRunnable);
- }
-
- nsCOMPtr<nsIRunnable> run = aRunnable;
- run->Run();
-
- return PR_TRUE;
-}
-
-/* static */
-void
nsContentUtils::HidePopupsInDocument(nsIDocument* aDocument)
{
NS_PRECONDITION(aDocument, "Null document");
#ifdef MOZ_XUL
nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
if (pm) {
nsCOMPtr<nsISupports> container = aDocument->GetContainer();
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -2696,34 +2696,38 @@ nsDocument::RemoveObserver(nsIDocumentOb
void
nsDocument::BeginUpdate(nsUpdateType aUpdateType)
{
if (mUpdateNestLevel == 0) {
mBindingManager->BeginOutermostUpdate();
}
++mUpdateNestLevel;
+ if (mScriptLoader) {
+ mScriptLoader->AddExecuteBlocker();
+ }
NS_DOCUMENT_NOTIFY_OBSERVERS(BeginUpdate, (this, aUpdateType));
-
- nsContentUtils::AddScriptBlocker();
}
void
nsDocument::EndUpdate(nsUpdateType aUpdateType)
{
- nsContentUtils::RemoveScriptBlocker();
NS_DOCUMENT_NOTIFY_OBSERVERS(EndUpdate, (this, aUpdateType));
--mUpdateNestLevel;
if (mUpdateNestLevel == 0) {
// This set of updates may have created XBL bindings. Let the
// binding manager know we're done.
mBindingManager->EndOutermostUpdate();
}
+ if (mScriptLoader) {
+ mScriptLoader->RemoveExecuteBlocker();
+ }
+
if (mUpdateNestLevel == 0) {
PRUint32 length = mFinalizableFrameLoaders.Length();
if (length > 0) {
nsTArray<nsRefPtr<nsFrameLoader> > loaders;
mFinalizableFrameLoaders.SwapElements(loaders);
for (PRInt32 i = 0; i < length; ++i) {
loaders[i]->Finalize();
}
--- a/content/base/src/nsObjectLoadingContent.cpp
+++ b/content/base/src/nsObjectLoadingContent.cpp
@@ -122,21 +122,20 @@ NS_IMETHODIMP
nsAsyncInstantiateEvent::Run()
{
// Check if we've been "revoked"
if (mContent->mPendingInstantiateEvent != this)
return NS_OK;
mContent->mPendingInstantiateEvent = nsnull;
// Make sure that we still have the right frame (NOTE: we don't need to check
- // the type here - GetExistingFrame() only returns object frames, and that
- // means we're a plugin)
+ // the type here - GetFrame() only returns object frames, and that means we're
+ // a plugin)
// Also make sure that we still refer to the same data.
- nsIObjectFrame* frame = mContent->
- GetExistingFrame(nsObjectLoadingContent::eFlushContent);
+ nsIObjectFrame* frame = mContent->GetFrame(PR_FALSE);
if (frame == mFrame &&
mContent->mURI == mURI &&
mContent->mContentType.Equals(mContentType)) {
if (LOG_ENABLED()) {
nsCAutoString spec;
if (mURI) {
mURI->GetSpec(spec);
}
@@ -512,17 +511,17 @@ nsObjectLoadingContent::OnStartRequest(n
case eType_Plugin:
mInstantiating = PR_TRUE;
if (mType != newType) {
// This can go away once plugin loading moves to content (bug 90268)
mType = newType;
notifier.Notify();
}
nsIObjectFrame* frame;
- frame = GetExistingFrame(eFlushLayout);
+ frame = GetFrame(PR_TRUE);
if (!frame) {
// Do nothing in this case: This is probably due to a display:none
// frame. If we ever get a frame, HasNewFrame will do the right thing.
// Abort the load though, we have no use for the data.
mInstantiating = PR_FALSE;
return NS_BINDING_ABORTED;
}
@@ -578,17 +577,17 @@ nsObjectLoadingContent::OnStartRequest(n
if (mContentType.EqualsLiteral("application/x-director")) {
LOG(("OBJLC [%p]: (ignoring)\n", this));
rv = NS_OK; // otherwise, the AutoFallback will make us fall back
return NS_BINDING_ABORTED;
}
#endif
Fallback(PR_FALSE);
} else if (mType == eType_Plugin) {
- nsIObjectFrame* frame = GetExistingFrame(eFlushContent);
+ nsIObjectFrame* frame = GetFrame(PR_FALSE);
if (frame) {
// We have to notify the wrapper here instead of right after
// Instantiate because the plugin only gets instantiated by
// OnStartRequest, not by Instantiate.
frame->TryNotifyContentObjectWrapper();
}
}
return rv;
@@ -667,17 +666,17 @@ nsObjectLoadingContent::EnsureInstantiat
// Must set our out parameter to null as we have various early returns with
// an NS_OK result.
*aInstance = nsnull;
if (mType != eType_Plugin) {
return NS_OK;
}
- nsIObjectFrame* frame = GetExistingFrame(eFlushContent);
+ nsIObjectFrame* frame = GetFrame(PR_FALSE);
if (frame) {
// If we have a frame, we may have pending instantiate events; revoke
// them.
if (mPendingInstantiateEvent) {
LOG(("OBJLC [%p]: Revoking pending instantiate event\n", this));
mPendingInstantiateEvent = nsnull;
}
} else {
@@ -704,17 +703,17 @@ nsObjectLoadingContent::EnsureInstantiat
nsPresShellIterator iter(doc);
nsCOMPtr<nsIPresShell> shell;
while ((shell = iter.GetNextShell())) {
shell->RecreateFramesFor(thisContent);
}
mInstantiating = PR_FALSE;
- frame = GetExistingFrame(eFlushContent);
+ frame = GetFrame(PR_FALSE);
if (!frame) {
return NS_OK;
}
}
nsIFrame *nsiframe;
CallQueryInterface(frame, &nsiframe);
nsWeakFrame weakFrame(nsiframe);
@@ -768,29 +767,16 @@ nsObjectLoadingContent::HasNewFrame(nsIO
// when the event runs.
mPendingInstantiateEvent = event;
}
}
return NS_OK;
}
NS_IMETHODIMP
-nsObjectLoadingContent::GetPluginInstance(nsIPluginInstance** aInstance)
-{
- *aInstance = nsnull;
-
- nsIObjectFrame* objFrame = GetExistingFrame(eDontFlush);
- if (!objFrame) {
- return NS_OK;
- }
-
- return objFrame->GetPluginInstance(*aInstance);
-}
-
-NS_IMETHODIMP
nsObjectLoadingContent::GetContentTypeForMIMEType(const nsACString& aMIMEType,
PRUint32* aType)
{
*aType = GetTypeOfContent(PromiseFlatCString(aMIMEType));
return NS_OK;
}
// nsIInterfaceRequestor
@@ -1536,22 +1522,23 @@ nsObjectLoadingContent::GetObjectBaseURI
thisContent->GetOwnerDoc(),
baseURI);
} else {
baseURI.swap(*aURI);
}
}
nsIObjectFrame*
-nsObjectLoadingContent::GetExistingFrame(FlushType aFlushType)
+nsObjectLoadingContent::GetFrame(PRBool aFlushLayout)
{
nsCOMPtr<nsIContent> thisContent =
do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
NS_ASSERTION(thisContent, "must be a content");
+ PRBool flushed = PR_FALSE;
nsIFrame* frame;
do {
nsIDocument* doc = thisContent->GetCurrentDoc();
if (!doc) {
return nsnull; // No current doc -> no frame
}
nsIPresShell* shell = doc->GetPrimaryShell();
@@ -1559,27 +1546,27 @@ nsObjectLoadingContent::GetExistingFrame
return nsnull; // No presentation -> no frame
}
frame = shell->GetPrimaryFrameFor(thisContent);
if (!frame) {
return nsnull;
}
- if (aFlushType == eDontFlush) {
+ if (flushed) {
break;
}
// OK, let's flush out and try again. Note that we want to reget
// the document, etc, since flushing might run script.
mozFlushType flushType =
- aFlushType == eFlushLayout ? Flush_Layout : Flush_ContentAndNotify;
+ aFlushLayout ? Flush_Layout : Flush_ContentAndNotify;
doc->FlushPendingNotifications(flushType);
- aFlushType = eDontFlush;
+ flushed = PR_TRUE;
} while (1);
nsIObjectFrame* objFrame;
CallQueryInterface(frame, &objFrame);
return objFrame;
}
void
@@ -1598,17 +1585,17 @@ nsObjectLoadingContent::HandleBeingBlock
}
}
}
nsresult
nsObjectLoadingContent::TryInstantiate(const nsACString& aMIMEType,
nsIURI* aURI)
{
- nsIObjectFrame* frame = GetExistingFrame(eFlushContent);
+ nsIObjectFrame* frame = GetFrame(PR_FALSE);
if (!frame) {
LOG(("OBJLC [%p]: No frame yet\n", this));
return NS_OK; // Not a failure to have no frame
}
nsIFrame* iframe;
CallQueryInterface(frame, &iframe);
if (iframe->GetStateBits() & NS_FRAME_FIRST_REFLOW) {
LOG(("OBJLC [%p]: Frame hasn't been reflown yet\n", this));
--- a/content/base/src/nsObjectLoadingContent.h
+++ b/content/base/src/nsObjectLoadingContent.h
@@ -265,37 +265,24 @@ class nsObjectLoadingContent : public ns
/**
* Gets the base URI to be used for this object. This differs from
* nsIContent::GetBaseURI in that it takes codebase attributes into
* account.
*/
void GetObjectBaseURI(nsIContent* thisContent, nsIURI** aURI);
-
/**
* Gets the frame that's associated with this content node in
- * presentation 0. Always returns null if the node doesn't currently
- * have a frame.
- *
- * @param aFlush When eFlushContent will flush content notifications
- * before returning a non-null value.
- * When eFlushLayout will flush layout and content
- * notifications before returning a non-null value.
- * When eDontFlush will never flush.
- *
- * eFlushLayout is needed in some cases by plug-ins to ensure
- * that NPP_SetWindow() gets called (from nsObjectFrame::DidReflow).
+ * presentation 0. If aFlushLayout is true, this function will
+ * flush layout before trying to get the frame. This is needed
+ * in some cases by plug-ins to ensure that NPP_SetWindow() gets
+ * called (from nsObjectFrame::DidReflow).
*/
- enum FlushType {
- eFlushContent,
- eFlushLayout,
- eDontFlush
- };
- nsIObjectFrame* GetExistingFrame(FlushType aFlushType);
+ nsIObjectFrame* GetFrame(PRBool aFlushLayout);
/**
* Handle being blocked by a content policy. aStatus is the nsresult
* return value of the Should* call, while aRetval is what it returned in
* its out parameter.
*/
void HandleBeingBlockedByContentPolicy(nsresult aStatus,
PRInt16 aRetval);
@@ -403,13 +390,13 @@ class nsObjectLoadingContent : public ns
*/
PRBool mInstantiating : 1;
// Blocking status from content policy
PRBool mUserDisabled : 1;
PRBool mSuppressed : 1;
// Whether we fell back because of an unsupported type
PRBool mTypeUnsupported:1;
- friend class nsAsyncInstantiateEvent;
+ friend struct nsAsyncInstantiateEvent;
};
#endif
--- a/content/base/src/nsScriptLoader.cpp
+++ b/content/base/src/nsScriptLoader.cpp
@@ -154,17 +154,18 @@ NS_IMPL_THREADSAFE_ISUPPORTS0(nsScriptLo
//////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////
nsScriptLoader::nsScriptLoader(nsIDocument *aDocument)
: mDocument(aDocument),
mBlockerCount(0),
- mEnabled(PR_TRUE)
+ mEnabled(PR_TRUE),
+ mHadPendingScripts(PR_FALSE)
{
}
nsScriptLoader::~nsScriptLoader()
{
mObservers.Clear();
for (PRInt32 i = 0; i < mPendingRequests.Count(); i++) {
@@ -485,42 +486,33 @@ nsScriptLoader::ProcessScriptElement(nsI
request->mLoading = PR_FALSE;
request->mIsInline = PR_TRUE;
request->mURI = mDocument->GetDocumentURI();
request->mLineNo = aElement->GetScriptLineNumber();
// If we've got existing pending requests, add ourselves
// to this list.
- if (mPendingRequests.Count() == 0 && ReadyToExecuteScripts() &&
- nsContentUtils::IsSafeToRunScript()) {
+ if (mPendingRequests.Count() == 0 && ReadyToExecuteScripts()) {
return ProcessRequest(request);
}
}
// Add the request to our pending requests list
NS_ENSURE_TRUE(mPendingRequests.AppendObject(request),
NS_ERROR_OUT_OF_MEMORY);
- // If there weren't any pending requests before, and this one is
- // ready to execute, do that as soon as it's safe.
- if (mPendingRequests.Count() == 1 && !request->mLoading &&
- ReadyToExecuteScripts()) {
- nsContentUtils::AddScriptRunner(new nsRunnableMethod<nsScriptLoader>(this,
- &nsScriptLoader::ProcessPendingRequests));
- }
-
// Added as pending request, now we can send blocking back
return NS_ERROR_HTMLPARSER_BLOCK;
}
nsresult
nsScriptLoader::ProcessRequest(nsScriptLoadRequest* aRequest)
{
- NS_ASSERTION(ReadyToExecuteScripts() && nsContentUtils::IsSafeToRunScript(),
+ NS_ASSERTION(ReadyToExecuteScripts(),
"Caller forgot to check ReadyToExecuteScripts()");
NS_ENSURE_ARG(aRequest);
nsAFlatString* script;
nsAutoString textData;
// If there's no script text, we try to get it from the element
if (aRequest->mIsInline) {
--- a/content/base/src/nsScriptLoader.h
+++ b/content/base/src/nsScriptLoader.h
@@ -142,25 +142,41 @@ public:
ProcessPendingRequestsAsync();
}
mEnabled = aEnabled;
}
/**
* Add/remove blocker. Blockers will stop scripts from executing, but not
* from loading.
+ * NOTE! Calling RemoveExecuteBlocker could potentially execute pending
+ * scripts synchronously. In other words, it should not be done at 'unsafe'
+ * times
*/
void AddExecuteBlocker()
{
- ++mBlockerCount;
+ if (!mBlockerCount++) {
+ mHadPendingScripts = mPendingRequests.Count() != 0;
+ }
}
void RemoveExecuteBlocker()
{
if (!--mBlockerCount) {
- ProcessPendingRequestsAsync();
+ // If there were pending scripts then the newly added scripts will
+ // execute once whatever event triggers the pending scripts fires.
+ // However, due to synchronous loads and pushed event queues it's
+ // possible that the requests that were there have already been processed
+ // if so we need to process any new requests asynchronously.
+ // Ideally that should be fixed such that it can't happen.
+ if (mHadPendingScripts) {
+ ProcessPendingRequestsAsync();
+ }
+ else {
+ ProcessPendingRequests();
+ }
}
}
/**
* Convert the given buffer to a UTF-16 string.
* @param aChannel Channel corresponding to the data. May be null.
* @param aData The data to convert
* @param aLength Length of the data
@@ -225,11 +241,12 @@ protected:
nsIDocument* mDocument; // [WEAK]
nsCOMArray<nsIScriptLoaderObserver> mObservers;
nsCOMArray<nsScriptLoadRequest> mPendingRequests;
nsCOMPtr<nsIScriptElement> mCurrentScript;
// XXXbz do we want to cycle-collect these or something? Not sure.
nsTArray< nsRefPtr<nsScriptLoader> > mPendingChildLoaders;
PRUint32 mBlockerCount;
PRPackedBool mEnabled;
+ PRPackedBool mHadPendingScripts;
};
#endif //__nsScriptLoader_h__
--- a/content/xbl/src/nsBindingManager.cpp
+++ b/content/xbl/src/nsBindingManager.cpp
@@ -967,23 +967,38 @@ void
nsBindingManager::ProcessAttachedQueue(PRUint32 aSkipSize)
{
if (mProcessingAttachedStack || mAttachedStack.Length() <= aSkipSize)
return;
mProcessingAttachedStack = PR_TRUE;
PRUint32 currentIndex = aSkipSize;
- // Excute constructors. Do this from high index to low
while (mAttachedStack.Length() > aSkipSize) {
- PRUint32 lastItem = mAttachedStack.Length() - 1;
- nsRefPtr<nsXBLBinding> binding = mAttachedStack.ElementAt(lastItem);
- mAttachedStack.RemoveElementAt(lastItem);
- if (binding) {
- binding->ExecuteAttachedHandler();
+ // First install all implementations. Do this from low index to high
+ // since that way we'll automatically get any new bindings added in the
+ // process.
+ for (; currentIndex < mAttachedStack.Length(); ++currentIndex) {
+ nsRefPtr<nsXBLBinding> binding = mAttachedStack.ElementAt(currentIndex);
+ if (binding) {
+ nsresult rv = binding->EnsureScriptAPI();
+ if (NS_FAILED(rv)) {
+ mAttachedStack[currentIndex] = nsnull;
+ }
+ }
+ }
+
+ // Then excute constructors. Do this from high index to low
+ while (currentIndex > aSkipSize && currentIndex == mAttachedStack.Length()) {
+ --currentIndex;
+ nsRefPtr<nsXBLBinding> binding = mAttachedStack.ElementAt(currentIndex);
+ mAttachedStack.RemoveElementAt(currentIndex);
+ if (binding) {
+ binding->ExecuteAttachedHandler();
+ }
}
}
// If NodeWillBeDestroyed has run we don't want to clobber
// mProcessingAttachedStack set there.
if (mDocument) {
mProcessingAttachedStack = PR_FALSE;
}
@@ -1517,16 +1532,26 @@ nsBindingManager::BeginOutermostUpdate()
void
nsBindingManager::EndOutermostUpdate()
{
if (!mProcessingAttachedStack) {
ProcessAttachedQueue(mAttachedStackSizeOnOutermost);
mAttachedStackSizeOnOutermost = 0;
}
+ else {
+ PRUint32 i = mAttachedStackSizeOnOutermost;
+ for (; i < mAttachedStack.Length(); ++i) {
+ nsRefPtr<nsXBLBinding> binding = mAttachedStack[i];
+ nsresult rv = binding->EnsureScriptAPI();
+ if (NS_FAILED(rv)) {
+ mAttachedStack[i] = nsnull;
+ }
+ }
+ }
}
void
nsBindingManager::HandleChildInsertion(nsIContent* aContainer,
nsIContent* aChild,
PRUint32 aIndexInContainer,
PRBool aAppend)
{
--- a/content/xbl/src/nsXBLBinding.cpp
+++ b/content/xbl/src/nsXBLBinding.cpp
@@ -267,17 +267,18 @@ nsXBLJSClass::Destroy()
// Implementation /////////////////////////////////////////////////////////////////
// Constructors/Destructors
nsXBLBinding::nsXBLBinding(nsXBLPrototypeBinding* aBinding)
: mPrototypeBinding(aBinding),
mInsertionPointTable(nsnull),
mIsStyleBinding(PR_TRUE),
- mMarkedForDeath(PR_FALSE)
+ mMarkedForDeath(PR_FALSE),
+ mInstalledAPI(PR_FALSE)
{
NS_ASSERTION(mPrototypeBinding, "Must have a prototype binding!");
// Grab a ref to the document info so the prototype binding won't die
NS_ADDREF(mPrototypeBinding->XBLDocumentInfo());
}
nsXBLBinding::~nsXBLBinding(void)
@@ -780,16 +781,32 @@ nsXBLBinding::GenerateAnonymousContent()
}
// Conserve space by wiping the attributes off the clone.
if (mContent)
mContent->UnsetAttr(namespaceID, name, PR_FALSE);
}
}
+nsresult
+nsXBLBinding::EnsureScriptAPI()
+{
+ if (mInstalledAPI) {
+ return NS_OK;
+ }
+
+ // Set mInstalledAPI right away since we'll recurse into here from
+ // nsElementSH::PostCreate when InstallImplementation is called.
+ mInstalledAPI = PR_TRUE;
+
+ InstallEventHandlers();
+
+ return InstallImplementation();
+}
+
void
nsXBLBinding::InstallEventHandlers()
{
// Don't install handlers if scripts aren't allowed.
if (AllowScripts()) {
// Fetch the handlers prototypes for this binding.
nsXBLPrototypeHandler* handlerChain = mPrototypeBinding->GetPrototypeHandlers();
--- a/content/xbl/src/nsXBLBinding.h
+++ b/content/xbl/src/nsXBLBinding.h
@@ -115,18 +115,17 @@ public:
PRBool HasStyleSheets() const;
PRBool InheritsStyle() const;
PRBool ImplementsInterface(REFNSIID aIID) const;
PRBool ShouldBuildChildFrames() const;
void GenerateAnonymousContent();
void InstallAnonymousContent(nsIContent* aAnonParent, nsIContent* aElement);
- void InstallEventHandlers();
- nsresult InstallImplementation();
+ nsresult EnsureScriptAPI();
void ExecuteAttachedHandler();
void ExecuteDetachedHandler();
void UnhookEventHandlers();
nsIAtom* GetBaseTag(PRInt32* aNameSpaceID);
nsXBLBinding* RootBinding();
nsXBLBinding* GetFirstStyleBinding();
@@ -163,24 +162,30 @@ public:
PRBool AllowScripts(); // XXX make const
void RemoveInsertionParent(nsIContent* aParent);
PRBool HasInsertionParent(nsIContent* aParent);
// MEMBER VARIABLES
protected:
+ // These two functions recursively install the event handlers
+ // and implementation on this binding and its base class bindings.
+ // External callers should call EnsureScriptAPI instead.
+ void InstallEventHandlers();
+ nsresult InstallImplementation();
nsAutoRefCnt mRefCnt;
nsXBLPrototypeBinding* mPrototypeBinding; // Weak, but we're holding a ref to the docinfo
nsCOMPtr<nsIContent> mContent; // Strong. Our anonymous content stays around with us.
nsRefPtr<nsXBLBinding> mNextBinding; // Strong. The derived binding owns the base class bindings.
nsIContent* mBoundElement; // [WEAK] We have a reference, but we don't own it.
// A hash from nsIContent* -> (a sorted array of nsXBLInsertionPoint)
nsClassHashtable<nsISupportsHashKey, nsInsertionPointList>* mInsertionPointTable;
PRPackedBool mIsStyleBinding;
PRPackedBool mMarkedForDeath;
+ PRPackedBool mInstalledAPI;
};
#endif // nsXBLBinding_h_
--- a/content/xbl/src/nsXBLService.cpp
+++ b/content/xbl/src/nsXBLService.cpp
@@ -558,23 +558,16 @@ nsXBLService::LoadBindings(nsIContent* a
}
// Set the binding's bound element.
newBinding->SetBoundElement(aContent);
// Tell the binding to build the anonymous content.
newBinding->GenerateAnonymousContent();
- // Tell the binding to install event handlers
- newBinding->InstallEventHandlers();
-
- // Set up our properties
- rv = newBinding->InstallImplementation();
- NS_ENSURE_SUCCESS(rv, rv);
-
// Figure out if we have any scoped sheets. If so, we do a second resolve.
*aResolveStyle = newBinding->HasStyleSheets();
newBinding.swap(*aBinding);
return NS_OK;
}
--- a/dom/src/base/nsDOMClassInfo.cpp
+++ b/dom/src/base/nsDOMClassInfo.cpp
@@ -54,18 +54,16 @@
#include "nsIScriptError.h"
#include "nsXPIDLString.h"
#include "nsReadableUtils.h"
#include "nsUnicharUtils.h"
#include "xptcall.h"
#include "prprf.h"
#include "nsTArray.h"
#include "nsCSSValue.h"
-#include "nsIRunnable.h"
-#include "nsThreadUtils.h"
// JavaScript includes
#include "jsapi.h"
#include "jsprvtd.h" // we are using private JS typedefs...
#include "jscntxt.h"
#include "jsdbgapi.h"
#include "jsnum.h"
#include "jsscope.h"
@@ -7136,27 +7134,30 @@ nsElementSH::PostCreate(nsIXPConnectWrap
// return here.
return NS_OK;
}
// We must ensure that the XBL Binding is installed before we hand
// back this object.
+ nsRefPtr<nsXBLBinding> binding;
if (content->HasFlag(NODE_MAY_BE_IN_BINDING_MNGR) &&
- doc->BindingManager()->GetBinding(content)) {
- // There's already a binding for this element so nothing left to
- // be done here.
-
- // In theory we could call ExecuteAttachedHandler here when it's safe to
- // run script if we also removed the binding from the PAQ queue, but that
- // seems like a scary change that would mosly just add more
- // inconsistencies.
-
- return NS_OK;
+ (binding = doc->BindingManager()->GetBinding(content))) {
+ // There's already a binding for this element, make sure that
+ // the script API has been installed.
+ // Note that this could end up recusing into code that calls
+ // WrapNative. So don't do anything important beyond this point
+ // as that will not be done to the wrapper returned from that
+ // WrapNative call.
+ // In theory we could also call ExecuteAttachedHandler here if
+ // we also removed the binding from the PAQ queue, but that seems
+ // like a scary change that would mosly just add more inconsistencies.
+
+ return binding->EnsureScriptAPI();
}
// See if we have a frame.
nsIPresShell *shell = doc->GetPrimaryShell();
if (!shell) {
return NS_OK;
}
@@ -7170,17 +7171,16 @@ nsElementSH::PostCreate(nsIXPConnectWrap
}
// Get the computed -moz-binding directly from the style context
nsPresContext *pctx = shell->GetPresContext();
NS_ENSURE_TRUE(pctx, NS_ERROR_UNEXPECTED);
// Make sure the style context goes away _before_ we execute the binding
// constructor, since the constructor can destroy the relevant presshell.
- nsRefPtr<nsXBLBinding> binding;
{
// Scope for the nsRefPtr
nsRefPtr<nsStyleContext> sc = pctx->StyleSet()->ResolveStyleFor(content,
nsnull);
NS_ENSURE_TRUE(sc, NS_ERROR_FAILURE);
nsCSSValue::URL *bindingURL = sc->GetStyleDisplay()->mBinding;
if (!bindingURL) {
@@ -7195,23 +7195,27 @@ nsElementSH::PostCreate(nsIXPConnectWrap
NS_ENSURE_TRUE(xblService, NS_ERROR_NOT_AVAILABLE);
xblService->LoadBindings(content, bindingURL->mURI,
bindingURL->mOriginPrincipal, PR_FALSE,
getter_AddRefs(binding), &dummy);
}
if (binding) {
- if (nsContentUtils::IsSafeToRunScript()) {
- binding->ExecuteAttachedHandler();
- }
- else {
- nsContentUtils::AddScriptRunner(new nsRunnableMethod<nsXBLBinding>(
- binding, &nsXBLBinding::ExecuteAttachedHandler));
- }
+
+#ifdef DEBUG
+ PRBool safeToRunScript = PR_FALSE;
+ pctx->PresShell()->IsSafeToFlush(safeToRunScript);
+ NS_ASSERTION(safeToRunScript, "Wrapping when it's not safe to flush");
+#endif
+
+ rv = binding->EnsureScriptAPI();
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ binding->ExecuteAttachedHandler();
}
return NS_OK;
}
NS_IMETHODIMP
nsElementSH::Enumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, PRBool *_retval)
@@ -8792,34 +8796,27 @@ nsHTMLSelectElementSH::SetProperty(nsIXP
// This resolve hook makes embed.nsIFoo work as if
// QueryInterface(Components.interfaces.nsIFoo) was called on the
// plugin instance, the result of calling QI, assuming it's
// successful, will be defined on the embed element as a nsIFoo
// property.
// static
nsresult
-nsHTMLPluginObjElementSH::GetPluginInstanceIfSafe(nsIXPConnectWrappedNative *wrapper,
- nsIPluginInstance **_result)
+nsHTMLPluginObjElementSH::GetPluginInstance(nsIXPConnectWrappedNative *wrapper,
+ nsIPluginInstance **_result)
{
*_result = nsnull;
nsCOMPtr<nsIContent> content(do_QueryWrappedNative(wrapper));
NS_ENSURE_TRUE(content, NS_ERROR_UNEXPECTED);
+ // Make sure that there is a plugin
nsCOMPtr<nsIObjectLoadingContent> objlc(do_QueryInterface(content));
NS_ASSERTION(objlc, "Object nodes must implement nsIObjectLoadingContent");
-
- // If it's not safe to run script we'll only return the instance if it
- // exists.
- if (!nsContentUtils::IsSafeToRunScript()) {
- return objlc->GetPluginInstance(_result);
- }
-
- // Make sure that there is a plugin
return objlc->EnsureInstantiation(_result);
}
// Check if proto is already in obj's prototype chain.
static PRBool
IsObjInProtoChain(JSContext *cx, JSObject *obj, JSObject *proto)
{
@@ -8835,61 +8832,32 @@ IsObjInProtoChain(JSContext *cx, JSObjec
}
o = p;
}
return PR_FALSE;
}
-class nsPluginProtoChainInstallRunner : public nsIRunnable
-{
-public:
- NS_DECL_ISUPPORTS
-
- nsPluginProtoChainInstallRunner(nsIXPConnectWrappedNative* wrapper,
- nsIScriptContext* scriptContext)
- : mWrapper(wrapper),
- mContext(scriptContext)
- {
- }
-
- NS_IMETHOD Run()
- {
- JSObject* obj = nsnull;
- mWrapper->GetJSObject(&obj);
- NS_ASSERTION(obj, "Should never be null");
- nsHTMLPluginObjElementSH::SetupProtoChain(
- mWrapper, (JSContext*)mContext->GetNativeContext(), obj);
- return NS_OK;
- }
-
-private:
- nsCOMPtr<nsIXPConnectWrappedNative> mWrapper;
- nsCOMPtr<nsIScriptContext> mContext;
-};
-
-NS_IMPL_ISUPPORTS1(nsPluginProtoChainInstallRunner, nsIRunnable)
-
-// static
-nsresult
-nsHTMLPluginObjElementSH::SetupProtoChain(nsIXPConnectWrappedNative *wrapper,
- JSContext *cx,
- JSObject *obj)
-{
- NS_ASSERTION(nsContentUtils::IsSafeToRunScript(),
- "Shouldn't have gotten in here");
-
- nsCxPusher cxPusher;
- if (!cxPusher.Push(cx)) {
- return NS_OK;
- }
+
+// Note that not only XPConnect calls this PostCreate() method when
+// it creates wrappers, nsObjectFrame also calls this method when a
+// plugin is loaded if the embed/object element is already wrapped to
+// get the scriptable plugin inserted into the embed/object's proto
+// chain.
+
+NS_IMETHODIMP
+nsHTMLPluginObjElementSH::PostCreate(nsIXPConnectWrappedNative *wrapper,
+ JSContext *cx, JSObject *obj)
+{
+ nsresult rv = nsElementSH::PostCreate(wrapper, cx, obj);
+ NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPluginInstance> pi;
- nsresult rv = GetPluginInstanceIfSafe(wrapper, getter_AddRefs(pi));
+ rv = GetPluginInstance(wrapper, getter_AddRefs(pi));
NS_ENSURE_SUCCESS(rv, rv);
if (!pi) {
// No plugin around for this object.
return NS_OK;
}
@@ -8903,17 +8871,17 @@ nsHTMLPluginObjElementSH::SetupProtoChai
// Didn't get a plugin instance JSObject, nothing we can do then.
return NS_OK;
}
if (IsObjInProtoChain(cx, obj, pi_obj)) {
// We must have re-entered ::PostCreate() from nsObjectFrame()
// (through the EnsureInstantiation() call in
- // GetPluginInstanceIfSafe()), this means that we've already done what
+ // GetPluginInstance()), this means that we've already done what
// we're about to do in this function so we can just return here.
return NS_OK;
}
// If we got an xpconnect-wrapped plugin object, set obj's
// prototype's prototype to the scriptable plugin.
@@ -8993,36 +8961,16 @@ nsHTMLPluginObjElementSH::SetupProtoChai
// | by LiveConnect
// |
// |__ xpc wrapped native embed node
//
return NS_OK;
}
-NS_IMETHODIMP
-nsHTMLPluginObjElementSH::PostCreate(nsIXPConnectWrappedNative *wrapper,
- JSContext *cx, JSObject *obj)
-{
- nsresult rv = nsElementSH::PostCreate(wrapper, cx, obj);
- NS_ENSURE_SUCCESS(rv, rv);
-
- if (nsContentUtils::IsSafeToRunScript()) {
- return SetupProtoChain(wrapper, cx, obj);
- }
-
- nsCOMPtr<nsIScriptContext> scriptContext =
- GetScriptContextFromJSContext(cx);
- NS_ENSURE_TRUE(scriptContext, NS_ERROR_UNEXPECTED);
-
- nsContentUtils::AddScriptRunner(
- new nsPluginProtoChainInstallRunner(wrapper, scriptContext));
-
- return NS_OK;
-}
NS_IMETHODIMP
nsHTMLPluginObjElementSH::GetProperty(nsIXPConnectWrappedNative *wrapper,
JSContext *cx, JSObject *obj, jsval id,
jsval *vp, PRBool *_retval)
{
JSAutoRequest ar(cx);
@@ -9114,17 +9062,17 @@ nsHTMLPluginObjElementSH::SetProperty(ns
}
NS_IMETHODIMP
nsHTMLPluginObjElementSH::Call(nsIXPConnectWrappedNative *wrapper,
JSContext *cx, JSObject *obj, PRUint32 argc,
jsval *argv, jsval *vp, PRBool *_retval)
{
nsCOMPtr<nsIPluginInstance> pi;
- nsresult rv = GetPluginInstanceIfSafe(wrapper, getter_AddRefs(pi));
+ nsresult rv = GetPluginInstance(wrapper, getter_AddRefs(pi));
NS_ENSURE_SUCCESS(rv, rv);
if (!pi) {
// No plugin around for this object.
return NS_ERROR_NOT_AVAILABLE;
}
@@ -9331,17 +9279,17 @@ nsHTMLPluginObjElementSH::NewResolve(nsI
}
// This code resolves embed.nsIFoo to the nsIFoo wrapper of the
// plugin/applet instance. We only want to do that for plugin
// instances that are not scriptable using NPRuntime or are Java
// plugin instances.
nsCOMPtr<nsIPluginInstance> pi;
- nsresult rv = GetPluginInstanceIfSafe(wrapper, getter_AddRefs(pi));
+ nsresult rv = GetPluginInstance(wrapper, getter_AddRefs(pi));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPluginInstanceInternal> plugin_internal =
do_QueryInterface(pi);
#ifdef OJI
nsCOMPtr<nsIJVMPluginInstance> java_plugin_instance =
do_QueryInterface(pi);
--- a/dom/src/base/nsDOMClassInfo.h
+++ b/dom/src/base/nsDOMClassInfo.h
@@ -972,18 +972,18 @@ protected:
: nsHTMLElementSH(aData)
{
}
virtual ~nsHTMLPluginObjElementSH()
{
}
- static nsresult GetPluginInstanceIfSafe(nsIXPConnectWrappedNative *aWrapper,
- nsIPluginInstance **aResult);
+ nsresult GetPluginInstance(nsIXPConnectWrappedNative *aWrapper,
+ nsIPluginInstance **aResult);
static nsresult GetPluginJSObject(JSContext *cx, JSObject *obj,
nsIPluginInstance *plugin_inst,
JSObject **plugin_obj,
JSObject **plugin_proto);
static nsresult GetJavaPluginJSObject(JSContext *cx, JSObject *obj,
nsIPluginInstance *plugin_inst,
@@ -999,20 +999,16 @@ public:
NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, jsval *vp, PRBool *_retval);
NS_IMETHOD SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, jsval *vp, PRBool *_retval);
NS_IMETHOD Call(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, PRUint32 argc, jsval *argv, jsval *vp,
PRBool *_retval);
-
- static nsresult SetupProtoChain(nsIXPConnectWrappedNative *wrapper,
- JSContext *cx, JSObject *obj);
-
static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
{
return new nsHTMLPluginObjElementSH(aData);
}
};
// HTMLOptionsCollection helper
--- a/layout/base/nsDocumentViewer.cpp
+++ b/layout/base/nsDocumentViewer.cpp
@@ -1043,19 +1043,16 @@ DocumentViewerImpl::PermitUnload(PRBool
nsPIDOMWindow *window = mDocument->GetWindow();
if (!window) {
// This is odd, but not fatal
NS_WARNING("window not set for document!");
return NS_OK;
}
- NS_ASSERTION(nsContentUtils::IsSafeToRunScript(),
- "This is unsafe unless we're inside a mutation event");
-
// Now, fire an BeforeUnload event to the document and see if it's ok
// to unload...
nsEventStatus status = nsEventStatus_eIgnore;
nsBeforePageUnloadEvent event(PR_TRUE, NS_BEFORE_PAGE_UNLOAD);
event.flags |= NS_EVENT_FLAG_CANT_BUBBLE;
// XXX Dispatching to |window|, but using |document| as the target.
event.target = mDocument;
nsresult rv = NS_OK;
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -755,17 +755,16 @@ FrameArena::FreeFrame(size_t aSize, void
struct nsCallbackEventRequest
{
nsIReflowCallback* callback;
nsCallbackEventRequest* next;
};
// ----------------------------------------------------------------------------
class nsPresShellEventCB;
-class nsAutoCauseReflowNotifier;
class PresShell : public nsIPresShell, public nsIViewObserver,
public nsStubDocumentObserver,
public nsISelectionController, public nsIObserver,
public nsSupportsWeakReference
{
public:
PresShell();
@@ -1005,24 +1004,18 @@ public:
protected:
virtual ~PresShell();
void HandlePostedReflowCallbacks();
void CancelPostedReflowCallbacks();
void UnsuppressAndInvalidate();
-
- void WillCauseReflow() {
- nsContentUtils::AddScriptBlocker();
- ++mChangeNestCount;
- }
+ void WillCauseReflow() { ++mChangeNestCount; }
nsresult DidCauseReflow();
- friend class nsAutoCauseReflowNotifier;
-
void WillDoReflow();
void DidDoReflow();
nsresult ProcessReflowCommands(PRBool aInterruptible);
void ClearReflowEventStatus();
void PostReflowEvent();
void DoReflow(nsIFrame* aFrame);
#ifdef DEBUG
@@ -1211,39 +1204,16 @@ private:
nsCOMPtr<nsITimer> mResizeEventTimer;
typedef void (*nsPluginEnumCallback)(PresShell*, nsIContent*);
void EnumeratePlugins(nsIDOMDocument *aDocument,
const nsString &aPluginTag,
nsPluginEnumCallback aCallback);
};
-class nsAutoCauseReflowNotifier
-{
-public:
- nsAutoCauseReflowNotifier(PresShell* aShell)
- : mShell(aShell)
- {
- mShell->WillCauseReflow();
- }
- ~nsAutoCauseReflowNotifier()
- {
- // This check should not be needed. Currently the only place that seem
- // to need it is the code that deals with bug 337586.
- if (!mShell->mHaveShutDown) {
- mShell->DidCauseReflow();
- }
- else {
- nsContentUtils::RemoveScriptBlocker();
- }
- }
-
- PresShell* mShell;
-};
-
class nsPresShellEventCB : public nsDispatchingCallback
{
public:
nsPresShellEventCB(PresShell* aPresShell) : mPresShell(aPresShell) {}
virtual void HandleEvent(nsEventChainPostVisitor& aVisitor)
{
if (aVisitor.mPresContext && aVisitor.mEvent->eventStructType != NS_EVENT) {
@@ -2408,45 +2378,41 @@ PresShell::InitialReflow(nscoord aWidth,
nsIFrame* rootFrame = FrameManager()->GetRootFrame();
if (root) {
MOZ_TIMER_DEBUGLOG(("Reset and start: Frame Creation: PresShell::InitialReflow(), this=%p\n",
(void*)this));
MOZ_TIMER_RESET(mFrameCreationWatch);
MOZ_TIMER_START(mFrameCreationWatch);
- {
- nsAutoCauseReflowNotifier reflowNotifier(this);
- mFrameConstructor->BeginUpdate();
-
- if (!rootFrame) {
- // Have style sheet processor construct a frame for the
- // precursors to the root content object's frame
- mFrameConstructor->ConstructRootFrame(root, &rootFrame);
- FrameManager()->SetRootFrame(rootFrame);
- }
-
- // Have the style sheet processor construct frame for the root
- // content object down
- mFrameConstructor->ContentInserted(nsnull, root, 0, nsnull);
- VERIFY_STYLE_TREE;
- MOZ_TIMER_DEBUGLOG(("Stop: Frame Creation: PresShell::InitialReflow(), this=%p\n",
- (void*)this));
- MOZ_TIMER_STOP(mFrameCreationWatch);
-
- // Something in mFrameConstructor->ContentInserted may have caused
- // Destroy() to get called, bug 337586.
- NS_ENSURE_STATE(!mHaveShutDown);
-
- mFrameConstructor->EndUpdate();
- }
-
- // DidCauseReflow may have killed us too
+ WillCauseReflow();
+ mFrameConstructor->BeginUpdate();
+
+ if (!rootFrame) {
+ // Have style sheet processor construct a frame for the
+ // precursors to the root content object's frame
+ mFrameConstructor->ConstructRootFrame(root, &rootFrame);
+ FrameManager()->SetRootFrame(rootFrame);
+ }
+
+ // Have the style sheet processor construct frame for the root
+ // content object down
+ mFrameConstructor->ContentInserted(nsnull, root, 0, nsnull);
+ VERIFY_STYLE_TREE;
+ MOZ_TIMER_DEBUGLOG(("Stop: Frame Creation: PresShell::InitialReflow(), this=%p\n",
+ (void*)this));
+ MOZ_TIMER_STOP(mFrameCreationWatch);
+
+ // Something in mFrameConstructor->ContentInserted may have caused
+ // Destroy() to get called, bug 337586.
NS_ENSURE_STATE(!mHaveShutDown);
+ mFrameConstructor->EndUpdate();
+ DidCauseReflow();
+
// Run the XBL binding constructors for any new frames we've constructed
mDocument->BindingManager()->ProcessAttachedQueue();
// Constructors may have killed us too
NS_ENSURE_STATE(!mHaveShutDown);
// Now flush out pending restyles before we actually reflow, in
// case XBL constructors changed styles somewhere.
@@ -2551,29 +2517,30 @@ PresShell::ResizeReflow(nscoord aWidth,
// Make sure style is up to date
mFrameConstructor->ProcessPendingRestyles();
if (!mIsDestroying) {
// XXX Do a full invalidate at the beginning so that invalidates along
// the way don't have region accumulation issues?
+ WillCauseReflow();
+ WillDoReflow();
+
{
- nsAutoCauseReflowNotifier crNotifier(this);
- WillDoReflow();
-
// Kick off a top-down reflow
AUTO_LAYOUT_PHASE_ENTRY_POINT(GetPresContext(), Reflow);
mIsReflowing = PR_TRUE;
mDirtyRoots.RemoveElement(rootFrame);
DoReflow(rootFrame);
mIsReflowing = PR_FALSE;
}
+ DidCauseReflow();
DidDoReflow();
}
batch.EndUpdateViewBatch(NS_VMREFRESH_NO_SYNC);
}
if (!mIsDestroying) {
CreateResizeEventTimer();
@@ -3106,17 +3073,16 @@ PresShell::RestoreRootScrollPosition()
{
// Restore frame state for the root scroll frame
nsCOMPtr<nsILayoutHistoryState> historyState =
mDocument->GetLayoutHistoryState();
// Make sure we don't reenter reflow via the sync paint that happens while
// we're scrolling to our restored position. Entering reflow for the
// scrollable frame will cause it to reenter ScrollToRestoredPosition(), and
// it'll get all confused.
- nsAutoScriptBlocker scriptBlocker;
++mChangeNestCount;
if (historyState) {
nsIFrame* scrollFrame = GetRootScrollFrame();
if (scrollFrame) {
nsIScrollableFrame* scrollableFrame;
CallQueryInterface(scrollFrame, &scrollableFrame);
if (scrollableFrame) {
@@ -3397,18 +3363,16 @@ PresShell::RecreateFramesFor(nsIContent*
NS_ASSERTION(mViewManager, "Should have view manager");
nsIViewManager::UpdateViewBatch batch(mViewManager);
// Have to make sure that the content notifications are flushed before we
// start messing with the frame model; otherwise we can get content doubling.
mDocument->FlushPendingNotifications(Flush_ContentAndNotify);
- nsAutoScriptBlocker scriptBlocker;
-
nsStyleChangeList changeList;
changeList.AppendChange(nsnull, aContent, nsChangeHint_ReconstructFrame);
// Mark ourselves as not safe to flush while we're doing frame construction.
++mChangeNestCount;
nsresult rv = mFrameConstructor->ProcessRestyledFrames(changeList);
--mChangeNestCount;
@@ -4490,40 +4454,32 @@ PresShell::HandlePostedReflowCallbacks()
if (shouldFlush)
FlushPendingNotifications(Flush_Layout);
}
NS_IMETHODIMP
PresShell::IsSafeToFlush(PRBool& aIsSafeToFlush)
{
- // XXX technically we don't need to check anything but
- // nsContentUtils::IsSafeToRunScript here since that should be false
- // if any of the other flags are set.
-
- // Not safe if we are reflowing or in the middle of frame construction
- aIsSafeToFlush = nsContentUtils::IsSafeToRunScript() &&
- !mIsReflowing &&
- !mChangeNestCount;
-
- if (aIsSafeToFlush) {
+ aIsSafeToFlush = PR_TRUE;
+
+ if (mIsReflowing || mChangeNestCount) {
+ // Not safe if we are reflowing or in the middle of frame construction
+ aIsSafeToFlush = PR_FALSE;
+ } else {
// Not safe if we are painting
nsIViewManager* viewManager = GetViewManager();
if (viewManager) {
PRBool isPainting = PR_FALSE;
viewManager->IsPainting(isPainting);
if (isPainting) {
aIsSafeToFlush = PR_FALSE;
}
}
}
-
- NS_ASSERTION(aIsSafeToFlush == nsContentUtils::IsSafeToRunScript(),
- "Someone forgot to block scripts");
-
return NS_OK;
}
NS_IMETHODIMP
PresShell::FlushPendingNotifications(mozFlushType aType)
{
return DoFlushPendingNotifications(aType, PR_FALSE);
@@ -4617,18 +4573,17 @@ PresShell::IsReflowLocked(PRBool* aIsRef
void
PresShell::CharacterDataChanged(nsIDocument *aDocument,
nsIContent* aContent,
CharacterDataChangeInfo* aInfo)
{
NS_PRECONDITION(!mIsDocumentGone, "Unexpected CharacterDataChanged");
NS_PRECONDITION(aDocument == mDocument, "Unexpected aDocument");
- nsAutoCauseReflowNotifier crNotifier(this);
-
+ WillCauseReflow();
if (mCaret) {
// Invalidate the caret's current location before we call into the frame
// constructor. It is important to do this now, and not wait until the
// resulting reflow, because this call causes continuation frames of the
// text frame the caret is in to forget what part of the content they
// refer to, making it hard for them to return the correct continuation
// frame to the caret.
mCaret->InvalidateOutsideCaret();
@@ -4647,31 +4602,33 @@ PresShell::CharacterDataChanged(nsIDocum
aContent)
mFrameConstructor->RestyleForAppend(container, index);
else
mFrameConstructor->RestyleForInsertOrChange(container, aContent);
}
mFrameConstructor->CharacterDataChanged(aContent, aInfo->mAppend);
VERIFY_STYLE_TREE;
+ DidCauseReflow();
}
void
PresShell::ContentStatesChanged(nsIDocument* aDocument,
nsIContent* aContent1,
nsIContent* aContent2,
PRInt32 aStateMask)
{
NS_PRECONDITION(!mIsDocumentGone, "Unexpected ContentStatesChanged");
NS_PRECONDITION(aDocument == mDocument, "Unexpected aDocument");
if (mDidInitialReflow) {
- nsAutoCauseReflowNotifier crNotifier(this);
+ WillCauseReflow();
mFrameConstructor->ContentStatesChanged(aContent1, aContent2, aStateMask);
VERIFY_STYLE_TREE;
+ DidCauseReflow();
}
}
void
PresShell::AttributeChanged(nsIDocument* aDocument,
nsIContent* aContent,
PRInt32 aNameSpaceID,
@@ -4681,76 +4638,79 @@ PresShell::AttributeChanged(nsIDocument*
{
NS_PRECONDITION(!mIsDocumentGone, "Unexpected AttributeChanged");
NS_PRECONDITION(aDocument == mDocument, "Unexpected aDocument");
// XXXwaterson it might be more elegant to wait until after the
// initial reflow to begin observing the document. That would
// squelch any other inappropriate notifications as well.
if (mDidInitialReflow) {
- nsAutoCauseReflowNotifier crNotifier(this);
+ WillCauseReflow();
mFrameConstructor->AttributeChanged(aContent, aNameSpaceID,
aAttribute, aModType, aStateMask);
VERIFY_STYLE_TREE;
+ DidCauseReflow();
}
}
void
PresShell::ContentAppended(nsIDocument *aDocument,
nsIContent* aContainer,
PRInt32 aNewIndexInContainer)
{
NS_PRECONDITION(!mIsDocumentGone, "Unexpected ContentAppended");
NS_PRECONDITION(aDocument == mDocument, "Unexpected aDocument");
NS_PRECONDITION(aContainer, "must have container");
if (!mDidInitialReflow) {
return;
}
- nsAutoCauseReflowNotifier crNotifier(this);
+ WillCauseReflow();
MOZ_TIMER_DEBUGLOG(("Start: Frame Creation: PresShell::ContentAppended(), this=%p\n", this));
MOZ_TIMER_START(mFrameCreationWatch);
// Call this here so it only happens for real content mutations and
// not cases when the frame constructor calls its own methods to force
// frame reconstruction.
mFrameConstructor->RestyleForAppend(aContainer, aNewIndexInContainer);
mFrameConstructor->ContentAppended(aContainer, aNewIndexInContainer);
VERIFY_STYLE_TREE;
MOZ_TIMER_DEBUGLOG(("Stop: Frame Creation: PresShell::ContentAppended(), this=%p\n", this));
MOZ_TIMER_STOP(mFrameCreationWatch);
+ DidCauseReflow();
}
void
PresShell::ContentInserted(nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer)
{
NS_PRECONDITION(!mIsDocumentGone, "Unexpected ContentInserted");
NS_PRECONDITION(aDocument == mDocument, "Unexpected aDocument");
if (!mDidInitialReflow) {
return;
}
- nsAutoCauseReflowNotifier crNotifier(this);
+ WillCauseReflow();
// Call this here so it only happens for real content mutations and
// not cases when the frame constructor calls its own methods to force
// frame reconstruction.
if (aContainer)
mFrameConstructor->RestyleForInsertOrChange(aContainer, aChild);
mFrameConstructor->ContentInserted(aContainer, aChild,
aIndexInContainer, nsnull);
VERIFY_STYLE_TREE;
+ DidCauseReflow();
}
void
PresShell::ContentRemoved(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer)
{
@@ -4761,37 +4721,41 @@ PresShell::ContentRemoved(nsIDocument *a
if (mCaret) {
mCaret->InvalidateOutsideCaret();
}
// Notify the ESM that the content has been removed, so that
// it can clean up any state related to the content.
mPresContext->EventStateManager()->ContentRemoved(aChild);
- nsAutoCauseReflowNotifier crNotifier(this);
+ WillCauseReflow();
// Call this here so it only happens for real content mutations and
// not cases when the frame constructor calls its own methods to force
// frame reconstruction.
if (aContainer)
mFrameConstructor->RestyleForRemove(aContainer, aChild, aIndexInContainer);
PRBool didReconstruct;
mFrameConstructor->ContentRemoved(aContainer, aChild,
aIndexInContainer, &didReconstruct);
VERIFY_STYLE_TREE;
+ DidCauseReflow();
}
nsresult
PresShell::ReconstructFrames(void)
{
- nsAutoCauseReflowNotifier crNotifier(this);
- nsresult rv = mFrameConstructor->ReconstructDocElementHierarchy();
+ nsresult rv = NS_OK;
+
+ WillCauseReflow();
+ rv = mFrameConstructor->ReconstructDocElementHierarchy();
VERIFY_STYLE_TREE;
+ DidCauseReflow();
return rv;
}
void
nsIPresShell::ReconstructStyleDataInternal()
{
mStylesHaveChanged = PR_FALSE;
@@ -5550,21 +5514,17 @@ nsresult PresShell::RetargetEventToParen
NS_IMETHODIMP
PresShell::HandleEvent(nsIView *aView,
nsGUIEvent* aEvent,
nsEventStatus* aEventStatus)
{
NS_ASSERTION(aView, "null view");
- NS_ASSERTION(nsContentUtils::IsSafeToRunScript(),
- "How did we get here if it's not safe to run scripts?");
-
- if (mIsDestroying || mIsReflowing || mChangeNestCount ||
- !nsContentUtils::IsSafeToRunScript()) {
+ if (mIsDestroying || mIsReflowing || mChangeNestCount) {
return NS_OK;
}
#ifdef ACCESSIBILITY
if (aEvent->eventStructType == NS_ACCESSIBLE_EVENT) {
return HandleEventInternal(aEvent, aView, aEventStatus);
}
#endif
@@ -6196,18 +6156,16 @@ PresShell::DidCauseReflow()
// our reflow. Make sure these get processed at some point.
// XXXbz why is this really needed? ProcessReflowCommands handles posting
// reflow events if there are reflow roots remaining, and FrameNeedsReflow
// posts events as needed as well. I think we should remove this.
PostReflowEvent();
}
- nsContentUtils::RemoveScriptBlocker();
-
return NS_OK;
}
void
PresShell::WillDoReflow()
{
// We just reflowed, tell the caret that its frame might have moved.
// XXXbz that comment makes no sense
@@ -6375,17 +6333,16 @@ PresShell::ProcessReflowCommands(PRBool
// If reflow is interruptible, then make a note of our deadline.
const PRIntervalTime deadline = aInterruptible
? PR_IntervalNow() + PR_MicrosecondsToInterval(gMaxRCProcessingTime)
: (PRIntervalTime)0;
// Scope for the reflow entry point
{
- nsAutoScriptBlocker scriptBlocker;
AUTO_LAYOUT_PHASE_ENTRY_POINT(GetPresContext(), Reflow);
mIsReflowing = PR_TRUE;
do {
// Send an incremental reflow notification to the target frame.
PRInt32 idx = mDirtyRoots.Count() - 1;
nsIFrame *target = static_cast<nsIFrame*>(mDirtyRoots[idx]);
mDirtyRoots.RemoveElementAt(idx);
@@ -6405,20 +6362,17 @@ PresShell::ProcessReflowCommands(PRBool
(!aInterruptible || PR_IntervalNow() < deadline));
// XXXwaterson for interruptible reflow, examine the tree and
// re-enqueue any unflowed reflow targets.
mIsReflowing = PR_FALSE;
}
- // Exiting the scriptblocker might have killed us
- if (!mIsDestroying) {
- DidDoReflow();
- }
+ DidDoReflow();
// DidDoReflow might have killed us
if (!mIsDestroying) {
#ifdef DEBUG
if (VERIFY_REFLOW_DUMP_COMMANDS & gVerifyReflowFlags) {
printf("\nPresShell::ProcessReflowCommands() finished: this=%p\n",
(void*)this);
}
@@ -6545,22 +6499,19 @@ PresShell::Observe(nsISupports* aSubject
// Because "chrome:" URL equality is messy, reframe image box
// frames (hack!).
nsStyleChangeList changeList;
WalkFramesThroughPlaceholders(mPresContext, rootFrame,
ReframeImageBoxes, &changeList);
// Mark ourselves as not safe to flush while we're doing frame
// construction.
- {
- nsAutoScriptBlocker scriptBlocker;
- ++mChangeNestCount;
- mFrameConstructor->ProcessRestyledFrames(changeList);
- --mChangeNestCount;
- }
+ ++mChangeNestCount;
+ mFrameConstructor->ProcessRestyledFrames(changeList);
+ --mChangeNestCount;
batch.EndUpdateViewBatch(NS_VMREFRESH_NO_SYNC);
#ifdef ACCESSIBILITY
InvalidateAccessibleSubtree(nsnull);
#endif
}
return NS_OK;
}
--- a/layout/generic/Makefile.in
+++ b/layout/generic/Makefile.in
@@ -182,17 +182,16 @@ LOCAL_INCLUDES += \
-I$(srcdir) \
-I$(srcdir)/../base \
-I$(srcdir)/../forms \
-I$(srcdir)/../tables \
-I$(srcdir)/../xul/base/src \
-I$(srcdir)/../../content/xul/content/src \
-I$(srcdir)/../../content/base/src \
-I$(srcdir)/../../content/html/content/src \
- -I$(srcdir)/../../dom/src/base \
$(MOZ_CAIRO_CFLAGS) \
$(NULL)
ifdef MOZ_ENABLE_GTK2
CXXFLAGS += $(MOZ_GTK2_CFLAGS)
endif
libs::
--- a/layout/generic/nsObjectFrame.cpp
+++ b/layout/generic/nsObjectFrame.cpp
@@ -103,17 +103,16 @@
#include "nsTransform2D.h"
#include "nsIImageLoadingContent.h"
#include "nsIObjectLoadingContent.h"
#include "nsPIDOMWindow.h"
#include "nsContentUtils.h"
#include "nsDisplayList.h"
#include "nsAttrName.h"
#include "nsDataHashtable.h"
-#include "nsDOMClassInfo.h"
// headers for plugin scriptability
#include "nsIScriptGlobalObject.h"
#include "nsIScriptContext.h"
#include "nsIXPConnect.h"
#include "nsIXPCScriptable.h"
#include "nsIClassInfo.h"
@@ -1838,27 +1837,47 @@ nsObjectFrame::NotifyContentObjectWrappe
nsCOMPtr<nsIXPConnectWrappedNative> wrapper;
nsContentUtils::XPConnect()->
GetWrappedNativeOfNativeObject(cx, sgo->GetGlobalJSObject(), mContent,
NS_GET_IID(nsISupports),
getter_AddRefs(wrapper));
if (!wrapper) {
- // Nothing to do here if there's no wrapper for mContent. The proto
- // chain will be fixed appropriately when the wrapper is created.
+ // Nothing to do here if there's no wrapper for mContent
+ return;
+ }
+
+ nsCOMPtr<nsIClassInfo> ci(do_QueryInterface(mContent));
+ if (!ci)
+ return;
+
+ nsCOMPtr<nsISupports> s;
+ ci->GetHelperForLanguage(nsIProgrammingLanguage::JAVASCRIPT,
+ getter_AddRefs(s));
+
+ nsCOMPtr<nsIXPCScriptable> helper(do_QueryInterface(s));
+
+ if (!helper) {
+ // There's nothing we can do if there's no helper
return;
}
JSObject *obj = nsnull;
nsresult rv = wrapper->GetJSObject(&obj);
if (NS_FAILED(rv))
return;
- nsHTMLPluginObjElementSH::SetupProtoChain(wrapper, cx, obj);
+ nsCxPusher cxPusher;
+ if (cxPusher.Push(mContent)) {
+ // Abuse the scriptable helper to trigger prototype setup for the
+ // wrapper for mContent so that this plugin becomes part of the DOM
+ // object.
+ helper->PostCreate(wrapper, cx, obj);
+ }
}
// static
nsIObjectFrame *
nsObjectFrame::GetNextObjectFrame(nsPresContext* aPresContext, nsIFrame* aRoot)
{
nsIFrame* child = aRoot->GetFirstChild(nsnull);
--- a/view/src/Makefile.in
+++ b/view/src/Makefile.in
@@ -52,19 +52,16 @@ LIBXUL_LIBRARY = 1
REQUIRES = xpcom \
string \
gfx \
widget \
dom \
pref \
thebes \
cairo \
- content \
- js \
- layout \
$(NULL)
EXTRA_DSO_LIBS = gkgfx
CPPSRCS = \
nsView.cpp \
nsScrollPortView.cpp \
nsViewManager.cpp \
--- a/view/src/nsViewManager.cpp
+++ b/view/src/nsViewManager.cpp
@@ -56,17 +56,16 @@
#include "nsIPrefBranch.h"
#include "nsIPrefService.h"
#include "nsRegion.h"
#include "nsInt64.h"
#include "nsScrollPortView.h"
#include "nsHashtable.h"
#include "nsCOMArray.h"
#include "nsThreadUtils.h"
-#include "nsContentUtils.h"
#include "gfxContext.h"
static NS_DEFINE_IID(kBlenderCID, NS_BLENDER_CID);
static NS_DEFINE_IID(kRegionCID, NS_REGION_CID);
static NS_DEFINE_IID(kRenderingContextCID, NS_RENDERING_CONTEXT_CID);
/**
@@ -448,61 +447,57 @@ void nsViewManager::Refresh(nsView *aVie
MOZ_TIMER_START(mWatch);
#endif
NS_ASSERTION(!IsPainting(), "recursive painting not permitted");
if (IsPainting()) {
RootViewManager()->mRecursiveRefreshPending = PR_TRUE;
return;
}
+ SetPainting(PR_TRUE);
- {
- nsAutoScriptBlocker scriptBlocker;
- SetPainting(PR_TRUE);
+ nsCOMPtr<nsIRenderingContext> localcx;
+ NS_ASSERTION(aView->GetWidget(),
+ "Must have a widget to calculate coordinates correctly");
+ if (nsnull == aContext)
+ {
+ localcx = CreateRenderingContext(*aView);
- nsCOMPtr<nsIRenderingContext> localcx;
- NS_ASSERTION(aView->GetWidget(),
- "Must have a widget to calculate coordinates correctly");
- if (nsnull == aContext)
- {
- localcx = CreateRenderingContext(*aView);
+ //couldn't get rendering context. this is ok at init time atleast
+ if (nsnull == localcx) {
+ SetPainting(PR_FALSE);
+ return;
+ }
+ } else {
+ // plain assignment grabs another reference.
+ localcx = aContext;
+ }
- //couldn't get rendering context. this is ok at init time atleast
- if (nsnull == localcx) {
- SetPainting(PR_FALSE);
- return;
- }
- } else {
- // plain assignment grabs another reference.
- localcx = aContext;
- }
+ PRInt32 p2a = mContext->AppUnitsPerDevPixel();
- PRInt32 p2a = mContext->AppUnitsPerDevPixel();
+ nsRefPtr<gfxContext> ctx = localcx->ThebesContext();
- nsRefPtr<gfxContext> ctx = localcx->ThebesContext();
+ ctx->Save();
- ctx->Save();
-
- nsPoint vtowoffset = aView->ViewToWidgetOffset();
- ctx->Translate(gfxPoint(gfxFloat(vtowoffset.x) / p2a,
- gfxFloat(vtowoffset.y) / p2a));
+ nsPoint vtowoffset = aView->ViewToWidgetOffset();
+ ctx->Translate(gfxPoint(gfxFloat(vtowoffset.x) / p2a,
+ gfxFloat(vtowoffset.y) / p2a));
- ctx->Translate(gfxPoint(-gfxFloat(viewRect.x) / p2a,
- -gfxFloat(viewRect.y) / p2a));
-
- nsRegion opaqueRegion;
- AddCoveringWidgetsToOpaqueRegion(opaqueRegion, mContext, aView);
- damageRegion.Sub(damageRegion, opaqueRegion);
+ ctx->Translate(gfxPoint(-gfxFloat(viewRect.x) / p2a,
+ -gfxFloat(viewRect.y) / p2a));
- RenderViews(aView, *localcx, damageRegion);
+ nsRegion opaqueRegion;
+ AddCoveringWidgetsToOpaqueRegion(opaqueRegion, mContext, aView);
+ damageRegion.Sub(damageRegion, opaqueRegion);
- ctx->Restore();
+ RenderViews(aView, *localcx, damageRegion);
- SetPainting(PR_FALSE);
- }
+ ctx->Restore();
+
+ SetPainting(PR_FALSE);
if (RootViewManager()->mRecursiveRefreshPending) {
// Unset this flag first, since if aUpdateFlags includes NS_VMREFRESH_IMMEDIATE
// we'll reenter this code from the UpdateAllViews call.
RootViewManager()->mRecursiveRefreshPending = PR_FALSE;
UpdateAllViews(aUpdateFlags);
}