Bug 1340483 - Part 2. Expose chrome-only previewValue attribute. r=heycam, baku draft
authorRay Lin <ralin@mozilla.com>
Tue, 21 Mar 2017 00:08:01 +0800
changeset 564425 6f0ad39d8e31ac0e680c5d3ee9b2ea705da0e94e
parent 564424 37b514edef7dfbe69efe244818bdc1976d925de1
child 564426 253f102b30031e2ad86fd2578297ff3ce2b4f5c0
push id54590
push userbmo:ralin@mozilla.com
push dateTue, 18 Apr 2017 14:37:59 +0000
reviewersheycam, baku
bugs1340483
milestone55.0a1
Bug 1340483 - Part 2. Expose chrome-only previewValue attribute. r=heycam, baku MozReview-Commit-ID: BCu0vXVm6wj
dom/html/HTMLInputElement.cpp
dom/html/HTMLInputElement.h
dom/html/HTMLTextAreaElement.cpp
dom/html/HTMLTextAreaElement.h
dom/html/nsITextControlElement.h
dom/html/nsTextEditorState.cpp
dom/html/nsTextEditorState.h
dom/webidl/HTMLInputElement.webidl
dom/webidl/HTMLTextAreaElement.webidl
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -2907,16 +2907,34 @@ HTMLInputElement::GetPreviewNode()
 {
   nsTextEditorState* state = GetEditorState();
   if (state) {
     return state->GetPreviewNode();
   }
   return nullptr;
 }
 
+NS_IMETHODIMP_(void)
+HTMLInputElement::SetPreviewValue(const nsAString& aValue)
+{
+  nsTextEditorState* state = GetEditorState();
+  if (state) {
+    state->SetPreviewText(aValue, true);
+  }
+}
+
+NS_IMETHODIMP_(void)
+HTMLInputElement::GetPreviewValue(nsAString& aValue)
+{
+  nsTextEditorState* state = GetEditorState();
+  if (state) {
+    state->GetPreviewText(aValue);
+  }
+}
+
 void
 HTMLInputElement::GetDisplayFileName(nsAString& aValue) const
 {
   if (OwnerDoc()->IsStaticDocument()) {
     aValue = mStaticDocFileList;
     return;
   }
 
--- a/dom/html/HTMLInputElement.h
+++ b/dom/html/HTMLInputElement.h
@@ -232,16 +232,18 @@ public:
   NS_IMETHOD_(void) UnbindFromFrame(nsTextControlFrame* aFrame) override;
   NS_IMETHOD CreateEditor() override;
   NS_IMETHOD_(Element*) GetRootEditorNode() override;
   NS_IMETHOD_(Element*) CreatePlaceholderNode() override;
   NS_IMETHOD_(Element*) GetPlaceholderNode() override;
   NS_IMETHOD_(Element*) CreatePreviewNode() override;
   NS_IMETHOD_(Element*) GetPreviewNode() override;
   NS_IMETHOD_(void) UpdatePlaceholderVisibility(bool aNotify) override;
+  NS_IMETHOD_(void) SetPreviewValue(const nsAString& aValue) override;
+  NS_IMETHOD_(void) GetPreviewValue(nsAString& aValue) override;
   NS_IMETHOD_(bool) GetPlaceholderVisibility() override;
   NS_IMETHOD_(void) InitializeKeyboardEventListeners() override;
   NS_IMETHOD_(void) OnValueChanged(bool aNotify, bool aWasInteractiveUserChange) override;
   virtual void GetValueFromSetRangeText(nsAString& aValue) override;
   virtual nsresult SetValueFromSetRangeText(const nsAString& aValue) override;
   NS_IMETHOD_(bool) HasCachedSelection() override;
 
   // Methods for nsFormFillController so it can do selection operations on input
--- a/dom/html/HTMLTextAreaElement.cpp
+++ b/dom/html/HTMLTextAreaElement.cpp
@@ -328,16 +328,27 @@ HTMLTextAreaElement::CreatePreviewNode()
 }
 
 NS_IMETHODIMP_(Element*)
 HTMLTextAreaElement::GetPreviewNode()
 {
   return mState.GetPreviewNode();
 }
 
+NS_IMETHODIMP_(void)
+HTMLTextAreaElement::SetPreviewValue(const nsAString& aValue)
+{
+  mState.SetPreviewText(aValue, true);
+}
+
+NS_IMETHODIMP_(void)
+HTMLTextAreaElement::GetPreviewValue(nsAString& aValue)
+{
+  mState.GetPreviewText(aValue);
+}
 
 nsresult
 HTMLTextAreaElement::SetValueInternal(const nsAString& aValue,
                                       uint32_t aFlags)
 {
   // Need to set the value changed flag here if our value has in fact changed
   // (i.e. if eSetValue_Notify is in aFlags), so that
   // nsTextControlFrame::UpdateValueDisplay retrieves the correct value if
--- a/dom/html/HTMLTextAreaElement.h
+++ b/dom/html/HTMLTextAreaElement.h
@@ -102,16 +102,18 @@ public:
   NS_IMETHOD CreateEditor() override;
   NS_IMETHOD_(Element*) GetRootEditorNode() override;
   NS_IMETHOD_(Element*) CreatePlaceholderNode() override;
   NS_IMETHOD_(Element*) GetPlaceholderNode() override;
   NS_IMETHOD_(Element*) CreatePreviewNode() override;
   NS_IMETHOD_(Element*) GetPreviewNode() override;
   NS_IMETHOD_(void) UpdatePlaceholderVisibility(bool aNotify) override;
   NS_IMETHOD_(bool) GetPlaceholderVisibility() override;
+  NS_IMETHOD_(void) SetPreviewValue(const nsAString& aValue) override;
+  NS_IMETHOD_(void) GetPreviewValue(nsAString& aValue) override;
   NS_IMETHOD_(void) InitializeKeyboardEventListeners() override;
   NS_IMETHOD_(void) OnValueChanged(bool aNotify, bool aWasInteractiveUserChange) override;
   virtual void GetValueFromSetRangeText(nsAString& aValue) override;
   virtual nsresult SetValueFromSetRangeText(const nsAString& aValue) override;
   NS_IMETHOD_(bool) HasCachedSelection() override;
 
 
   // nsIContent
--- a/dom/html/nsITextControlElement.h
+++ b/dom/html/nsITextControlElement.h
@@ -160,16 +160,26 @@ public:
   NS_IMETHOD_(mozilla::dom::Element*) CreatePreviewNode() = 0;
 
   /**
    * Get the preview anonymous node for the text control.
    */
   NS_IMETHOD_(mozilla::dom::Element*) GetPreviewNode() = 0;
 
   /**
+   * Update preview value for the text control.
+   */
+  NS_IMETHOD_(void) SetPreviewValue(const nsAString& aValue) = 0;
+
+  /**
+   * Get the current preview value for text control.
+   */
+  NS_IMETHOD_(void) GetPreviewValue(nsAString& aValue) = 0;
+
+  /**
    * Initialize the keyboard event listeners.
    */
   NS_IMETHOD_(void) InitializeKeyboardEventListeners() = 0;
 
   /**
    * Update the placeholder visibility based on the element's state.
    */
   NS_IMETHOD_(void) UpdatePlaceholderVisibility(bool aNotify) = 0;
--- a/dom/html/nsTextEditorState.cpp
+++ b/dom/html/nsTextEditorState.cpp
@@ -2718,16 +2718,47 @@ nsTextEditorState::UpdatePlaceholderText
   nsCOMPtr<nsIContent> content = do_QueryInterface(mTextCtrlElement);
   content->GetAttr(kNameSpaceID_None, nsGkAtoms::placeholder, placeholderValue);
   nsContentUtils::RemoveNewlines(placeholderValue);
   NS_ASSERTION(mPlaceholderDiv->GetFirstChild(), "placeholder div has no child");
   mPlaceholderDiv->GetFirstChild()->SetText(placeholderValue, aNotify);
 }
 
 void
+nsTextEditorState::SetPreviewText(const nsAString& aValue, bool aNotify)
+{
+  MOZ_ASSERT(mPreviewDiv, "This function should not be called if "
+                            "mPreviewDiv isn't set");
+
+  // If we don't have a preview div, there's nothing to do.
+  if (!mPreviewDiv)
+    return;
+
+  nsAutoString previewValue(aValue);
+
+  nsContentUtils::RemoveNewlines(previewValue);
+  MOZ_ASSERT(mPreviewDiv->GetFirstChild(), "preview div has no child");
+  mPreviewDiv->GetFirstChild()->SetText(previewValue, aNotify);
+}
+
+void
+nsTextEditorState::GetPreviewText(nsAString& aValue)
+{
+  // If we don't have a preview div, there's nothing to do.
+  if (!mPreviewDiv)
+    return;
+
+  MOZ_ASSERT(mPreviewDiv->GetFirstChild(), "preview div has no child");
+  const nsTextFragment *text = mPreviewDiv->GetFirstChild()->GetText();
+
+  aValue.Truncate();
+  text->AppendTo(aValue);
+}
+
+void
 nsTextEditorState::UpdatePlaceholderVisibility(bool aNotify)
 {
   nsAutoString value;
   GetValue(value, true);
 
   mPlaceholderVisibility = value.IsEmpty();
 
   if (mPlaceholderVisibility &&
--- a/dom/html/nsTextEditorState.h
+++ b/dom/html/nsTextEditorState.h
@@ -218,18 +218,23 @@ public:
     return mTextCtrlElement->GetRows();
   }
 
   // placeholder methods
   void UpdatePlaceholderVisibility(bool aNotify);
   bool GetPlaceholderVisibility() {
     return mPlaceholderVisibility;
   }
+
   void UpdatePlaceholderText(bool aNotify);
 
+  // preview methods
+  void SetPreviewText(const nsAString& aValue, bool aNotify);
+  void GetPreviewText(nsAString& aValue);
+
   /**
    * Get the maxlength attribute
    * @param aMaxLength the value of the max length attr
    * @returns false if attr not defined
    */
   bool GetMaxLength(int32_t* aMaxLength);
 
   void ClearValueCache() { mCachedValue.Truncate(); }
--- a/dom/webidl/HTMLInputElement.webidl
+++ b/dom/webidl/HTMLInputElement.webidl
@@ -260,8 +260,13 @@ partial interface HTMLInputElement {
   void updateDateTimePicker(optional DateTimeValue value);
 
   [Pref="dom.forms.datetime", Func="IsChromeOrXBL"]
   void closeDateTimePicker();
 
   [Pref="dom.forms.datetime", Func="IsChromeOrXBL"]
   void setFocusState(boolean aIsFocused);
 };
+
+partial interface HTMLInputElement {
+  [ChromeOnly]
+  attribute DOMString previewValue;
+};
--- a/dom/webidl/HTMLTextAreaElement.webidl
+++ b/dom/webidl/HTMLTextAreaElement.webidl
@@ -93,8 +93,13 @@ partial interface HTMLTextAreaElement {
 
   // This is similar to set .value on nsIDOMInput/TextAreaElements, but
   // handling of the value change is closer to the normal user input, so
   // 'change' event for example will be dispatched when focusing out the
   // element.
   [ChromeOnly]
   void setUserInput(DOMString input);
 };
+
+partial interface HTMLTextAreaElement {
+  [ChromeOnly]
+  attribute DOMString previewValue;
+};