Fix for bug 395340 (Crash [@ nsINode::GetNodeParent] with CSS counters and contentEditable). r/sr=bz, a=endgame.
authorpeterv@propagandism.org
Fri, 26 Oct 2007 03:30:44 -0700
changeset 7199 14b8540ade44305407f05d972950a26478a10081
parent 7198 d6d74250a8bfaf5c14c6fd4d9b898e4e09f7398c
child 7200 38eb784bf571da848f1e2062211ca670fd8b07f8
push id1
push userbsmedberg@mozilla.com
push dateThu, 20 Mar 2008 16:49:24 +0000
treeherdermozilla-central@61007906a1f8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersendgame
bugs395340
milestone1.9a9pre
Fix for bug 395340 (Crash [@ nsINode::GetNodeParent] with CSS counters and contentEditable). r/sr=bz, a=endgame.
content/base/src/nsDocument.h
content/html/document/src/nsHTMLDocument.cpp
content/html/document/src/nsHTMLDocument.h
--- a/content/base/src/nsDocument.h
+++ b/content/base/src/nsDocument.h
@@ -787,16 +787,19 @@ protected:
   nsRefPtr<nsHTMLStyleSheet> mAttrStyleSheet;
   nsCOMPtr<nsIHTMLCSSStyleSheet> mStyleAttrStyleSheet;
   nsRefPtr<nsXMLEventsManager> mXMLEventsManager;
 
   nsCOMPtr<nsIScriptEventManager> mScriptEventManager;
 
   nsString mBaseTarget;
 
+  // Our update nesting level
+  PRUint32 mUpdateNestLevel;
+
 private:
   friend class nsUnblockOnloadEvent;
 
   void PostUnblockOnloadEvent();
   void DoUnblockOnload();
 
   /**
    * See if aDocument is a child of this.  If so, return the frame element in
@@ -828,15 +831,12 @@ private:
   
   // A map from unvisited URI hashes to content elements
   nsTHashtable<nsUint32ToContentHashEntry> mLinkMap;
   // URIs whose visitedness has changed while we were hidden
   nsCOMArray<nsIURI> mVisitednessChangedURIs;
 
   // Member to store out last-selected stylesheet set.
   nsString mLastStyleSheetSet;
-
-  // Our update nesting level
-  PRUint32 mUpdateNestLevel;
 };
 
 
 #endif /* nsDocument_h___ */
--- a/content/html/document/src/nsHTMLDocument.cpp
+++ b/content/html/document/src/nsHTMLDocument.cpp
@@ -3727,26 +3727,37 @@ nsHTMLDocument::GetDesignMode(nsAString 
     aDesignMode.AssignLiteral("on");
   }
   else {
     aDesignMode.AssignLiteral("off");
   }
   return NS_OK;
 }
 
+void
+nsHTMLDocument::EndUpdate(nsUpdateType aUpdateType)
+{
+  nsDocument::EndUpdate(aUpdateType);
+
+  if (mUpdateNestLevel == 0 && EditingShouldBeOn() != IsEditingOn()) {
+    EditingStateChanged();
+  }
+}
+
 nsresult
 nsHTMLDocument::ChangeContentEditableCount(nsIContent *aElement,
                                            PRInt32 aChange)
 {
   NS_ASSERTION(mContentEditableCount + aChange >= 0,
                "Trying to decrement too much.");
 
   mContentEditableCount += aChange;
 
-  if (mParser) {
+  if (mParser ||
+      (mUpdateNestLevel > 0 && EditingShouldBeOn() != IsEditingOn())) {
     return NS_OK;
   }
 
   EditingState oldState = mEditingState;
 
   nsresult rv = EditingStateChanged();
   NS_ENSURE_SUCCESS(rv, rv);
 
--- a/content/html/document/src/nsHTMLDocument.h
+++ b/content/html/document/src/nsHTMLDocument.h
@@ -207,16 +207,27 @@ public:
     return mEditingState;
   }
 
   virtual void DisableCookieAccess()
   {
     mDisableCookieAccess = PR_TRUE;
   }
 
+  /**
+   * Returns whether the document should be editable. This can be different from
+   * IsEditingOn() (for example if we're delaying turning the editor on/off).
+   */
+  PRBool EditingShouldBeOn()
+  {
+    return HasFlag(NODE_IS_EDITABLE) || mContentEditableCount > 0;
+  }
+
+  void EndUpdate(nsUpdateType aUpdateType);
+
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(nsHTMLDocument, nsDocument)
 
 protected:
   nsresult GetBodySize(PRInt32* aWidth,
                        PRInt32* aHeight);
 
   nsresult RegisterNamedItems(nsIContent *aContent);
   nsresult UnregisterNamedItems(nsIContent *aContent);