Back out bug 240933 and bug 590554 because of reftest failure on Win7 and also bug 593211
authorEhsan Akhgari <ehsan@mozilla.com>
Thu, 02 Sep 2010 19:54:23 -0400
changeset 51936 4235cd33ad433012678d87ca668203b67c48ad57
parent 51917 b1849145f9eda0643c74e0a6a7fcc894f1e51b0a
child 51937 03f80b4e03189acaedb128390051a822a284ee91
push idunknown
push userunknown
push dateunknown
bugs240933, 590554, 593211
milestone2.0b6pre
Back out bug 240933 and bug 590554 because of reftest failure on Win7 and also bug 593211
accessible/tests/mochitest/tree/test_txtctrl.html
content/base/src/nsGenericDOMDataNode.cpp
content/base/src/nsGenericDOMDataNode.h
content/base/src/nsTextFragment.cpp
content/base/src/nsTextFragment.h
editor/libeditor/base/Makefile.in
editor/libeditor/base/nsEditor.cpp
editor/libeditor/text/nsPlaintextEditor.cpp
editor/libeditor/text/nsTextEditRules.cpp
editor/libeditor/text/nsTextEditRules.h
editor/libeditor/text/tests/Makefile.in
editor/libeditor/text/tests/test_bug590554.html
editor/libeditor/text/tests/test_texteditor_keyevent_handling.html
layout/base/tests/Makefile.in
layout/base/tests/bug240933-1-ref.html
layout/base/tests/bug240933-1.html
layout/base/tests/bug240933-2.html
layout/base/tests/test_reftests_with_caret.html
layout/forms/nsTextControlFrame.cpp
layout/generic/nsFrame.cpp
layout/generic/nsIFrame.h
layout/generic/nsTextFrame.h
layout/generic/nsTextFrameThebes.cpp
layout/generic/test/Makefile.in
layout/generic/test/test_bug240933.html
layout/generic/test/test_bug288789.html
layout/generic/test/test_movement_by_characters.html
layout/reftests/bugs/240933-1-ref.html
layout/reftests/bugs/240933-1.html
layout/reftests/bugs/240933-2-ref.html
layout/reftests/bugs/240933-2.html
layout/reftests/bugs/reftest.list
layout/reftests/editor/caret_on_textarea_lastline-ref.html
layout/reftests/editor/caret_on_textarea_lastline.html
layout/reftests/editor/reftest.list
--- a/accessible/tests/mochitest/tree/test_txtctrl.html
+++ b/accessible/tests/mochitest/tree/test_txtctrl.html
@@ -45,17 +45,29 @@
 
       testAccessibleTree("txc2", accTree);
 
       // textarea
       accTree = {
         role: ROLE_ENTRY,
         children: [
           {
-            role: ROLE_TEXT_LEAF // hello1\nhello2 text
+            role: ROLE_TEXT_LEAF // hello1 text
+          },
+          {
+            role: ROLE_WHITESPACE
+          },
+          {
+            role: ROLE_TEXT_LEAF, // hello2 text
+          },
+          {
+            role: ROLE_WHITESPACE
+          },
+          {
+            role: ROLE_TEXT_LEAF, // whitepsace text
           },
           {
             role: ROLE_WHITESPACE
           }
         ]
       };
 
       testAccessibleTree("txc3", accTree);
--- a/content/base/src/nsGenericDOMDataNode.cpp
+++ b/content/base/src/nsGenericDOMDataNode.cpp
@@ -380,17 +380,17 @@ nsGenericDOMDataNode::SetTextInternal(PR
     }
 
     // XXX Add OOM checking to this
     mText.SetTo(to, newLength);
 
     delete [] to;
   }
 
-  UpdateBidiStatus(aBuffer, aLength);
+  SetBidiStatus();
 
   // Notify observers
   if (aNotify) {
     CharacterDataChangeInfo info = {
       aOffset == textLength,
       aOffset,
       endOffset,
       aLength
@@ -1079,25 +1079,25 @@ nsGenericDOMDataNode::TextIsOnlyWhitespa
 }
 
 void
 nsGenericDOMDataNode::AppendTextTo(nsAString& aResult)
 {
   mText.AppendTo(aResult);
 }
 
-void nsGenericDOMDataNode::UpdateBidiStatus(const PRUnichar* aBuffer, PRUint32 aLength)
+void nsGenericDOMDataNode::SetBidiStatus()
 {
   nsIDocument *document = GetCurrentDoc();
   if (document && document->GetBidiEnabled()) {
     // OK, we already know it's Bidi, so we won't test again
     return;
   }
 
-  mText.UpdateBidiFlag(aBuffer, aLength);
+  mText.SetBidiFlag();
 
   if (document && mText.IsBidi()) {
     document->SetBidiEnabled();
   }
 }
 
 already_AddRefed<nsIAtom>
 nsGenericDOMDataNode::GetCurrentValueAtom()
--- a/content/base/src/nsGenericDOMDataNode.h
+++ b/content/base/src/nsGenericDOMDataNode.h
@@ -353,17 +353,17 @@ protected:
    * @return the clone
    */
   virtual nsGenericDOMDataNode *CloneDataNode(nsINodeInfo *aNodeInfo,
                                               PRBool aCloneText) const = 0;
 
   nsTextFragment mText;
 
 private:
-  void UpdateBidiStatus(const PRUnichar* aBuffer, PRUint32 aLength);
+  void SetBidiStatus();
 
   already_AddRefed<nsIAtom> GetCurrentValueAtom();
 };
 
 class nsGenericTextNode : public nsGenericDOMDataNode
 {
 public:
   nsGenericTextNode(already_AddRefed<nsINodeInfo> aNodeInfo)
--- a/content/base/src/nsTextFragment.cpp
+++ b/content/base/src/nsTextFragment.cpp
@@ -367,21 +367,21 @@ nsTextFragment::Append(const PRUnichar* 
   m1b = buff;
   mState.mLength += aLength;
 
 }
 
 // To save time we only do this when we really want to know, not during
 // every allocation
 void
-nsTextFragment::UpdateBidiFlag(const PRUnichar* aBuffer, PRUint32 aLength)
+nsTextFragment::SetBidiFlag()
 {
   if (mState.mIs2b && !mState.mIsBidi) {
-    const PRUnichar* cp = aBuffer;
-    const PRUnichar* end = cp + aLength;
+    const PRUnichar* cp = m2b;
+    const PRUnichar* end = cp + mState.mLength;
     while (cp < end) {
       PRUnichar ch1 = *cp++;
       PRUint32 utf32Char = ch1;
       if (NS_IS_HIGH_SURROGATE(ch1) &&
           cp < end &&
           NS_IS_LOW_SURROGATE(*cp)) {
         PRUnichar ch2 = *cp++;
         utf32Char = SURROGATE_TO_UCS4(ch1, ch2);
--- a/content/base/src/nsTextFragment.h
+++ b/content/base/src/nsTextFragment.h
@@ -107,17 +107,17 @@ public:
   PRBool Is2b() const
   {
     return mState.mIs2b;
   }
 
   /**
    * Return PR_TRUE if this fragment contains Bidi text
    * For performance reasons this flag is not set automatically, but
-   * requires an explicit call to UpdateBidiFlag()
+   * requires an explicit call to SetBidiFlag()
    */
   PRBool IsBidi() const
   {
     return mState.mIsBidi;
   }
 
   /**
    * Get a pointer to constant PRUnichar data.
@@ -204,17 +204,17 @@ public:
     NS_ASSERTION(PRUint32(aIndex) < mState.mLength, "bad index");
     return mState.mIs2b ? m2b[aIndex] : static_cast<unsigned char>(m1b[aIndex]);
   }
 
   /**
    * Scan the contents of the fragment and turn on mState.mIsBidi if it
    * includes any Bidi characters.
    */
-  void UpdateBidiFlag(const PRUnichar* aBuffer, PRUint32 aLength);
+  void SetBidiFlag();
 
   struct FragmentBits {
     // PRUint32 to ensure that the values are unsigned, because we
     // want 0/1, not 0/-1!
     // Making these PRPackedBool causes Windows to not actually pack them,
     // which causes crashes because we assume this structure is no more than
     // 32 bits!
     PRUint32 mInHeap : 1;
--- a/editor/libeditor/base/Makefile.in
+++ b/editor/libeditor/base/Makefile.in
@@ -85,13 +85,12 @@ CPPSRCS		+=                          \
 		$(NULL)
 
 # don't want the shared lib; force the creation of a static lib.
 FORCE_STATIC_LIB = 1
 
 include $(topsrcdir)/config/rules.mk
 
 INCLUDES	+= \
-		-I$(topsrcdir)/editor/libeditor/text \
 		-I$(topsrcdir)/content/base/src \
 		-I$(topsrcdir)/content/events/src \
 		-I$(topsrcdir)/layout/style \
 		$(NULL)
--- a/editor/libeditor/base/nsEditor.cpp
+++ b/editor/libeditor/base/nsEditor.cpp
@@ -108,17 +108,16 @@
 #include "nsISelectionDisplay.h"
 #include "nsIInlineSpellChecker.h"
 #include "nsINameSpaceManager.h"
 #include "nsIHTMLDocument.h"
 #include "nsIParserService.h"
 
 #include "nsITransferable.h"
 #include "nsComputedDOMStyle.h"
-#include "nsTextEditUtils.h"
 
 #include "mozilla/FunctionTimer.h"
 
 #define NS_ERROR_EDITOR_NO_SELECTION NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_EDITOR,1)
 #define NS_ERROR_EDITOR_NO_TEXTNODE  NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_EDITOR,2)
 
 #ifdef NS_DEBUG_EDITOR
 static PRBool gNoisy = PR_FALSE;
@@ -899,37 +898,24 @@ nsEditor::EndPlaceHolderTransaction()
    // to EndUpdateViewBatch and ScrollSelectionIntoView, we are able to
    // allow the selection to cache a frame offset which is used by the
    // caret drawing code. We only enable this cache here; at other times,
    // we have no way to know whether reflow invalidates it
    // See bugs 35296 and 199412.
     if (selPrivate) {
       selPrivate->SetCanCacheFrameOffset(PR_TRUE);
     }
-
-    {
-      // Hide the caret here to avoid hiding it twice, once in EndUpdateViewBatch
-      // and once in ScrollSelectionIntoView.
-      nsRefPtr<nsCaret> caret;
-      nsCOMPtr<nsIPresShell> presShell;
-      GetPresShell(getter_AddRefs(presShell));
-
-      if (presShell)
-        caret = presShell->GetCaret();
-
-      StCaretHider caretHider(caret);
-
-      // time to turn off the batch
-      EndUpdateViewBatch();
-      // make sure selection is in view
-
-      // After ScrollSelectionIntoView(), the pending notifications might be
-      // flushed and PresShell/PresContext/Frames may be dead. See bug 418470.
-      ScrollSelectionIntoView(PR_FALSE);
-    }
+    
+    // time to turn off the batch
+    EndUpdateViewBatch();
+    // make sure selection is in view
+
+    // After ScrollSelectionIntoView(), the pending notifications might be
+    // flushed and PresShell/PresContext/Frames may be dead. See bug 418470.
+    ScrollSelectionIntoView(PR_FALSE);
 
     // cached for frame offset are Not available now
     if (selPrivate) {
       selPrivate->SetCanCacheFrameOffset(PR_FALSE);
     }
 
     if (mSelState)
     {
@@ -2282,85 +2268,21 @@ NS_IMETHODIMP nsEditor::InsertTextImpl(c
                                           nsCOMPtr<nsIDOMNode> *aInOutNode, 
                                           PRInt32 *aInOutOffset,
                                           nsIDOMDocument *aDoc)
 {
   // NOTE: caller *must* have already used nsAutoTxnsConserveSelection stack-based
   // class to turn off txn selection updating.  Caller also turned on rules sniffing
   // if desired.
   
-  nsresult res;
   NS_ENSURE_TRUE(aInOutNode && *aInOutNode && aInOutOffset && aDoc, NS_ERROR_NULL_POINTER);
   if (!mInIMEMode && aStringToInsert.IsEmpty()) return NS_OK;
   nsCOMPtr<nsIDOMText> nodeAsText = do_QueryInterface(*aInOutNode);
-  if (!nodeAsText && IsPlaintextEditor()) {
-    // In some cases, aInOutNode is the anonymous DIV, and aInOutOffset is 0.
-    // To avoid injecting unneeded text nodes, we first look to see if we have
-    // one available.  In that case, we'll just adjust aInOutNode and aInOutOffset
-    // accordingly.
-    if (*aInOutNode == GetRoot() && *aInOutOffset == 0) {
-      nsCOMPtr<nsIDOMNode> possibleTextNode;
-      res = (*aInOutNode)->GetFirstChild(getter_AddRefs(possibleTextNode));
-      if (NS_SUCCEEDED(res)) {
-        nodeAsText = do_QueryInterface(possibleTextNode);
-        if (nodeAsText) {
-          *aInOutNode = possibleTextNode;
-        }
-      }
-    }
-    // In some other cases, aInOutNode is the anonymous DIV, and aInOutOffset points
-    // to the terminating mozBR.  In that case, we'll adjust aInOutNode and aInOutOffset
-    // to the preceding text node, if any.
-    if (!nodeAsText && *aInOutNode == GetRoot() && *aInOutOffset > 0) {
-      nsCOMPtr<nsIDOMNodeList> children;
-      res = (*aInOutNode)->GetChildNodes(getter_AddRefs(children));
-      if (NS_SUCCEEDED(res)) {
-        nsCOMPtr<nsIDOMNode> possibleMozBRNode;
-        res = children->Item(*aInOutOffset, getter_AddRefs(possibleMozBRNode));
-        if (NS_SUCCEEDED(res) && nsTextEditUtils::IsMozBR(possibleMozBRNode)) {
-          nsCOMPtr<nsIDOMNode> possibleTextNode;
-          res = children->Item(*aInOutOffset - 1, getter_AddRefs(possibleTextNode));
-          if (NS_SUCCEEDED(res)) {
-            nodeAsText = do_QueryInterface(possibleTextNode);
-            if (nodeAsText) {
-              PRUint32 length;
-              res = nodeAsText->GetLength(&length);
-              if (NS_SUCCEEDED(res)) {
-                *aInOutOffset = PRInt32(length);
-                *aInOutNode = possibleTextNode;
-              }
-            }
-          }
-        }
-      }
-    }
-    // Sometimes, aInOutNode is the mozBR element itself.  In that case, we'll
-    // adjust the insertion point to the previous text node, if one exists, or
-    // to the parent anonymous DIV.
-    if (nsTextEditUtils::IsMozBR(*aInOutNode) && *aInOutOffset == 0) {
-      nsCOMPtr<nsIDOMNode> previous;
-      (*aInOutNode)->GetPreviousSibling(getter_AddRefs(previous));
-      nodeAsText = do_QueryInterface(previous);
-      if (nodeAsText) {
-        PRUint32 length;
-        res = nodeAsText->GetLength(&length);
-        if (NS_SUCCEEDED(res)) {
-          *aInOutOffset = PRInt32(length);
-          *aInOutNode = previous;
-        }
-      } else {
-        nsCOMPtr<nsIDOMNode> parent;
-        (*aInOutNode)->GetParentNode(getter_AddRefs(parent));
-        if (parent == GetRoot()) {
-          *aInOutNode = parent;
-        }
-      }
-    }
-  }
   PRInt32 offset = *aInOutOffset;
+  nsresult res;
   if (mInIMEMode)
   {
     if (!nodeAsText)
     {
       // create a text node
       res = aDoc->CreateTextNode(EmptyString(), getter_AddRefs(nodeAsText));
       NS_ENSURE_SUCCESS(res, res);
       NS_ENSURE_TRUE(nodeAsText, NS_ERROR_NULL_POINTER);
@@ -3619,19 +3541,18 @@ nsEditor::IsEditable(nsIDOMNode *aNode)
       {
         // In the past a comment said:
         //   "assume all text nodes with dirty frames are editable"
         // Nowadays we use a virtual function, that assumes TRUE
         // in the simple editor world,
         // and uses enhanced logic to find out in the HTML world.
         return IsTextInDirtyFrameVisible(aNode);
       }
-      if (resultFrame->HasAnyNoncollapsedCharacters()) {
-        return PR_TRUE;
-      }
+      if (resultFrame->GetSize().width > 0) 
+        return PR_TRUE;  // text node has width
       resultFrame = resultFrame->GetNextContinuation();
     }
   }
   return PR_FALSE;  // didn't pass any editability test
 }
 
 PRBool
 nsEditor::IsMozEditorBogusNode(nsIDOMNode *aNode)
--- a/editor/libeditor/text/nsPlaintextEditor.cpp
+++ b/editor/libeditor/text/nsPlaintextEditor.cpp
@@ -618,29 +618,23 @@ nsPlaintextEditor::GetTextSelectionOffse
       }
       if (editable) {
         PRUint32 length;
         textNode->GetLength(&length);
         totalLength += length;
       }
     }
 #ifdef NS_DEBUG
-    // The post content iterator might return the parent node (which is the
-    // editor's root node) as the last item.  Don't count the root node itself
-    // as one of its children!
-    if (!SameCOMIdentity(currentNode, rootNode)) {
-      ++nodeCount;
-    }
+    ++nodeCount;
 #endif
   }
 
   if (endOffset == -1) {
     NS_ASSERTION(endNode == rootNode, "failed to find the end node");
-    NS_ASSERTION(IsPasswordEditor() ||
-                 (endNodeOffset == nodeCount-1 || endNodeOffset == 0),
+    NS_ASSERTION(endNodeOffset == nodeCount-1 || endNodeOffset == 0,
                  "invalid end node offset");
     endOffset = endNodeOffset == 0 ? 0 : totalLength;
   }
   if (startOffset == -1) {
     NS_ASSERTION(startNode == rootNode, "failed to find the start node");
     NS_ASSERTION(startNodeOffset == nodeCount-1 || startNodeOffset == 0,
                  "invalid start node offset");
     startOffset = startNodeOffset == 0 ? 0 : totalLength;
@@ -863,65 +857,67 @@ NS_IMETHODIMP nsPlaintextEditor::InsertL
   // Batching the selection and moving nodes out from under the caret causes
   // caret turds. Ask the shell to invalidate the caret now to avoid the turds.
   nsCOMPtr<nsIPresShell> shell;
   res = GetPresShell(getter_AddRefs(shell));
   NS_ENSURE_SUCCESS(res, res);
   shell->MaybeInvalidateCaretPosition();
 
   nsTextRulesInfo ruleInfo(nsTextEditRules::kInsertBreak);
-  ruleInfo.maxLength = mMaxTextLength;
   PRBool cancel, handled;
   res = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
   NS_ENSURE_SUCCESS(res, res);
   if (!cancel && !handled)
   {
-    // get the (collapsed) selection location
-    nsCOMPtr<nsIDOMNode> selNode;
-    PRInt32 selOffset;
-    res = GetStartNodeAndOffset(selection, getter_AddRefs(selNode), &selOffset);
-    NS_ENSURE_SUCCESS(res, res);
-
-    // don't put text in places that can't have it
-    if (!IsTextNode(selNode) && !CanContainTag(selNode, NS_LITERAL_STRING("#text")))
-      return NS_ERROR_FAILURE;
-
-    // we need to get the doc
-    nsCOMPtr<nsIDOMDocument> doc;
-    res = GetDocument(getter_AddRefs(doc));
-    NS_ENSURE_SUCCESS(res, res);
-    NS_ENSURE_TRUE(doc, NS_ERROR_NULL_POINTER);
-
-    // don't spaz my selection in subtransactions
-    nsAutoTxnsConserveSelection dontSpazMySelection(this);
-
-    // insert a linefeed character
-    res = InsertTextImpl(NS_LITERAL_STRING("\n"), address_of(selNode),
-                         &selOffset, doc);
-    if (!selNode) res = NS_ERROR_NULL_POINTER; // don't return here, so DidDoAction is called
+    // create the new BR node
+    nsCOMPtr<nsIDOMNode> newNode;
+    res = DeleteSelectionAndCreateNode(NS_LITERAL_STRING("br"), getter_AddRefs(newNode));
+    if (!newNode) res = NS_ERROR_NULL_POINTER; // don't return here, so DidDoAction is called
     if (NS_SUCCEEDED(res))
     {
-      // set the selection to the correct location
-      res = selection->Collapse(selNode, selOffset);
-
+      // set the selection to the new node
+      nsCOMPtr<nsIDOMNode>parent;
+      res = newNode->GetParentNode(getter_AddRefs(parent));
+      if (!parent) res = NS_ERROR_NULL_POINTER; // don't return here, so DidDoAction is called
       if (NS_SUCCEEDED(res))
       {
-        // see if we're at the end of the editor range
-        nsCOMPtr<nsIDOMNode> endNode;
-        PRInt32 endOffset;
-        res = GetEndNodeAndOffset(selection, getter_AddRefs(endNode), &endOffset);
-
-        if (NS_SUCCEEDED(res) && endNode == selNode && endOffset == selOffset)
+        PRInt32 offsetInParent=-1;  // we use the -1 as a marker to see if we need to compute this or not
+        nsCOMPtr<nsIDOMNode>nextNode;
+        newNode->GetNextSibling(getter_AddRefs(nextNode));
+        if (nextNode)
         {
-          // SetInterlinePosition(PR_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.
-          nsCOMPtr<nsISelectionPrivate> selPriv(do_QueryInterface(selection));
-          selPriv->SetInterlinePosition(PR_TRUE);
+          nsCOMPtr<nsIDOMCharacterData>nextTextNode = do_QueryInterface(nextNode);
+          if (!nextTextNode) {
+            nextNode = do_QueryInterface(newNode); // is this QI needed?
+          }
+          else { 
+            offsetInParent=0; 
+          }
+        }
+        else {
+          nextNode = do_QueryInterface(newNode); // is this QI needed?
+        }
+
+        if (-1==offsetInParent) 
+        {
+          nextNode->GetParentNode(getter_AddRefs(parent));
+          res = GetChildOffset(nextNode, parent, offsetInParent);
+          if (NS_SUCCEEDED(res)) {
+            // SetInterlinePosition(PR_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.
+            nsCOMPtr<nsISelectionPrivate> selPriv(do_QueryInterface(selection));
+            selPriv->SetInterlinePosition(PR_TRUE);
+            res = selection->Collapse(parent, offsetInParent+1);  // +1 to insert just after the break
+          }
+        }
+        else
+        {
+          res = selection->Collapse(nextNode, offsetInParent);
         }
       }
     }
   }
   if (!cancel)
   {
     // post-process, always called if WillInsertBreak didn't return cancel==PR_TRUE
     res = mRules->DidDoAction(selection, &ruleInfo, res);
--- a/editor/libeditor/text/nsTextEditRules.cpp
+++ b/editor/libeditor/text/nsTextEditRules.cpp
@@ -262,19 +262,16 @@ nsTextEditRules::AfterEdit(PRInt32 actio
 
     // detect empty doc
     res = CreateBogusNodeIfNeeded(selection);
     NS_ENSURE_SUCCESS(res, res);
     
     // insure trailing br node
     res = CreateTrailingBRIfNeeded();
     NS_ENSURE_SUCCESS(res, res);
-
-    // collapse the selection to the trailing BR if it's at the end of our text node
-    CollapseSelectionToTrailingBRIfNeeded(selection);
     
     /* After inserting text the cursor Bidi level must be set to the level of the inserted text.
      * This is difficult, because we cannot know what the level is until after the Bidi algorithm
      * is applied to the whole paragraph.
      *
      * So we set the cursor Bidi level to UNDEFINED here, and the caret code will set it correctly later
      */
     if (action == nsEditor::kOpInsertText
@@ -307,17 +304,17 @@ nsTextEditRules::WillDoAction(nsISelecti
   *aHandled = PR_FALSE;
 
   // my kingdom for dynamic cast
   nsTextRulesInfo *info = static_cast<nsTextRulesInfo*>(aInfo);
     
   switch (info->action)
   {
     case kInsertBreak:
-      return WillInsertBreak(aSelection, aCancel, aHandled, info->maxLength);
+      return WillInsertBreak(aSelection, aCancel, aHandled);
     case kInsertText:
     case kInsertTextIME:
       return WillInsertText(info->action,
                             aSelection, 
                             aCancel,
                             aHandled, 
                             info->inString,
                             info->outString,
@@ -419,47 +416,31 @@ nsTextEditRules::WillInsert(nsISelection
 
 nsresult
 nsTextEditRules::DidInsert(nsISelection *aSelection, nsresult aResult)
 {
   return NS_OK;
 }
 
 nsresult
-nsTextEditRules::WillInsertBreak(nsISelection *aSelection,
-                                 PRBool *aCancel,
-                                 PRBool *aHandled,
-                                 PRInt32 aMaxLength)
+nsTextEditRules::WillInsertBreak(nsISelection *aSelection, PRBool *aCancel, PRBool *aHandled)
 {
   if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
   CANCEL_OPERATION_IF_READONLY_OR_DISABLED
   *aHandled = PR_FALSE;
   if (IsSingleLineEditor()) {
     *aCancel = PR_TRUE;
   }
   else 
   {
-    // handle docs with a max length
-    // NOTE, this function copies inString into outString for us.
-    NS_NAMED_LITERAL_STRING(inString, "\n");
-    nsAutoString outString;
-    PRBool didTruncate;
-    nsresult res = TruncateInsertionIfNeeded(aSelection, &inString, &outString,
-                                             aMaxLength, &didTruncate);
-    NS_ENSURE_SUCCESS(res, res);
-    if (didTruncate) {
-      *aCancel = PR_TRUE;
-      return NS_OK;
-    }
-
     *aCancel = PR_FALSE;
 
     // if the selection isn't collapsed, delete it.
     PRBool bCollapsed;
-    res = aSelection->GetIsCollapsed(&bCollapsed);
+    nsresult res = aSelection->GetIsCollapsed(&bCollapsed);
     NS_ENSURE_SUCCESS(res, res);
     if (!bCollapsed)
     {
       res = mEditor->DeleteSelection(nsIEditor::eNone);
       NS_ENSURE_SUCCESS(res, res);
     }
 
     res = WillInsert(aSelection, aCancel);
@@ -470,63 +451,57 @@ nsTextEditRules::WillInsertBreak(nsISele
   
   }
   return NS_OK;
 }
 
 nsresult
 nsTextEditRules::DidInsertBreak(nsISelection *aSelection, nsresult aResult)
 {
-  return NS_OK;
-}
-
-nsresult
-nsTextEditRules::CollapseSelectionToTrailingBRIfNeeded(nsISelection* aSelection)
-{
   // we only need to execute the stuff below if we are a plaintext editor.
   // html editors have a different mechanism for putting in mozBR's
   // (because there are a bunch more places you have to worry about it in html) 
   if (!IsPlaintextEditor()) {
     return NS_OK;
   }
 
-  // if we are at the end of the textarea, we need to set the
-  // selection to stick to the mozBR at the end of the textarea.
+  // if we are at the end of the document, we need to insert 
+  // a special mozBR following the normal br, and then set the
+  // selection to stick to the mozBR.
   PRInt32 selOffset;
   nsCOMPtr<nsIDOMNode> selNode;
   nsresult res;
   res = mEditor->GetStartNodeAndOffset(aSelection, getter_AddRefs(selNode), &selOffset);
   NS_ENSURE_SUCCESS(res, res);
-
-  nsCOMPtr<nsIDOMText> nodeAsText = do_QueryInterface(selNode);
-  if (!nodeAsText) return NS_OK; // nothing to do if we're not at a text node
-
-  PRUint32 length;
-  res = nodeAsText->GetLength(&length);
-  NS_ENSURE_SUCCESS(res, res);
+  // confirm we are at end of document
+  if (selOffset == 0) return NS_OK;  // can't be after a br if we are at offset 0
+  nsIDOMElement *rootElem = mEditor->GetRoot();
 
-  // nothing to do if we're not at the end of the text node
-  if (selOffset != length) return NS_OK;
-
-  nsCOMPtr<nsIDOMNode> parentNode;
-  PRInt32 parentOffset;
-  res = nsEditor::GetNodeLocation(selNode, address_of(parentNode),
-                                  &parentOffset);
-  NS_ENSURE_SUCCESS(res, res);
-
-  nsIDOMElement *rootElem = mEditor->GetRoot();
   nsCOMPtr<nsIDOMNode> root = do_QueryInterface(rootElem);
   NS_ENSURE_TRUE(root, NS_ERROR_NULL_POINTER);
-  if (parentNode != root) return NS_OK;
+  if (selNode != root) return NS_OK; // must be inside text node or somewhere other than end of root
+
+  nsCOMPtr<nsIDOMNode> temp = mEditor->GetChildAt(selNode, selOffset);
+  if (temp) return NS_OK; // can't be at end if there is a node after us.
 
-  nsCOMPtr<nsIDOMNode> nextNode = mEditor->GetChildAt(parentNode,
-                                                      parentOffset + 1);
-  if (nextNode && nsTextEditUtils::IsMozBR(nextNode))
+  nsCOMPtr<nsIDOMNode> nearNode = mEditor->GetChildAt(selNode, selOffset-1);
+  if (nearNode && nsTextEditUtils::IsBreak(nearNode) && !nsTextEditUtils::IsMozBR(nearNode))
   {
-    res = aSelection->Collapse(parentNode, parentOffset + 1);
+    nsCOMPtr<nsISelectionPrivate>selPrivate(do_QueryInterface(aSelection));
+    // need to insert special moz BR. Why?  Because if we don't
+    // the user will see no new line for the break.  Also, things
+    // like table cells won't grow in height.
+    nsCOMPtr<nsIDOMNode> brNode;
+    res = CreateMozBR(selNode, selOffset, address_of(brNode));
+    NS_ENSURE_SUCCESS(res, res);
+
+    res = nsEditor::GetNodeLocation(brNode, address_of(selNode), &selOffset);
+    NS_ENSURE_SUCCESS(res, res);
+    selPrivate->SetInterlinePosition(PR_TRUE);
+    res = aSelection->Collapse(selNode, selOffset);
     NS_ENSURE_SUCCESS(res, res);
   }
   return res;
 }
 
 static inline already_AddRefed<nsIDOMNode>
 GetTextNode(nsISelection *selection, nsEditor *editor) {
   PRInt32 selOffset;
@@ -653,17 +628,17 @@ nsTextEditRules::WillInsertText(PRInt32 
   }
   
   // initialize out param
   *aCancel = PR_FALSE;
   *aHandled = PR_TRUE;
 
   // handle docs with a max length
   // NOTE, this function copies inString into outString for us.
-  nsresult res = TruncateInsertionIfNeeded(aSelection, inString, outString, aMaxLength, nsnull);
+  nsresult res = TruncateInsertionIfNeeded(aSelection, inString, outString, aMaxLength);
   NS_ENSURE_SUCCESS(res, res);
   
   PRUint32 start = 0;
   PRUint32 end = 0;  
 
   // handle password field docs
   if (IsPasswordEditor())
   {
@@ -768,42 +743,153 @@ nsTextEditRules::WillInsertText(PRInt32 
     NS_ENSURE_SUCCESS(res, res);
   }
   else // aAction == kInsertText
   {
     // find where we are
     nsCOMPtr<nsIDOMNode> curNode = selNode;
     PRInt32 curOffset = selOffset;
 
+    // is our text going to be PREformatted?  
+    // We remember this so that we know how to handle tabs.
+    PRBool isPRE;
+    res = mEditor->IsPreformatted(selNode, &isPRE);
+    NS_ENSURE_SUCCESS(res, res);    
+
     // don't spaz my selection in subtransactions
     nsAutoTxnsConserveSelection dontSpazMySelection(mEditor);
+    nsString tString(*outString);
+    const PRUnichar *unicodeBuf = tString.get();
+    nsCOMPtr<nsIDOMNode> unused;
+    PRInt32 pos = 0;
 
-    res = mEditor->InsertTextImpl(*outString, address_of(curNode),
-                                  &curOffset, doc);
-    NS_ENSURE_SUCCESS(res, res);
+    // for efficiency, break out the pre case separately.  This is because
+    // it's a lot cheaper to search the input string for only newlines than
+    // it is to search for both tabs and newlines.
+    if (isPRE)
+    {
+      while (unicodeBuf && (pos != -1) && ((PRUint32)pos < tString.Length()))
+      {
+        PRInt32 oldPos = pos;
+        PRInt32 subStrLen;
+        pos = tString.FindChar(nsCRT::LF, oldPos);
+        
+        if (pos != -1) 
+        {
+          subStrLen = pos - oldPos;
+          // if first char is newline, then use just it
+          if (subStrLen == 0)
+            subStrLen = 1;
+        }
+        else
+        {
+          subStrLen = tString.Length() - oldPos;
+          pos = tString.Length();
+        }
+
+        nsDependentSubstring subStr(tString, oldPos, subStrLen);
+        
+        // is it a return?
+        if (subStr.EqualsLiteral(LFSTR))
+        {
+          if (IsSingleLineEditor())
+          {
+            NS_ASSERTION((mEditor->mNewlineHandling == nsIPlaintextEditor::eNewlinesPasteIntact),
+                  "Newline improperly getting into single-line edit field!");
+            res = mEditor->InsertTextImpl(subStr, address_of(curNode), &curOffset, doc);
+          }
+          else
+          {
+            res = mEditor->CreateBRImpl(address_of(curNode), &curOffset, address_of(unused), nsIEditor::eNone);
+
+            // If the newline is the last character in the string, and the BR we
+            // just inserted is the last node in the content tree, we need to add
+            // a mozBR so that a blank line is created.
+
+            if (NS_SUCCEEDED(res) && curNode && pos == (PRInt32)(tString.Length() - 1))
+            {
+              nsCOMPtr<nsIDOMNode> nextChild = mEditor->GetChildAt(curNode, curOffset);
+
+              if (!nextChild)
+              {
+                // We must be at the end since there isn't a nextChild.
+                //
+                // curNode and curOffset should be set to the position after
+                // the BR we added above, so just create a mozBR at that position.
+                //
+                // Note that we don't update curOffset after we've created/inserted
+                // the mozBR since we never want the selection to be placed after it.
+
+                res = CreateMozBR(curNode, curOffset, address_of(unused));
+              }
+            }
+          }
+          pos++;
+        }
+        else
+        {
+          res = mEditor->InsertTextImpl(subStr, address_of(curNode), &curOffset, doc);
+        }
+        NS_ENSURE_SUCCESS(res, res);
+      }
+    }
+    else
+    {
+      char specialChars[] = {TAB, nsCRT::LF, 0};
+      while (unicodeBuf && (pos != -1) && ((PRUint32)pos < tString.Length()))
+      {
+        PRInt32 oldPos = pos;
+        PRInt32 subStrLen;
+        pos = tString.FindCharInSet(specialChars, oldPos);
+        
+        if (pos != -1) 
+        {
+          subStrLen = pos - oldPos;
+          // if first char is newline, then use just it
+          if (subStrLen == 0)
+            subStrLen = 1;
+        }
+        else
+        {
+          subStrLen = tString.Length() - oldPos;
+          pos = tString.Length();
+        }
+
+        nsDependentSubstring subStr(tString, oldPos, subStrLen);
+        
+        // is it a tab?
+        if (subStr.EqualsLiteral("\t"))
+        {
+          res = mEditor->InsertTextImpl(NS_LITERAL_STRING("    "), address_of(curNode), &curOffset, doc);
+          pos++;
+        }
+        // is it a return?
+        else if (subStr.EqualsLiteral(LFSTR))
+        {
+          res = mEditor->CreateBRImpl(address_of(curNode), &curOffset, address_of(unused), nsIEditor::eNone);
+          pos++;
+        }
+        else
+        {
+          res = mEditor->InsertTextImpl(subStr, address_of(curNode), &curOffset, doc);
+        }
+        NS_ENSURE_SUCCESS(res, res);
+      }
+    }
+    outString->Assign(tString);
 
     if (curNode) 
     {
+      aSelection->Collapse(curNode, curOffset);
+      
       // Make the caret attach to the inserted text, unless this text ends with a LF, 
       // in which case make the caret attach to the next line.
-      PRBool endsWithLF =
-        !outString->IsEmpty() && outString->Last() == nsCRT::LF;
+      PRBool endsWithLF = !tString.IsEmpty() && tString.get()[tString.Length() - 1] == nsCRT::LF;
       nsCOMPtr<nsISelectionPrivate>selPrivate(do_QueryInterface(aSelection));
       selPrivate->SetInterlinePosition(endsWithLF);
-
-      // If the last character is a linefeed character, make sure that we inject
-      // a BR element for correct caret positioning.
-      if (endsWithLF) {
-        nsCOMPtr<nsIDOMNode> mozBR;
-        res = CreateMozBR(curNode, curOffset, address_of(mozBR));
-        NS_ENSURE_SUCCESS(res, res);
-        curNode = mozBR;
-        curOffset = 0;
-      }
-      aSelection->Collapse(curNode, curOffset);
     }
   }
   ASSERT_PASSWORD_LENGTHS_EQUAL()
   return res;
 }
 
 nsresult
 nsTextEditRules::DidInsertText(nsISelection *aSelection, 
@@ -1267,26 +1353,22 @@ nsTextEditRules::CreateBogusNodeIfNeeded
   return res;
 }
 
 
 nsresult
 nsTextEditRules::TruncateInsertionIfNeeded(nsISelection *aSelection, 
                                            const nsAString  *aInString,
                                            nsAString  *aOutString,
-                                           PRInt32          aMaxLength,
-                                           PRBool *aTruncated)
+                                           PRInt32          aMaxLength)
 {
   if (!aSelection || !aInString || !aOutString) {return NS_ERROR_NULL_POINTER;}
   
   nsresult res = NS_OK;
   *aOutString = *aInString;
-  if (aTruncated) {
-    *aTruncated = PR_FALSE;
-  }
   
   if ((-1 != aMaxLength) && IsPlaintextEditor() && !mEditor->IsIMEComposing() )
   {
     // Get the current text length.
     // Get the length of inString.
     // Get the length of the selection.
     //   If selection is collapsed, it is length 0.
     //   Subtract the length of the selection from the len(doc) 
@@ -1309,29 +1391,23 @@ nsTextEditRules::TruncateInsertionIfNeed
     res = mEditor->GetIMEBufferLength(&oldCompStrLength);
     if (NS_FAILED(res)) { return res; }
 
     const PRInt32 selectionLength = end - start;
     const PRInt32 resultingDocLength = docLength - selectionLength - oldCompStrLength;
     if (resultingDocLength >= aMaxLength)
     {
       aOutString->Truncate();
-      if (aTruncated) {
-        *aTruncated = PR_TRUE;
-      }
     }
     else
     {
       PRInt32 inCount = aOutString->Length();
       if (inCount + resultingDocLength > aMaxLength)
       {
         aOutString->Truncate(aMaxLength - resultingDocLength);
-        if (aTruncated) {
-          *aTruncated = PR_TRUE;
-        }
       }
     }
   }
   return res;
 }
 
 nsresult
 nsTextEditRules::ResetIMETextPWBuf()
--- a/editor/libeditor/text/nsTextEditRules.h
+++ b/editor/libeditor/text/nsTextEditRules.h
@@ -155,18 +155,17 @@ protected:
                             PRBool          *aCancel,
                             PRBool          *aHandled,
                             const nsAString *inString,
                             nsAString       *outString,
                             PRInt32          aMaxLength);
   nsresult DidInsertText(nsISelection *aSelection, nsresult aResult);
   nsresult GetTopEnclosingPre(nsIDOMNode *aNode, nsIDOMNode** aOutPreNode);
 
-  nsresult WillInsertBreak(nsISelection *aSelection, PRBool *aCancel,
-                           PRBool *aHandled, PRInt32 aMaxLength);
+  nsresult WillInsertBreak(nsISelection *aSelection, PRBool *aCancel, PRBool *aHandled);
   nsresult DidInsertBreak(nsISelection *aSelection, nsresult aResult);
 
   nsresult WillInsert(nsISelection *aSelection, PRBool *aCancel);
   nsresult DidInsert(nsISelection *aSelection, nsresult aResult);
 
   nsresult WillDeleteSelection(nsISelection *aSelection, 
                                nsIEditor::EDirection aCollapsedAction, 
                                PRBool *aCancel,
@@ -214,34 +213,31 @@ protected:
  /** creates a bogus text node if the document has no editable content */
   nsresult CreateBogusNodeIfNeeded(nsISelection *aSelection);
 
   /** returns a truncated insertion string if insertion would place us
       over aMaxLength */
   nsresult TruncateInsertionIfNeeded(nsISelection             *aSelection, 
                                      const nsAString          *aInString,
                                      nsAString                *aOutString,
-                                     PRInt32                   aMaxLength,
-                                     PRBool                   *aTruncated);
+                                     PRInt32                   aMaxLength);
 
   /** Remove IME composition text from password buffer */
   nsresult RemoveIMETextFromPWBuf(PRUint32 &aStart, nsAString *aIMEString);
 
   nsresult CreateMozBR(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outBRNode);
 
   nsresult CheckBidiLevelForDeletion(nsISelection         *aSelection,
                                      nsIDOMNode           *aSelNode, 
                                      PRInt32               aSelOffset, 
                                      nsIEditor::EDirection aAction,
                                      PRBool               *aCancel);
 
   nsresult HideLastPWInput();
 
-  nsresult CollapseSelectionToTrailingBRIfNeeded(nsISelection *aSelection);
-
   PRBool IsPasswordEditor() const
   {
     return mEditor ? mEditor->IsPasswordEditor() : PR_FALSE;
   }
   PRBool IsSingleLineEditor() const
   {
     return mEditor ? mEditor->IsSingleLineEditor() : PR_FALSE;
   }
--- a/editor/libeditor/text/tests/Makefile.in
+++ b/editor/libeditor/text/tests/Makefile.in
@@ -42,17 +42,16 @@ VPATH		= @srcdir@
 relativesrcdir  = editor/libeditor/text/tests
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _TEST_FILES = \
 		test_bug471722.html \
 		test_bug569988.html \
-		test_bug590554.html \
 		$(NULL)
 
 # disables the key handling test on gtk2 because gtk2 overrides some key events
 # on our editor, and the combinations depend on the system.
 ifneq ($(MOZ_WIDGET_TOOLKIT),gtk2)
 _TEST_FILES += \
 		test_texteditor_keyevent_handling.html \
 		$(NULL)
deleted file mode 100644
--- a/editor/libeditor/text/tests/test_bug590554.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=590554
--->
-
-<head>
-  <title>Test for Bug 590554</title>
-  <script type="application/javascript" src="/MochiKit/packed.js"></script>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>  
-</head>
-
-<body>
-
-  <script type="application/javascript">
-
-    /** Test for Bug 590554 **/
-
-    SimpleTest.waitForExplicitFinish();
-
-    SimpleTest.waitForFocus(function() {
-      var t = document.querySelector("textarea");
-      t.focus();
-      synthesizeKey("VK_ENTER", {});
-      is(t.value, "\n", "Pressing enter should work the first time");
-      synthesizeKey("VK_ENTER", {});
-      is(t.value, "\n", "Pressing enter should not work the second time");
-      SimpleTest.finish();
-    });
-
-  </script>
-
-  <textarea maxlength="1"></textarea>
-</body>
-</html>
--- a/editor/libeditor/text/tests/test_texteditor_keyevent_handling.html
+++ b/editor/libeditor/text/tests/test_texteditor_keyevent_handling.html
@@ -282,33 +282,23 @@ function runTests()
 
     // Tab key:
     //   If editor is tabbable, editor doesn't consume all tab key events.
     //   Otherwise, editor consumes tab key event without any modifier keys.
     reset("a");
     synthesizeKey("VK_TAB", { });
     check(aDescription + "Tab",
           true, true, !aIsTabbable && !aIsReadonly);
-    is(aElement.value, !aIsTabbable && !aIsReadonly ? "a\t" : "a",
+    // The tab char is converted to 4 space characters because textarea/input
+    // elements are not preformatted editor.
+    is(aElement.value, !aIsTabbable && !aIsReadonly ? "a    " : "a",
        aDescription + "Tab");
     is(fm.focusedElement, aElement,
        aDescription + "focus moved unexpectedly (Tab)");
 
-    // If the editor is not tabbable, make sure that it accepts tab characters
-    // even if it's empty.
-    if (!aIsTabbable && !aIsReadonly) {
-      reset("");
-      synthesizeKey("VK_TAB", {});
-      check(aDescription + "Tab on empty textarea",
-            true, true, !aIsReadonly);
-      is(aElement.value, "\t", aDescription + "Tab on empty textarea");
-      is(fm.focusedElement, aElement,
-         aDescription + "focus moved unexpectedly (Tab on empty textarea");
-    }
-
     reset("a");
     synthesizeKey("VK_TAB", { shiftKey: true });
     check(aDescription + "Shift+Tab", true, true, false);
     is(aElement.value, "a", aDescription + "Shift+Tab");
     is(fm.focusedElement, aElement,
        aDescription + "focus moved unexpectedly (Shift+Tab)");
 
     // Ctrl+Tab may be consumed by tabbrowser but editor shouldn't consume this.
--- a/layout/base/tests/Makefile.in
+++ b/layout/base/tests/Makefile.in
@@ -87,19 +87,16 @@ DEFINES += -D_IMPL_NS_LAYOUT
 		test_bug435293-scale.html \
 		test_bug435293-interaction.html \
 		test_bug435293-skew.html \
 		test_bug495648.xul \
 		test_reftests_with_caret.html \
 		     bug106855-1.html \
 		     bug106855-2.html \
 		     bug106855-1-ref.html \
-		     bug240933-1.html \
-		     bug240933-2.html \
-		     bug240933-1-ref.html \
 		     bug482484.html \
 		     bug482484-ref.html \
 		     bug512295-1.html \
 		     bug512295-1-ref.html \
 		     bug512295-2.html \
 		     bug512295-2-ref.html \
 		     bug585922.html \
 		     bug585922-ref.html \
deleted file mode 100644
--- a/layout/base/tests/bug240933-1-ref.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE HTML><html>
-<body>
-<textarea id="t" rows="4">
-
-</textarea>
-<script>
-  document.getElementById("t").focus();
-</script>
-</body>
-</html>
deleted file mode 100644
--- a/layout/base/tests/bug240933-1.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<!DOCTYPE HTML><html><head>
-  <script type="text/javascript" src="/MochiKit/packed.js"></script>
-  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
-</head>
-<body>
-<textarea id="t" rows="4"></textarea>
-<script>
-  var area = document.getElementById('t');
-  area.focus();
-
-  sendKey('VK_ENTER'); // press Enter once
-</script>
-</body>
-</html>
deleted file mode 100644
--- a/layout/base/tests/bug240933-2.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<!DOCTYPE HTML><html><head>
-  <script type="text/javascript" src="/MochiKit/packed.js"></script>
-  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
-</head>
-<body>
-<textarea id="t" rows="4"></textarea>
-<script>
-  var area = document.getElementById('t');
-  area.focus();
-
-  sendKey('VK_ENTER'); // press Enter twice
-  sendKey('VK_ENTER');
-  sendKey('VK_BACK_SPACE'); // press Backspace once
-</script>
-</body>
-</html>
--- a/layout/base/tests/test_reftests_with_caret.html
+++ b/layout/base/tests/test_reftests_with_caret.html
@@ -83,18 +83,16 @@ function endTest() {
   var prefs = Components.classes["@mozilla.org/preferences-service;1"]
                         .getService(Components.interfaces.nsIPrefBranch);
   prefs.setIntPref("ui.caretBlinkTime", caretBlinkTime);
 }
 
 var tests = [
     [ 'bug106855-1.html' , 'bug106855-1-ref.html' ] ,
     [ 'bug106855-2.html' , 'bug106855-1-ref.html' ] ,
-    [ 'bug240933-1.html' , 'bug240933-1-ref.html' ] ,
-    [ 'bug240933-2.html' , 'bug240933-1-ref.html' ] ,
     [ 'bug482484.html'   , 'bug482484-ref.html'   ] ,
     [ 'bug512295-1.html' , 'bug512295-1-ref.html' ] ,
     [ 'bug512295-2.html' , 'bug512295-2-ref.html' ] ,
     [ 'bug585922.html'   , 'bug585922-ref.html'   ]
 ];
 var testIndex = 0;
 
 function nextTest() {
--- a/layout/forms/nsTextControlFrame.cpp
+++ b/layout/forms/nsTextControlFrame.cpp
@@ -993,37 +993,61 @@ nsTextControlFrame::DOMPointToOffset(nsI
 
   PRUint32 length = 0;
   rv = nodeList->GetLength(&length);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!length || aNodeOffset < 0)
     return NS_OK;
 
-  NS_ASSERTION(length <= 2, "We should have one text node and one mozBR at most");
+  PRInt32 i, textOffset = 0;
+  PRInt32 lastIndex = (PRInt32)length - 1;
+
+  for (i = 0; i < (PRInt32)length; i++) {
+    if (rootNode == aNode && i == aNodeOffset) {
+      *aResult = textOffset;
+      return NS_OK;
+    }
 
-  nsCOMPtr<nsIDOMNode> firstNode;
-  rv = nodeList->Item(0, getter_AddRefs(firstNode));
-  NS_ENSURE_SUCCESS(rv, rv);
-  nsCOMPtr<nsIDOMText> textNode = do_QueryInterface(firstNode);
+    nsCOMPtr<nsIDOMNode> item;
+    rv = nodeList->Item(i, getter_AddRefs(item));
+    NS_ENSURE_SUCCESS(rv, rv);
+    NS_ENSURE_TRUE(item, NS_ERROR_FAILURE);
+
+    nsCOMPtr<nsIDOMText> domText(do_QueryInterface(item));
+
+    if (domText) {
+      PRUint32 textLength = 0;
 
-  nsCOMPtr<nsIDOMText> nodeAsText = do_QueryInterface(aNode);
-  if (nodeAsText || (aNode == rootNode && aNodeOffset == 0)) {
-    // Selection is somewhere inside the text node; the offset is aNodeOffset
-    *aResult = aNodeOffset;
-  } else {
-    // Selection is on the mozBR node, so offset should be set to the length
-    // of the text node.
-    if (textNode) {
-      rv = textNode->GetLength(&length);
+      rv = domText->GetLength(&textLength);
       NS_ENSURE_SUCCESS(rv, rv);
-      *aResult = PRInt32(length);
+
+      if (item == aNode) {
+        NS_ASSERTION((aNodeOffset >= 0 && aNodeOffset <= (PRInt32)textLength),
+                     "Invalid aNodeOffset!");
+        *aResult = textOffset + aNodeOffset;
+        return NS_OK;
+      }
+
+      textOffset += textLength;
+    }
+    else {
+      // Must be a BR node. If it's not the last BR node
+      // under the root, count it as a newline.
+
+      if (i != lastIndex)
+        ++textOffset;
     }
   }
 
+  NS_ASSERTION((aNode == rootNode && aNodeOffset == (PRInt32)length),
+               "Invalid node offset!");
+
+  *aResult = textOffset;
+  
   return NS_OK;
 }
 
 nsresult
 nsTextControlFrame::OffsetToDOMPoint(PRInt32 aOffset,
                                      nsIDOMNode** aResult,
                                      PRInt32* aPosition)
 {
@@ -1045,35 +1069,81 @@ nsTextControlFrame::OffsetToDOMPoint(PRI
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ENSURE_TRUE(nodeList, NS_ERROR_FAILURE);
 
   PRUint32 length = 0;
 
   rv = nodeList->GetLength(&length);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  NS_ASSERTION(length <= 2, "We should have one text node and one mozBR at most");
-
-  nsCOMPtr<nsIDOMNode> firstNode;
-  rv = nodeList->Item(0, getter_AddRefs(firstNode));
-  NS_ENSURE_SUCCESS(rv, rv);
-  nsCOMPtr<nsIDOMText> textNode = do_QueryInterface(firstNode);
-
-  if (length == 0 || aOffset < 0) {
-    NS_IF_ADDREF(*aResult = rootNode);
+  if (!length || aOffset < 0) {
     *aPosition = 0;
-  } else if (textNode) {
-    NS_IF_ADDREF(*aResult = firstNode);
-    *aPosition = aOffset;
-  } else {
-    NS_IF_ADDREF(*aResult = rootNode);
-    *aPosition = 0;
+    *aResult = rootNode;
+    NS_ADDREF(*aResult);
+    return NS_OK;
   }
 
-  return NS_OK;
+  PRInt32 textOffset = 0;
+  PRUint32 lastIndex = length - 1;
+
+  for (PRUint32 i=0; i<length; i++) {
+    nsCOMPtr<nsIDOMNode> item;
+    rv = nodeList->Item(i, getter_AddRefs(item));
+    NS_ENSURE_SUCCESS(rv, rv);
+    NS_ENSURE_TRUE(item, NS_ERROR_FAILURE);
+
+    nsCOMPtr<nsIDOMText> domText(do_QueryInterface(item));
+
+    if (domText) {
+      PRUint32 textLength = 0;
+
+      rv = domText->GetLength(&textLength);
+      NS_ENSURE_SUCCESS(rv, rv);
+
+      // Check if aOffset falls within this range.
+      if (aOffset >= textOffset && aOffset <= textOffset+(PRInt32)textLength) {
+        *aPosition = aOffset - textOffset;
+        *aResult = item;
+        NS_ADDREF(*aResult);
+        return NS_OK;
+      }
+
+      textOffset += textLength;
+
+      // If there aren't any more siblings after this text node,
+      // return the point at the end of this text node!
+
+      if (i == lastIndex) {
+        *aPosition = textLength;
+        *aResult = item;
+        NS_ADDREF(*aResult);
+        return NS_OK;
+      }
+    }
+    else {
+      // Must be a BR node, count it as a newline.
+
+      if (aOffset == textOffset || i == lastIndex) {
+        // We've found the correct position, or aOffset takes us
+        // beyond the last child under rootNode, just return the point
+        // under rootNode that is in front of this br.
+
+        *aPosition = i;
+        *aResult = rootNode;
+        NS_ADDREF(*aResult);
+        return NS_OK;
+      }
+
+      ++textOffset;
+    }
+  }
+
+  NS_ERROR("We should never get here!");
+
+  return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsTextControlFrame::GetSelectionRange(PRInt32* aSelectionStart, PRInt32* aSelectionEnd)
 {
   // make sure we have an editor
   nsresult rv = EnsureEditorInitialized();
   NS_ENSURE_SUCCESS(rv, rv);
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -5214,28 +5214,28 @@ nsIFrame::PeekOffset(nsPeekOffsetStruct*
   PRInt32 offset = aPos->mStartOffset - range.start;
   nsIFrame* current = this;
   
   switch (aPos->mAmount) {
     case eSelectCharacter:
     {
       PRBool eatingNonRenderableWS = PR_FALSE;
       PRBool done = PR_FALSE;
-      PRBool jumpedLine = PR_FALSE;
       
       while (!done) {
         PRBool movingInFrameDirection =
           IsMovingInFrameDirection(current, aPos->mDirection, aPos->mVisual);
 
         if (eatingNonRenderableWS)
           done = current->PeekOffsetNoAmount(movingInFrameDirection, &offset); 
         else
           done = current->PeekOffsetCharacter(movingInFrameDirection, &offset); 
 
         if (!done) {
+          PRBool jumpedLine;
           result =
             current->GetFrameFromDirection(aPos->mDirection, aPos->mVisual,
                                            aPos->mJumpLines, aPos->mScrollViewStop,
                                            &current, &offset, &jumpedLine);
           if (NS_FAILED(result))
             return result;
 
           // If we jumped lines, it's as if we found a character, but we still need
@@ -5246,25 +5246,16 @@ nsIFrame::PeekOffset(nsPeekOffsetStruct*
       }
 
       // Set outputs
       range = GetRangeForFrame(current);
       aPos->mResultFrame = current;
       aPos->mResultContent = range.content;
       // Output offset is relative to content, not frame
       aPos->mContentOffset = offset < 0 ? range.end : range.start + offset;
-      // If we're dealing with a text frame and moving backward positions us at
-      // the end of that line, decrease the offset by one to make sure that
-      // we're placed before the linefeed character on the previous line.
-      if (offset < 0 && jumpedLine &&
-          aPos->mDirection == eDirPrevious &&
-          current->GetStyleText()->NewlineIsSignificant() &&
-          current->HasTerminalNewline()) {
-        --aPos->mContentOffset;
-      }
       
       break;
     }
     case eSelectWord:
     {
       // wordSelectEatSpace means "are we looking for a boundary between whitespace
       // and non-whitespace (in the direction we're moving in)".
       // It is true when moving forward and looking for a beginning of a word, or
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -1631,24 +1631,16 @@ public:
   virtual nsresult GetRenderedText(nsAString* aAppendToString = nsnull,
                                    gfxSkipChars* aSkipChars = nsnull,
                                    gfxSkipCharsIterator* aSkipIter = nsnull,
                                    PRUint32 aSkippedStartOffset = 0,
                                    PRUint32 aSkippedMaxLength = PR_UINT32_MAX)
   { return NS_ERROR_NOT_IMPLEMENTED; }
 
   /**
-   * Returns true if the frame contains any non-collapsed characters.
-   * This method is only available for text frames, and it will return false
-   * for all other frame types.
-   */
-  virtual PRBool HasAnyNoncollapsedCharacters()
-  { return PR_FALSE; }
-
-  /**
    * Accessor functions to get/set the associated view object
    *
    * GetView returns non-null if and only if |HasView| returns true.
    */
   PRBool HasView() const { return !!(mState & NS_FRAME_HAS_VIEW); }
   nsIView* GetView() const;
   virtual nsIView* GetViewExternal() const;
   nsresult SetView(nsIView* aView);
--- a/layout/generic/nsTextFrame.h
+++ b/layout/generic/nsTextFrame.h
@@ -455,13 +455,11 @@ protected:
                                        nsRect& aRect);
 
   PRBool IsFloatingFirstLetterChild();
 
   ContentOffsets GetCharacterOffsetAtFramePointInternal(const nsPoint &aPoint,
                    PRBool aForInsertionPoint);
 
   void ClearFrameOffsetCache();
-
-  virtual PRBool HasAnyNoncollapsedCharacters();
 };
 
 #endif
--- a/layout/generic/nsTextFrameThebes.cpp
+++ b/layout/generic/nsTextFrameThebes.cpp
@@ -5057,23 +5057,16 @@ nsTextFrame::GetCharacterOffsetAtFramePo
   } else {
     // All characters fitted, we're at (or beyond) the end of the text.
     // XXX This could be some pathological situation where negative spacing
     // caused characters to move backwards. We can't really handle that
     // in the current frame system because frames can't have negative
     // intrinsic widths.
     selectedOffset =
         provider.GetStart().GetOriginalOffset() + provider.GetOriginalLength();
-    // If we're at the end of a preformatted line which has a terminating
-    // linefeed, we want to reduce the offset by one to make sure that the
-    // selection is placed before the linefeed character.
-    if (GetStyleText()->NewlineIsSignificant() &&
-        HasTerminalNewline()) {
-      --selectedOffset;
-    }
   }
 
   offsets.content = GetContent();
   offsets.offset = offsets.secondaryOffset = selectedOffset;
   offsets.associateWithNext = mContentOffset == offsets.offset;
   return offsets;
 }
 
@@ -5427,17 +5420,18 @@ static PRBool
 IsAcceptableCaretPosition(const gfxSkipCharsIterator& aIter, gfxTextRun* aTextRun,
                           nsIFrame* aFrame)
 {
   if (aIter.IsOriginalCharSkipped())
     return PR_FALSE;
   PRUint32 index = aIter.GetSkippedOffset();
   if (!aTextRun->IsClusterStart(index))
     return PR_FALSE;
-  return PR_TRUE;
+  return !(aFrame->GetStyleText()->NewlineIsSignificant() &&
+           aTextRun->GetChar(index) == '\n');
 }
 
 PRBool
 nsTextFrame::PeekOffsetCharacter(PRBool aForward, PRInt32* aOffset)
 {
   PRInt32 contentLength = GetContentLength();
   NS_ASSERTION(aOffset && *aOffset <= contentLength, "aOffset out of range");
 
@@ -5452,40 +5446,37 @@ nsTextFrame::PeekOffsetCharacter(PRBool 
     return PR_FALSE;
 
   TrimmedOffsets trimmed = GetTrimmedOffsets(mContent->GetText(), PR_FALSE);
 
   // A negative offset means "end of frame".
   PRInt32 startOffset = GetContentOffset() + (*aOffset < 0 ? contentLength : *aOffset);
 
   if (!aForward) {
-    // If at the beginning of the line, look at the previous continuation
-    for (PRInt32 i = NS_MIN(trimmed.GetEnd(), startOffset) - 1;
+    PRInt32 i;
+    for (i = NS_MIN(trimmed.GetEnd(), startOffset) - 1;
          i >= trimmed.mStart; --i) {
       iter.SetOriginalOffset(i);
       if (IsAcceptableCaretPosition(iter, mTextRun, this)) {
         *aOffset = i - mContentOffset;
         return PR_TRUE;
       }
     }
     *aOffset = 0;
   } else {
-    // If we're at the end of a line, look at the next continuation
-    iter.SetOriginalOffset(startOffset);
-    if (iter.GetSkippedOffset() <= PRUint32(trimmed.GetEnd()) &&
-        !(iter.GetSkippedOffset() < PRUint32(trimmed.GetEnd()) &&
-          GetStyleText()->NewlineIsSignificant() &&
-          mTextRun->GetChar(iter.GetSkippedOffset()) == '\n')) {
-      for (PRInt32 i = startOffset + 1; i <= trimmed.GetEnd(); ++i) {
-        iter.SetOriginalOffset(i);
-        if (i == trimmed.GetEnd() ||
-            IsAcceptableCaretPosition(iter, mTextRun, this)) {
-          *aOffset = i - mContentOffset;
-          return PR_TRUE;
-        }
+    PRInt32 i;
+    for (i = startOffset + 1; i <= trimmed.GetEnd(); ++i) {
+      iter.SetOriginalOffset(i);
+      // XXX we can't necessarily stop at the end of this frame,
+      // but we really have no choice right now. We need to do a deeper
+      // fix/restructuring of PeekOffsetCharacter
+      if (i == trimmed.GetEnd() ||
+          IsAcceptableCaretPosition(iter, mTextRun, this)) {
+        *aOffset = i - mContentOffset;
+        return PR_TRUE;
       }
     }
     *aOffset = contentLength;
   }
   
   return PR_FALSE;
 }
 
@@ -7126,19 +7117,8 @@ nsTextFrame::HasTerminalNewline() const
   return ::HasTerminalNewline(this);
 }
 
 PRBool
 nsTextFrame::IsAtEndOfLine() const
 {
   return (GetStateBits() & TEXT_END_OF_LINE) != 0;
 }
-
-PRBool
-nsTextFrame::HasAnyNoncollapsedCharacters()
-{
-  gfxSkipCharsIterator iter = EnsureTextRun();
-  PRInt32 offset = GetContentOffset(),
-          offsetEnd = GetContentEnd();
-  PRInt32 skippedOffset = iter.ConvertOriginalToSkipped(offset);
-  PRInt32 skippedOffsetEnd = iter.ConvertOriginalToSkipped(offsetEnd);
-  return skippedOffset != skippedOffsetEnd;
-}
--- a/layout/generic/test/Makefile.in
+++ b/layout/generic/test/Makefile.in
@@ -53,17 +53,16 @@ include $(topsrcdir)/config/rules.mk
 		frame_selection_underline.css \
 		plugin_clipping_helper.xhtml \
 		plugin_clipping_helper2.xhtml \
 		plugin_clipping_helper_transformed.xhtml \
 		plugin_clipping_helper_table.xhtml \
 		plugin_clipping_lib.js \
 		plugin_focus_helper.html \
 		test_backspace_delete.xul \
-		test_bug240933.html \
 		test_bug263683.html \
 		test_bug288789.html \
 		test_bug290397.html \
 		test_bug323656.html \
 		test_bug344830.html \
 		test_bug348681.html \
 		test_bug382429.html \
 		test_bug384527.html \
deleted file mode 100644
--- a/layout/generic/test/test_bug240933.html
+++ /dev/null
@@ -1,68 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=240933
--->
-
-<head>
-  <title>Test for Bug 240933</title>
-  <script type="application/javascript" src="/MochiKit/MochiKit.js"></script>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-
-<body>
-  <a target="_blank"
-     href="https://bugzilla.mozilla.org/show_bug.cgi?id=240933">
-    Mozilla Bug 240933
-  </a>
-  <p id="display"></p>
-  <div id="content" style="display: none">
-  </div>
-
-  <pre id="test">
-    <script type="application/javascript">
-
-      /** Test for Bug 240933 **/
-
-      SimpleTest.waitForExplicitFinish();
-
-      SimpleTest.waitForFocus(function() {
-        var t = document.getElementById("t");
-        synthesizeMouse(t, t.clientWidth / 2, 5, {}, window);
-        is(t.selectionStart, 3, "The selection should be set before the newline");
-        is(t.selectionEnd,   3, "The selection should be set before the newline");
-
-        t = document.getElementById("ta");
-        t.focus();
-        var val = t.value;
-        synthesizeKey("VK_ENTER", {});
-        is(t.value, val + "\n", "Pressing enter right after focusing the textarea should work");
-
-        t = document.getElementById("tb");
-        t.focus();
-        synthesizeKey("VK_ENTER", {});
-        is(t.value, "\n", "Pressing enter for the first time should work");
-        synthesizeKey("VK_ENTER", {});
-        is(t.value, "\n\n", "Pressing enter for the second time should work");
-        synthesizeKey("VK_BACK_SPACE", {});
-        is(t.value, "\n", "Pressing backspace for the first time should work");
-        synthesizeKey("VK_BACK_SPACE", {});
-        is(t.value, "", "Pressing backspace for the second time should work");
-        SimpleTest.finish();
-      });
-
-    </script>
-  </pre>
-
-  <textarea id="t" rows="10" cols="10">abc
-</textarea>
-  <textarea id="ta" rows="10" cols="10">
-test
-
-</textarea>
-  <textarea id="tb" rows="10" cols="10"></textarea>
-
-</body>
-</html>
--- a/layout/generic/test/test_bug288789.html
+++ b/layout/generic/test/test_bug288789.html
@@ -14,21 +14,16 @@ https://bugzilla.mozilla.org/show_bug.cg
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=288789">Mozilla Bug 288789</a>
 <p id="display"></p>
 <div id="content">
 <textarea id="ta" dir="rtl">
 
 &#x05d0;a&#x05d1;
 
 </textarea>
-<textarea id="tb">
-
-abc
-
-</textarea>
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 /** Test for Bug 288789 **/
 
 SimpleTest.waitForExplicitFinish();
 
@@ -50,69 +45,19 @@ function test() {
 
   function testLeft(offset) {
     synthesizeKey("VK_LEFT", {});
     is(textarea.selectionStart, offset, "Left movement broken");
   }
 
   textarea.focus();
   collapse(0);
-  ok(true, "Testing forward movement in RTL mode");
-  for (var i = 0; i < textarea.textContent.length; ++i) {
-    if (i == 0) {
-      testRight(i);
-    }
-    if (textarea.textContent[i] == 'a') {
-      testLeft(i);
-    } else {
-      testLeft(i + 1);
-    }
-    if (i == textarea.textContent.length - 1) {
-      testLeft(i + 1);
-    }
-  }
-  ok(true, "Testing backward movement in RTL mode");
-  for (var i = textarea.textContent.length; i > 0; --i) {
-    if (i == textarea.textContent.length) {
-      testLeft(i);
-    }
-    if (i > 0 && textarea.textContent[i - 1] == 'a') {
-      testRight(i);
-    } else {
-      testRight(i - 1);
-    }
-    if (i == 1) {
-      testRight(i - 1);
-    }
-  }
-
-  textarea = $("tb");
-  textarea.focus();
-  collapse(0);
-  ok(true, "Testing forward movement in LTR mode");
-  for (var i = 0; i < textarea.textContent.length; ++i) {
-    if (i == 0) {
-      testLeft(i);
-    }
-    testRight(i + 1);
-    if (i == textarea.textContent.length - 1) {
-      testRight(i + 1);
-    }
-  }
-  ok(true, "Testing backward movement in LTR mode");
-  for (var i = textarea.textContent.length; i > 0; --i) {
-    if (i == textarea.textContent.length) {
-      testRight(i);
-    }
-    testLeft(i - 1);
-    if (i == 1) {
-      testLeft(i - 1);
-    }
-  }
-
+  testLeft(1);
+  collapse(5);
+  testRight(4);
   SimpleTest.finish();
 }
 
 </script>
 </pre>
 </body>
 </html>
 
--- a/layout/generic/test/test_movement_by_characters.html
+++ b/layout/generic/test/test_movement_by_characters.html
@@ -63,23 +63,23 @@ function test() {
   testLeft(editor.firstChild.nextSibling.nextSibling, 0);
   testLeft(editor, 1);
   testLeft(editor.firstChild, 1);
   testLeft(editor.firstChild, 0);
 
   editor.innerHTML = "<pre>aa\nbb</pre>";
   sel.collapse(editor.firstChild.firstChild, 0);
   testRight(editor.firstChild.firstChild, 1);
-  // at the end of the first line, before the \n
-  testRight(editor.firstChild.firstChild, 2);
+  // at the 'bb' but HINTLEFT so appears at the end of the first line
+  testRight(editor.firstChild.firstChild, 3);  
   testRight(editor.firstChild.firstChild, 3);
   testRight(editor.firstChild.firstChild, 4);
   testLeft(editor.firstChild.firstChild, 3);
-  // at the end of the first line, before the \n
-  testLeft(editor.firstChild.firstChild, 2);
+  // at the 'bb' but HINTLEFT so appears at the end of the first line
+  testLeft(editor.firstChild.firstChild, 3);
   testLeft(editor.firstChild.firstChild, 1);
   testLeft(editor.firstChild.firstChild, 0);
 
   SimpleTest.finish();
 }
 
 
 </script>
deleted file mode 100644
--- a/layout/reftests/bugs/240933-1-ref.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<!DOCTYPE html>
-<html>
-<body onload="setup()">
-<textarea id="ta" dir="rtl">
-
-&#x05d0;a&#x05d1;
-
-</textarea>
-<textarea id="tb">
-
-abc
-
-</textarea>
-
-<div id="coords1"></div>
-<div id="coords2"></div>
-
-<script>
-  function setup() {
-    document.getElementById("coords1").innerHTML = document.getElementById("ta").selectionStart;
-    document.getElementById("coords2").innerHTML = document.getElementById("tb").selectionStart;
-  }
-</script>
-</body>
-</html>
deleted file mode 100644
--- a/layout/reftests/bugs/240933-1.html
+++ /dev/null
@@ -1,19 +0,0 @@
-<!DOCTYPE html>
-<html>
-<body>
-<textarea id="ta" dir="rtl">
-
-&#x05d0;a&#x05d1;
-
-</textarea>
-<textarea id="tb">
-
-abc
-
-</textarea>
-
-<div id="coords1">6</div>
-<div id="coords2">6</div>
-
-</body>
-</html>
deleted file mode 100644
--- a/layout/reftests/bugs/240933-2-ref.html
+++ /dev/null
@@ -1,29 +0,0 @@
-<!DOCTYPE html>
-<html>
-<body onload="setup()">
-<textarea id="ta" dir="rtl">
-
-&#x05d0;a&#x05d1;
-
-</textarea>
-<textarea id="tb">
-
-abc
-
-</textarea>
-
-<div id="coords1"></div>
-<div id="coords2"></div>
-
-<script>
-  function setup() {
-    document.getElementById("ta").selectionStart = 3;
-    document.getElementById("ta").selectionEnd = 3;
-    document.getElementById("coords1").innerHTML = document.getElementById("ta").selectionStart;
-    document.getElementById("tb").selectionStart = 3;
-    document.getElementById("tb").selectionEnd = 3;
-    document.getElementById("coords2").innerHTML = document.getElementById("tb").selectionStart;
-  }
-</script>
-</body>
-</html>
deleted file mode 100644
--- a/layout/reftests/bugs/240933-2.html
+++ /dev/null
@@ -1,19 +0,0 @@
-<!DOCTYPE html>
-<html>
-<body>
-<textarea id="ta" dir="rtl">
-
-&#x05d0;a&#x05d1;
-
-</textarea>
-<textarea id="tb">
-
-abc
-
-</textarea>
-
-<div id="coords1">3</div>
-<div id="coords2">3</div>
-
-</body>
-</html>
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -200,18 +200,16 @@ random == 99850-1b.html 99850-1-ref.html
 == 234686-18.html 234686-ref.html
 == 234686-19.html 234686-ref.html
 == 234964-1.html 234964-1-ref.html
 == 234964-2.html 234964-2-ref.html
 == 235593-1.html 235593-1-ref.html
 == 236539-1.html 236539-1-ref.html
 == 240029-1.html 240029-1-ref.html
 == 240470-1.html 240470-1-ref.html
-== 240933-1.html 240933-1-ref.html
-== 240933-2.html 240933-2-ref.html
 == 243266-1.html 243266-1-ref.html
 == 243302-1.html 243302-1-ref.html
 == 243519-1.html 243519-1-ref.html
 == 243519-2.html 243519-2-ref.html
 == 243519-3.html 243519-3-ref.html
 == 243519-4a.html 243519-4-ref.html
 == 243519-4b.html 243519-4-ref.html
 == 243519-4c.html 243519-4-ref.html
deleted file mode 100644
--- a/layout/reftests/editor/caret_on_textarea_lastline-ref.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE html>
-<html>
-<body onload="document.querySelector('textarea').focus();">
-<textarea>foo</textarea>
-</body>
-</html>
deleted file mode 100644
--- a/layout/reftests/editor/caret_on_textarea_lastline.html
+++ /dev/null
@@ -1,7 +0,0 @@
-<!DOCTYPE html>
-<html>
-<body onload="document.querySelector('textarea').focus();">
-<textarea>foo
-</textarea>
-</body>
-</html>
--- a/layout/reftests/editor/reftest.list
+++ b/layout/reftests/editor/reftest.list
@@ -13,9 +13,8 @@ include xul/reftest.list
 == passwd-1.html passwd-ref.html
 != passwd-2.html passwd-ref.html
 == passwd-3.html passwd-ref.html
 == passwd-4.html passwd-ref.html
 == emptypasswd-1.html emptypasswd-ref.html
 == emptypasswd-2.html emptypasswd-ref.html
 == caret_on_positioned.html caret_on_positioned-ref.html
 == spellcheck-1.html spellcheck-ref.html
-!= caret_on_textarea_lastline.html caret_on_textarea_lastline-ref.html