Bug 1360154 - Part 2. Add fast path to check whether valus is emtpy. r=masayuki
authorMakoto Kato <m_kato@ga2.so-net.ne.jp>
Thu, 11 May 2017 14:04:18 +0900
changeset 408250 fab114e7628c2349a3d9b503a313efdb254a7181
parent 408249 b508ea40328581196c327d2e515ba0d598c8914e
child 408251 f42fac2bcca869760c75b6456d50a9bba7841131
push id1490
push usermtabara@mozilla.com
push dateMon, 31 Jul 2017 14:08:16 +0000
treeherdermozilla-release@70e32e6bf15e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmasayuki
bugs1360154
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1360154 - Part 2. Add fast path to check whether valus is emtpy. r=masayuki Actually, we use GetValue to check whether value is empty or not for placeholder. But since GetValue uses TextEditor::OutputToString when on editor, it is expensive. Since editor has DocumentIsEmpty method, we should use it for this case. MozReview-Commit-ID: rQX8yjnWQz
dom/html/nsTextEditorState.cpp
dom/html/nsTextEditorState.h
--- a/dom/html/nsTextEditorState.cpp
+++ b/dom/html/nsTextEditorState.cpp
@@ -2677,16 +2677,33 @@ nsTextEditorState::SetValue(const nsAStr
   ValueWasChanged(!!mRootNode);
 
   mTextCtrlElement->OnValueChanged(/* aNotify = */ !!mRootNode,
                                    /* aWasInteractiveUserChange = */ false);
 
   return true;
 }
 
+bool
+nsTextEditorState::HasNonEmptyValue()
+{
+  if (mEditor && mBoundFrame && mEditorInitialized &&
+      !mIsCommittingComposition) {
+    bool empty;
+    nsresult rv = mEditor->GetDocumentIsEmpty(&empty);
+    if (NS_SUCCEEDED(rv)) {
+      return !empty;
+    }
+  }
+
+  nsAutoString value;
+  GetValue(value, true);
+  return !value.IsEmpty();
+}
+
 void
 nsTextEditorState::InitializeKeyboardEventListeners()
 {
   //register key listeners
   nsCOMPtr<EventTarget> target = do_QueryInterface(mTextCtrlElement);
   EventListenerManager* manager = target->GetOrCreateListenerManager();
   if (manager) {
     manager->AddEventListenerByType(mTextListener,
@@ -2760,21 +2777,21 @@ nsTextEditorState::GetPreviewText(nsAStr
   aValue.Truncate();
   text->AppendTo(aValue);
 }
 
 void
 nsTextEditorState::UpdateOverlayTextVisibility(bool aNotify)
 {
   nsAutoString value, previewValue;
-  GetValue(value, true);
+  bool valueIsEmpty = !HasNonEmptyValue();
   GetPreviewText(previewValue);
 
-  mPreviewVisibility = value.IsEmpty() && !previewValue.IsEmpty();
-  mPlaceholderVisibility = value.IsEmpty() && previewValue.IsEmpty();
+  mPreviewVisibility = valueIsEmpty && !previewValue.IsEmpty();
+  mPlaceholderVisibility = valueIsEmpty && previewValue.IsEmpty();
 
   if (mPlaceholderVisibility &&
       !Preferences::GetBool("dom.placeholder.show_on_focus", true)) {
     nsCOMPtr<nsIContent> content = do_QueryInterface(mTextCtrlElement);
     mPlaceholderVisibility = !nsContentUtils::IsFocusedContent(content);
   }
 
   if (mBoundFrame && aNotify) {
--- a/dom/html/nsTextEditorState.h
+++ b/dom/html/nsTextEditorState.h
@@ -176,16 +176,21 @@ public:
     // cached selection offsets), in the case when the value has changed.  If
     // this is not set, the cached selection offsets will simply be clamped to
     // be within the length of the new value.  In either case, if the value has
     // not changed the cursor won't move.
     eSetValue_MoveCursorToEndIfValueChanged = 1 << 3,
   };
   MOZ_MUST_USE bool SetValue(const nsAString& aValue, uint32_t aFlags);
   void GetValue(nsAString& aValue, bool aIgnoreWrap) const;
+  bool HasNonEmptyValue();
+  // The following methods are for textarea element to use whether default
+  // value or not.
+  // XXX We might have to add assertion when it is into editable,
+  // or reconsider fixing bug 597525 to remove these.
   void EmptyValue() { if (mValue) mValue->Truncate(); }
   bool IsEmpty() const { return mValue ? mValue->IsEmpty() : true; }
 
   nsresult CreatePlaceholderNode();
   nsresult CreatePreviewNode();
   mozilla::dom::Element* CreateEmptyDivNode();
 
   mozilla::dom::Element* GetRootNode() {