Bug 467005. Be smarter about our removable script blockers. r=sicking

This commit is contained in:
Boris Zbarsky 2009-10-29 21:48:38 -04:00
Родитель 2bfc0f34a2
Коммит 4c55c31dc5
10 изменённых файлов: 56 добавлений и 30 удалений

Просмотреть файл

@ -70,6 +70,7 @@ class nsIContent;
class nsIDOMNode;
class nsIDOMKeyEvent;
class nsIDocument;
class nsIDocumentObserver;
class nsIDocShell;
class nsINameSpaceManager;
class nsIScriptSecurityManager;
@ -1674,27 +1675,13 @@ public:
class mozAutoRemovableBlockerRemover
{
public:
mozAutoRemovableBlockerRemover()
{
mNestingLevel = nsContentUtils::GetRemovableScriptBlockerLevel();
for (PRUint32 i = 0; i < mNestingLevel; ++i) {
nsContentUtils::RemoveRemovableScriptBlocker();
}
NS_ASSERTION(nsContentUtils::IsSafeToRunScript(), "killing mutation events");
}
~mozAutoRemovableBlockerRemover()
{
NS_ASSERTION(nsContentUtils::GetRemovableScriptBlockerLevel() == 0,
"Should have had none");
for (PRUint32 i = 0; i < mNestingLevel; ++i) {
nsContentUtils::AddRemovableScriptBlocker();
}
}
mozAutoRemovableBlockerRemover(nsIDocument* aDocument);
~mozAutoRemovableBlockerRemover();
private:
PRUint32 mNestingLevel;
nsCOMPtr<nsIDocument> mDocument;
nsCOMPtr<nsIDocumentObserver> mObserver;
};
#define NS_AUTO_GCROOT_PASTE2(tok,line) tok##line

Просмотреть файл

@ -105,8 +105,8 @@ class nsIBoxObject;
// IID for the nsIDocument interface
#define NS_IDOCUMENT_IID \
{ 0x2ca82a51, 0x4a6a, 0x4dfa, \
{ 0xa6, 0x5f, 0x49, 0x52, 0xa3, 0xaa, 0x02, 0xef } }
{ 0xd16d73c1, 0xe0f7, 0x415c, \
{ 0xbd, 0x68, 0x9c, 0x1f, 0x93, 0xb8, 0x73, 0x7a } }
// Flag for AddStyleSheet().
#define NS_STYLESHEET_FROM_CATALOG (1 << 0)
@ -1207,6 +1207,8 @@ public:
*/
virtual nsresult SetFirstBaseNodeWithHref(nsIContent *node) = 0;
virtual nsISupports* GetCurrentContentSink() = 0;
protected:
~nsIDocument()
{

Просмотреть файл

@ -1587,7 +1587,7 @@ void
nsContentSink::BeginUpdate(nsIDocument *aDocument, nsUpdateType aUpdateType)
{
// Remember nested updates from updates that we started.
if (mInNotification && mUpdatesInNotification < 2) {
if (mInNotification > 0 && mUpdatesInNotification < 2) {
++mUpdatesInNotification;
}

Просмотреть файл

@ -5173,3 +5173,31 @@ nsContentUtils::WrapNative(JSContext *cx, JSObject *scope, nsISupports *native,
return rv;
}
mozAutoRemovableBlockerRemover::mozAutoRemovableBlockerRemover(nsIDocument* aDocument)
{
mNestingLevel = nsContentUtils::GetRemovableScriptBlockerLevel();
mDocument = aDocument;
nsISupports* sink = aDocument ? aDocument->GetCurrentContentSink() : nsnull;
mObserver = do_QueryInterface(sink);
for (PRUint32 i = 0; i < mNestingLevel; ++i) {
if (mObserver) {
mObserver->EndUpdate(mDocument, UPDATE_CONTENT_MODEL);
}
nsContentUtils::RemoveRemovableScriptBlocker();
}
NS_ASSERTION(nsContentUtils::IsSafeToRunScript(), "killing mutation events");
}
mozAutoRemovableBlockerRemover::~mozAutoRemovableBlockerRemover()
{
NS_ASSERTION(nsContentUtils::GetRemovableScriptBlockerLevel() == 0,
"Should have had none");
for (PRUint32 i = 0; i < mNestingLevel; ++i) {
nsContentUtils::AddRemovableScriptBlocker();
if (mObserver) {
mObserver->BeginUpdate(mDocument, UPDATE_CONTENT_MODEL);
}
}
}

Просмотреть файл

@ -723,7 +723,7 @@ nsDOMAttribute::RemoveChildAt(PRUint32 aIndex, PRBool aNotify, PRBool aMutationE
nsContentUtils::HasMutationListeners(mChild,
NS_EVENT_BITS_MUTATION_NODEREMOVED,
this)) {
mozAutoRemovableBlockerRemover blockerRemover;
mozAutoRemovableBlockerRemover blockerRemover(GetOwnerDoc());
nsMutationEvent mutation(PR_TRUE, NS_MUTATION_NODEREMOVED);
mutation.mRelatedNode =
do_QueryInterface(static_cast<nsIAttribute*>(this));

Просмотреть файл

@ -7326,7 +7326,7 @@ nsDocument::MutationEventDispatched(nsINode* aTarget)
PRInt32 realTargetCount = realTargets.Count();
for (PRInt32 k = 0; k < realTargetCount; ++k) {
mozAutoRemovableBlockerRemover blockerRemover;
mozAutoRemovableBlockerRemover blockerRemover(this);
nsMutationEvent mutation(PR_TRUE, NS_MUTATION_SUBTREEMODIFIED);
nsEventDispatcher::Dispatch(realTargets[k], nsnull, &mutation);
@ -7770,6 +7770,12 @@ nsDocument::UnsuppressEventHandlingAndFireEvents(PRBool aFireEvents)
}
}
nsISupports*
nsDocument::GetCurrentContentSink()
{
return mParser ? mParser->GetContentSink() : nsnull;
}
void
nsIDocument::RegisterFreezableElement(nsIContent* aContent)
{

Просмотреть файл

@ -1011,6 +1011,9 @@ public:
void MaybeEndOutermostXBLUpdate();
virtual void MaybePreLoadImage(nsIURI* uri);
virtual nsISupports* GetCurrentContentSink();
protected:
friend class nsNodeUtils;
void RegisterNamedItems(nsIContent *aContent);

Просмотреть файл

@ -441,7 +441,7 @@ nsGenericDOMDataNode::SetTextInternal(PRUint32 aOffset, PRUint32 aCount,
nsNodeUtils::CharacterDataChanged(this, &info);
if (haveMutationListeners) {
mozAutoRemovableBlockerRemover blockerRemover;
mozAutoRemovableBlockerRemover blockerRemover(GetOwnerDoc());
nsMutationEvent mutation(PR_TRUE, NS_MUTATION_CHARACTERDATAMODIFIED);

Просмотреть файл

@ -3300,7 +3300,7 @@ nsGenericElement::doInsertChildAt(nsIContent* aKid, PRUint32 aIndex,
if (nsContentUtils::HasMutationListeners(aKid,
NS_EVENT_BITS_MUTATION_NODEINSERTED, container)) {
mozAutoRemovableBlockerRemover blockerRemover;
mozAutoRemovableBlockerRemover blockerRemover(container->GetOwnerDoc());
nsMutationEvent mutation(PR_TRUE, NS_MUTATION_NODEINSERTED);
mutation.mRelatedNode = do_QueryInterface(container);
@ -3372,7 +3372,7 @@ nsGenericElement::doRemoveChildAt(PRUint32 aIndex, PRBool aNotify,
aMutationEvent &&
nsContentUtils::HasMutationListeners(aKid,
NS_EVENT_BITS_MUTATION_NODEREMOVED, container)) {
mozAutoRemovableBlockerRemover blockerRemover;
mozAutoRemovableBlockerRemover blockerRemover(container->GetOwnerDoc());
nsMutationEvent mutation(PR_TRUE, NS_MUTATION_NODEREMOVED);
mutation.mRelatedNode = do_QueryInterface(container);
@ -3938,7 +3938,7 @@ nsGenericElement::doReplaceOrInsertBefore(PRBool aReplace,
if (nsContentUtils::HasMutationListeners(childContent,
NS_EVENT_BITS_MUTATION_NODEINSERTED, container)) {
mozAutoRemovableBlockerRemover blockerRemover;
mozAutoRemovableBlockerRemover blockerRemover(container->GetOwnerDoc());
nsMutationEvent mutation(PR_TRUE, NS_MUTATION_NODEINSERTED);
mutation.mRelatedNode = do_QueryInterface(container);
@ -4448,7 +4448,7 @@ nsGenericElement::SetAttrAndNotify(PRInt32 aNamespaceID,
}
if (aFireMutation) {
mozAutoRemovableBlockerRemover blockerRemover;
mozAutoRemovableBlockerRemover blockerRemover(GetOwnerDoc());
nsMutationEvent mutation(PR_TRUE, NS_MUTATION_ATTRMODIFIED);
@ -4704,7 +4704,7 @@ nsGenericElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
NS_ENSURE_SUCCESS(rv, rv);
if (hasMutationListeners) {
mozAutoRemovableBlockerRemover blockerRemover;
mozAutoRemovableBlockerRemover blockerRemover(GetOwnerDoc());
nsCOMPtr<nsIDOMEventTarget> node =
do_QueryInterface(static_cast<nsIContent *>(this));

Просмотреть файл

@ -1434,7 +1434,7 @@ nsXULElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aName, PRBool aNotify)
}
if (hasMutationListeners) {
mozAutoRemovableBlockerRemover blockerRemover;
mozAutoRemovableBlockerRemover blockerRemover(GetOwnerDoc());
nsMutationEvent mutation(PR_TRUE, NS_MUTATION_ATTRMODIFIED);