Bug 1340483 - Part 3. Enable preview function only when input is marked as autofill field. r=heycam
MozReview-Commit-ID: FFqYJ3icRd7
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -1094,16 +1094,17 @@ HTMLInputElement::HTMLInputElement(alrea
, mCanShowValidUI(true)
, mCanShowInvalidUI(true)
, mHasRange(false)
, mIsDraggingRange(false)
, mNumberControlSpinnerIsSpinning(false)
, mNumberControlSpinnerSpinsUp(false)
, mPickerRunning(false)
, mSelectionCached(true)
+ , mIsPreviewEnabled(false)
{
// We are in a type=text so we now we currenty need a nsTextEditorState.
mInputData.mState =
nsTextEditorState::Construct(this, &sCachedTextEditorState);
if (!gUploadLastDir)
HTMLInputElement::InitUploadLastDir();
@@ -2925,16 +2926,34 @@ NS_IMETHODIMP_(void)
HTMLInputElement::GetPreviewValue(nsAString& aValue)
{
nsTextEditorState* state = GetEditorState();
if (state) {
state->GetPreviewText(aValue);
}
}
+NS_IMETHODIMP_(void)
+HTMLInputElement::EnablePreview()
+{
+ if (mIsPreviewEnabled) {
+ return;
+ }
+
+ mIsPreviewEnabled = true;
+ // Reconstruct the frame to append an anonymous preview node
+ nsLayoutUtils::PostRestyleEvent(this, nsRestyleHint(0), nsChangeHint_ReconstructFrame);
+}
+
+NS_IMETHODIMP_(bool)
+HTMLInputElement::IsPreviewEnabled()
+{
+ return mIsPreviewEnabled;
+}
+
void
HTMLInputElement::GetDisplayFileName(nsAString& aValue) const
{
if (OwnerDoc()->IsStaticDocument()) {
aValue = mStaticDocFileList;
return;
}
--- a/dom/html/HTMLInputElement.h
+++ b/dom/html/HTMLInputElement.h
@@ -234,16 +234,18 @@ public:
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_(void) EnablePreview() override;
+ NS_IMETHOD_(bool) IsPreviewEnabled() 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
@@ -1635,16 +1637,17 @@ protected:
bool mCanShowValidUI : 1;
bool mCanShowInvalidUI : 1;
bool mHasRange : 1;
bool mIsDraggingRange : 1;
bool mNumberControlSpinnerIsSpinning : 1;
bool mNumberControlSpinnerSpinsUp : 1;
bool mPickerRunning : 1;
bool mSelectionCached : 1;
+ bool mIsPreviewEnabled : 1;
private:
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
GenericSpecifiedValues* aGenericData);
/**
* Returns true if this input's type will fire a DOM "change" event when it
* loses focus if its value has changed since it gained focus.
--- a/dom/html/HTMLTextAreaElement.cpp
+++ b/dom/html/HTMLTextAreaElement.cpp
@@ -57,16 +57,17 @@ HTMLTextAreaElement::HTMLTextAreaElement
mValueChanged(false),
mLastValueChangeWasInteractive(false),
mHandlingSelect(false),
mDoneAddingChildren(!aFromParser),
mInhibitStateRestoration(!!(aFromParser & FROM_PARSER_FRAGMENT)),
mDisabledChanged(false),
mCanShowInvalidUI(true),
mCanShowValidUI(true),
+ mIsPreviewEnabled(false),
mState(this)
{
AddMutationObserver(this);
// Set up our default state. By default we're enabled (since we're
// a control type that can be disabled but not actually disabled
// right now), optional, and valid. We are NOT readwrite by default
// until someone calls UpdateEditableState on us, apparently! Also
@@ -340,16 +341,34 @@ HTMLTextAreaElement::SetPreviewValue(con
}
NS_IMETHODIMP_(void)
HTMLTextAreaElement::GetPreviewValue(nsAString& aValue)
{
mState.GetPreviewText(aValue);
}
+NS_IMETHODIMP_(void)
+HTMLTextAreaElement::EnablePreview()
+{
+ if (mIsPreviewEnabled) {
+ return;
+ }
+
+ mIsPreviewEnabled = true;
+ // Reconstruct the frame to append an anonymous preview node
+ nsLayoutUtils::PostRestyleEvent(this, nsRestyleHint(0), nsChangeHint_ReconstructFrame);
+}
+
+NS_IMETHODIMP_(bool)
+HTMLTextAreaElement::IsPreviewEnabled()
+{
+ return mIsPreviewEnabled;
+}
+
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
// needed.
--- a/dom/html/HTMLTextAreaElement.h
+++ b/dom/html/HTMLTextAreaElement.h
@@ -104,16 +104,18 @@ public:
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) EnablePreview() override;
+ NS_IMETHOD_(bool) IsPreviewEnabled() 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
@@ -321,16 +323,17 @@ protected:
/** Whether state restoration should be inhibited in DoneAddingChildren. */
bool mInhibitStateRestoration;
/** Whether our disabled state has changed from the default **/
bool mDisabledChanged;
/** Whether we should make :-moz-ui-invalid apply on the element. **/
bool mCanShowInvalidUI;
/** Whether we should make :-moz-ui-valid apply on the element. **/
bool mCanShowValidUI;
+ bool mIsPreviewEnabled;
void FireChangeEventIfNeeded();
nsString mFocusedValue;
/** The state of the text editor (selection controller and the editor) **/
nsTextEditorState mState;
--- a/dom/html/nsITextControlElement.h
+++ b/dom/html/nsITextControlElement.h
@@ -170,16 +170,26 @@ public:
NS_IMETHOD_(void) SetPreviewValue(const nsAString& aValue) = 0;
/**
* Get the current preview value for text control.
*/
NS_IMETHOD_(void) GetPreviewValue(nsAString& aValue) = 0;
/**
+ * Enable preview for text control.
+ */
+ NS_IMETHOD_(void) EnablePreview() = 0;
+
+ /**
+ * Find out whether this control enables preview for form autofoll.
+ */
+ NS_IMETHOD_(bool) IsPreviewEnabled() = 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/layout/forms/nsTextControlFrame.cpp
+++ b/layout/forms/nsTextControlFrame.cpp
@@ -104,16 +104,17 @@ private:
#endif
nsTextControlFrame::nsTextControlFrame(nsStyleContext* aContext)
: nsContainerFrame(aContext)
, mFirstBaseline(NS_INTRINSIC_WIDTH_UNKNOWN)
, mEditorHasBeenInitialized(false)
, mIsProcessing(false)
, mUsePlaceholder(false)
+ , mUsePreview(false)
#ifdef DEBUG
, mInEditorInitialization(false)
#endif
{
}
nsTextControlFrame::~nsTextControlFrame()
{
@@ -362,21 +363,25 @@ nsTextControlFrame::CreateAnonymousConte
if (!IsSingleLineTextControl()) {
// For textareas, UpdateValueDisplay doesn't initialize the visibility
// status of the placeholder because it returns early, so we have to
// do that manually here.
txtCtrl->UpdatePlaceholderVisibility(true);
}
}
- // Create the preview anonymous content if needed.
- Element* previewNode = txtCtrl->CreatePreviewNode();
- NS_ENSURE_TRUE(previewNode, NS_ERROR_OUT_OF_MEMORY);
+ mUsePreview = txtCtrl->IsPreviewEnabled();
- aElements.AppendElement(previewNode);
+ if (mUsePreview) {
+ // Create the preview anonymous content if needed.
+ Element* previewNode = txtCtrl->CreatePreviewNode();
+ NS_ENSURE_TRUE(previewNode, NS_ERROR_OUT_OF_MEMORY);
+
+ aElements.AppendElement(previewNode);
+ }
rv = UpdateValueDisplay(false);
NS_ENSURE_SUCCESS(rv, rv);
// textareas are eagerly initialized
bool initEagerly = !IsSingleLineTextControl();
if (!initEagerly) {
// Also, input elements which have a cached selection should get eager
--- a/layout/forms/nsTextControlFrame.h
+++ b/layout/forms/nsTextControlFrame.h
@@ -334,16 +334,18 @@ private:
// Reflow.
nscoord mFirstBaseline;
// these packed bools could instead use the high order bits on mState, saving 4 bytes
bool mEditorHasBeenInitialized;
bool mIsProcessing;
// Keep track if we have asked a placeholder node creation.
bool mUsePlaceholder;
+ // Similarly for preview node creation.
+ bool mUsePreview;
#ifdef DEBUG
bool mInEditorInitialization;
friend class EditorInitializerEntryTracker;
#endif
nsRevocableEventPtr<ScrollOnFocusEvent> mScrollEvent;
};
--- a/toolkit/components/satchel/nsFormFillController.cpp
+++ b/toolkit/components/satchel/nsFormFillController.cpp
@@ -318,16 +318,19 @@ nsFormFillController::MarkAsAutofillFiel
if (mAutofillInputs.Get(node)) {
return NS_OK;
}
mAutofillInputs.Put(node, true);
node->AddMutationObserverUnlessExists(this);
+ nsCOMPtr<nsITextControlElement> txtCtrl = do_QueryInterface(aInput);
+ txtCtrl->EnablePreview();
+
nsFocusManager *fm = nsFocusManager::GetFocusManager();
if (fm) {
nsCOMPtr<nsIContent> focusedContent = fm->GetFocusedContent();
if (SameCOMIdentity(focusedContent, node)) {
nsCOMPtr<nsIDOMHTMLInputElement> input = do_QueryInterface(node);
MaybeStartControllingInput(input);
}
}