зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1368888 - Don't get previous value twice in input.value setter. r=smaug
We get previous input.value twice in HTMLInputElement::SetValue and nsTextEditorState::SetValue when setting input.value. Since nsTextEditorState::GetValue uses DocumentEncoder, it is expensive. So we should use old value as parameter of nsTextEditorState::SetValue if possible. MozReview-Commit-ID: A1UPfETTVCn --HG-- extra : rebase_source : f751289b42b4d9d5c389042f688c53bde47d1620
This commit is contained in:
Родитель
4de4243edc
Коммит
23c3e741f1
|
@ -1873,8 +1873,12 @@ HTMLInputElement::SetValue(const nsAString& aValue, CallerType aCallerType,
|
|||
nsAutoString currentValue;
|
||||
GetValue(currentValue, aCallerType);
|
||||
|
||||
// Some types sanitize value, so GetValue doesn't return pure
|
||||
// previous value correctly.
|
||||
nsresult rv =
|
||||
SetValueInternal(aValue,
|
||||
(IsExperimentalMobileType(mType) || IsDateTimeInputType(mType)) ?
|
||||
nullptr : ¤tValue,
|
||||
nsTextEditorState::eSetValue_ByContent |
|
||||
nsTextEditorState::eSetValue_Notify |
|
||||
nsTextEditorState::eSetValue_MoveCursorToEndIfValueChanged);
|
||||
|
@ -3032,7 +3036,9 @@ HTMLInputElement::UpdateFileList()
|
|||
}
|
||||
|
||||
nsresult
|
||||
HTMLInputElement::SetValueInternal(const nsAString& aValue, uint32_t aFlags)
|
||||
HTMLInputElement::SetValueInternal(const nsAString& aValue,
|
||||
const nsAString* aOldValue,
|
||||
uint32_t aFlags)
|
||||
{
|
||||
NS_PRECONDITION(GetValueMode() != VALUE_MODE_FILENAME,
|
||||
"Don't call SetValueInternal for file inputs");
|
||||
|
@ -3056,7 +3062,7 @@ HTMLInputElement::SetValueInternal(const nsAString& aValue, uint32_t aFlags)
|
|||
}
|
||||
|
||||
if (IsSingleLineTextControl(false)) {
|
||||
if (!mInputData.mState->SetValue(value, aFlags)) {
|
||||
if (!mInputData.mState->SetValue(value, aOldValue, aFlags)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
if (mType == NS_FORM_INPUT_EMAIL) {
|
||||
|
|
|
@ -942,9 +942,19 @@ protected:
|
|||
* Setting the value.
|
||||
*
|
||||
* @param aValue String to set.
|
||||
* @param aOldValue Previous value before setting aValue.
|
||||
If previous value is unknown, aOldValue can be nullptr.
|
||||
* @param aFlags See nsTextEditorState::SetValueFlags.
|
||||
*/
|
||||
nsresult SetValueInternal(const nsAString& aValue, uint32_t aFlags);
|
||||
nsresult SetValueInternal(const nsAString& aValue,
|
||||
const nsAString* aOldValue,
|
||||
uint32_t aFlags);
|
||||
|
||||
nsresult SetValueInternal(const nsAString& aValue,
|
||||
uint32_t aFlags)
|
||||
{
|
||||
return SetValueInternal(aValue, nullptr, aFlags);
|
||||
}
|
||||
|
||||
// Generic getter for the value that doesn't do experimental control type
|
||||
// sanitization.
|
||||
|
|
|
@ -2492,7 +2492,8 @@ nsTextEditorState::GetValue(nsAString& aValue, bool aIgnoreWrap) const
|
|||
}
|
||||
|
||||
bool
|
||||
nsTextEditorState::SetValue(const nsAString& aValue, uint32_t aFlags)
|
||||
nsTextEditorState::SetValue(const nsAString& aValue, const nsAString* aOldValue,
|
||||
uint32_t aFlags)
|
||||
{
|
||||
nsAutoString newValue(aValue);
|
||||
|
||||
|
@ -2505,6 +2506,9 @@ nsTextEditorState::SetValue(const nsAString& aValue, uint32_t aFlags)
|
|||
// mIsCommittingComposition is set false. See below.
|
||||
if (mIsCommittingComposition) {
|
||||
mValueBeingSet = aValue;
|
||||
// GetValue doesn't return current text frame's content during committing.
|
||||
// So we cannot trust this old value
|
||||
aOldValue = nullptr;
|
||||
}
|
||||
|
||||
// Note that if this may be called during reframe of the editor. In such
|
||||
|
@ -2525,7 +2529,15 @@ nsTextEditorState::SetValue(const nsAString& aValue, uint32_t aFlags)
|
|||
// If setting value won't change current value, we shouldn't commit
|
||||
// composition for compatibility with the other browsers.
|
||||
nsAutoString currentValue;
|
||||
mBoundFrame->GetText(currentValue);
|
||||
if (aOldValue) {
|
||||
#ifdef DEBUG
|
||||
mBoundFrame->GetText(currentValue);
|
||||
MOZ_ASSERT(currentValue.Equals(*aOldValue));
|
||||
#endif
|
||||
currentValue.Assign(*aOldValue);
|
||||
} else {
|
||||
mBoundFrame->GetText(currentValue);
|
||||
}
|
||||
if (newValue == currentValue) {
|
||||
// Note that in this case, we shouldn't fire any events with setting
|
||||
// value because event handlers may try to set value recursively but
|
||||
|
@ -2533,6 +2545,9 @@ nsTextEditorState::SetValue(const nsAString& aValue, uint32_t aFlags)
|
|||
// script (see below).
|
||||
return true;
|
||||
}
|
||||
// IME might commit composition, then change value, so we cannot
|
||||
// trust old value from parameter.
|
||||
aOldValue = nullptr;
|
||||
}
|
||||
// If there is composition, need to commit composition first because
|
||||
// other browsers do that.
|
||||
|
@ -2593,7 +2608,15 @@ nsTextEditorState::SetValue(const nsAString& aValue, uint32_t aFlags)
|
|||
#endif
|
||||
|
||||
nsAutoString currentValue;
|
||||
mBoundFrame->GetText(currentValue);
|
||||
if (aOldValue) {
|
||||
#ifdef DEBUG
|
||||
mBoundFrame->GetText(currentValue);
|
||||
MOZ_ASSERT(currentValue.Equals(*aOldValue));
|
||||
#endif
|
||||
currentValue.Assign(*aOldValue);
|
||||
} else {
|
||||
mBoundFrame->GetText(currentValue);
|
||||
}
|
||||
|
||||
AutoWeakFrame weakFrame(mBoundFrame);
|
||||
|
||||
|
|
|
@ -179,7 +179,14 @@ public:
|
|||
// not changed the cursor won't move.
|
||||
eSetValue_MoveCursorToEndIfValueChanged = 1 << 3,
|
||||
};
|
||||
MOZ_MUST_USE bool SetValue(const nsAString& aValue, uint32_t aFlags);
|
||||
MOZ_MUST_USE bool SetValue(const nsAString& aValue,
|
||||
const nsAString* aOldValue,
|
||||
uint32_t aFlags);
|
||||
MOZ_MUST_USE bool SetValue(const nsAString& aValue,
|
||||
uint32_t aFlags)
|
||||
{
|
||||
return SetValue(aValue, nullptr, aFlags);
|
||||
}
|
||||
void GetValue(nsAString& aValue, bool aIgnoreWrap) const;
|
||||
bool HasNonEmptyValue();
|
||||
// The following methods are for textarea element to use whether default
|
||||
|
|
Загрузка…
Ссылка в новой задаче