Add a routine to clear the direction set by a textnode without resetting it. Bug 894137, a=abillings
authorSimon Montagu <smontagu@smontagu.org>
Wed, 14 Aug 2013 10:25:26 +0300
changeset 153731 2f898f833ad0c26b655c07afd50fdf5449c99696
parent 153730 8e86314a9540afcf49727fa1894f309d88adeb61
child 153732 42c525c9745ea193376109a6a9b0166b3ad6ab7f
push id2859
push userakeybl@mozilla.com
push dateMon, 16 Sep 2013 19:14:59 +0000
treeherdermozilla-beta@87d3c51cd2bf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersabillings
bugs894137
milestone25.0a2
Add a routine to clear the direction set by a textnode without resetting it. Bug 894137, a=abillings
content/base/public/DirectionalityUtils.h
content/base/src/DirectionalityUtils.cpp
content/base/src/nsTextNode.cpp
--- a/content/base/public/DirectionalityUtils.h
+++ b/content/base/public/DirectionalityUtils.h
@@ -90,18 +90,22 @@ void SetDirectionFromChangedTextNode(nsI
  * When a text node is appended to an element, find any ancestors with dir=auto
  * whose directionality will be determined by the text node
  */
 void SetDirectionFromNewTextNode(nsIContent* aTextNode);
 
 /**
  * When a text node is removed from a document, find any ancestors whose
  * directionality it determined and redetermine their directionality
+ *
+ * @param aTextNode the text node
+ * @param aNullParent whether the the parent is also being removed
+ *        (passed from UnbindFromTree)
  */
-void ResetDirectionSetByTextNode(nsTextNode* aTextNode);
+void ResetDirectionSetByTextNode(nsTextNode* aTextNode, bool aNullParent);
 
 /**
  * Set the directionality of an element according to the directionality of the
  * text in aValue
  */
 void SetDirectionalityFromValue(mozilla::dom::Element* aElement,
                                 const nsAString& aValue,
                                 bool aNotify);
--- a/content/base/src/DirectionalityUtils.cpp
+++ b/content/base/src/DirectionalityUtils.cpp
@@ -497,17 +497,17 @@ private:
   static PLDHashOperator ResetNodeDirection(nsPtrHashKey<Element>* aEntry, void* aData)
   {
     MOZ_ASSERT(aEntry->GetKey()->IsElement(), "Must be an Element");
     // run the downward propagation algorithm
     // and remove the text node from the map
     nsINode* oldTextNode = static_cast<Element*>(aData);
     Element* rootNode = aEntry->GetKey();
     nsINode* newTextNode = nullptr;
-    if (rootNode->HasDirAuto()) {
+    if (oldTextNode && rootNode->HasDirAuto()) {
       newTextNode = WalkDescendantsSetDirectionFromText(rootNode, true,
                                                         oldTextNode);
     }
     if (newTextNode) {
       nsTextNodeDirectionalityMap::AddEntryToMap(newTextNode, rootNode);
     } else {
       rootNode->ClearHasDirAutoSet();
       rootNode->UnsetProperty(nsGkAtoms::dirAutoSetBy);
@@ -524,16 +524,21 @@ private:
   }
 
 public:
   void UpdateAutoDirection(Directionality aDir)
   {
     mElements.EnumerateEntries(SetNodeDirection, &aDir);
   }
 
+  void ClearAutoDirection()
+  {
+    mElements.EnumerateEntries(ResetNodeDirection, nullptr);
+  }
+
   void ResetAutoDirection(nsINode* aTextNode)
   {
     mElements.EnumerateEntries(ResetNodeDirection, aTextNode);
   }
 
   void EnsureMapIsClear(nsINode* aTextNode)
   {
     DebugOnly<uint32_t> clearedEntries =
@@ -560,16 +565,23 @@ public:
 
   static void UpdateTextNodeDirection(nsINode* aTextNode, Directionality aDir)
   {
     MOZ_ASSERT(aTextNode->HasTextNodeDirectionalityMap(),
                "Map missing in UpdateTextNodeDirection");
     GetDirectionalityMap(aTextNode)->UpdateAutoDirection(aDir);
   }
 
+  static void ClearTextNodeDirection(nsINode* aTextNode)
+  {
+    MOZ_ASSERT(aTextNode->HasTextNodeDirectionalityMap(),
+               "Map missing in ResetTextNodeDirection");
+    GetDirectionalityMap(aTextNode)->ClearAutoDirection();
+  }
+
   static void ResetTextNodeDirection(nsINode* aTextNode)
   {
     MOZ_ASSERT(aTextNode->HasTextNodeDirectionalityMap(),
                "Map missing in ResetTextNodeDirection");
     GetDirectionalityMap(aTextNode)->ResetAutoDirection(aTextNode);
   }
 
   static void EnsureMapIsClearFor(nsINode* aTextNode)
@@ -866,26 +878,30 @@ SetDirectionFromNewTextNode(nsIContent* 
 
   Directionality dir = GetDirectionFromText(aTextNode->GetText());
   if (dir != eDir_NotSet) {
     SetAncestorDirectionIfAuto(aTextNode, dir);
   }
 }
 
 void
-ResetDirectionSetByTextNode(nsTextNode* aTextNode)
+ResetDirectionSetByTextNode(nsTextNode* aTextNode, bool aNullParent)
 {
   if (!NodeAffectsDirAutoAncestor(aTextNode)) {
     nsTextNodeDirectionalityMap::EnsureMapIsClearFor(aTextNode);
     return;
   }
 
   Directionality dir = GetDirectionFromText(aTextNode->GetText());
   if (dir != eDir_NotSet && aTextNode->HasTextNodeDirectionalityMap()) {
-    nsTextNodeDirectionalityMap::ResetTextNodeDirection(aTextNode);
+    if (aNullParent) {
+      nsTextNodeDirectionalityMap::ClearTextNodeDirection(aTextNode);
+    } else {
+      nsTextNodeDirectionalityMap::ResetTextNodeDirection(aTextNode);
+    }
   }
 }
 
 void
 SetDirectionalityFromValue(Element* aElement, const nsAString& value,
                            bool aNotify)
 {
   Directionality dir = GetDirectionFromText(PromiseFlatString(value).get(),
--- a/content/base/src/nsTextNode.cpp
+++ b/content/base/src/nsTextNode.cpp
@@ -142,17 +142,17 @@ nsTextNode::BindToTree(nsIDocument* aDoc
 
   SetDirectionFromNewTextNode(this);
 
   return NS_OK;
 }
 
 void nsTextNode::UnbindFromTree(bool aDeep, bool aNullParent)
 {
-  ResetDirectionSetByTextNode(this);
+  ResetDirectionSetByTextNode(this, aNullParent);
 
   nsGenericDOMDataNode::UnbindFromTree(aDeep, aNullParent);
 }
 
 #ifdef DEBUG
 void
 nsTextNode::List(FILE* out, int32_t aIndent) const
 {