Back out the editor lazy inititialization patches (bug 221820) to try to solve the orange in bug 557689
authorEhsan Akhgari <ehsan@mozilla.com>
Tue, 06 Apr 2010 21:08:58 -0400
changeset 40522 309acf8ab20fae89fa0378de4a9752ecf4cce5b4
parent 40514 40038cc9f245f07b2cc6b1bd42b39aecdcf1b2a2
child 40523 b931ea32034b6ab61214cb3aaec814da8aff159d
push id12646
push usereakhgari@mozilla.com
push dateWed, 07 Apr 2010 01:11:51 +0000
treeherdermozilla-central@b931ea32034b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs221820, 557689
milestone1.9.3a4pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
Back out the editor lazy inititialization patches (bug 221820) to try to solve the orange in bug 557689
content/base/public/nsContentUtils.h
content/base/src/nsContentUtils.cpp
content/html/content/src/Makefile.in
content/html/content/src/nsHTMLInputElement.cpp
content/html/content/src/nsHTMLTextAreaElement.cpp
content/html/content/test/test_bug518122.html
editor/libeditor/text/nsTextEditRules.cpp
layout/forms/Makefile.in
layout/forms/nsITextControlFrame.h
layout/forms/nsTextControlFrame.cpp
layout/forms/nsTextControlFrame.h
layout/forms/test/test_bug446663.html
toolkit/content/tests/chrome/test_bug418874.xul
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -1578,28 +1578,16 @@ public:
    * fixes all the prototypes. Assumes obj is properly rooted, that obj has no
    * getter functions that can cause side effects, and that the only types of
    * objects nested within obj are the types that are cloneable via the
    * CreateStructuredClone function above.
    */
   static nsresult ReparentClonedObjectToScope(JSContext* cx, JSObject* obj,
                                               JSObject* scope);
 
-  /**
-   * Strip all \n, \r and nulls from the given string
-   * @param aString the string to remove newlines from [in/out]
-   */
-  static void RemoveNewlines(nsString &aString);
-
-  /**
-   * Convert Windows and Mac platform linebreaks to \n.
-   * @param aString the string to convert the newlines inside [in/out]
-   */
-  static void PlatformToDOMLineBreaks(nsString &aString);
-
 private:
 
   static PRBool InitializeEventTable();
 
   static nsresult EnsureStringBundle(PropertiesFile aFile);
 
   static nsIDOMScriptObjectFactory *GetDOMScriptObjectFactory();
 
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -5926,29 +5926,8 @@ mozAutoRemovableBlockerRemover::~mozAuto
                "Should have had none");
   for (PRUint32 i = 0; i < mNestingLevel; ++i) {
     nsContentUtils::AddRemovableScriptBlocker();
     if (mObserver) {
       mObserver->BeginUpdate(mDocument, UPDATE_CONTENT_MODEL);
     }
   }
 }
-
-void nsContentUtils::RemoveNewlines(nsString &aString)
-{
-  // strip CR/LF and null
-  static const char badChars[] = {'\r', '\n', 0};
-  aString.StripChars(badChars);
-}
-
-void nsContentUtils::PlatformToDOMLineBreaks(nsString &aString)
-{
-  if (aString.FindChar(PRUnichar('\r')) != -1) {
-    // Windows linebreaks: Map CRLF to LF:
-    aString.ReplaceSubstring(NS_LITERAL_STRING("\r\n").get(),
-                             NS_LITERAL_STRING("\n").get());
-
-    // Mac linebreaks: Map any remaining CR to LF:
-    aString.ReplaceSubstring(NS_LITERAL_STRING("\r").get(),
-                             NS_LITERAL_STRING("\n").get());
-  }
-}
-
--- a/content/html/content/src/Makefile.in
+++ b/content/html/content/src/Makefile.in
@@ -125,14 +125,12 @@ INCLUDES	+= \
 		-I$(srcdir)/../../../base/src \
 		-I$(srcdir)/../../../events/src \
 		-I$(srcdir)/../../../xbl/src \
 		-I$(srcdir)/../../../../layout/style \
 		-I$(srcdir)/../../../../layout/tables \
 		-I$(srcdir)/../../../../layout/xul/base/src \
 		-I$(srcdir)/../../../../layout/generic \
 		-I$(srcdir)/../../../../dom/base \
-		-I$(srcdir)/../../../../editor/libeditor/base \
-		-I$(srcdir)/../../../../editor/libeditor/text \
 		-I$(srcdir) \
 		$(NULL)
 
 DEFINES += -D_IMPL_NS_LAYOUT
--- a/content/html/content/src/nsHTMLInputElement.cpp
+++ b/content/html/content/src/nsHTMLInputElement.cpp
@@ -105,18 +105,16 @@
 
 // input type=image
 #include "nsImageLoadingContent.h"
 #include "nsIDOMWindowInternal.h"
 
 #include "mozAutoDocUpdate.h"
 #include "nsHTMLFormElement.h"
 
-#include "nsTextEditRules.h"
-
 // XXX align=left, hspace, vspace, border? other nav4 attrs
 
 static NS_DEFINE_CID(kXULControllersCID,  NS_XULCONTROLLERS_CID);
 static NS_DEFINE_CID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
 
 //
 // Accessors for mBitField
 //
@@ -420,22 +418,16 @@ protected:
    */
   nsresult MaybeSubmitForm(nsPresContext* aPresContext);
 
   /**
    * Update mFileList with the currently selected file.
    */
   nsresult UpdateFileList();
 
-  /**
-   * Determine whether the editor needs to be initialized explicitly for
-   * a particular event.
-   */
-  PRBool NeedToInitializeEditorForEvent(nsEventChainPreVisitor& aVisitor) const;
-
   nsCOMPtr<nsIControllers> mControllers;
 
   /**
    * The type of this input (<input type=...>) as an integer.
    * @see nsIFormControl.h (specifically NS_FORM_INPUT_*)
    */
   PRInt8                   mType;
   /**
@@ -877,23 +869,16 @@ nsHTMLInputElement::GetValue(nsAString& 
     if (frameOwnsValue) {
       formControlFrame->GetFormProperty(nsGkAtoms::value, aValue);
     } else {
       if (!GET_BOOLBIT(mBitField, BF_VALUE_CHANGED) || !mValue) {
         GetDefaultValue(aValue);
       } else {
         CopyUTF8toUTF16(mValue, aValue);
       }
-
-      // If the value is not owned by the frame, then we should handle any
-      // exiting newline characters inside it, instead of relying on the
-      // editor to do it for us.
-      nsString value(aValue);
-      nsTextEditRules::HandleNewLines(value, -1);
-      aValue.Assign(value);
     }
 
     return NS_OK;
   }
 
   if (mType == NS_FORM_INPUT_FILE) {
     if (nsContentUtils::IsCallerTrustedForCapability("UniversalFileRead")) {
       if (!mFileNames.IsEmpty()) {
@@ -1011,19 +996,17 @@ nsHTMLInputElement::SetUserInput(const n
 }
 
 NS_IMETHODIMP
 nsHTMLInputElement::TakeTextFrameValue(const nsAString& aValue)
 {
   if (mValue) {
     nsMemory::Free(mValue);
   }
-  nsString value(aValue);
-  nsContentUtils::PlatformToDOMLineBreaks(value);
-  mValue = ToNewUTF8String(value);
+  mValue = ToNewUTF8String(aValue);
   return NS_OK;
 }
 
 void
 nsHTMLInputElement::GetDisplayFileName(nsAString& aValue)
 {
   aValue.Truncate();
   for (PRUint32 i = 0; i < mFileNames.Length(); ++i) {
@@ -1134,18 +1117,19 @@ nsHTMLInputElement::SetValueInternal(con
       formControlFrame = GetFormControlFrame(PR_FALSE);
     }
 
     if (formControlFrame) {
       // Always set the value in the frame.  If the frame does not own the
       // value yet (per OwnsValue()), it will turn around and call
       // TakeTextFrameValue() on us, but will update its display with the new
       // value if needed.
-      return formControlFrame->SetFormProperty(
+      formControlFrame->SetFormProperty(
         aUserInput ? nsGkAtoms::userInput : nsGkAtoms::value, aValue);
+      return NS_OK;
     }
 
     SetValueChanged(PR_TRUE);
     return TakeTextFrameValue(aValue);
   }
 
   if (mType == NS_FORM_INPUT_FILE) {
     return NS_ERROR_UNEXPECTED;
@@ -1585,42 +1569,16 @@ nsHTMLInputElement::Click()
 
       SET_BOOLBIT(mBitField, BF_HANDLING_CLICK, PR_FALSE);
     }
   }
 
   return NS_OK;
 }
 
-PRBool
-nsHTMLInputElement::NeedToInitializeEditorForEvent(nsEventChainPreVisitor& aVisitor) const
-{
-  // We only need to initialize the editor for text input controls because they
-  // are lazily initialized.  We don't need to initialize the control for
-  // certain types of events, because we know that those events are safe to be
-  // handled without the editor being initialized.  These events include:
-  // mousein/move/out, and DOM mutation events.
-  if ((mType == NS_FORM_INPUT_TEXT ||
-       mType == NS_FORM_INPUT_PASSWORD) &&
-      aVisitor.mEvent->eventStructType != NS_MUTATION_EVENT) {
-
-    switch (aVisitor.mEvent->message) {
-    case NS_MOUSE_MOVE:
-    case NS_MOUSE_ENTER:
-    case NS_MOUSE_EXIT:
-    case NS_MOUSE_ENTER_SYNTH:
-    case NS_MOUSE_EXIT_SYNTH:
-      return PR_FALSE;
-      break;
-    }
-    return PR_TRUE;
-  }
-  return PR_FALSE;
-}
-
 nsresult
 nsHTMLInputElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
 {
   // Do not process any DOM events if the element is disabled
   aVisitor.mCanHandle = PR_FALSE;
   PRBool disabled;
   nsresult rv = GetDisabled(&disabled);
   NS_ENSURE_SUCCESS(rv, rv);
@@ -1637,23 +1595,16 @@ nsHTMLInputElement::PreHandleEvent(nsEve
 
       if (uiStyle->mUserInput == NS_STYLE_USER_INPUT_NONE ||
           uiStyle->mUserInput == NS_STYLE_USER_INPUT_DISABLED) {
         return NS_OK;
       }
     }
   }
 
-  // Initialize the editor if needed.
-  if (NeedToInitializeEditorForEvent(aVisitor)) {
-    nsITextControlFrame* textControlFrame = do_QueryFrame(GetPrimaryFrame());
-    if (textControlFrame)
-      textControlFrame->EnsureEditorInitialized();
-  }
-
   //FIXME Allow submission etc. also when there is no prescontext, Bug 329509.
   if (!aVisitor.mPresContext) {
     return nsGenericHTMLElement::PreHandleEvent(aVisitor);
   }
   //
   // Web pages expect the value of a radio button or checkbox to be set
   // *before* onclick and DOMActivate fire, and they expect that if they set
   // the value explicitly during onclick or DOMActivate it will not be toggled
--- a/content/html/content/src/nsHTMLTextAreaElement.cpp
+++ b/content/html/content/src/nsHTMLTextAreaElement.cpp
@@ -430,19 +430,17 @@ nsHTMLTextAreaElement::GetValueInternal(
 }
 
 NS_IMETHODIMP
 nsHTMLTextAreaElement::TakeTextFrameValue(const nsAString& aValue)
 {
   if (mValue) {
     nsMemory::Free(mValue);
   }
-  nsString value(aValue);
-  nsContentUtils::PlatformToDOMLineBreaks(value);
-  mValue = ToNewUTF8String(value);
+  mValue = ToNewUTF8String(aValue);
   return NS_OK;
 }
 
 nsresult
 nsHTMLTextAreaElement::SetValueInternal(const nsAString& aValue,
                                         nsITextControlFrame* aFrame,
                                         PRBool aUserInput)
 {
--- a/content/html/content/test/test_bug518122.html
+++ b/content/html/content/test/test_bug518122.html
@@ -100,22 +100,18 @@ function runTestsFor(el, simpleTests, ap
   }
 }
 
 function runTests() {
   var textareas = document.getElementsByTagName("textarea");
   for (var i = 0; i < textareas.length; ++i) {
     runTestsFor(textareas[i], simple_tests, value_append_tests);
   }
-  var input = document.getElementsByTagName("input")[0];
-  runTestsFor(input, simple_tests_for_input, value_append_tests_for_input);
-  // initialize the editor
-  input.focus();
-  input.blur();
-  runTestsFor(input, simple_tests_for_input, value_append_tests_for_input);
+  runTestsFor(document.getElementsByTagName("input")[0],
+              simple_tests_for_input, value_append_tests_for_input);
   SimpleTest.finish();
 }
 
 
 </script>
 </pre>
 <textarea cols="30" rows="7" wrap="none"></textarea>
 <textarea cols="30" rows="7" wrap="off"></textarea><br>
--- a/editor/libeditor/text/nsTextEditRules.cpp
+++ b/editor/libeditor/text/nsTextEditRules.cpp
@@ -151,26 +151,16 @@ nsTextEditRules::Init(nsPlaintextEditor 
   // Cache our body node, if available.
   nsIDOMNode *body = mEditor->GetRoot();
 
   // Put in a magic br if needed. This method handles null selection,
   // which should never happen anyway
   nsresult res = CreateBogusNodeIfNeeded(selection);
   if (NS_FAILED(res)) return res;
 
-  // If the selection hasn't been set up yet, set it up collapsed to the end of
-  // our editable content.
-  PRInt32 rangeCount;
-  res = selection->GetRangeCount(&rangeCount);
-  NS_ENSURE_SUCCESS(res, res);
-  if (!rangeCount) {
-    res = mEditor->EndOfDocument();
-    NS_ENSURE_SUCCESS(res, res);
-  }
-
   if (mFlags & nsIPlaintextEditor::eEditorPlaintextMask)
   {
     // ensure trailing br node
     res = CreateTrailingBRIfNeeded();
     if (NS_FAILED(res)) return res;
   }
 
   if (body)
--- a/layout/forms/Makefile.in
+++ b/layout/forms/Makefile.in
@@ -86,13 +86,11 @@ FORCE_STATIC_LIB = 1
 include $(topsrcdir)/config/rules.mk
 
 LOCAL_INCLUDES	= \
 		-I$(srcdir)/../base \
 		-I$(srcdir)/../generic \
 		-I$(srcdir)/../xul/base/src \
 		-I$(srcdir)/../../content/base/src \
 		-I$(srcdir)/../../content/html/content/src \
-		-I$(srcdir)/../../editor/libeditor/base \
-		-I$(srcdir)/../../editor/libeditor/text \
 		$(NULL)
 
 DEFINES += -D_IMPL_NS_LAYOUT
--- a/layout/forms/nsITextControlFrame.h
+++ b/layout/forms/nsITextControlFrame.h
@@ -82,18 +82,11 @@ public:
   
   NS_IMETHOD    SetSelectionRange(PRInt32 aSelectionStart, PRInt32 aSelectionEnd) = 0;
   NS_IMETHOD    GetSelectionRange(PRInt32* aSelectionStart, PRInt32* aSelectionEnd) = 0;
 
   virtual nsISelectionController* GetOwnedSelectionController() = 0;
   virtual nsFrameSelection* GetOwnedFrameSelection() = 0;
 
   virtual nsresult GetPhonetic(nsAString& aPhonetic) = 0;
-
-  /**
-   * Ensure editor is initialized with the proper flags and the default value.
-   * @throws NS_ERROR_NOT_INITIALIZED if mEditor has not been created
-   * @throws various and sundry other things
-   */
-  virtual nsresult EnsureEditorInitialized() = 0;
 };
 
 #endif
--- a/layout/forms/nsTextControlFrame.cpp
+++ b/layout/forms/nsTextControlFrame.cpp
@@ -113,17 +113,16 @@
 #include "nsNodeInfoManager.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsIDOMKeyListener.h"
 #include "nsIDOMEventGroup.h"
 #include "nsIDOM3EventTarget.h"
 #include "nsINativeKeyBindings.h"
 #include "nsIJSContextStack.h"
 #include "nsFocusManager.h"
-#include "nsTextEditRules.h"
 
 #define DEFAULT_COLUMN_WIDTH 20
 
 #include "nsContentCID.h"
 static NS_DEFINE_IID(kRangeCID,     NS_RANGE_CID);
 
 static NS_DEFINE_CID(kTextEditorCID, NS_TEXTEDITOR_CID);
 static NS_DEFINE_CID(kFrameSelectionCID, NS_FRAMESELECTION_CID);
@@ -131,16 +130,28 @@ static NS_DEFINE_CID(kFrameSelectionCID,
 static const PRInt32 DEFAULT_COLS = 20;
 static const PRInt32 DEFAULT_ROWS = 1;
 static const PRInt32 DEFAULT_ROWS_TEXTAREA = 2;
 static const PRInt32 DEFAULT_UNDO_CAP = 1000;
 
 static nsINativeKeyBindings *sNativeInputBindings = nsnull;
 static nsINativeKeyBindings *sNativeTextAreaBindings = nsnull;
 
+static void
+PlatformToDOMLineBreaks(nsString &aString)
+{
+  // Windows linebreaks: Map CRLF to LF:
+  aString.ReplaceSubstring(NS_LITERAL_STRING("\r\n").get(),
+                           NS_LITERAL_STRING("\n").get());
+
+  // Mac linebreaks: Map any remaining CR to LF:
+  aString.ReplaceSubstring(NS_LITERAL_STRING("\r").get(),
+                           NS_LITERAL_STRING("\n").get());
+}
+
 // wrap can be one of these three values.  
 typedef enum {
   eHTMLTextWrap_Off     = 1,    // "off"
   eHTMLTextWrap_Hard    = 2,    // "hard"
   eHTMLTextWrap_Soft    = 3     // the default
 } nsHTMLTextWrap;
 
 static PRBool 
@@ -934,53 +945,25 @@ NS_IMETHODIMP nsTextControlFrame::GetAcc
   if (accService) {
     return accService->CreateHTMLTextFieldAccessible(static_cast<nsIFrame*>(this), aAccessible);
   }
 
   return NS_ERROR_FAILURE;
 }
 #endif
 
-#ifdef DEBUG
-class EditorInitializerEntryTracker {
-public:
-  explicit EditorInitializerEntryTracker(nsTextControlFrame &frame)
-    : mFrame(frame)
-    , mFirstEntry(PR_FALSE)
-  {
-    if (!mFrame.mInEditorInitialization) {
-      mFrame.mInEditorInitialization = PR_TRUE;
-      mFirstEntry = PR_TRUE;
-    }
-  }
-  ~EditorInitializerEntryTracker()
-  {
-    if (mFirstEntry) {
-      mFrame.mInEditorInitialization = PR_FALSE;
-    }
-  }
-  PRBool EnteredMoreThanOnce() const { return !mFirstEntry; }
-private:
-  nsTextControlFrame &mFrame;
-  PRBool mFirstEntry;
-};
-#endif
-
 nsTextControlFrame::nsTextControlFrame(nsIPresShell* aShell, nsStyleContext* aContext)
   : nsStackFrame(aShell, aContext)
   , mUseEditor(PR_FALSE)
   , mIsProcessing(PR_FALSE)
   , mNotifyOnInput(PR_TRUE)
   , mDidPreDestroy(PR_FALSE)
   , mFireChangeEventState(PR_FALSE)
   , mInSecureKeyboardInputMode(PR_FALSE)
   , mTextListener(nsnull)
-#ifdef DEBUG
-  , mInEditorInitialization(PR_FALSE)
-#endif
 {
 }
 
 nsTextControlFrame::~nsTextControlFrame()
 {
   NS_IF_RELEASE(mTextListener);
 }
 
@@ -1311,16 +1294,48 @@ nsTextControlFrame::CalcIntrinsicSize(ns
     aIntrinsicSize.width  += scrollbarSizes.LeftRight();
     
     aIntrinsicSize.height += scrollbarSizes.TopBottom();;
   }
 
   return NS_OK;
 }
 
+void
+nsTextControlFrame::DelayedEditorInit()
+{
+  nsIDocument* doc = mContent->GetCurrentDoc();
+  if (!doc) {
+    return;
+  }
+  
+  nsWeakFrame weakFrame(this);
+
+  // Flush out content on our document.  Have to do this, because script
+  // blockers don't prevent the sink flushing out content and notifying in the
+  // process, which can destroy frames.
+  doc->FlushPendingNotifications(Flush_ContentAndNotify);
+  if (!weakFrame.IsAlive()) {
+    return;
+  }
+  
+  // Make sure that editor init doesn't do things that would kill us off
+  // (especially off the script blockers it'll create for its DOM mutations).
+  nsAutoScriptBlocker scriptBlocker;
+
+  // Time to mess with our security context... See comments in GetValue()
+  // for why this is needed.
+  nsCxPusher pusher;
+  pusher.PushNull();
+
+  InitEditor();
+  if (IsFocusedContent(GetContent()))
+    SetFocus(PR_TRUE, PR_FALSE);
+}
+
 PRInt32
 nsTextControlFrame::GetWrapCols()
 {
   if (IsTextArea()) {
     // wrap=off means -1 for wrap width no matter what cols is
     nsHTMLTextWrap wrapProp;
     ::GetWrapPropertyEnum(mContent, wrapProp);
     if (wrapProp == eHTMLTextWrap_Off) {
@@ -1332,78 +1347,33 @@ nsTextControlFrame::GetWrapCols()
     return GetCols();
   }
 
   // Never wrap non-textareas
   return -1;
 }
 
 nsresult
-nsTextControlFrame::EnsureEditorInitialized()
-{
-  nsWeakFrame weakFrame(this);
-  nsresult rv = EnsureEditorInitializedInternal();
-  NS_ENSURE_STATE(weakFrame.IsAlive());
-  return rv;
-}
-
-nsresult
-nsTextControlFrame::EnsureEditorInitializedInternal()
+nsTextControlFrame::InitEditor()
 {
   // This method initializes our editor, if needed.
-
+  
   // This code used to be called from CreateAnonymousContent(), but
   // when the editor set the initial string, it would trigger a
   // PresShell listener which called FlushPendingNotifications()
   // during frame construction. This was causing other form controls
-  // to display wrong values.  Additionally, calling this every time
-  // a text frame control is instantiated means that we're effectively
-  // instantiating the editor for all text fields, even if they
-  // never get used.  So, now this method is being called lazily only
-  // when we actually need an editor.
+  // to display wrong values.  So we call this from a script runner
+  // now.
 
   // Check if this method has been called already.
   // If so, just return early.
+
   if (mUseEditor)
     return NS_OK;
 
-  nsIDocument* doc = mContent->GetCurrentDoc();
-  NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
-
-  nsWeakFrame weakFrame(this);
-
-  // Flush out content on our document.  Have to do this, because script
-  // blockers don't prevent the sink flushing out content and notifying in the
-  // process, which can destroy frames.
-  doc->FlushPendingNotifications(Flush_ContentAndNotify);
-  NS_ENSURE_TRUE(weakFrame.IsAlive(), NS_ERROR_FAILURE);
-
-  // Make sure that editor init doesn't do things that would kill us off
-  // (especially off the script blockers it'll create for its DOM mutations).
-  nsAutoScriptBlocker scriptBlocker;
-
-  // Time to mess with our security context... See comments in GetValue()
-  // for why this is needed.
-  nsCxPusher pusher;
-  pusher.PushNull();
-
-  // Make sure that we try to focus the content even if the method fails
-  class EnsureSetFocus {
-  public:
-    explicit EnsureSetFocus(nsTextControlFrame* aFrame)
-      : mFrame(aFrame) {}
-    ~EnsureSetFocus() {
-      if (IsFocusedContent(mFrame->GetContent()))
-        mFrame->SetFocus(PR_TRUE, PR_FALSE);
-    }
-  private:
-    nsTextControlFrame *mFrame;
-  };
-  EnsureSetFocus makeSureSetFocusHappens(this);
-
   // Create an editor
 
   nsresult rv;
   mEditor = do_CreateInstance(kTextEditorCID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
   
   // Setup the editor flags
 
@@ -1434,19 +1404,16 @@ nsTextControlFrame::EnsureEditorInitiali
   nsPresContext *presContext = PresContext();
   nsIPresShell *shell = presContext->GetPresShell();
 
   // Get the DOM document
   nsCOMPtr<nsIDOMDocument> domdoc = do_QueryInterface(shell->GetDocument());
   if (!domdoc)
     return NS_ERROR_FAILURE;
 
-  // Make sure we clear out the non-breaking space before we initialize the editor
-  UpdateValueDisplay(PR_FALSE, PR_TRUE);
-
   rv = mEditor->Init(domdoc, shell, mValueDiv, mSelCon, editorFlags);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Initialize the controller for the editor
 
   if (!SuppressEventHandlers(presContext)) {
     nsCOMPtr<nsIControllers> controllers;
     nsCOMPtr<nsIDOMNSHTMLInputElement> inputElement =
@@ -1527,63 +1494,58 @@ nsTextControlFrame::EnsureEditorInitiali
   // Get the current value of the textfield from the content.
   nsAutoString defaultValue;
   GetValue(defaultValue, PR_TRUE);
 
   // Turn on mUseEditor so that subsequent calls will use the
   // editor.
   mUseEditor = PR_TRUE;
 
-#ifdef DEBUG
-  // Make sure we are not being called again until we're finished.
-  // If reentrancy happens, just pretend that we don't have an editor.
-  const EditorInitializerEntryTracker tracker(*this);
-  NS_ASSERTION(!tracker.EnteredMoreThanOnce(),
-               "EnsureEditorInitialized has been called while a previous call was in progress");
-#endif
-
-  // Set the editor's contents to our default value. We have to be
-  // sure to use the editor so that '*' characters get displayed for
-  // password fields, etc. SetValue() will call the editor for us.  We
-  // want to call this even if defaultValue is empty, since empty text
-  // inputs have a single non-breaking space in the textnode under
-  // mAnonymousDiv, and this space needs to go away as we init the
-  // editor.
-
-  // Avoid causing reentrant painting and reflowing by telling the editor
-  // that we don't want it to force immediate view refreshes or force
-  // immediate reflows during any editor calls.
-
-  rv = mEditor->SetFlags(editorFlags |
-                         nsIPlaintextEditor::eEditorUseAsyncUpdatesMask);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // Now call SetValue() which will make the necessary editor calls to set
-  // the default value.  Make sure to turn off undo before setting the default
-  // value, and turn it back on afterwards. This will make sure we can't undo
-  // past the default value.
-
-  rv = mEditor->EnableUndo(PR_FALSE);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  SetValue(defaultValue);
-
-  rv = mEditor->EnableUndo(PR_TRUE);
-  NS_ASSERTION(NS_SUCCEEDED(rv),"Transaction Manager must have failed");
-
-  // Now restore the original editor flags.
-  rv = mEditor->SetFlags(editorFlags);
-  NS_ENSURE_SUCCESS(rv, rv);
+  // If we have a default value, insert it under the div we created
+  // above, but be sure to use the editor so that '*' characters get
+  // displayed for password fields, etc. SetValue() will call the
+  // editor for us.
 
   if (!defaultValue.IsEmpty()) {
+    // Avoid causing reentrant painting and reflowing by telling the editor
+    // that we don't want it to force immediate view refreshes or force
+    // immediate reflows during any editor calls.
+
+    rv = mEditor->SetFlags(editorFlags |
+                           nsIPlaintextEditor::eEditorUseAsyncUpdatesMask);
+
+    if (NS_FAILED(rv))
+      return rv;
+
+    // Now call SetValue() which will make the necessary editor calls to set
+    // the default value.  Make sure to turn off undo before setting the default
+    // value, and turn it back on afterwards. This will make sure we can't undo
+    // past the default value.
+
+    rv = mEditor->EnableUndo(PR_FALSE);
+
+    if (NS_FAILED(rv))
+      return rv;
+
+    SetValue(defaultValue);
+
+    rv = mEditor->EnableUndo(PR_TRUE);
+    NS_ASSERTION(NS_SUCCEEDED(rv),"Transaction Manager must have failed");
+
+    // Now restore the original editor flags.
+    rv = mEditor->SetFlags(editorFlags);
+
     // By default the placeholder is shown,
     // we should hide it if the default value is not empty.
     nsWeakFrame weakFrame(this);
     HidePlaceholder();
     NS_ENSURE_STATE(weakFrame.IsAlive());
+
+    if (NS_FAILED(rv))
+      return rv;
   }
 
   nsCOMPtr<nsITransactionManager> transMgr;
   mEditor->GetTransactionManager(getter_AddRefs(transMgr));
   NS_ENSURE_TRUE(transMgr, NS_ERROR_FAILURE);
 
   transMgr->SetMaxTransactionCount(DEFAULT_UNDO_CAP);
 
@@ -1604,17 +1566,17 @@ nsTextControlFrame::EnsureEditorInitiali
   return NS_OK;
 }
 
 nsresult
 nsTextControlFrame::CreateAnonymousContent(nsTArray<nsIContent*>& aElements)
 {
   mState |= NS_FRAME_INDEPENDENT_SELECTION;
 
-  nsIPresShell *shell = PresContext()->GetPresShell();
+  nsIPresShell* shell = PresContext()->GetPresShell();
   if (!shell)
     return NS_ERROR_FAILURE;
 
   nsIDocument *doc = shell->GetDocument();
   if (!doc)
     return NS_ERROR_FAILURE;
 
   // Now create a DIV and add it to the anonymous content child list.
@@ -1652,23 +1614,16 @@ nsTextControlFrame::CreateAnonymousConte
   }
   rv = mValueDiv->SetAttr(kNameSpaceID_None, nsGkAtoms::_class,
                           classValue, PR_FALSE);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!aElements.AppendElement(mValueDiv))
     return NS_ERROR_OUT_OF_MEMORY;
 
-  // Now create the placeholder anonymous content
-  rv = CreatePlaceholderDiv(aElements, doc->NodeInfoManager());
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  rv = UpdateValueDisplay(PR_FALSE);
-  NS_ENSURE_SUCCESS(rv, rv);
-
   // Create selection
 
   mFrameSel = do_CreateInstance(kFrameSelectionCID, &rv);
   if (NS_FAILED(rv))
     return rv;
 
   // Create a SelectionController
 
@@ -1699,26 +1654,27 @@ nsTextControlFrame::CreateAnonymousConte
         selPriv->AddSelectionListener(listener);
       }
     }
 
     selPriv->AddSelectionListener(static_cast<nsISelectionListener*>
                                              (mTextListener));
   }
 
-  if (!IsSingleLineTextControl()) {
-    // textareas are eagerly initialized
-    NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(),
-                 "Someone forgot a script blocker?");
-
-    if (!nsContentUtils::AddScriptRunner(new EditorInitializer(this))) {
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
+  NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(),
+               "Someone forgot a script blocker?");
+
+  if (!nsContentUtils::AddScriptRunner(new EditorInitializer(this))) {
+    return NS_ERROR_OUT_OF_MEMORY;
   }
 
+  // Now create the placeholder anonymous content
+  rv = CreatePlaceholderDiv(aElements, doc->NodeInfoManager());
+  NS_ENSURE_SUCCESS(rv, rv);
+
   return NS_OK;
 }
 
 void
 nsTextControlFrame::AppendAnonymousContentTo(nsBaseContentList& aElements)
 {
   aElements.MaybeAppendElement(mValueDiv);
   aElements.MaybeAppendElement(mPlaceholderDiv);
@@ -1973,40 +1929,36 @@ nsresult nsTextControlFrame::SetFormProp
       //      of select all which merely builds a range that selects
       //      all of the content and adds that to the selection.
 
       SelectAllOrCollapseToEndOfText(PR_TRUE);
     }
     mIsProcessing = PR_FALSE;
   }
   return NS_OK;
-}
+}      
 
 nsresult
 nsTextControlFrame::GetFormProperty(nsIAtom* aName, nsAString& aValue) const
 {
   // Return the value of the property from the widget it is not null.
   // If widget is null, assume the widget is GFX-rendered and return a member variable instead.
 
   if (nsGkAtoms::value == aName) {
     GetValue(aValue, PR_FALSE);
   }
   return NS_OK;
-}
+}  
 
 
 
 NS_IMETHODIMP
 nsTextControlFrame::GetEditor(nsIEditor **aEditor)
 {
   NS_ENSURE_ARG_POINTER(aEditor);
-
-  nsresult rv = EnsureEditorInitialized();
-  NS_ENSURE_SUCCESS(rv, rv);
-
   *aEditor = mEditor;
   NS_IF_ADDREF(*aEditor);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsTextControlFrame::OwnsValue(PRBool* aOwnsValue)
 {
@@ -2132,60 +2084,57 @@ nsTextControlFrame::SetSelectionEndPoint
   }
 
   return SetSelectionInternal(startNode, startOffset, endNode, endOffset);
 }
 
 NS_IMETHODIMP
 nsTextControlFrame::SetSelectionRange(PRInt32 aSelStart, PRInt32 aSelEnd)
 {
-  nsresult rv = EnsureEditorInitialized();
-  NS_ENSURE_SUCCESS(rv, rv);
-
+  NS_ENSURE_TRUE(mEditor, NS_ERROR_NOT_INITIALIZED);
+  
   if (aSelStart > aSelEnd) {
     // Simulate what we'd see SetSelectionStart() was called, followed
     // by a SetSelectionEnd().
 
     aSelStart   = aSelEnd;
   }
 
   return SetSelectionEndPoints(aSelStart, aSelEnd);
 }
 
 
 NS_IMETHODIMP
 nsTextControlFrame::SetSelectionStart(PRInt32 aSelectionStart)
 {
-  nsresult rv = EnsureEditorInitialized();
-  NS_ENSURE_SUCCESS(rv, rv);
+  NS_ENSURE_TRUE(mEditor, NS_ERROR_NOT_INITIALIZED);
 
   PRInt32 selStart = 0, selEnd = 0; 
 
-  rv = GetSelectionRange(&selStart, &selEnd);
+  nsresult rv = GetSelectionRange(&selStart, &selEnd);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (aSelectionStart > selEnd) {
     // Collapse to the new start point.
     selEnd = aSelectionStart; 
   }
 
   selStart = aSelectionStart;
   
   return SetSelectionEndPoints(selStart, selEnd);
 }
 
 NS_IMETHODIMP
 nsTextControlFrame::SetSelectionEnd(PRInt32 aSelectionEnd)
 {
-  nsresult rv = EnsureEditorInitialized();
-  NS_ENSURE_SUCCESS(rv, rv);
-
+  NS_ENSURE_TRUE(mEditor, NS_ERROR_NOT_INITIALIZED);
+  
   PRInt32 selStart = 0, selEnd = 0; 
 
-  rv = GetSelectionRange(&selStart, &selEnd);
+  nsresult rv = GetSelectionRange(&selStart, &selEnd);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (aSelectionEnd < selStart) {
     // Collapse to the new end point.
     selStart = aSelectionEnd; 
   }
 
   selEnd = aSelectionEnd;
@@ -2197,28 +2146,25 @@ nsresult
 nsTextControlFrame::DOMPointToOffset(nsIDOMNode* aNode,
                                      PRInt32 aNodeOffset,
                                      PRInt32* aResult)
 {
   NS_ENSURE_ARG_POINTER(aNode && aResult);
 
   *aResult = 0;
 
-  nsresult rv = EnsureEditorInitialized();
-  NS_ENSURE_SUCCESS(rv, rv);
-
   nsCOMPtr<nsIDOMElement> rootElement;
   mEditor->GetRootElement(getter_AddRefs(rootElement));
   nsCOMPtr<nsIDOMNode> rootNode(do_QueryInterface(rootElement));
 
   NS_ENSURE_TRUE(rootNode, NS_ERROR_FAILURE);
 
   nsCOMPtr<nsIDOMNodeList> nodeList;
 
-  rv = rootNode->GetChildNodes(getter_AddRefs(nodeList));
+  nsresult rv = rootNode->GetChildNodes(getter_AddRefs(nodeList));
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ENSURE_TRUE(nodeList, NS_ERROR_FAILURE);
 
   PRUint32 length = 0;
   rv = nodeList->GetLength(&length);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!length || aNodeOffset < 0)
@@ -2277,28 +2223,25 @@ nsTextControlFrame::OffsetToDOMPoint(PRI
                                      nsIDOMNode** aResult,
                                      PRInt32* aPosition)
 {
   NS_ENSURE_ARG_POINTER(aResult && aPosition);
 
   *aResult = nsnull;
   *aPosition = 0;
 
-  nsresult rv = EnsureEditorInitialized();
-  NS_ENSURE_SUCCESS(rv, rv);
-
   nsCOMPtr<nsIDOMElement> rootElement;
   mEditor->GetRootElement(getter_AddRefs(rootElement));
   nsCOMPtr<nsIDOMNode> rootNode(do_QueryInterface(rootElement));
 
   NS_ENSURE_TRUE(rootNode, NS_ERROR_FAILURE);
 
   nsCOMPtr<nsIDOMNodeList> nodeList;
 
-  rv = rootNode->GetChildNodes(getter_AddRefs(nodeList));
+  nsresult rv = rootNode->GetChildNodes(getter_AddRefs(nodeList));
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ENSURE_TRUE(nodeList, NS_ERROR_FAILURE);
 
   PRUint32 length = 0;
 
   rv = nodeList->GetLength(&length);
   NS_ENSURE_SUCCESS(rv, rv);
 
@@ -2368,24 +2311,23 @@ nsTextControlFrame::OffsetToDOMPoint(PRI
 
   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);
+  NS_ENSURE_TRUE(mEditor, NS_ERROR_NOT_INITIALIZED);
 
   *aSelectionStart = 0;
   *aSelectionEnd = 0;
 
   nsCOMPtr<nsISelection> selection;
-  rv = mSelCon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(selection));  
+  nsresult rv = mSelCon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(selection));  
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
 
   PRInt32 numRanges = 0;
   selection->GetRangeCount(&numRanges);
 
   if (numRanges < 1)
     return NS_OK;
@@ -2437,25 +2379,16 @@ nsTextControlFrame::GetOwnedSelectionCon
 /////END INTERFACE IMPLEMENTATIONS
 
 ////NSIFRAME
 NS_IMETHODIMP
 nsTextControlFrame::AttributeChanged(PRInt32         aNameSpaceID,
                                      nsIAtom*        aAttribute,
                                      PRInt32         aModType)
 {
-  // First, check for the placeholder attribute, because it doesn't
-  // depend on the editor being present.
-  if (nsGkAtoms::placeholder == aAttribute)
-  {
-    nsWeakFrame weakFrame(this);
-    UpdatePlaceholderText(PR_TRUE);
-    NS_ENSURE_STATE(weakFrame.IsAlive());
-  }
-
   if (!mEditor || !mSelCon) 
     return nsBoxFrame::AttributeChanged(aNameSpaceID, aAttribute, aModType);;
 
   nsresult rv = NS_OK;
 
   if (nsGkAtoms::maxlength == aAttribute) 
   {
     PRInt32 maxLength;
@@ -2486,17 +2419,17 @@ nsTextControlFrame::AttributeChanged(PRI
         mSelCon->SetCaretEnabled(PR_FALSE);
     }
     else 
     { // unset readonly
       flags &= ~(nsIPlaintextEditor::eEditorReadonlyMask);
       if (!(flags & nsIPlaintextEditor::eEditorDisabledMask) &&
           IsFocusedContent(mContent))
         mSelCon->SetCaretEnabled(PR_TRUE);
-    }
+    }    
     mEditor->SetFlags(flags);
   }
   else if (nsGkAtoms::disabled == aAttribute) 
   {
     PRUint32 flags;
     mEditor->GetFlags(&flags);
     if (AttributeExists(nsGkAtoms::disabled))
     { // set disabled
@@ -2504,21 +2437,24 @@ nsTextControlFrame::AttributeChanged(PRI
       mSelCon->SetDisplaySelection(nsISelectionController::SELECTION_OFF);
       if (IsFocusedContent(mContent))
         mSelCon->SetCaretEnabled(PR_FALSE);
     }
     else 
     { // unset disabled
       flags &= ~(nsIPlaintextEditor::eEditorDisabledMask);
       mSelCon->SetDisplaySelection(nsISelectionController::SELECTION_HIDDEN);
-    }
+    }    
     mEditor->SetFlags(flags);
   }
-  else if (!mUseEditor && nsGkAtoms::value == aAttribute) {
-    UpdateValueDisplay(PR_TRUE);
+  else if (nsGkAtoms::placeholder == aAttribute)
+  {
+    nsWeakFrame weakFrame(this);
+    UpdatePlaceholderText(PR_TRUE);
+    NS_ENSURE_STATE(weakFrame.IsAlive());
   }
   // Allow the base class to handle common attributes supported
   // by all form elements... 
   else {
     rv = nsBoxFrame::AttributeChanged(aNameSpaceID, aAttribute, aModType);
   }
 
   return rv;
@@ -2527,47 +2463,53 @@ nsTextControlFrame::AttributeChanged(PRI
 
 nsresult
 nsTextControlFrame::GetText(nsString& aText)
 {
   nsresult rv = NS_OK;
   if (IsSingleLineTextControl()) {
     // If we're going to remove newlines anyway, ignore the wrap property
     GetValue(aText, PR_TRUE);
-    nsContentUtils::RemoveNewlines(aText);
+    RemoveNewlines(aText);
   } else {
     nsCOMPtr<nsIDOMHTMLTextAreaElement> textArea = do_QueryInterface(mContent);
     if (textArea) {
       rv = textArea->GetValue(aText);
     }
   }
   return rv;
 }
 
 
 nsresult
 nsTextControlFrame::GetPhonetic(nsAString& aPhonetic)
 {
   aPhonetic.Truncate(0); 
-
-  nsresult rv = EnsureEditorInitialized();
-  NS_ENSURE_SUCCESS(rv, rv);
-
+  if (!mEditor)
+    return NS_ERROR_NOT_INITIALIZED;
   nsCOMPtr<nsIEditorIMESupport> imeSupport = do_QueryInterface(mEditor);
   if (imeSupport) {
     nsCOMPtr<nsIPhonetic> phonetic = do_QueryInterface(imeSupport);
     if (phonetic)
       phonetic->GetPhonetic(aPhonetic);
   }
   return NS_OK;
 }
 
 ///END NSIFRAME OVERLOADS
 /////BEGIN PROTECTED METHODS
 
+void nsTextControlFrame::RemoveNewlines(nsString &aString)
+{
+  // strip CR/LF and null
+  static const char badChars[] = {10, 13, 0};
+  aString.StripChars(badChars);
+}
+
+
 PRBool
 nsTextControlFrame::GetMaxLength(PRInt32* aSize)
 {
   *aSize = -1;
 
   nsGenericHTMLElement *content = nsGenericHTMLElement::FromContent(mContent);
   if (content) {
     const nsAttrValue* attr = content->GetParsedAttr(nsGkAtoms::maxlength);
@@ -2729,17 +2671,19 @@ nsTextControlFrame::SetValue(const nsASt
     // this is necessary to avoid infinite recursion
     if (!currentValue.Equals(aValue))
     {
       // \r is an illegal character in the dom, but people use them,
       // so convert windows and mac platform linebreaks to \n:
       // Unfortunately aValue is declared const, so we have to copy
       // in order to do this substitution.
       nsString newValue(aValue);
-      nsContentUtils::PlatformToDOMLineBreaks(newValue);
+      if (aValue.FindChar(PRUnichar('\r')) != -1) {
+        ::PlatformToDOMLineBreaks(newValue);
+      }
 
       nsCOMPtr<nsIDOMDocument> domDoc;
       editor->GetDocument(getter_AddRefs(domDoc));
       NS_ENSURE_STATE(domDoc);
 
       PRBool outerTransaction;
       // Time to mess with our security context... See comments in GetValue()
       // for why this is needed.  Note that we have to do this up here, because
@@ -2844,22 +2788,16 @@ nsTextControlFrame::SetValue(const nsASt
   else
   {
     // Otherwise set the value in content.
     nsCOMPtr<nsITextControlElement> textControl = do_QueryInterface(mContent);
     if (textControl)
     {
       textControl->TakeTextFrameValue(aValue);
     }
-    // The only time mEditor is non-null but mUseEditor is false is when the
-    // frame is being torn down.  If that's what's going on, don't bother with
-    // updating the display.
-    if (!mEditor) {
-      UpdateValueDisplay(PR_TRUE, PR_FALSE, &aValue);
-    }
   }
   return NS_OK;
 }
 
 
 NS_IMETHODIMP
 nsTextControlFrame::SetInitialChildList(nsIAtom*        aListName,
                                         nsFrameList&    aChildList)
@@ -2916,125 +2854,16 @@ nsTextControlFrame::SetValueChanged(PRBo
   }
 
   nsCOMPtr<nsITextControlElement> elem = do_QueryInterface(mContent);
   if (elem) {
     elem->SetValueChanged(aValueChanged);
   }
 }
 
-
-nsresult
-nsTextControlFrame::UpdateValueDisplay(PRBool aNotify,
-                                       PRBool aBeforeEditorInit,
-                                       const nsAString *aValue)
-{
-  if (!IsSingleLineTextControl()) // textareas don't use this
-    return NS_OK;
-
-  NS_PRECONDITION(mValueDiv, "Must have a div content\n");
-  NS_PRECONDITION(!mUseEditor,
-                  "Do not call this after editor has been initialized");
-  NS_ASSERTION(mValueDiv->GetChildCount() <= 1,
-               "Cannot have more than one child node");
-  NS_ASSERTION(mPlaceholderDiv, "A placeholder div must exist");
-
-  enum {
-    NO_NODE,
-    TXT_NODE,
-    BR_NODE
-  } childNodeType = NO_NODE;
-  nsIContent* childNode = mValueDiv->GetChildAt(0);
-#ifdef NS_DEBUG
-  if (aBeforeEditorInit)
-    NS_ASSERTION(childNode, "A child node should exist before initializing the editor");
-#endif
-
-  if (childNode) {
-    if (childNode->IsNodeOfType(nsINode::eELEMENT))
-      childNodeType = BR_NODE;
-    else if (childNode->IsNodeOfType(nsINode::eTEXT))
-      childNodeType = TXT_NODE;
-#ifdef NS_DEBUG
-    else
-      NS_NOTREACHED("Invalid child node found");
-#endif
-  }
-
-  // Get the current value of the textfield from the content.
-  nsAutoString value;
-  if (aValue) {
-    value = *aValue;
-  } else {
-    GetValue(value, PR_TRUE);
-  }
-
-  // Update the display of the placeholder value if needed.
-  {
-    nsWeakFrame weakFrame(this);
-    if (value.IsEmpty()) {
-      ShowPlaceholder();
-    } else {
-      HidePlaceholder();
-    }
-    NS_ENSURE_STATE(weakFrame.IsAlive());
-  }
-
-  if (aBeforeEditorInit && value.IsEmpty()) {
-    mValueDiv->RemoveChildAt(0, PR_TRUE, PR_FALSE);
-    return NS_OK;
-  }
-
-  nsTextEditRules::HandleNewLines(value, -1);
-  nsresult rv;
-  if (value.IsEmpty()) {
-    if (childNodeType != BR_NODE) {
-      nsCOMPtr<nsINodeInfo> nodeInfo;
-      nodeInfo = mContent->NodeInfo()
-                         ->NodeInfoManager()
-                         ->GetNodeInfo(nsGkAtoms::br, nsnull,
-                                       kNameSpaceID_XHTML);
-      NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
-
-      nsCOMPtr<nsIContent> brNode;
-      rv = NS_NewHTMLElement(getter_AddRefs(brNode), nodeInfo, PR_FALSE);
-      NS_ENSURE_SUCCESS(rv, rv);
-
-      nsCOMPtr<nsIDOMElement> brElement = do_QueryInterface(brNode);
-      NS_ENSURE_TRUE(brElement, NS_ERROR_UNEXPECTED);
-      brElement->SetAttribute(kMOZEditorBogusNodeAttr, kMOZEditorBogusNodeValue);
-
-      mValueDiv->RemoveChildAt(0, aNotify, PR_FALSE);
-      mValueDiv->AppendChildTo(brNode, aNotify);
-    }
-  } else {
-    if (IsPasswordTextControl())
-      nsTextEditRules::FillBufWithPWChars(&value, value.Length());
-
-    // Set up a textnode with our value
-    nsCOMPtr<nsIContent> textNode;
-    if (childNodeType != TXT_NODE) {
-      rv = NS_NewTextNode(getter_AddRefs(textNode),
-                          mContent->NodeInfo()->NodeInfoManager());
-      NS_ENSURE_SUCCESS(rv, rv);
-
-      NS_ASSERTION(textNode, "Must have textcontent!\n");
-
-      mValueDiv->RemoveChildAt(0, aNotify, PR_FALSE);
-      mValueDiv->AppendChildTo(textNode, aNotify);
-    } else {
-      textNode = childNode;
-    }
-
-    textNode->SetText(value, aNotify);
-  }
-  return NS_OK;
-}
-
-
 /* static */ void
 nsTextControlFrame::ShutDown()
 {
   NS_IF_RELEASE(sNativeTextAreaBindings);
   NS_IF_RELEASE(sNativeInputBindings);
 }
 
 nsresult
@@ -3107,17 +2936,17 @@ nsTextControlFrame::SetPlaceholderClass(
 }
 
 nsresult
 nsTextControlFrame::UpdatePlaceholderText(PRBool aNotify)
 {
   nsAutoString placeholderValue;
 
   mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::placeholder, placeholderValue);
-  nsContentUtils::RemoveNewlines(placeholderValue);
+  RemoveNewlines(placeholderValue);
   NS_ASSERTION(mPlaceholderDiv->GetChildAt(0), "placeholder div has no child");
   mPlaceholderDiv->GetChildAt(0)->SetText(placeholderValue, aNotify);
 
   return NS_OK;
 }
 
 NS_IMPL_ISUPPORTS1(nsAnonDivObserver, nsIMutationObserver)
 
--- a/layout/forms/nsTextControlFrame.h
+++ b/layout/forms/nsTextControlFrame.h
@@ -57,17 +57,16 @@ class nsISelectionController;
 class nsTextInputSelectionImpl;
 class nsTextInputListener;
 class nsIDOMCharacterData;
 #ifdef ACCESSIBILITY
 class nsIAccessible;
 #endif
 class nsTextInputSelectionImpl;
 class nsTextControlFrame;
-class EditorInitializerEntryTracker;
 
 class nsAnonDivObserver : public nsStubMutationObserver
 {
 public:
   nsAnonDivObserver(nsTextControlFrame* aTextControl)
   : mTextControl(aTextControl) {}
   NS_DECL_ISUPPORTS
   NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED
@@ -171,23 +170,16 @@ public:
   NS_IMETHOD    SetSelectionRange(PRInt32 aSelectionStart, PRInt32 aSelectionEnd);
   NS_IMETHOD    GetSelectionRange(PRInt32* aSelectionStart, PRInt32* aSelectionEnd);
   virtual nsISelectionController* GetOwnedSelectionController();
   virtual nsFrameSelection* GetOwnedFrameSelection()
     { return mFrameSel; }
 
   nsresult GetPhonetic(nsAString& aPhonetic);
 
-  /**
-   * Ensure mEditor is initialized with the proper flags and the default value.
-   * @throws NS_ERROR_NOT_INITIALIZED if mEditor has not been created
-   * @throws various and sundry other things
-   */
-  virtual nsresult EnsureEditorInitialized();
-
 //==== END NSITEXTCONTROLFRAME
 //==== OVERLOAD of nsIFrame
   virtual nsIAtom* GetType() const;
 
   /** handler for attribute changes to mContent */
   NS_IMETHOD AttributeChanged(PRInt32         aNameSpaceID,
                               nsIAtom*        aAttribute,
                               PRInt32         aModType);
@@ -251,79 +243,84 @@ protected:
       mFrame(aFrame) {}
 
     NS_IMETHOD Run() {
       if (mWeakFrame) {
         nsCOMPtr<nsIPresShell> shell =
           mWeakFrame.GetFrame()->PresContext()->GetPresShell();
         PRBool observes = shell->ObservesNativeAnonMutationsForPrint();
         shell->ObserveNativeAnonMutationsForPrint(PR_TRUE);
-        mFrame->EnsureEditorInitializedInternal();
+        mFrame->DelayedEditorInit();
         shell->ObserveNativeAnonMutationsForPrint(observes);
       }
       return NS_OK;
     }
 
   private:
     nsWeakFrame mWeakFrame;
     nsTextControlFrame* mFrame;
   };
 
+  // Init our editor and then make sure to focus our text input
+  // listener if our content node has focus.
+  void DelayedEditorInit();
+
   nsresult DOMPointToOffset(nsIDOMNode* aNode, PRInt32 aNodeOffset, PRInt32 *aResult);
   nsresult OffsetToDOMPoint(PRInt32 aOffset, nsIDOMNode** aResult, PRInt32* aPosition);
 
   /**
    * Find out whether this control is scrollable (i.e. if it is not a single
    * line text control)
    * @return whether this control is scrollable
    */
   PRBool IsScrollable() const;
-
   /**
-   * Update the textnode under our anonymous div to show the new
-   * value. This should only be called when we have no editor yet.
-   * @throws NS_ERROR_UNEXPECTED if the div has no text content
+   * Initialize mEditor with the proper flags and the default value.
+   * @throws NS_ERROR_NOT_INITIALIZED if mEditor has not been created
+   * @throws various and sundry other things
    */
-  nsresult UpdateValueDisplay(PRBool aNotify,
-                              PRBool aBeforeEditorInit = PR_FALSE,
-                              const nsAString *aValue = nsnull);
-
+  nsresult InitEditor();
+  /**
+   * Strip all \n, \r and nulls from the given string
+   * @param aString the string to remove newlines from [in/out]
+   */
+  void RemoveNewlines(nsString &aString);
   /**
    * Get the maxlength attribute
    * @param aMaxLength the value of the max length attr
    * @returns PR_FALSE if attr not defined
    */
   PRBool GetMaxLength(PRInt32* aMaxLength);
-
   /**
    * Find out whether an attribute exists on the content or not.
    * @param aAtt the attribute to determine the existence of
    * @returns PR_FALSE if it does not exist
    */
   PRBool AttributeExists(nsIAtom *aAtt) const
   { return mContent && mContent->HasAttr(kNameSpaceID_None, aAtt); }
 
   /**
    * We call this when we are being destroyed or removed from the PFM.
    * @param aPresContext the current pres context
    */
   void PreDestroy();
+  /**
+   * Fire the onChange event.
+   */
 
   // Helper methods
   /**
    * Get the cols attribute (if textarea) or a default
    * @return the number of columns to use
    */
   PRInt32 GetCols();
-
   /**
    * Get the column index to wrap at, or -1 if we shouldn't wrap
    */
   PRInt32 GetWrapCols();
-
   /**
    * Get the rows attribute (if textarea) or a default
    * @return the number of rows to use
    */
   PRInt32 GetRows();
 
   // Compute our intrinsic size.  This does not include any borders, paddings,
   // etc.  Just the size of our actual area for the text (and the scrollbars,
@@ -340,42 +337,32 @@ private:
 
   // placeholder methods
   nsresult CreatePlaceholderDiv(nsTArray<nsIContent*>& aElements, nsNodeInfoManager* pNodeInfoManager);
   nsresult ShowPlaceholder();
   nsresult HidePlaceholder();
   nsresult SetPlaceholderClass(PRBool aVisible, PRBool aNotify);
   nsresult UpdatePlaceholderText(PRBool aNotify); 
 
-  // This method performs the actual tasks of initializing the editor.
-  // EnsureEditorInitialized is a wrapper of this method which wraps it with
-  // a weak frame check.
-  virtual nsresult EnsureEditorInitializedInternal();
-
 private:
   nsCOMPtr<nsIContent> mValueDiv;
   nsCOMPtr<nsIContent> mPlaceholderDiv;
 
   nsCOMPtr<nsIEditor> mEditor;
 
   // these packed bools could instead use the high order bits on mState, saving 4 bytes 
   PRPackedBool mUseEditor;
   PRPackedBool mIsProcessing;
   PRPackedBool mNotifyOnInput;//default this to off to stop any notifications until setup is complete
   PRPackedBool mDidPreDestroy; // has PreDestroy been called
   // Calls to SetValue will be treated as user values (i.e. trigger onChange
   // eventually) when mFireChangeEventState==true, this is used by nsFileControlFrame.
   PRPackedBool mFireChangeEventState;
   PRPackedBool mInSecureKeyboardInputMode;
 
-#ifdef DEBUG
-  PRPackedBool mInEditorInitialization;
-  friend class EditorInitializerEntryTracker;
-#endif
-
   nsRefPtr<nsTextInputSelectionImpl> mSelCon;
   nsCOMPtr<nsFrameSelection> mFrameSel;
   nsTextInputListener* mTextListener;
   nsString mFocusedValue;
   nsString mCachedValue; // Caches non-hard-wrapped value on a multiline control.
   nsRefPtr<nsAnonDivObserver> mMutationObserver;
 };
 
--- a/layout/forms/test/test_bug446663.html
+++ b/layout/forms/test/test_bug446663.html
@@ -22,17 +22,16 @@ https://bugzilla.mozilla.org/show_bug.cg
 <script class="testbody" type="text/javascript">
 
 /** Test for Bug 446663 **/
 
 function test_edit_cmds(id) {
   netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
 
   var elm = document.getElementById(id);
-  elm.focus();
   elm.select();
   elm.controllers.getControllerForCommand('cmd_cut')
                          .doCommand('cmd_cut');
   is(elm.value, '', id + " cut");
 
   elm.controllers.getControllerForCommand('cmd_undo')
                          .doCommand('cmd_undo');
   is(elm.value, '123', id + " undo");
--- a/toolkit/content/tests/chrome/test_bug418874.xul
+++ b/toolkit/content/tests/chrome/test_bug418874.xul
@@ -67,39 +67,31 @@
 
   <!-- test code goes here -->
   <script type="application/javascript"><![CDATA[
     SimpleTest.waitForExplicitFinish();
 
     function doTest() {
       var t1 = $("t1");
       var t2 = $("t2");
-      setTextboxValue(t1, "1");
+      t1.value = "1";
       var t1Enabled = {};
       var t1CanUndo = {};
       t1.editor.canUndo(t1Enabled, t1CanUndo);
       is(t1CanUndo.value, true,
          "undo correctly enabled when placeholder was not changed through property");
 
       t2.placeholder = "reallyempty";
-      setTextboxValue(t2, "2");
+      t2.value = "2";
       var t2Enabled = {};
       var t2CanUndo = {};
       t2.editor.canUndo(t2Enabled, t2CanUndo);
       is(t2CanUndo.value, true,
          "undo correctly enabled when placeholder explicitly changed through property");
 
       SimpleTest.finish();
    }
 
-   function setTextboxValue(textbox, value) {
-      textbox.focus();
-      for (var i = 0; i < value.length; ++i) {
-          synthesizeKey(value.charAt(i), {});
-      }
-      textbox.blur();
-   }
-
    SimpleTest.waitForFocus(doTest);
 
   ]]></script>
 
 </window>