Bug 1004522 part 7 - Clean up nsWSRunObject::Prior/NextVisibleNode; r=ehsan
☠☠ backed out by 318f472972ac ☠ ☠
authorAryeh Gregor <ayg@aryeh.name>
Fri, 02 May 2014 15:15:27 +0300
changeset 202968 6cc778964f67d6efe91de3f394fa0e3a04c6d558
parent 202967 774ba83e548f3e316764d5ec979c9be1e8afd913
child 202969 59107353aa68a66f6432bff7548e2503f118ce4b
push id494
push userraliiev@mozilla.com
push dateMon, 25 Aug 2014 18:42:16 +0000
treeherdermozilla-release@a3cc3e46b571 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs1004522
milestone32.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1004522 part 7 - Clean up nsWSRunObject::Prior/NextVisibleNode; r=ehsan
editor/libeditor/html/nsHTMLDataTransfer.cpp
editor/libeditor/html/nsHTMLEditRules.cpp
editor/libeditor/html/nsHTMLEditor.cpp
editor/libeditor/html/nsWSRunObject.cpp
editor/libeditor/html/nsWSRunObject.h
--- a/editor/libeditor/html/nsHTMLDataTransfer.cpp
+++ b/editor/libeditor/html/nsHTMLDataTransfer.cpp
@@ -622,17 +622,17 @@ nsHTMLEditor::DoInsertHTMLWithContext(co
         offsetOfNewNode++;
       }
     }
 
     // Now collapse the selection to the end of what we just inserted:
     if (lastInsertNode) 
     {
       // set selection to the end of what we just pasted.
-      nsCOMPtr<nsIDOMNode> selNode, tmp, visNode, highTable;
+      nsCOMPtr<nsIDOMNode> selNode, tmp, highTable;
       int32_t selOffset;
 
       // but don't cross tables
       if (!nsHTMLEditUtils::IsTable(lastInsertNode))
       {
         rv = GetLastEditableLeaf(lastInsertNode, address_of(selNode));
         NS_ENSURE_SUCCESS(rv, rv);
         tmp = selNode;
@@ -658,36 +658,39 @@ nsHTMLEditor::DoInsertHTMLWithContext(co
       {
         tmp = selNode;
         selNode = GetNodeLocation(tmp, &selOffset);
         ++selOffset;  // want to be *after* last leaf node in paste
       }
 
       // make sure we don't end up with selection collapsed after an invisible break node
       nsWSRunObject wsRunObj(this, selNode, selOffset);
+      nsCOMPtr<nsINode> visNode;
       int32_t outVisOffset=0;
       WSType visType;
-      wsRunObj.PriorVisibleNode(selNode, selOffset, address_of(visNode),
+      nsCOMPtr<nsINode> selNode_(do_QueryInterface(selNode));
+      wsRunObj.PriorVisibleNode(selNode_, selOffset, address_of(visNode),
                                 &outVisOffset, &visType);
       if (visType == WSType::br) {
         // we are after a break.  Is it visible?  Despite the name, 
         // PriorVisibleNode does not make that determination for breaks.
         // It also may not return the break in visNode.  We have to pull it
         // out of the nsWSRunObject's state.
         if (!IsVisBreak(wsRunObj.mStartReasonNode))
         {
           // don't leave selection past an invisible break;
           // reset {selNode,selOffset} to point before break
           selNode = GetNodeLocation(GetAsDOMNode(wsRunObj.mStartReasonNode), &selOffset);
           // we want to be inside any inline style prior to break
           nsWSRunObject wsRunObj(this, selNode, selOffset);
-          wsRunObj.PriorVisibleNode(selNode, selOffset, address_of(visNode),
+          selNode_ = do_QueryInterface(selNode);
+          wsRunObj.PriorVisibleNode(selNode_, selOffset, address_of(visNode),
                                     &outVisOffset, &visType);
           if (visType == WSType::text || visType == WSType::normalWS) {
-            selNode = visNode;
+            selNode = GetAsDOMNode(visNode);
             selOffset = outVisOffset;  // PriorVisibleNode already set offset to _after_ the text or ws
           } else if (visType == WSType::special) {
             // prior visible thing is an image or some other non-text thingy.  
             // We want to be right after it.
             selNode = GetNodeLocation(GetAsDOMNode(wsRunObj.mStartReasonNode), &selOffset);
             ++selOffset;
           }
         }
--- a/editor/libeditor/html/nsHTMLEditRules.cpp
+++ b/editor/libeditor/html/nsHTMLEditRules.cpp
@@ -1684,44 +1684,45 @@ nsHTMLEditRules::StandardBreakImpl(nsIDO
   nsCOMPtr<nsISelectionPrivate> selPriv(do_QueryInterface(aSelection));
 
   if (IsPlaintextEditor()) {
     NS_ENSURE_STATE(mHTMLEditor);
     res = mHTMLEditor->CreateBR(node, aOffset, address_of(brNode));
   } else {
     NS_ENSURE_STATE(mHTMLEditor);
     nsWSRunObject wsObj(mHTMLEditor, node, aOffset);
-    nsCOMPtr<nsIDOMNode> visNode, linkNode;
     int32_t visOffset = 0, newOffset;
     WSType wsType;
-    wsObj.PriorVisibleNode(node, aOffset, address_of(visNode),
+    nsCOMPtr<nsINode> node_(do_QueryInterface(node)), visNode;
+    wsObj.PriorVisibleNode(node_, aOffset, address_of(visNode),
                            &visOffset, &wsType);
     if (wsType & WSType::block) {
       bAfterBlock = true;
     }
-    wsObj.NextVisibleNode(node, aOffset, address_of(visNode),
+    wsObj.NextVisibleNode(node_, aOffset, address_of(visNode),
                           &visOffset, &wsType);
     if (wsType & WSType::block) {
       bBeforeBlock = true;
     }
     NS_ENSURE_STATE(mHTMLEditor);
+    nsCOMPtr<nsIDOMNode> linkNode;
     if (mHTMLEditor->IsInLink(node, address_of(linkNode))) {
       // split the link
       nsCOMPtr<nsIDOMNode> linkParent;
       res = linkNode->GetParentNode(getter_AddRefs(linkParent));
       NS_ENSURE_SUCCESS(res, res);
       NS_ENSURE_STATE(mHTMLEditor);
       res = mHTMLEditor->SplitNodeDeep(linkNode, node, aOffset,
                                        &newOffset, true);
       NS_ENSURE_SUCCESS(res, res);
       // reset {node,aOffset} to the point where link was split
       node = linkParent;
       aOffset = newOffset;
     }
-    nsCOMPtr<nsINode> node_ = do_QueryInterface(node);
+    node_ = do_QueryInterface(node);
     nsCOMPtr<Element> br =
       wsObj.InsertBreak(address_of(node_), &aOffset, nsIEditor::eNone);
     node = GetAsDOMNode(node_);
     brNode = GetAsDOMNode(br);
     NS_ENSURE_TRUE(brNode, NS_ERROR_FAILURE);
   }
   NS_ENSURE_SUCCESS(res, res);
   node = nsEditor::GetNodeLocation(brNode, &aOffset);
@@ -1730,33 +1731,34 @@ nsHTMLEditRules::StandardBreakImpl(nsIDO
     // we just placed a br between block boundaries.  This is the one case
     // where we want the selection to be before the br we just placed, as the
     // br will be on a new line, rather than at end of prior line.
     selPriv->SetInterlinePosition(true);
     res = aSelection->Collapse(node, aOffset);
   } else {
     NS_ENSURE_STATE(mHTMLEditor);
     nsWSRunObject wsObj(mHTMLEditor, node, aOffset+1);
-    nsCOMPtr<nsIDOMNode> secondBR;
+    nsCOMPtr<nsINode> secondBR;
     int32_t visOffset = 0;
     WSType wsType;
-    wsObj.NextVisibleNode(node, aOffset+1, address_of(secondBR),
+    nsCOMPtr<nsINode> node_(do_QueryInterface(node));
+    wsObj.NextVisibleNode(node_, aOffset+1, address_of(secondBR),
                           &visOffset, &wsType);
     if (wsType == WSType::br) {
       // the next thing after the break we inserted is another break.  Move
       // the 2nd break to be the first breaks sibling.  This will prevent them
       // from being in different inline nodes, which would break
       // SetInterlinePosition().  It will also assure that if the user clicks
       // away and then clicks back on their new blank line, they will still
       // get the style from the line above.
       int32_t brOffset;
-      nsCOMPtr<nsIDOMNode> brParent = nsEditor::GetNodeLocation(secondBR, &brOffset);
+      nsCOMPtr<nsIDOMNode> brParent = nsEditor::GetNodeLocation(GetAsDOMNode(secondBR), &brOffset);
       if (brParent != node || brOffset != aOffset + 1) {
         NS_ENSURE_STATE(mHTMLEditor);
-        res = mHTMLEditor->MoveNode(secondBR, node, aOffset+1);
+        res = mHTMLEditor->MoveNode(GetAsDOMNode(secondBR), node, aOffset+1);
         NS_ENSURE_SUCCESS(res, res);
       }
     }
     // SetInterlinePosition(true) means we want the caret to stick to the
     // content on the "right".  We want the caret to stick to whatever is past
     // the break.  This is because the break is on the same line we were on,
     // but the next content will be on the following line.
 
@@ -1800,29 +1802,30 @@ nsHTMLEditRules::SplitMailCites(nsISelec
     // a break here ourselves to preserve the "blockness" of the inline span mailquote
     // (in the inline case), and :
     // it means the break won't end up making an empty line that happens to be inside a
     // mailquote (in either inline or block case).  
     // The latter can confuse a user if they click there and start typing,
     // because being in the mailquote may affect wrapping behavior, or font color, etc.
     NS_ENSURE_STATE(mHTMLEditor);
     nsWSRunObject wsObj(mHTMLEditor, selNode, selOffset);
-    nsCOMPtr<nsIDOMNode> visNode;
+    nsCOMPtr<nsINode> visNode;
     int32_t visOffset=0;
     WSType wsType;
-    wsObj.NextVisibleNode(selNode, selOffset, address_of(visNode),
+    nsCOMPtr<nsINode> selNode_(do_QueryInterface(selNode));
+    wsObj.NextVisibleNode(selNode_, selOffset, address_of(visNode),
                           &visOffset, &wsType);
     if (wsType == WSType::br) {
       // ok, we are just before a break.  is it inside the mailquote?
       int32_t unused;
-      if (nsEditorUtils::IsDescendantOf(visNode, citeNode, &unused))
+      if (nsEditorUtils::IsDescendantOf(GetAsDOMNode(visNode), citeNode, &unused))
       {
         // it is.  so lets reset our selection to be just after it.
         NS_ENSURE_STATE(mHTMLEditor);
-        selNode = mHTMLEditor->GetNodeLocation(visNode, &selOffset);
+        selNode = mHTMLEditor->GetNodeLocation(GetAsDOMNode(visNode), &selOffset);
         ++selOffset;
       }
     }
      
     nsCOMPtr<nsIDOMNode> brNode;
     NS_ENSURE_STATE(mHTMLEditor);
     res = mHTMLEditor->SplitNodeDeep(citeNode, selNode, selOffset, &newOffset, 
                        true, address_of(leftCite), address_of(rightCite));
@@ -1839,26 +1842,27 @@ nsHTMLEditRules::SplitMailCites(nsISelec
     // if citeNode wasn't a block, we might also want another break before it.
     // We need to examine the content both before the br we just added and also
     // just after it.  If we don't have another br or block boundary adjacent,
     // then we will need a 2nd br added to achieve blank line that user expects.
     if (IsInlineNode(citeNode))
     {
       NS_ENSURE_STATE(mHTMLEditor);
       nsWSRunObject wsObj(mHTMLEditor, selNode, newOffset);
-      nsCOMPtr<nsIDOMNode> visNode;
+      nsCOMPtr<nsINode> visNode;
       int32_t visOffset=0;
       WSType wsType;
-      wsObj.PriorVisibleNode(selNode, newOffset, address_of(visNode),
+      nsCOMPtr<nsINode> selNode_(do_QueryInterface(selNode));
+      wsObj.PriorVisibleNode(selNode_, newOffset, address_of(visNode),
                              &visOffset, &wsType);
       if (wsType == WSType::normalWS || wsType == WSType::text ||
           wsType == WSType::special) {
         NS_ENSURE_STATE(mHTMLEditor);
         nsWSRunObject wsObjAfterBR(mHTMLEditor, selNode, newOffset+1);
-        wsObjAfterBR.NextVisibleNode(selNode, newOffset+1, address_of(visNode),
+        wsObjAfterBR.NextVisibleNode(selNode_, newOffset+1, address_of(visNode),
                                      &visOffset, &wsType);
         if (wsType == WSType::normalWS || wsType == WSType::text ||
             wsType == WSType::special) {
           NS_ENSURE_STATE(mHTMLEditor);
           res = mHTMLEditor->CreateBR(selNode, newOffset, address_of(brNode));
           NS_ENSURE_SUCCESS(res, res);
         }
       }
@@ -1979,34 +1983,36 @@ nsHTMLEditRules::WillDeleteSelection(Sel
     bCollapsed = aSelection->Collapsed();
   }
 
   if (bCollapsed)
   {
     // what's in the direction we are deleting?
     NS_ENSURE_STATE(mHTMLEditor);
     nsWSRunObject wsObj(mHTMLEditor, startNode, startOffset);
-    nsCOMPtr<nsIDOMNode> visNode;
+    nsCOMPtr<nsINode> visNode_;
     int32_t visOffset;
     WSType wsType;
 
     // find next visible node
+    nsCOMPtr<nsINode> startNode_(do_QueryInterface(startNode));
     if (aAction == nsIEditor::eNext)
-      wsObj.NextVisibleNode(startNode, startOffset, address_of(visNode),
+      wsObj.NextVisibleNode(startNode_, startOffset, address_of(visNode_),
                             &visOffset, &wsType);
     else
-      wsObj.PriorVisibleNode(startNode, startOffset, address_of(visNode),
+      wsObj.PriorVisibleNode(startNode_, startOffset, address_of(visNode_),
                              &visOffset, &wsType);
     
-    if (!visNode) // can't find anything to delete!
+    if (!visNode_) // can't find anything to delete!
     {
       *aCancel = true;
       return res;
     }
     
+    nsCOMPtr<nsIDOMNode> visNode(GetAsDOMNode(visNode_));
     if (wsType == WSType::normalWS) {
       // we found some visible ws to delete.  Let ws code handle it.
       if (aAction == nsIEditor::eNext)
         res = wsObj.DeleteWSForward();
       else
         res = wsObj.DeleteWSBackward();
       *aHandled = true;
       NS_ENSURE_SUCCESS(res, res);
@@ -2041,17 +2047,16 @@ nsHTMLEditRules::WillDeleteSelection(Sel
 #endif
 
         res = range->GetStartOffset(&so);
         NS_ENSURE_SUCCESS(res, res);
         res = range->GetEndOffset(&eo);
         NS_ENSURE_SUCCESS(res, res);
       }
       NS_ENSURE_STATE(mHTMLEditor);
-      nsCOMPtr<nsINode> visNode_(do_QueryInterface(visNode));
       res = nsWSRunObject::PrepareToDeleteRange(mHTMLEditor,
           address_of(visNode_), &so, address_of(visNode_), &eo);
       NS_ENSURE_SUCCESS(res, res);
       visNode = GetAsDOMNode(visNode_);
       nsCOMPtr<nsIDOMCharacterData> nodeAsText(do_QueryInterface(visNode));
       NS_ENSURE_STATE(mHTMLEditor);
       res = mHTMLEditor->DeleteText(nodeAsText, std::min(so, eo), DeprecatedAbs(eo - so));
       *aHandled = true;
@@ -2119,20 +2124,21 @@ nsHTMLEditRules::WillDeleteSelection(Sel
           aSelection->SetInterlinePosition(false);
           mDidExplicitlySetInterline = true;
           *aHandled = true;
 
           // There is one exception to the move only case.
           // If the <hr> is followed by a <br> we want to delete the <br>.
 
           WSType otherWSType;
-          nsCOMPtr<nsIDOMNode> otherNode;
+          nsCOMPtr<nsINode> otherNode;
           int32_t otherOffset;
 
-          wsObj.NextVisibleNode(startNode, startOffset, address_of(otherNode),
+          nsCOMPtr<nsINode> startNode_(do_QueryInterface(startNode));
+          wsObj.NextVisibleNode(startNode_, startOffset, address_of(otherNode),
                                 &otherOffset, &otherWSType);
 
           if (otherWSType == WSType::br) {
             // Delete the <br>
 
             NS_ENSURE_STATE(mHTMLEditor);
             nsCOMPtr<nsIContent> otherContent(do_QueryInterface(otherNode));
             res = nsWSRunObject::PrepareToDeleteNode(mHTMLEditor, otherContent);
@@ -2194,25 +2200,26 @@ nsHTMLEditRules::WillDeleteSelection(Sel
         return NS_OK;
       }
       
       // next to a block.  See if we are between a block and a br.  If so, we really
       // want to delete the br.  Else join content at selection to the block.
       
       bool bDeletedBR = false;
       WSType otherWSType;
-      nsCOMPtr<nsIDOMNode> otherNode;
+      nsCOMPtr<nsINode> otherNode;
       int32_t otherOffset;
       
       // find node in other direction
+      nsCOMPtr<nsINode> startNode_(do_QueryInterface(startNode));
       if (aAction == nsIEditor::eNext)
-        wsObj.PriorVisibleNode(startNode, startOffset, address_of(otherNode),
+        wsObj.PriorVisibleNode(startNode_, startOffset, address_of(otherNode),
                                &otherOffset, &otherWSType);
       else
-        wsObj.NextVisibleNode(startNode, startOffset, address_of(otherNode),
+        wsObj.NextVisibleNode(startNode_, startOffset, address_of(otherNode),
                               &otherOffset, &otherWSType);
       
       // first find the adjacent node in the block
       nsCOMPtr<nsIDOMNode> leafNode, leftNode, rightNode;
       if (aAction == nsIEditor::ePrevious) 
       {
         NS_ENSURE_STATE(mHTMLEditor);
         res = mHTMLEditor->GetLastEditableLeaf( visNode, address_of(leafNode));
@@ -5320,30 +5327,32 @@ nsHTMLEditRules::ExpandSelectionForDelet
   res = range->GetCommonAncestorContainer(getter_AddRefs(selCommon));
   NS_ENSURE_SUCCESS(res, res);
   if (!IsBlockNode(selCommon))
     selCommon = nsHTMLEditor::GetBlockNodeParent(selCommon);
   NS_ENSURE_STATE(selCommon);
 
   // set up for loops and cache our root element
   bool stillLooking = true;
-  nsCOMPtr<nsIDOMNode> visNode, firstBRParent;
+  nsCOMPtr<nsIDOMNode> firstBRParent;
+  nsCOMPtr<nsINode> unused;
   int32_t visOffset=0, firstBROffset=0;
   WSType wsType;
   nsCOMPtr<nsIContent> rootContent = mHTMLEditor->GetActiveEditingHost();
   nsCOMPtr<nsIDOMNode> rootElement = do_QueryInterface(rootContent);
   NS_ENSURE_TRUE(rootElement, NS_ERROR_FAILURE);
 
   // find previous visible thingy before start of selection
   if ((selStartNode!=selCommon) && (selStartNode!=rootElement))
   {
     while (stillLooking)
     {
       nsWSRunObject wsObj(mHTMLEditor, selStartNode, selStartOffset);
-      wsObj.PriorVisibleNode(selStartNode, selStartOffset, address_of(visNode),
+      nsCOMPtr<nsINode> selStartNode_(do_QueryInterface(selStartNode));
+      wsObj.PriorVisibleNode(selStartNode_, selStartOffset, address_of(unused),
                              &visOffset, &wsType);
       if (wsType == WSType::thisBlock) {
         // we want to keep looking up.  But stop if we are crossing table element
         // boundaries, or if we hit the root.
         if (nsHTMLEditUtils::IsTableElement(wsObj.mStartReasonNode) ||
             selCommon == GetAsDOMNode(wsObj.mStartReasonNode) ||
             rootElement == GetAsDOMNode(wsObj.mStartReasonNode)) {
           stillLooking = false;
@@ -5363,17 +5372,18 @@ nsHTMLEditRules::ExpandSelectionForDelet
   
   stillLooking = true;
   // find next visible thingy after end of selection
   if ((selEndNode!=selCommon) && (selEndNode!=rootElement))
   {
     while (stillLooking)
     {
       nsWSRunObject wsObj(mHTMLEditor, selEndNode, selEndOffset);
-      wsObj.NextVisibleNode(selEndNode, selEndOffset, address_of(visNode),
+      nsCOMPtr<nsINode> selEndNode_(do_QueryInterface(selEndNode));
+      wsObj.NextVisibleNode(selEndNode_, selEndOffset, address_of(unused),
                             &visOffset, &wsType);
       if (wsType == WSType::br) {
         if (mHTMLEditor->IsVisBreak(wsObj.mEndReasonNode))
         {
           stillLooking = false;
         }
         else
         { 
@@ -5498,25 +5508,26 @@ nsHTMLEditRules::NormalizeSelection(nsIS
   
   // adjusted values default to original values
   newStartNode = startNode; 
   newStartOffset = startOffset;
   newEndNode = endNode; 
   newEndOffset = endOffset;
   
   // some locals we need for whitespace code
-  nsCOMPtr<nsIDOMNode> someNode;
+  nsCOMPtr<nsINode> unused;
   int32_t offset;
   WSType wsType;
 
   // let the whitespace code do the heavy lifting
   nsWSRunObject wsEndObj(mHTMLEditor, endNode, endOffset);
   // is there any intervening visible whitespace?  if so we can't push selection past that,
   // it would visibly change maening of users selection
-  wsEndObj.PriorVisibleNode(endNode, endOffset, address_of(someNode),
+  nsCOMPtr<nsINode> endNode_(do_QueryInterface(endNode));
+  wsEndObj.PriorVisibleNode(endNode_, endOffset, address_of(unused),
                             &offset, &wsType);
   if (wsType != WSType::text && wsType != WSType::normalWS) {
     // eThisBlock and eOtherBlock conveniently distinquish cases
     // of going "down" into a block and "up" out of a block.
     if (wsEndObj.mStartReason == WSType::otherBlock) {
       // endpoint is just after the close of a block.
       nsCOMPtr<nsIDOMNode> child = mHTMLEditor->GetRightmostChild(GetAsDOMNode(wsEndObj.mStartReasonNode), true);
       if (child)
@@ -5543,17 +5554,18 @@ nsHTMLEditRules::NormalizeSelection(nsIS
     }
   }
   
   
   // similar dealio for start of range
   nsWSRunObject wsStartObj(mHTMLEditor, startNode, startOffset);
   // is there any intervening visible whitespace?  if so we can't push selection past that,
   // it would visibly change maening of users selection
-  wsStartObj.NextVisibleNode(startNode, startOffset, address_of(someNode),
+  nsCOMPtr<nsINode> startNode_(do_QueryInterface(startNode));
+  wsStartObj.NextVisibleNode(startNode_, startOffset, address_of(unused),
                              &offset, &wsType);
   if (wsType != WSType::text && wsType != WSType::normalWS) {
     // eThisBlock and eOtherBlock conveniently distinquish cases
     // of going "down" into a block and "up" out of a block.
     if (wsStartObj.mEndReason == WSType::otherBlock) {
       // startpoint is just before the start of a block.
       nsCOMPtr<nsIDOMNode> child = mHTMLEditor->GetLeftmostChild(GetAsDOMNode(wsStartObj.mEndReasonNode), true);
       if (child)
@@ -7040,21 +7052,23 @@ nsHTMLEditRules::ReturnInListItem(nsISel
           nsCOMPtr<nsIDOMNode> brParent = nsEditor::GetNodeLocation(brNode, &offset);
           return aSelection->Collapse(brParent, offset);
         }
       }
       else
       {
         NS_ENSURE_STATE(mHTMLEditor);
         nsWSRunObject wsObj(mHTMLEditor, aListItem, 0);
-        nsCOMPtr<nsIDOMNode> visNode;
+        nsCOMPtr<nsINode> visNode_;
         int32_t visOffset = 0;
         WSType wsType;
-        wsObj.NextVisibleNode(aListItem, 0, address_of(visNode),
+        nsCOMPtr<nsINode> aListItem_(do_QueryInterface(aListItem));
+        wsObj.NextVisibleNode(aListItem_, 0, address_of(visNode_),
                               &visOffset, &wsType);
+        nsCOMPtr<nsIDOMNode> visNode(GetAsDOMNode(visNode_));
         if (wsType == WSType::special || wsType == WSType::br ||
             nsHTMLEditUtils::IsHR(visNode)) {
           int32_t offset;
           nsCOMPtr<nsIDOMNode> parent = nsEditor::GetNodeLocation(visNode, &offset);
           return aSelection->Collapse(parent, offset);
         }
         else
         {
--- a/editor/libeditor/html/nsHTMLEditor.cpp
+++ b/editor/libeditor/html/nsHTMLEditor.cpp
@@ -527,26 +527,26 @@ nsHTMLEditor::BeginningOfDocument()
 
   // find first editable thingy
   bool done = false;
   nsCOMPtr<nsIDOMNode> curNode(rootElement), selNode;
   int32_t curOffset = 0, selOffset;
   while (!done)
   {
     nsWSRunObject wsObj(this, curNode, curOffset);
-    nsCOMPtr<nsIDOMNode> visNode;
     int32_t visOffset=0;
     WSType visType;
-    wsObj.NextVisibleNode(curNode, curOffset, address_of(visNode), &visOffset, &visType);
+    nsCOMPtr<nsINode> visNode, curNode_(do_QueryInterface(curNode));
+    wsObj.NextVisibleNode(curNode_, curOffset, address_of(visNode), &visOffset, &visType);
     if (visType == WSType::normalWS || visType == WSType::text) {
-      selNode = visNode;
+      selNode = GetAsDOMNode(visNode);
       selOffset = visOffset;
       done = true;
     } else if (visType == WSType::br || visType == WSType::special) {
-      selNode = GetNodeLocation(visNode, &selOffset);
+      selNode = GetNodeLocation(GetAsDOMNode(visNode), &selOffset);
       done = true;
     } else if (visType == WSType::otherBlock) {
       // By definition of nsWSRunObject, a block element terminates 
       // a whitespace run. That is, although we are calling a method 
       // that is named "NextVisibleNode", the node returned
       // might not be visible/editable!
       // If the given block does not contain any visible/editable items,
       // we want to skip it and continue our search.
@@ -554,32 +554,32 @@ nsHTMLEditor::BeginningOfDocument()
       if (!IsContainer(visNode))
       {
         // However, we were given a block that is not a container.
         // Since the block can not contain anything that's visible,
         // such a block only makes sense if it is visible by itself,
         // like a <hr>
         // We want to place the caret in front of that block.
 
-        selNode = GetNodeLocation(visNode, &selOffset);
+        selNode = GetNodeLocation(GetAsDOMNode(visNode), &selOffset);
         done = true;
       }
       else
       {
         bool isEmptyBlock;
-        if (NS_SUCCEEDED(IsEmptyNode(visNode, &isEmptyBlock)) &&
+        if (NS_SUCCEEDED(IsEmptyNode(GetAsDOMNode(visNode), &isEmptyBlock)) &&
             isEmptyBlock)
         {
           // skip the empty block
-          curNode = GetNodeLocation(visNode, &curOffset);
+          curNode = GetNodeLocation(GetAsDOMNode(visNode), &curOffset);
           ++curOffset;
         }
         else
         {
-          curNode = visNode;
+          curNode = GetAsDOMNode(visNode);
           curOffset = 0;
         }
         // keep looping
       }
     }
     else
     {
       // else we found nothing useful
@@ -966,20 +966,20 @@ nsHTMLEditor::IsVisBreak(nsINode* aNode)
     
   // Sigh.  We have to use expensive whitespace calculation code to 
   // determine what is going on
   int32_t selOffset;
   nsCOMPtr<nsINode> selNode = GetNodeLocation(aNode, &selOffset);
   // Let's look after the break
   selOffset++;
   nsWSRunObject wsObj(this, selNode, selOffset);
-  nsCOMPtr<nsIDOMNode> visNode;
+  nsCOMPtr<nsINode> unused;
   int32_t visOffset = 0;
   WSType visType;
-  wsObj.NextVisibleNode(selNode->AsDOMNode(), selOffset, address_of(visNode),
+  wsObj.NextVisibleNode(selNode, selOffset, address_of(unused),
                         &visOffset, &visType);
   if (visType & WSType::block) {
     return false;
   }
   
   return true;
 }
 
@@ -1448,45 +1448,45 @@ nsHTMLEditor::NormalizeEOLInsertPosition
     4) We do not want to skip if the previous visible thing is in a different block
        than the insertion position.
   */
 
   if (!IsBlockNode(firstNodeToInsert))
     return;
 
   nsWSRunObject wsObj(this, *insertParentNode, *insertOffset);
-  nsCOMPtr<nsIDOMNode> nextVisNode;
-  nsCOMPtr<nsIDOMNode> prevVisNode;
+  nsCOMPtr<nsINode> nextVisNode, prevVisNode;
   int32_t nextVisOffset=0;
   WSType nextVisType;
   int32_t prevVisOffset=0;
   WSType prevVisType;
 
-  wsObj.NextVisibleNode(*insertParentNode, *insertOffset, address_of(nextVisNode), &nextVisOffset, &nextVisType);
+  nsCOMPtr<nsINode> parent(do_QueryInterface(*insertParentNode));
+  wsObj.NextVisibleNode(parent, *insertOffset, address_of(nextVisNode), &nextVisOffset, &nextVisType);
   if (!nextVisNode)
     return;
 
   if (!(nextVisType & WSType::br)) {
     return;
   }
 
-  wsObj.PriorVisibleNode(*insertParentNode, *insertOffset, address_of(prevVisNode), &prevVisOffset, &prevVisType);
+  wsObj.PriorVisibleNode(parent, *insertOffset, address_of(prevVisNode), &prevVisOffset, &prevVisType);
   if (!prevVisNode)
     return;
 
   if (prevVisType & WSType::br) {
     return;
   }
 
   if (prevVisType & WSType::thisBlock) {
     return;
   }
 
   int32_t brOffset=0;
-  nsCOMPtr<nsIDOMNode> brNode = GetNodeLocation(nextVisNode, &brOffset);
+  nsCOMPtr<nsIDOMNode> brNode = GetNodeLocation(GetAsDOMNode(nextVisNode), &brOffset);
 
   *insertParentNode = brNode;
   *insertOffset = brOffset + 1;
 }
 
 NS_IMETHODIMP
 nsHTMLEditor::InsertElementAtSelection(nsIDOMElement* aElement, bool aDeleteSelection)
 {
@@ -4379,25 +4379,24 @@ nsHTMLEditor::IsVisTextNode(nsIContent* 
     {
       *outIsEmptyNode = false;
     }
   }
   else if (length)
   {
     if (aNode->TextIsOnlyWhitespace())
     {
-      nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aNode);
-      nsWSRunObject wsRunObj(this, node, 0);
-      nsCOMPtr<nsIDOMNode> visNode;
+      nsWSRunObject wsRunObj(this, aNode, 0);
+      nsCOMPtr<nsINode> visNode;
       int32_t outVisOffset=0;
       WSType visType;
-      wsRunObj.NextVisibleNode(node, 0, address_of(visNode),
+      wsRunObj.NextVisibleNode(aNode, 0, address_of(visNode),
                                &outVisOffset, &visType);
       if (visType == WSType::normalWS || visType == WSType::text) {
-        *outIsEmptyNode = (node != visNode);
+        *outIsEmptyNode = (aNode != visNode);
       }
     }
     else
     {
       *outIsEmptyNode = false;
     }
   }
   return NS_OK;  
--- a/editor/libeditor/html/nsWSRunObject.cpp
+++ b/editor/libeditor/html/nsWSRunObject.cpp
@@ -484,114 +484,99 @@ nsWSRunObject::DeleteWSForward()
 
     // Finally, delete that ws
     return DeleteChars(GetAsDOMNode(node), startOffset, GetAsDOMNode(node), endOffset);
   }
   return NS_OK;
 }
 
 void
-nsWSRunObject::PriorVisibleNode(nsIDOMNode *aNode, 
-                                int32_t aOffset, 
-                                nsCOMPtr<nsIDOMNode> *outVisNode, 
-                                int32_t *outVisOffset,
-                                WSType *outType)
+nsWSRunObject::PriorVisibleNode(nsINode* aNode,
+                                int32_t aOffset,
+                                nsCOMPtr<nsINode>* outVisNode,
+                                int32_t* outVisOffset,
+                                WSType* outType)
 {
-  // Find first visible thing before the point.  position outVisNode/outVisOffset
-  // just _after_ that thing.  If we don't find anything return start of ws.
+  // Find first visible thing before the point.  Position
+  // outVisNode/outVisOffset just _after_ that thing.  If we don't find
+  // anything return start of ws.
   MOZ_ASSERT(aNode && outVisNode && outVisOffset && outType);
-    
-  *outType = WSType::none;
-  WSFragment *run;
-  FindRun(aNode, aOffset, &run, false);
-  
-  // is there a visible run there or earlier?
-  while (run)
-  {
+
+  WSFragment* run;
+  FindRun(GetAsDOMNode(aNode), aOffset, &run, false);
+
+  // Is there a visible run there or earlier?
+  for (; run; run = run->mLeft) {
     if (run->mType == WSType::normalWS) {
-      WSPoint point = GetCharBefore(aNode, aOffset);
-      if (point.mTextNode)
-      {
-        *outVisNode = do_QueryInterface(point.mTextNode);
-        *outVisOffset = point.mOffset+1;
-        if (nsCRT::IsAsciiSpace(point.mChar) || (point.mChar==nbsp))
-        {
+      WSPoint point = GetCharBefore(GetAsDOMNode(aNode), aOffset);
+      if (point.mTextNode) {
+        *outVisNode = point.mTextNode;
+        *outVisOffset = point.mOffset + 1;
+        if (nsCRT::IsAsciiSpace(point.mChar) || point.mChar == nbsp) {
           *outType = WSType::normalWS;
-        }
-        else if (!point.mChar)
-        {
+        } else if (!point.mChar) {
           // MOOSE: not possible?
           *outType = WSType::none;
-        }
-        else
-        {
+        } else {
           *outType = WSType::text;
         }
         return;
       }
-      // else if no text node then keep looking.  We should eventually fall out of loop
+      // If no text node, keep looking.  We should eventually fall out of loop
     }
-
-    run = run->mLeft;
   }
-  
-  // if we get here then nothing in ws data to find.  return start reason
-  *outVisNode = GetAsDOMNode(mStartReasonNode);
-  *outVisOffset = mStartOffset;  // this really isn't meaningful if mStartReasonNode!=mStartNode
+
+  // If we get here, then nothing in ws data to find.  Return start reason.
+  *outVisNode = mStartReasonNode;
+  // This really isn't meaningful if mStartReasonNode != mStartNode
+  *outVisOffset = mStartOffset;
   *outType = mStartReason;
 }
 
 
 void
-nsWSRunObject::NextVisibleNode (nsIDOMNode *aNode, 
-                                int32_t aOffset, 
-                                nsCOMPtr<nsIDOMNode> *outVisNode, 
-                                int32_t *outVisOffset,
-                                WSType *outType)
+nsWSRunObject::NextVisibleNode(nsINode* aNode,
+                               int32_t aOffset,
+                               nsCOMPtr<nsINode>* outVisNode,
+                               int32_t* outVisOffset,
+                               WSType* outType)
 {
-  // Find first visible thing after the point.  position outVisNode/outVisOffset
-  // just _before_ that thing.  If we don't find anything return end of ws.
+  // Find first visible thing after the point.  Position
+  // outVisNode/outVisOffset just _before_ that thing.  If we don't find
+  // anything return end of ws.
   MOZ_ASSERT(aNode && outVisNode && outVisOffset && outType);
-    
-  WSFragment *run;
-  FindRun(aNode, aOffset, &run, true);
-  
-  // is there a visible run there or later?
-  while (run)
-  {
+
+  WSFragment* run;
+  FindRun(GetAsDOMNode(aNode), aOffset, &run, true);
+
+  // Is there a visible run there or later?
+  for (; run; run = run->mRight) {
     if (run->mType == WSType::normalWS) {
-      WSPoint point = GetCharAfter(aNode, aOffset);
-      if (point.mTextNode)
-      {
-        *outVisNode = do_QueryInterface(point.mTextNode);
+      WSPoint point = GetCharAfter(GetAsDOMNode(aNode), aOffset);
+      if (point.mTextNode) {
+        *outVisNode = point.mTextNode;
         *outVisOffset = point.mOffset;
-        if (nsCRT::IsAsciiSpace(point.mChar) || (point.mChar==nbsp))
-        {
+        if (nsCRT::IsAsciiSpace(point.mChar) || point.mChar == nbsp) {
           *outType = WSType::normalWS;
-        }
-        else if (!point.mChar)
-        {
+        } else if (!point.mChar) {
           // MOOSE: not possible?
           *outType = WSType::none;
-        }
-        else
-        {
+        } else {
           *outType = WSType::text;
         }
         return;
       }
-      // else if no text node then keep looking.  We should eventually fall out of loop
+      // If no text node, keep looking.  We should eventually fall out of loop
     }
-
-    run = run->mRight;
   }
-  
-  // if we get here then nothing in ws data to find.  return end reason
-  *outVisNode = GetAsDOMNode(mEndReasonNode);
-  *outVisOffset = mEndOffset; // this really isn't meaningful if mEndReasonNode!=mEndNode
+
+  // If we get here, then nothing in ws data to find.  Return end reason
+  *outVisNode = mEndReasonNode;
+  // This really isn't meaningful if mEndReasonNode != mEndNode
+  *outVisOffset = mEndOffset;
   *outType = mEndReason;
 }
 
 nsresult 
 nsWSRunObject::AdjustWhitespace()
 {
   // this routine examines a run of ws and tries to get rid of some unneeded nbsp's,
   // replacing them with regualr ascii space if possible.  Keeping things simple
--- a/editor/libeditor/html/nsWSRunObject.h
+++ b/editor/libeditor/html/nsWSRunObject.h
@@ -223,38 +223,36 @@ class MOZ_STACK_CLASS nsWSRunObject
     // significance.
     nsresult DeleteWSBackward();
 
     // DeleteWSForward deletes a single visible piece of ws after the ws point
     // (the point to create the wsRunObject, passed to its constructor).  It
     // makes any needed conversion to adjacent ws to retain its significance.
     nsresult DeleteWSForward();
 
-    // PriorVisibleNode returns the first piece of visible thing
-    // before {aNode,aOffset}.  If there is no visible ws qualifying
-    // it returns what is before the ws run.  Note that 
-    // {outVisNode,outVisOffset} is set to just AFTER the visible
-    // object.
-    void PriorVisibleNode(nsIDOMNode *aNode,
+    // PriorVisibleNode returns the first piece of visible thing before
+    // {aNode,aOffset}.  If there is no visible ws qualifying it returns what
+    // is before the ws run.  Note that {outVisNode,outVisOffset} is set to
+    // just AFTER the visible object.
+    void PriorVisibleNode(nsINode* aNode,
                           int32_t aOffset,
-                          nsCOMPtr<nsIDOMNode> *outVisNode,
-                          int32_t *outVisOffset,
-                          WSType *outType);
+                          nsCOMPtr<nsINode>* outVisNode,
+                          int32_t* outVisOffset,
+                          WSType* outType);
 
-    // NextVisibleNode returns the first piece of visible thing
-    // after {aNode,aOffset}.  If there is no visible ws qualifying
-    // it returns what is after the ws run.  Note that 
-    // {outVisNode,outVisOffset} is set to just BEFORE the visible
-    // object.
-    void NextVisibleNode(nsIDOMNode *aNode,
+    // NextVisibleNode returns the first piece of visible thing after
+    // {aNode,aOffset}.  If there is no visible ws qualifying it returns what
+    // is after the ws run.  Note that {outVisNode,outVisOffset} is set to just
+    // BEFORE the visible object.
+    void NextVisibleNode(nsINode* aNode,
                          int32_t aOffset,
-                         nsCOMPtr<nsIDOMNode> *outVisNode,
-                         int32_t *outVisOffset,
-                         WSType *outType);
-    
+                         nsCOMPtr<nsINode>* outVisNode,
+                         int32_t* outVisOffset,
+                         WSType* outType);
+
     // AdjustWhitespace examines the ws object for nbsp's that can
     // be safely converted to regular ascii space and converts them.
     nsresult AdjustWhitespace();
 
   protected:
     
     // WSFragment struct ---------------------------------------------------------
     // WSFragment represents a single run of ws (all leadingws, or all normalws,