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