diff --git a/mozilla/content/base/public/nsContentUtils.h b/mozilla/content/base/public/nsContentUtils.h index 24fb65c29c8..4abe2184c0a 100644 --- a/mozilla/content/base/public/nsContentUtils.h +++ b/mozilla/content/base/public/nsContentUtils.h @@ -90,7 +90,6 @@ class nsIWordBreaker; class nsIJSRuntimeService; class nsIEventListenerManager; class nsIScriptContext; -class nsIRunnable; template class nsCOMArray; class nsIPref; class nsVoidArray; @@ -1178,45 +1177,6 @@ public: */ 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(); @@ -1289,9 +1249,6 @@ private: #endif static PRBool sInitialized; - static PRUint32 sScriptBlockerCount; - static nsCOMArray* sBlockedScriptRunners; - static PRUint32 sRunnersCountAtFirstBlocker; }; #define NS_HOLD_JS_OBJECTS(obj, clazz) \ @@ -1310,7 +1267,6 @@ public: // Returns PR_FALSE if something erroneous happened. PRBool Push(nsISupports *aCurrentTarget); - PRBool Push(JSContext *cx); void Pop(); private: @@ -1361,16 +1317,6 @@ private: 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) diff --git a/mozilla/content/base/public/nsIObjectLoadingContent.idl b/mozilla/content/base/public/nsIObjectLoadingContent.idl index 3305780c345..f76231d63a0 100644 --- a/mozilla/content/base/public/nsIObjectLoadingContent.idl +++ b/mozilla/content/base/public/nsIObjectLoadingContent.idl @@ -43,7 +43,7 @@ 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; @@ -71,13 +71,6 @@ interface nsIObjectLoadingContent : nsISupports */ 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 diff --git a/mozilla/content/base/src/nsContentUtils.cpp b/mozilla/content/base/src/nsContentUtils.cpp index 5b15a473169..0f3bcb40aaf 100644 --- a/mozilla/content/base/src/nsContentUtils.cpp +++ b/mozilla/content/base/src/nsContentUtils.cpp @@ -149,8 +149,6 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID); #include "nsXULPopupManager.h" #include "nsIPermissionManager.h" #include "nsIScriptObjectPrincipal.h" -#include "nsIRunnable.h" -#include "nsDOMJSUtils.h" #ifdef IBMBIDI #include "nsIBidiKeyboard.h" @@ -197,9 +195,6 @@ PRUint32 nsContentUtils::sJSGCThingRootCount; #ifdef IBMBIDI nsIBidiKeyboard *nsContentUtils::sBidiKeyboard = nsnull; #endif -PRUint32 nsContentUtils::sScriptBlockerCount = 0; -nsCOMArray* nsContentUtils::sBlockedScriptRunners = nsnull; -PRUint32 nsContentUtils::sRunnersCountAtFirstBlocker = 0; nsIJSRuntimeService *nsAutoGCRoot::sJSRuntimeService; JSRuntime *nsAutoGCRoot::sJSScriptRuntime; @@ -328,9 +323,6 @@ nsContentUtils::Init() } } - sBlockedScriptRunners = new nsCOMArray; - NS_ENSURE_TRUE(sBlockedScriptRunners, NS_ERROR_OUT_OF_MEMORY); - sInitialized = PR_TRUE; return NS_OK; @@ -829,12 +821,6 @@ nsContentUtils::Shutdown() } } - NS_ASSERTION(!sBlockedScriptRunners || - sBlockedScriptRunners->Count() == 0, - "How'd this happen?"); - delete sBlockedScriptRunners; - sBlockedScriptRunners = nsnull; - nsAutoGCRoot::Shutdown(); } @@ -2602,41 +2588,17 @@ nsCxPusher::Push(nsISupports *aCurrentTarget) JSContext *cx = nsnull; - nsCOMPtr scx; - if (sgo) { - scx = sgo->GetContext(); + mScx = sgo->GetContext(); - if (scx) { - cx = (JSContext *)scx->GetNativeContext(); + 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); } @@ -2650,6 +2612,13 @@ nsCxPusher::Push(JSContext *cx) 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; } @@ -3991,65 +3960,6 @@ nsContentUtils::DOMEventToNativeKeyEvent(nsIDOMEvent* 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 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 run = aRunnable; - run->Run(); - - return PR_TRUE; -} - /* static */ void nsContentUtils::HidePopupsInDocument(nsIDocument* aDocument) diff --git a/mozilla/content/base/src/nsDocument.cpp b/mozilla/content/base/src/nsDocument.cpp index 69b9356d73d..6ff43836737 100644 --- a/mozilla/content/base/src/nsDocument.cpp +++ b/mozilla/content/base/src/nsDocument.cpp @@ -2701,15 +2701,15 @@ nsDocument::BeginUpdate(nsUpdateType aUpdateType) } ++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; @@ -2719,6 +2719,10 @@ nsDocument::EndUpdate(nsUpdateType aUpdateType) mBindingManager->EndOutermostUpdate(); } + if (mScriptLoader) { + mScriptLoader->RemoveExecuteBlocker(); + } + if (mUpdateNestLevel == 0) { PRUint32 length = mFinalizableFrameLoaders.Length(); if (length > 0) { diff --git a/mozilla/content/base/src/nsObjectLoadingContent.cpp b/mozilla/content/base/src/nsObjectLoadingContent.cpp index 038860deba5..f8de508567a 100644 --- a/mozilla/content/base/src/nsObjectLoadingContent.cpp +++ b/mozilla/content/base/src/nsObjectLoadingContent.cpp @@ -127,11 +127,10 @@ nsAsyncInstantiateEvent::Run() 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)) { @@ -517,7 +516,7 @@ nsObjectLoadingContent::OnStartRequest(nsIRequest *aRequest, nsISupports *aConte 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. @@ -583,7 +582,7 @@ nsObjectLoadingContent::OnStartRequest(nsIRequest *aRequest, nsISupports *aConte #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 @@ -672,7 +671,7 @@ nsObjectLoadingContent::EnsureInstantiation(nsIPluginInstance** aInstance) 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. @@ -709,7 +708,7 @@ nsObjectLoadingContent::EnsureInstantiation(nsIPluginInstance** aInstance) mInstantiating = PR_FALSE; - frame = GetExistingFrame(eFlushContent); + frame = GetFrame(PR_FALSE); if (!frame) { return NS_OK; } @@ -772,19 +771,6 @@ nsObjectLoadingContent::HasNewFrame(nsIObjectFrame* aFrame) 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) @@ -1541,12 +1527,13 @@ nsObjectLoadingContent::GetObjectBaseURI(nsIContent* thisContent, nsIURI** aURI) } nsIObjectFrame* -nsObjectLoadingContent::GetExistingFrame(FlushType aFlushType) +nsObjectLoadingContent::GetFrame(PRBool aFlushLayout) { nsCOMPtr thisContent = do_QueryInterface(static_cast(this)); NS_ASSERTION(thisContent, "must be a content"); + PRBool flushed = PR_FALSE; nsIFrame* frame; do { nsIDocument* doc = thisContent->GetCurrentDoc(); @@ -1564,17 +1551,17 @@ nsObjectLoadingContent::GetExistingFrame(FlushType aFlushType) 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; @@ -1603,7 +1590,7 @@ 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 diff --git a/mozilla/content/base/src/nsObjectLoadingContent.h b/mozilla/content/base/src/nsObjectLoadingContent.h index dda21413fa3..793713c5e21 100644 --- a/mozilla/content/base/src/nsObjectLoadingContent.h +++ b/mozilla/content/base/src/nsObjectLoadingContent.h @@ -270,27 +270,14 @@ class nsObjectLoadingContent : public nsImageLoadingContent */ 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 @@ -408,7 +395,7 @@ class nsObjectLoadingContent : public nsImageLoadingContent // Whether we fell back because of an unsupported type PRBool mTypeUnsupported:1; - friend class nsAsyncInstantiateEvent; + friend struct nsAsyncInstantiateEvent; }; diff --git a/mozilla/content/base/src/nsScriptLoader.cpp b/mozilla/content/base/src/nsScriptLoader.cpp index ff3c00693c2..f7caf28a4c5 100644 --- a/mozilla/content/base/src/nsScriptLoader.cpp +++ b/mozilla/content/base/src/nsScriptLoader.cpp @@ -159,7 +159,8 @@ NS_IMPL_THREADSAFE_ISUPPORTS0(nsScriptLoadRequest) nsScriptLoader::nsScriptLoader(nsIDocument *aDocument) : mDocument(aDocument), mBlockerCount(0), - mEnabled(PR_TRUE) + mEnabled(PR_TRUE), + mHadPendingScripts(PR_FALSE) { } @@ -490,8 +491,7 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement) // 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); } } @@ -500,14 +500,6 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement) 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(this, - &nsScriptLoader::ProcessPendingRequests)); - } - // Added as pending request, now we can send blocking back return NS_ERROR_HTMLPARSER_BLOCK; } @@ -515,7 +507,7 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement) nsresult nsScriptLoader::ProcessRequest(nsScriptLoadRequest* aRequest) { - NS_ASSERTION(ReadyToExecuteScripts() && nsContentUtils::IsSafeToRunScript(), + NS_ASSERTION(ReadyToExecuteScripts(), "Caller forgot to check ReadyToExecuteScripts()"); NS_ENSURE_ARG(aRequest); diff --git a/mozilla/content/base/src/nsScriptLoader.h b/mozilla/content/base/src/nsScriptLoader.h index b89cc6b30b1..58d855675b4 100644 --- a/mozilla/content/base/src/nsScriptLoader.h +++ b/mozilla/content/base/src/nsScriptLoader.h @@ -147,15 +147,31 @@ public: /** * 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(); + } } } @@ -230,6 +246,7 @@ protected: nsTArray< nsRefPtr > mPendingChildLoaders; PRUint32 mBlockerCount; PRPackedBool mEnabled; + PRPackedBool mHadPendingScripts; }; #endif //__nsScriptLoader_h__ diff --git a/mozilla/content/xbl/src/nsBindingManager.cpp b/mozilla/content/xbl/src/nsBindingManager.cpp index bbb9f7ebaaa..ae3ba028568 100644 --- a/mozilla/content/xbl/src/nsBindingManager.cpp +++ b/mozilla/content/xbl/src/nsBindingManager.cpp @@ -972,13 +972,28 @@ nsBindingManager::ProcessAttachedQueue(PRUint32 aSkipSize) 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 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 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 binding = mAttachedStack.ElementAt(currentIndex); + mAttachedStack.RemoveElementAt(currentIndex); + if (binding) { + binding->ExecuteAttachedHandler(); + } } } @@ -1522,6 +1537,16 @@ nsBindingManager::EndOutermostUpdate() ProcessAttachedQueue(mAttachedStackSizeOnOutermost); mAttachedStackSizeOnOutermost = 0; } + else { + PRUint32 i = mAttachedStackSizeOnOutermost; + for (; i < mAttachedStack.Length(); ++i) { + nsRefPtr binding = mAttachedStack[i]; + nsresult rv = binding->EnsureScriptAPI(); + if (NS_FAILED(rv)) { + mAttachedStack[i] = nsnull; + } + } + } } void diff --git a/mozilla/content/xbl/src/nsXBLBinding.cpp b/mozilla/content/xbl/src/nsXBLBinding.cpp index a1f62a8b078..7a7ca8c5434 100644 --- a/mozilla/content/xbl/src/nsXBLBinding.cpp +++ b/mozilla/content/xbl/src/nsXBLBinding.cpp @@ -272,7 +272,8 @@ 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 @@ -785,6 +786,22 @@ nsXBLBinding::GenerateAnonymousContent() } } +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() { diff --git a/mozilla/content/xbl/src/nsXBLBinding.h b/mozilla/content/xbl/src/nsXBLBinding.h index c61f18bb2b1..77658efdd4b 100644 --- a/mozilla/content/xbl/src/nsXBLBinding.h +++ b/mozilla/content/xbl/src/nsXBLBinding.h @@ -120,8 +120,7 @@ public: void GenerateAnonymousContent(); void InstallAnonymousContent(nsIContent* aAnonParent, nsIContent* aElement); - void InstallEventHandlers(); - nsresult InstallImplementation(); + nsresult EnsureScriptAPI(); void ExecuteAttachedHandler(); void ExecuteDetachedHandler(); @@ -168,6 +167,11 @@ public: // 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 @@ -181,6 +185,7 @@ protected: PRPackedBool mIsStyleBinding; PRPackedBool mMarkedForDeath; + PRPackedBool mInstalledAPI; }; #endif // nsXBLBinding_h_ diff --git a/mozilla/content/xbl/src/nsXBLService.cpp b/mozilla/content/xbl/src/nsXBLService.cpp index 5d8a5006f4b..3eb9a7e90c8 100644 --- a/mozilla/content/xbl/src/nsXBLService.cpp +++ b/mozilla/content/xbl/src/nsXBLService.cpp @@ -563,13 +563,6 @@ nsXBLService::LoadBindings(nsIContent* aContent, nsIURI* aURL, // 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(); diff --git a/mozilla/dom/src/base/nsDOMClassInfo.cpp b/mozilla/dom/src/base/nsDOMClassInfo.cpp index fe8d8ad3c8f..8751722146b 100644 --- a/mozilla/dom/src/base/nsDOMClassInfo.cpp +++ b/mozilla/dom/src/base/nsDOMClassInfo.cpp @@ -59,8 +59,6 @@ #include "prprf.h" #include "nsTArray.h" #include "nsCSSValue.h" -#include "nsIRunnable.h" -#include "nsThreadUtils.h" // JavaScript includes #include "jsapi.h" @@ -7141,17 +7139,20 @@ nsElementSH::PostCreate(nsIXPConnectWrappedNative *wrapper, JSContext *cx, // We must ensure that the XBL Binding is installed before we hand // back this object. + nsRefPtr 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. + (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. - // 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; + return binding->EnsureScriptAPI(); } // See if we have a frame. @@ -7175,7 +7176,6 @@ nsElementSH::PostCreate(nsIXPConnectWrappedNative *wrapper, JSContext *cx, // Make sure the style context goes away _before_ we execute the binding // constructor, since the constructor can destroy the relevant presshell. - nsRefPtr binding; { // Scope for the nsRefPtr nsRefPtr sc = pctx->StyleSet()->ResolveStyleFor(content, @@ -7200,13 +7200,17 @@ nsElementSH::PostCreate(nsIXPConnectWrappedNative *wrapper, JSContext *cx, } if (binding) { - if (nsContentUtils::IsSafeToRunScript()) { - binding->ExecuteAttachedHandler(); - } - else { - nsContentUtils::AddScriptRunner(new nsRunnableMethod( - 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; @@ -8797,24 +8801,17 @@ nsHTMLSelectElementSH::SetProperty(nsIXPConnectWrappedNative *wrapper, // static nsresult -nsHTMLPluginObjElementSH::GetPluginInstanceIfSafe(nsIXPConnectWrappedNative *wrapper, - nsIPluginInstance **_result) +nsHTMLPluginObjElementSH::GetPluginInstance(nsIXPConnectWrappedNative *wrapper, + nsIPluginInstance **_result) { *_result = nsnull; nsCOMPtr content(do_QueryWrappedNative(wrapper)); NS_ENSURE_TRUE(content, NS_ERROR_UNEXPECTED); + // Make sure that there is a plugin nsCOMPtr 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); } @@ -8840,51 +8837,22 @@ IsObjInProtoChain(JSContext *cx, JSObject *obj, JSObject *proto) return PR_FALSE; } -class nsPluginProtoChainInstallRunner : public nsIRunnable + +// 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) { -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 mWrapper; - nsCOMPtr 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; - } + nsresult rv = nsElementSH::PostCreate(wrapper, cx, obj); + NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr pi; - nsresult rv = GetPluginInstanceIfSafe(wrapper, getter_AddRefs(pi)); + rv = GetPluginInstance(wrapper, getter_AddRefs(pi)); NS_ENSURE_SUCCESS(rv, rv); if (!pi) { @@ -8908,7 +8876,7 @@ nsHTMLPluginObjElementSH::SetupProtoChain(nsIXPConnectWrappedNative *wrapper, 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; @@ -8998,26 +8966,6 @@ nsHTMLPluginObjElementSH::SetupProtoChain(nsIXPConnectWrappedNative *wrapper, 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 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, @@ -9119,7 +9067,7 @@ nsHTMLPluginObjElementSH::Call(nsIXPConnectWrappedNative *wrapper, jsval *argv, jsval *vp, PRBool *_retval) { nsCOMPtr pi; - nsresult rv = GetPluginInstanceIfSafe(wrapper, getter_AddRefs(pi)); + nsresult rv = GetPluginInstance(wrapper, getter_AddRefs(pi)); NS_ENSURE_SUCCESS(rv, rv); if (!pi) { @@ -9336,7 +9284,7 @@ nsHTMLPluginObjElementSH::NewResolve(nsIXPConnectWrappedNative *wrapper, // plugin instances. nsCOMPtr pi; - nsresult rv = GetPluginInstanceIfSafe(wrapper, getter_AddRefs(pi)); + nsresult rv = GetPluginInstance(wrapper, getter_AddRefs(pi)); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr plugin_internal = diff --git a/mozilla/dom/src/base/nsDOMClassInfo.h b/mozilla/dom/src/base/nsDOMClassInfo.h index 10803f91d6d..0d806061d76 100644 --- a/mozilla/dom/src/base/nsDOMClassInfo.h +++ b/mozilla/dom/src/base/nsDOMClassInfo.h @@ -977,8 +977,8 @@ protected: { } - static nsresult GetPluginInstanceIfSafe(nsIXPConnectWrappedNative *aWrapper, - nsIPluginInstance **aResult); + nsresult GetPluginInstance(nsIXPConnectWrappedNative *aWrapper, + nsIPluginInstance **aResult); static nsresult GetPluginJSObject(JSContext *cx, JSObject *obj, nsIPluginInstance *plugin_inst, @@ -1004,10 +1004,6 @@ public: 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); diff --git a/mozilla/layout/base/nsDocumentViewer.cpp b/mozilla/layout/base/nsDocumentViewer.cpp index f84c9aceabb..c791de42fee 100644 --- a/mozilla/layout/base/nsDocumentViewer.cpp +++ b/mozilla/layout/base/nsDocumentViewer.cpp @@ -1048,9 +1048,6 @@ DocumentViewerImpl::PermitUnload(PRBool *aPermitUnload) 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; diff --git a/mozilla/layout/base/nsPresShell.cpp b/mozilla/layout/base/nsPresShell.cpp index 141c30930a7..779723060c2 100644 --- a/mozilla/layout/base/nsPresShell.cpp +++ b/mozilla/layout/base/nsPresShell.cpp @@ -760,7 +760,6 @@ struct nsCallbackEventRequest // ---------------------------------------------------------------------------- class nsPresShellEventCB; -class nsAutoCauseReflowNotifier; class PresShell : public nsIPresShell, public nsIViewObserver, public nsStubDocumentObserver, @@ -1010,14 +1009,8 @@ protected: void UnsuppressAndInvalidate(); - - void WillCauseReflow() { - nsContentUtils::AddScriptBlocker(); - ++mChangeNestCount; - } + void WillCauseReflow() { ++mChangeNestCount; } nsresult DidCauseReflow(); - friend class nsAutoCauseReflowNotifier; - void WillDoReflow(); void DidDoReflow(); nsresult ProcessReflowCommands(PRBool aInterruptible); @@ -1216,29 +1209,6 @@ private: 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: @@ -2413,35 +2383,31 @@ PresShell::InitialReflow(nscoord aWidth, nscoord aHeight) MOZ_TIMER_RESET(mFrameCreationWatch); MOZ_TIMER_START(mFrameCreationWatch); - { - nsAutoCauseReflowNotifier reflowNotifier(this); - mFrameConstructor->BeginUpdate(); + 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(); + 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); } - // DidCauseReflow may have killed us too + // 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(); @@ -2556,10 +2522,10 @@ PresShell::ResizeReflow(nscoord aWidth, nscoord aHeight) // XXX Do a full invalidate at the beginning so that invalidates along // the way don't have region accumulation issues? - { - nsAutoCauseReflowNotifier crNotifier(this); - WillDoReflow(); + WillCauseReflow(); + WillDoReflow(); + { // Kick off a top-down reflow AUTO_LAYOUT_PHASE_ENTRY_POINT(GetPresContext(), Reflow); mIsReflowing = PR_TRUE; @@ -2569,6 +2535,7 @@ PresShell::ResizeReflow(nscoord aWidth, nscoord aHeight) mIsReflowing = PR_FALSE; } + DidCauseReflow(); DidDoReflow(); } @@ -3111,7 +3078,6 @@ PresShell::RestoreRootScrollPosition() // 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) { @@ -3402,8 +3368,6 @@ PresShell::RecreateFramesFor(nsIContent* aContent) // 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); @@ -4495,16 +4459,12 @@ PresShell::HandlePostedReflowCallbacks() 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; + aIsSafeToFlush = PR_TRUE; - if (aIsSafeToFlush) { + 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) { @@ -4515,10 +4475,6 @@ PresShell::IsSafeToFlush(PRBool& aIsSafeToFlush) } } } - - NS_ASSERTION(aIsSafeToFlush == nsContentUtils::IsSafeToRunScript(), - "Someone forgot to block scripts"); - return NS_OK; } @@ -4622,8 +4578,7 @@ PresShell::CharacterDataChanged(nsIDocument *aDocument, 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 @@ -4652,6 +4607,7 @@ PresShell::CharacterDataChanged(nsIDocument *aDocument, mFrameConstructor->CharacterDataChanged(aContent, aInfo->mAppend); VERIFY_STYLE_TREE; + DidCauseReflow(); } void @@ -4664,9 +4620,10 @@ PresShell::ContentStatesChanged(nsIDocument* aDocument, NS_PRECONDITION(aDocument == mDocument, "Unexpected aDocument"); if (mDidInitialReflow) { - nsAutoCauseReflowNotifier crNotifier(this); + WillCauseReflow(); mFrameConstructor->ContentStatesChanged(aContent1, aContent2, aStateMask); VERIFY_STYLE_TREE; + DidCauseReflow(); } } @@ -4686,10 +4643,11 @@ PresShell::AttributeChanged(nsIDocument* aDocument, // 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(); } } @@ -4706,7 +4664,7 @@ PresShell::ContentAppended(nsIDocument *aDocument, return; } - nsAutoCauseReflowNotifier crNotifier(this); + WillCauseReflow(); MOZ_TIMER_DEBUGLOG(("Start: Frame Creation: PresShell::ContentAppended(), this=%p\n", this)); MOZ_TIMER_START(mFrameCreationWatch); @@ -4720,6 +4678,7 @@ PresShell::ContentAppended(nsIDocument *aDocument, MOZ_TIMER_DEBUGLOG(("Stop: Frame Creation: PresShell::ContentAppended(), this=%p\n", this)); MOZ_TIMER_STOP(mFrameCreationWatch); + DidCauseReflow(); } void @@ -4735,7 +4694,7 @@ PresShell::ContentInserted(nsIDocument* aDocument, 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 @@ -4746,6 +4705,7 @@ PresShell::ContentInserted(nsIDocument* aDocument, mFrameConstructor->ContentInserted(aContainer, aChild, aIndexInContainer, nsnull); VERIFY_STYLE_TREE; + DidCauseReflow(); } void @@ -4766,7 +4726,7 @@ PresShell::ContentRemoved(nsIDocument *aDocument, // 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 @@ -4779,14 +4739,18 @@ PresShell::ContentRemoved(nsIDocument *aDocument, 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; } @@ -5555,11 +5519,7 @@ PresShell::HandleEvent(nsIView *aView, { 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; } @@ -6201,8 +6161,6 @@ PresShell::DidCauseReflow() PostReflowEvent(); } - nsContentUtils::RemoveScriptBlocker(); - return NS_OK; } @@ -6380,7 +6338,6 @@ PresShell::ProcessReflowCommands(PRBool aInterruptible) // Scope for the reflow entry point { - nsAutoScriptBlocker scriptBlocker; AUTO_LAYOUT_PHASE_ENTRY_POINT(GetPresContext(), Reflow); mIsReflowing = PR_TRUE; @@ -6410,10 +6367,7 @@ PresShell::ProcessReflowCommands(PRBool aInterruptible) mIsReflowing = PR_FALSE; } - // Exiting the scriptblocker might have killed us - if (!mIsDestroying) { - DidDoReflow(); - } + DidDoReflow(); // DidDoReflow might have killed us if (!mIsDestroying) { @@ -6550,12 +6504,9 @@ PresShell::Observe(nsISupports* aSubject, 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 diff --git a/mozilla/layout/generic/Makefile.in b/mozilla/layout/generic/Makefile.in index fe437852bd1..528ad19e3a4 100644 --- a/mozilla/layout/generic/Makefile.in +++ b/mozilla/layout/generic/Makefile.in @@ -187,7 +187,6 @@ LOCAL_INCLUDES += \ -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) diff --git a/mozilla/layout/generic/nsObjectFrame.cpp b/mozilla/layout/generic/nsObjectFrame.cpp index 03f0df3fd5b..99327b682ef 100644 --- a/mozilla/layout/generic/nsObjectFrame.cpp +++ b/mozilla/layout/generic/nsObjectFrame.cpp @@ -108,7 +108,6 @@ #include "nsDisplayList.h" #include "nsAttrName.h" #include "nsDataHashtable.h" -#include "nsDOMClassInfo.h" // headers for plugin scriptability #include "nsIScriptGlobalObject.h" @@ -1843,8 +1842,22 @@ nsObjectFrame::NotifyContentObjectWrapper() 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 ci(do_QueryInterface(mContent)); + if (!ci) + return; + + nsCOMPtr s; + ci->GetHelperForLanguage(nsIProgrammingLanguage::JAVASCRIPT, + getter_AddRefs(s)); + + nsCOMPtr helper(do_QueryInterface(s)); + + if (!helper) { + // There's nothing we can do if there's no helper return; } @@ -1853,7 +1866,13 @@ nsObjectFrame::NotifyContentObjectWrapper() 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 diff --git a/mozilla/view/src/Makefile.in b/mozilla/view/src/Makefile.in index ffff5980ec3..a9a78e64c36 100644 --- a/mozilla/view/src/Makefile.in +++ b/mozilla/view/src/Makefile.in @@ -57,9 +57,6 @@ REQUIRES = xpcom \ pref \ thebes \ cairo \ - content \ - js \ - layout \ $(NULL) EXTRA_DSO_LIBS = gkgfx diff --git a/mozilla/view/src/nsViewManager.cpp b/mozilla/view/src/nsViewManager.cpp index 8ca479517d2..1331776a417 100644 --- a/mozilla/view/src/nsViewManager.cpp +++ b/mozilla/view/src/nsViewManager.cpp @@ -61,7 +61,6 @@ #include "nsHashtable.h" #include "nsCOMArray.h" #include "nsThreadUtils.h" -#include "nsContentUtils.h" #include "gfxContext.h" @@ -453,51 +452,47 @@ void nsViewManager::Refresh(nsView *aView, nsIRenderingContext *aContext, RootViewManager()->mRecursiveRefreshPending = PR_TRUE; return; } + SetPainting(PR_TRUE); - { - nsAutoScriptBlocker scriptBlocker; - SetPainting(PR_TRUE); + nsCOMPtr localcx; + NS_ASSERTION(aView->GetWidget(), + "Must have a widget to calculate coordinates correctly"); + if (nsnull == aContext) + { + localcx = CreateRenderingContext(*aView); - nsCOMPtr 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 ctx = localcx->ThebesContext(); + nsRefPtr 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)); + ctx->Translate(gfxPoint(-gfxFloat(viewRect.x) / p2a, + -gfxFloat(viewRect.y) / p2a)); - nsRegion opaqueRegion; - AddCoveringWidgetsToOpaqueRegion(opaqueRegion, mContext, aView); - damageRegion.Sub(damageRegion, opaqueRegion); + nsRegion opaqueRegion; + AddCoveringWidgetsToOpaqueRegion(opaqueRegion, mContext, aView); + damageRegion.Sub(damageRegion, opaqueRegion); - RenderViews(aView, *localcx, damageRegion); + RenderViews(aView, *localcx, damageRegion); - ctx->Restore(); + ctx->Restore(); - SetPainting(PR_FALSE); - } + SetPainting(PR_FALSE); if (RootViewManager()->mRecursiveRefreshPending) { // Unset this flag first, since if aUpdateFlags includes NS_VMREFRESH_IMMEDIATE