Bug 1007940 - Improve the performance of editor initialization; r=bzbarsky a=sylvestre
authorEhsan Akhgari <ehsan@mozilla.com>
Fri, 09 May 2014 17:02:29 -0400
changeset 192304 d3ccc8465e4b
parent 192303 70f056b3a700
child 192305 46fdf6041673
push id3565
push usereakhgari@mozilla.com
push date2014-05-17 13:06 +0000
treeherdermozilla-beta@d3ccc8465e4b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbzbarsky, sylvestre
bugs1007940
milestone30.0
Bug 1007940 - Improve the performance of editor initialization; r=bzbarsky a=sylvestre
editor/libeditor/html/nsHTMLEditRules.cpp
editor/libeditor/html/nsHTMLEditRules.h
editor/libeditor/html/nsHTMLEditor.cpp
editor/libeditor/text/nsPlaintextEditor.cpp
editor/libeditor/text/nsTextEditRules.cpp
editor/libeditor/text/nsTextEditRules.h
--- a/editor/libeditor/html/nsHTMLEditRules.cpp
+++ b/editor/libeditor/html/nsHTMLEditRules.cpp
@@ -164,26 +164,35 @@ class nsEditableTextFunctor : public nsB
     nsHTMLEditor* mHTMLEditor;
 };
 
 
 /********************************************************
  *  Constructor/Destructor 
  ********************************************************/
 
-nsHTMLEditRules::nsHTMLEditRules() : 
-mDocChangeRange(nullptr)
-,mListenerEnabled(true)
-,mReturnInEmptyLIKillsList(true)
-,mDidDeleteSelection(false)
-,mDidRangedDelete(false)
-,mRestoreContentEditableCount(false)
-,mUtilRange(nullptr)
-,mJoinOffset(0)
-{
+nsHTMLEditRules::nsHTMLEditRules()
+{
+  InitFields();
+}
+
+void
+nsHTMLEditRules::InitFields()
+{
+  mHTMLEditor = nullptr;
+  mDocChangeRange = nullptr;
+  mListenerEnabled = true;
+  mReturnInEmptyLIKillsList = true;
+  mDidDeleteSelection = false;
+  mDidRangedDelete = false;
+  mRestoreContentEditableCount = false;
+  mUtilRange = nullptr;
+  mJoinOffset = 0;
+  mNewBlock = nullptr;
+  mRangeItem = new nsRangeStore();
   // populate mCachedStyles
   mCachedStyles[0] = StyleCache(nsEditProperty::b, EmptyString(), EmptyString());
   mCachedStyles[1] = StyleCache(nsEditProperty::i, EmptyString(), EmptyString());
   mCachedStyles[2] = StyleCache(nsEditProperty::u, EmptyString(), EmptyString());
   mCachedStyles[3] = StyleCache(nsEditProperty::font, NS_LITERAL_STRING("face"), EmptyString());
   mCachedStyles[4] = StyleCache(nsEditProperty::font, NS_LITERAL_STRING("size"), EmptyString());
   mCachedStyles[5] = StyleCache(nsEditProperty::font, NS_LITERAL_STRING("color"), EmptyString());
   mCachedStyles[6] = StyleCache(nsEditProperty::tt, EmptyString(), EmptyString());
@@ -194,17 +203,16 @@ mDocChangeRange(nullptr)
   mCachedStyles[11] = StyleCache(nsEditProperty::samp, EmptyString(), EmptyString());
   mCachedStyles[12] = StyleCache(nsEditProperty::var, EmptyString(), EmptyString());
   mCachedStyles[13] = StyleCache(nsEditProperty::cite, EmptyString(), EmptyString());
   mCachedStyles[14] = StyleCache(nsEditProperty::abbr, EmptyString(), EmptyString());
   mCachedStyles[15] = StyleCache(nsEditProperty::acronym, EmptyString(), EmptyString());
   mCachedStyles[16] = StyleCache(nsEditProperty::cssBackgroundColor, EmptyString(), EmptyString());
   mCachedStyles[17] = StyleCache(nsEditProperty::sub, EmptyString(), EmptyString());
   mCachedStyles[18] = StyleCache(nsEditProperty::sup, EmptyString(), EmptyString());
-  mRangeItem = new nsRangeStore();
 }
 
 nsHTMLEditRules::~nsHTMLEditRules()
 {
   // remove ourselves as a listener to edit actions
   // In some cases, we have already been removed by 
   // ~nsHTMLEditor, in which case we will get a null pointer here
   // which we ignore.  But this allows us to add the ability to
@@ -224,19 +232,21 @@ NS_IMPL_QUERY_INTERFACE_INHERITED1(nsHTM
 
 /********************************************************
  *  Public methods 
  ********************************************************/
 
 NS_IMETHODIMP
 nsHTMLEditRules::Init(nsPlaintextEditor *aEditor)
 {
+  InitFields();
+
   mHTMLEditor = static_cast<nsHTMLEditor*>(aEditor);
   nsresult res;
-  
+
   // call through to base class Init 
   res = nsTextEditRules::Init(aEditor);
   NS_ENSURE_SUCCESS(res, res);
 
   // cache any prefs we care about
   static const char kPrefName[] =
     "editor.html.typing.returnInEmptyListItemClosesList";
   nsAdoptingCString returnInEmptyLIKillsList =
--- a/editor/libeditor/html/nsHTMLEditRules.h
+++ b/editor/libeditor/html/nsHTMLEditRules.h
@@ -119,16 +119,18 @@ protected:
   };
 
   enum BRLocation
   {
     kBeforeBlock,
     kBlockEnd
   };
 
+  void InitFields();
+
   // nsHTMLEditRules implementation methods
   nsresult WillInsert(nsISelection *aSelection, bool *aCancel);
   nsresult WillInsertText(  EditAction aAction,
                             mozilla::Selection* aSelection,
                             bool            *aCancel,
                             bool            *aHandled,
                             const nsAString *inString,
                             nsAString       *outString,
--- a/editor/libeditor/html/nsHTMLEditor.cpp
+++ b/editor/libeditor/html/nsHTMLEditor.cpp
@@ -485,19 +485,20 @@ nsHTMLEditor::SetFlags(uint32_t aFlags)
   mCSSAware = !NoCSS() && !IsMailEditor();
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHTMLEditor::InitRules()
 {
-  MOZ_ASSERT(!mRules);
-  // instantiate the rules for the html editor
-  mRules = new nsHTMLEditRules();
+  if (!mRules) {
+    // instantiate the rules for the html editor
+    mRules = new nsHTMLEditRules();
+  }
   return mRules->Init(static_cast<nsPlaintextEditor*>(this));
 }
 
 NS_IMETHODIMP
 nsHTMLEditor::BeginningOfDocument()
 {
   if (!mDocWeak) { return NS_ERROR_NOT_INITIALIZED; }
 
--- a/editor/libeditor/text/nsPlaintextEditor.cpp
+++ b/editor/libeditor/text/nsPlaintextEditor.cpp
@@ -118,17 +118,16 @@ NS_IMETHODIMP nsPlaintextEditor::Init(ns
                                       uint32_t aFlags)
 {
   NS_PRECONDITION(aDoc, "bad arg");
   NS_ENSURE_TRUE(aDoc, NS_ERROR_NULL_POINTER);
   
   nsresult res = NS_OK, rulesRes = NS_OK;
   if (mRules) {
     mRules->DetachEditor();
-    mRules = nullptr;
   }
   
   if (1)
   {
     // block to scope nsAutoEditInitRulesTrigger
     nsAutoEditInitRulesTrigger rulesTrigger(this, rulesRes);
   
     // Init the base editor
@@ -311,19 +310,20 @@ nsPlaintextEditor::UpdateMetaCharset(nsI
                                   NS_ConvertASCIItoUTF16(aCharacterSet));
     return NS_SUCCEEDED(rv);
   }
   return false;
 }
 
 NS_IMETHODIMP nsPlaintextEditor::InitRules()
 {
-  MOZ_ASSERT(!mRules);
-  // instantiate the rules for this text editor
-  mRules = new nsTextEditRules();
+  if (!mRules) {
+    // instantiate the rules for this text editor
+    mRules = new nsTextEditRules();
+  }
   return mRules->Init(this);
 }
 
 
 NS_IMETHODIMP
 nsPlaintextEditor::GetIsDocumentEditable(bool *aIsDocumentEditable)
 {
   NS_ENSURE_ARG_POINTER(aIsDocumentEditable);
--- a/editor/libeditor/text/nsTextEditRules.cpp
+++ b/editor/libeditor/text/nsTextEditRules.cpp
@@ -52,27 +52,38 @@ using namespace mozilla;
   };
 
 
 /********************************************************
  *  Constructor/Destructor 
  ********************************************************/
 
 nsTextEditRules::nsTextEditRules()
-: mEditor(nullptr)
-, mPasswordText()
-, mPasswordIMEText()
-, mPasswordIMEIndex(0)
-, mActionNesting(0)
-, mLockRulesSniffing(false)
-, mDidExplicitlySetInterline(false)
-, mTheAction(EditAction::none)
-, mLastStart(0)
-, mLastLength(0)
 {
+  InitFields();
+}
+
+void
+nsTextEditRules::InitFields()
+{
+  mEditor = nullptr;
+  mPasswordText.Truncate();
+  mPasswordIMEText.Truncate();
+  mPasswordIMEIndex = 0;
+  mBogusNode = nullptr;
+  mCachedSelectionNode = nullptr;
+  mCachedSelectionOffset = 0;
+  mActionNesting = 0;
+  mLockRulesSniffing = false;
+  mDidExplicitlySetInterline = false;
+  mDeleteBidiImmediately = false;
+  mTheAction = EditAction::none;
+  mTimer = nullptr;
+  mLastStart = 0;
+  mLastLength = 0;
 }
 
 nsTextEditRules::~nsTextEditRules()
 {
    // do NOT delete mEditor here.  We do not hold a ref count to mEditor.  mEditor owns our lifespan.
 
   if (mTimer)
     mTimer->Cancel();
@@ -97,16 +108,18 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(nsTextE
  *  Public methods 
  ********************************************************/
 
 NS_IMETHODIMP
 nsTextEditRules::Init(nsPlaintextEditor *aEditor)
 {
   if (!aEditor) { return NS_ERROR_NULL_POINTER; }
 
+  InitFields();
+
   mEditor = aEditor;  // we hold a non-refcounted reference back to our editor
   nsCOMPtr<nsISelection> selection;
   mEditor->GetSelection(getter_AddRefs(selection));
   NS_WARN_IF_FALSE(selection, "editor cannot get selection");
 
   // Put in a magic br if needed. This method handles null selection,
   // which should never happen anyway
   nsresult res = CreateBogusNodeIfNeeded(selection);
--- a/editor/libeditor/text/nsTextEditRules.h
+++ b/editor/libeditor/text/nsTextEditRules.h
@@ -94,16 +94,18 @@ public:
    *        aOutString will contain aLength password characters.
    * @param aLength the number of password characters that aOutString should
    *        contain.
    */
   static void FillBufWithPWChars(nsAString *aOutString, int32_t aLength);
 
 protected:
 
+  void InitFields();
+
   // nsTextEditRules implementation methods
   nsresult WillInsertText(  EditAction aAction,
                             mozilla::Selection* aSelection,
                             bool            *aCancel,
                             bool            *aHandled,
                             const nsAString *inString,
                             nsAString       *outString,
                             int32_t          aMaxLength);