Issue #2790 - Part 5: Persistent highlight despite blur click

This commit is contained in:
MeladJM 2025-07-26 03:06:37 +08:00 • committed by roytam1
commit 156c755085
5 changed files with 64 additions and 16 deletions

View file

@ -2607,7 +2607,7 @@ HTMLInputElement::MozSetFileNameArray(const Sequence<nsString>& 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<nsIFile> 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);

View file

@ -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<OwningFileOrDirectory>& 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<nsIFilePicker> mFilePicker;
RefPtr<HTMLInputElement> mInput;
};
void EnsureAutofillState();
};
} // namespace dom

View file

@ -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;
}