Bug 1676702 - part 3: Make TextControlState store unmasked range while it does not have TextEditor r=m_kato
`TextControlState` is alive during reframing, but `TextEditor` is not so. Therefore, `TextControlState` should take the `PasswordMaskData` before `TextEditor` is destroyed. And if `TextEditor` is recreated, and the value hasn't been modified, unmasked range should be restored in the new editor. Depends on D118757 Differential Revision: https://phabricator.services.mozilla.com/D118758
This commit is contained in:
@@ -1653,9 +1653,11 @@ nsresult TextControlState::BindToFrame(nsTextControlFrame* aFrame) {
|
||||
|
||||
struct MOZ_STACK_CLASS PreDestroyer {
|
||||
void Init(TextEditor* aTextEditor) { mTextEditor = aTextEditor; }
|
||||
MOZ_CAN_RUN_SCRIPT ~PreDestroyer() {
|
||||
~PreDestroyer() {
|
||||
if (mTextEditor) {
|
||||
MOZ_KnownLive(mTextEditor)->PreDestroy();
|
||||
// In this case, we don't need to restore the unmasked range of password
|
||||
// editor.
|
||||
UniquePtr<PasswordMaskData> passwordMaskData = mTextEditor->PreDestroy();
|
||||
}
|
||||
}
|
||||
void Swap(RefPtr<TextEditor>& aTextEditor) {
|
||||
@@ -1791,11 +1793,13 @@ nsresult TextControlState::PrepareEditor(const nsAString* aValue) {
|
||||
OwningNonNull<TextInputSelectionController> selectionController(*mSelCon);
|
||||
UniquePtr<PasswordMaskData> passwordMaskData;
|
||||
if (editorFlags & nsIEditor::eEditorPasswordMask) {
|
||||
const bool needToUpdatePasswordMaskData =
|
||||
newTextEditor != mTextEditor || !mTextEditor->IsPasswordEditor();
|
||||
if (needToUpdatePasswordMaskData) {
|
||||
if (mPasswordMaskData) {
|
||||
passwordMaskData = std::move(mPasswordMaskData);
|
||||
} else {
|
||||
passwordMaskData = MakeUnique<PasswordMaskData>();
|
||||
}
|
||||
} else {
|
||||
mPasswordMaskData = nullptr;
|
||||
}
|
||||
nsresult rv =
|
||||
newTextEditor->Init(*doc, *anonymousDivElement, selectionController,
|
||||
@@ -2342,8 +2346,10 @@ void TextControlState::DestroyEditor() {
|
||||
// changes the DOM tree or selection so that it's safe to call
|
||||
// PreDestroy() here even while we're handling actions with
|
||||
// mTextEditor.
|
||||
MOZ_ASSERT(!mPasswordMaskData);
|
||||
RefPtr<TextEditor> textEditor = mTextEditor;
|
||||
textEditor->PreDestroy();
|
||||
mPasswordMaskData = textEditor->PreDestroy();
|
||||
MOZ_ASSERT_IF(mPasswordMaskData, !mPasswordMaskData->mTimer);
|
||||
mEditorInitialized = false;
|
||||
}
|
||||
}
|
||||
@@ -2578,6 +2584,17 @@ bool TextControlState::SetValue(const nsAString& aValue,
|
||||
aOldValue = nullptr;
|
||||
}
|
||||
|
||||
if (mPasswordMaskData) {
|
||||
if (mHandlingState &&
|
||||
mHandlingState->Is(TextControlAction::UnbindFromFrame)) {
|
||||
// If we're called by UnbindFromFrame, we shouldn't reset unmasked range.
|
||||
} else {
|
||||
// Otherwise, we should mask the new password, even if it's same value
|
||||
// since the same value may be one for different web app's.
|
||||
mPasswordMaskData->Reset();
|
||||
}
|
||||
}
|
||||
|
||||
const bool wasHandlingSetValue =
|
||||
mHandlingState && mHandlingState->IsHandling(TextControlAction::SetValue);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user