diff --git a/dom/html/HTMLInputElement.cpp b/dom/html/HTMLInputElement.cpp index eb2fdba516..120e816eed 100644 --- a/dom/html/HTMLInputElement.cpp +++ b/dom/html/HTMLInputElement.cpp @@ -2607,7 +2607,7 @@ HTMLInputElement::MozSetFileNameArray(const Sequence& aFileNames, NS_IMETHODIMP HTMLInputElement::MozSetFileNameArray(const char16_t** aFileNames, - uint32_t aLength) + uint32_t aLength) { if (!nsContentUtils::IsCallerChrome()) { // setting the value of a "FILE" input widget requires chrome privilege @@ -2631,7 +2631,7 @@ HTMLInputElement::MozSetFileNameArray(const char16_t** aFileNames, void HTMLInputElement::MozSetDirectory(const nsAString& aDirectoryPath, - ErrorResult& aRv) + ErrorResult& aRv) { nsCOMPtr file; aRv = NS_NewLocalFile(aDirectoryPath, true, getter_AddRefs(file)); @@ -2835,11 +2835,14 @@ HTMLInputElement::SetUserInput(const nsAString& aValue) void HTMLInputElement::SetAutofilled(bool aAutofilled) { - + nsAutoString value; + GetValueInternal(value); if (aAutofilled) { AddStates(NS_EVENT_STATE_AUTOFILL); + mAutofilledValue = value; } else { RemoveStates(NS_EVENT_STATE_AUTOFILL); + mAutofilledValue.Truncate(); } } @@ -7092,6 +7095,13 @@ HTMLInputElement::IntrinsicState() const state |= NS_EVENT_STATE_MOZ_SUBMITINVALID; } + // Autofill highlight should persist as long as the value matches the autofilled value + nsAutoString value; + GetValueInternal(value); + if (!mAutofilledValue.IsEmpty() && value == mAutofilledValue) { + state |= NS_EVENT_STATE_AUTOFILL; + } + return state; } @@ -8533,10 +8543,15 @@ HTMLInputElement::OnValueChanged(bool aNotify, bool aWasInteractiveUserChange) // Only remove autofilled state if the value actually changed from autofilled value if (aWasInteractiveUserChange && State().HasState(NS_EVENT_STATE_AUTOFILL)) { - if (mAutofilledValue != value) { + if (!mAutofilledValue.IsEmpty() && mAutofilledValue != value) { RemoveStates(NS_EVENT_STATE_AUTOFILL); mAutofilledValue.Truncate(); } + } else if (aWasInteractiveUserChange && !State().HasState(NS_EVENT_STATE_AUTOFILL)) { + // If the value is changed back to the autofilled value, restore the state + if (!mAutofilledValue.IsEmpty() && mAutofilledValue == value) { + AddStates(NS_EVENT_STATE_AUTOFILL); + } } UpdateAllValidityStates(aNotify); diff --git a/dom/html/HTMLInputElement.h b/dom/html/HTMLInputElement.h index 1ee639ca5a..462d29b524 100644 --- a/dom/html/HTMLInputElement.h +++ b/dom/html/HTMLInputElement.h @@ -849,9 +849,8 @@ public: /** * Sets or clears the autofilled state of this input element. - * This is used by the browser's autofill system to indicate when - * a value has been automatically filled (e.g., from saved passwords - * or form data). + * When setting, also stores the autofilled value for persistence. + * When clearing, clears the stored autofilled value. * * @param aAutofilled Whether the element should be marked as autofilled */ @@ -872,6 +871,8 @@ public: void UpdateEntries(const nsTArray& aFilesOrDirectories); + void SetAutofilledValue(const nsAString& aValue) { mAutofilledValue = aValue; } + protected: virtual ~HTMLInputElement(); @@ -1641,6 +1642,10 @@ protected: bool mNumberControlSpinnerSpinsUp : 1; bool mPickerRunning : 1; bool mSelectionCached : 1; + /** + * The value that was autofilled by the browser. Used to persist the autofill + * highlight as long as the value matches, regardless of focus/blur. + */ nsString mAutofilledValue; private: @@ -1785,6 +1790,8 @@ private: nsCOMPtr mFilePicker; RefPtr mInput; }; + + void EnsureAutofillState(); }; } // namespace dom diff --git a/dom/html/HTMLTextAreaElement.cpp b/dom/html/HTMLTextAreaElement.cpp index fca321aec6..69a1fdea45 100644 --- a/dom/html/HTMLTextAreaElement.cpp +++ b/dom/html/HTMLTextAreaElement.cpp @@ -383,11 +383,6 @@ HTMLTextAreaElement::OnValueChanged(bool aNotify, bool aWasInteractiveUserChange { nsAutoString value; GetValueInternal(value, true); - // printf("[TextArea] OnValueChanged: aWasInteractiveUserChange=%d, value='%s', autofilled='%s', autofill state=%d\n", - // aWasInteractiveUserChange, - // NS_ConvertUTF16toUTF8(value).get(), - // NS_ConvertUTF16toUTF8(mAutofilledValue).get(), - // State().HasState(NS_EVENT_STATE_AUTOFILL)); // Only remove autofilled state if the value actually changed from autofilled value if (State().HasState(NS_EVENT_STATE_AUTOFILL) || !mAutofilledValue.IsEmpty()) { @@ -395,7 +390,6 @@ HTMLTextAreaElement::OnValueChanged(bool aNotify, bool aWasInteractiveUserChange RemoveStates(NS_EVENT_STATE_AUTOFILL); mAutofilledValue.Truncate(); } else if (aWasInteractiveUserChange && mAutofilledValue == value) { - // Defensive: re-add the autofill state if it was removed by something else AddStates(NS_EVENT_STATE_AUTOFILL); } } @@ -1248,7 +1242,6 @@ HTMLTextAreaElement::IntrinsicState() const { EventStates state = nsGenericHTMLFormElementWithState::IntrinsicState(); - // PATCH: Persist autofill state if autofilled if (!mAutofilledValue.IsEmpty()) { state |= NS_EVENT_STATE_AUTOFILL; } @@ -1295,8 +1288,6 @@ HTMLTextAreaElement::IntrinsicState() const state |= NS_EVENT_STATE_PLACEHOLDERSHOWN; } - state |= NS_EVENT_STATE_AUTOFILL; - return state; } diff --git a/layout/style/res/forms.css b/layout/style/res/forms.css index bc07a8ff4a..d0f2c101fd 100644 --- a/layout/style/res/forms.css +++ b/layout/style/res/forms.css @@ -82,8 +82,24 @@ label { /* Note: Values in nsNativeTheme IsWidgetStyled function need to match textfield background/border values here */ +/* Autofill persistent highlight styles */ +input:-moz-autofill { + background-color: #FFEB3B !important; + background-image: none !important; + color: fieldtext !important; +} + +input:-moz-autofill:hover, +input:-moz-autofill:focus, +input:-moz-autofill:active { + background-color: #FFEB3B !important; + background-image: none !important; + color: fieldtext !important; +} + input { -moz-appearance: textfield; + appearance: textfield; /* The sum of border and padding on block-start and block-end must be the same here, for buttons, and for