From 6e4225fe342ad798c5137b2acb47de5dfd87b9c4 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Wed, 14 Jan 2009 07:49:18 -0500 Subject: [PATCH] Bug 453736. Make more like other scripts and fix up a few other minor issues. r=roc, r+sr=sicking --- content/base/src/nsScriptElement.cpp | 9 ++- content/base/test/Makefile.in | 1 + content/base/test/test_bug453736.html | 97 ++++++++++++++++++++++++ content/html/content/src/nsHTMLScriptElement.cpp | 4 +- content/svg/content/src/nsSVGScriptElement.cpp | 33 +++++--- layout/base/nsCSSFrameConstructor.cpp | 16 +++- layout/base/nsCSSFrameConstructor.h | 4 +- 7 files changed, 146 insertions(+), 18 deletions(-) create mode 100644 content/base/test/test_bug453736.html diff --git a/content/base/src/nsScriptElement.cpp b/content/base/src/nsScriptElement.cpp index 83a885ef09..dd489e43cf 100755 --- a/content/base/src/nsScriptElement.cpp +++ b/content/base/src/nsScriptElement.cpp @@ -177,8 +177,13 @@ nsScriptElement::MaybeProcessScript() "You forgot to add self as observer"); if (mIsEvaluated || !mDoneAddingChildren || !cont->IsInDoc() || - mMalformed || InNonScriptingContainer(cont) || - !HasScriptContent()) { + mMalformed || !HasScriptContent()) { + return NS_OK; + } + + if (InNonScriptingContainer(cont)) { + // Make sure to flag ourselves as evaluated + mIsEvaluated = PR_TRUE; return NS_OK; } diff --git a/content/base/test/Makefile.in b/content/base/test/Makefile.in index 792e8ccb11..3eddcee413 100644 --- a/content/base/test/Makefile.in +++ b/content/base/test/Makefile.in @@ -240,6 +240,7 @@ _TEST_FILES = test_bug5141.html \ test_bug368972.html \ test_bug448993.html \ test_bug450160.html \ + test_bug453736.html \ test_bug454326.html \ test_bug457746.html \ bug457746.sjs \ diff --git a/content/base/test/test_bug453736.html b/content/base/test/test_bug453736.html new file mode 100644 index 0000000000..4b3f7941ed --- /dev/null +++ b/content/base/test/test_bug453736.html @@ -0,0 +1,97 @@ + + + + + Test for Bug 453736 + + + + + +Mozilla Bug 453736 +

+ +
+
+
+ + diff --git a/content/html/content/src/nsHTMLScriptElement.cpp b/content/html/content/src/nsHTMLScriptElement.cpp index b35049202b..f3f9affd00 100644 --- a/content/html/content/src/nsHTMLScriptElement.cpp +++ b/content/html/content/src/nsHTMLScriptElement.cpp @@ -432,9 +432,7 @@ nsHTMLScriptElement::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const nsresult rv = CopyInnerTo(it); NS_ENSURE_SUCCESS(rv, rv); - // The clone should be marked evaluated if we are. It should also be marked - // evaluated if we're evaluating, to handle the case when this script node's - // script clones the node. + // The clone should be marked evaluated if we are. it->mIsEvaluated = mIsEvaluated; it->mLineNumber = mLineNumber; it->mMalformed = mMalformed; diff --git a/content/svg/content/src/nsSVGScriptElement.cpp b/content/svg/content/src/nsSVGScriptElement.cpp index 1b69ca58bf..4e1cf9ce62 100644 --- a/content/svg/content/src/nsSVGScriptElement.cpp +++ b/content/svg/content/src/nsSVGScriptElement.cpp @@ -101,10 +101,6 @@ protected: enum { HREF }; nsSVGString mStringAttributes[1]; static StringInfo sStringInfo[1]; - - PRUint32 mLineNumber; - PRPackedBool mIsEvaluated; - PRPackedBool mEvaluating; }; nsSVGElement::StringInfo nsSVGScriptElement::sStringInfo[1] = @@ -132,10 +128,7 @@ NS_INTERFACE_MAP_END_INHERITING(nsSVGScriptElementBase) // Implementation nsSVGScriptElement::nsSVGScriptElement(nsINodeInfo *aNodeInfo) - : nsSVGScriptElementBase(aNodeInfo), - mLineNumber(0), - mIsEvaluated(PR_FALSE), - mEvaluating(PR_FALSE) + : nsSVGScriptElementBase(aNodeInfo) { AddMutationObserver(this); } @@ -143,7 +136,29 @@ nsSVGScriptElement::nsSVGScriptElement(nsINodeInfo *aNodeInfo) //---------------------------------------------------------------------- // nsIDOMNode methods -NS_IMPL_ELEMENT_CLONE_WITH_INIT(nsSVGScriptElement) +nsresult +nsSVGScriptElement::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const +{ + *aResult = nsnull; + + nsSVGScriptElement* it = new nsSVGScriptElement(aNodeInfo); + if (!it) { + return NS_ERROR_OUT_OF_MEMORY; + } + + nsCOMPtr kungFuDeathGrip = it; + nsresult rv = CopyInnerTo(it); + NS_ENSURE_SUCCESS(rv, rv); + + // The clone should be marked evaluated if we are. + it->mIsEvaluated = mIsEvaluated; + it->mLineNumber = mLineNumber; + it->mMalformed = mMalformed; + + kungFuDeathGrip.swap(*aResult); + + return NS_OK; +} //---------------------------------------------------------------------- // nsIDOMSVGScriptElement methods diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index a518ebc7e1..66a2137678 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -9674,6 +9674,8 @@ nsCSSFrameConstructor::CharacterDataChanged(nsIContent* aContent, nsresult nsCSSFrameConstructor::ProcessRestyledFrames(nsStyleChangeList& aChangeList) { + NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(), + "Someone forgot a script blocker"); PRInt32 count = aChangeList.Count(); if (!count) return NS_OK; @@ -13261,6 +13263,11 @@ nsCSSFrameConstructor::RebuildAllStyleData(nsChangeHint aExtraHint) return; } + nsAutoScriptBlocker scriptBlocker; + + // Make sure that the viewmanager will outlive the presshell + nsIViewManager::UpdateViewBatch batch(mPresShell->GetViewManager()); + // Processing the style changes could cause a flush that propagates to // the parent frame and thus destroys the pres shell. nsCOMPtr kungFuDeathGrip(mPresShell); @@ -13268,8 +13275,10 @@ nsCSSFrameConstructor::RebuildAllStyleData(nsChangeHint aExtraHint) // Tell the style set to get the old rule tree out of the way // so we can recalculate while maintaining rule tree immutability nsresult rv = mPresShell->StyleSet()->BeginReconstruct(); - if (NS_FAILED(rv)) + if (NS_FAILED(rv)) { + batch.EndUpdateViewBatch(NS_VMREFRESH_NO_SYNC); return; + } // Recalculate all of the style contexts for the document // Note that we can ignore the return value of ComputeStyleChangeFor @@ -13290,6 +13299,7 @@ nsCSSFrameConstructor::RebuildAllStyleData(nsChangeHint aExtraHint) // reconstructed will still have their old style context pointers // until they are destroyed). mPresShell->StyleSet()->EndReconstruct(); + batch.EndUpdateViewBatch(NS_VMREFRESH_NO_SYNC); } void @@ -13450,8 +13460,10 @@ nsCSSFrameConstructor::LazyGenerateChildrenEvent::Run() nsFrameConstructorState state(mPresShell, nsnull, nsnull, nsnull); nsresult rv = fc->ProcessChildren(state, mContent, frame->GetStyleContext(), frame, PR_FALSE, childItems, PR_FALSE); - if (NS_FAILED(rv)) + if (NS_FAILED(rv)) { + fc->EndUpdate(); return rv; + } frame->SetInitialChildList(nsnull, childItems.childList); diff --git a/layout/base/nsCSSFrameConstructor.h b/layout/base/nsCSSFrameConstructor.h index 62f88074b9..48a791c7f5 100644 --- a/layout/base/nsCSSFrameConstructor.h +++ b/layout/base/nsCSSFrameConstructor.h @@ -164,7 +164,7 @@ public: PRUint32 GetHoverGeneration() const { return mHoverGeneration; } // Note: It's the caller's responsibility to make sure to wrap a - // ProcessRestyledFrames call in a view update batch. + // ProcessRestyledFrames call in a view update batch and a script blocker. // This function does not call ProcessAttachedQueue() on the binding manager. // If the caller wants that to happen synchronously, it needs to handle that // itself. @@ -198,7 +198,7 @@ public: PRInt32 aNewIndexInContainer); // Note: It's the caller's responsibility to make sure to wrap a - // ProcessPendingRestyles call in a view update batch. + // ProcessPendingRestyles call in a view update batch and a script blocker. // This function does not call ProcessAttachedQueue() on the binding manager. // If the caller wants that to happen synchronously, it needs to handle that // itself. -- 2.11.4.GIT