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:
Masayuki Nakano
2021-06-28 04:37:54 +00:00
parent b224f9cb5b
commit 2eac55a01e
5 changed files with 70 additions and 35 deletions

View File

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