Skip to content

Commit 3b643c8

Browse files
Olli PettayOlli Pettay
authored andcommitted
Bug 1832026, create TextControlState lazily, r=masayuki
Differential Revision: https://phabricator.services.mozilla.com/D195383
1 parent bdd8262 commit 3b643c8

File tree

2 files changed

+26
-7
lines changed

2 files changed

+26
-7
lines changed

dom/html/HTMLInputElement.cpp

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,8 +1022,8 @@ HTMLInputElement::HTMLInputElement(already_AddRefed<dom::NodeInfo>&& aNodeInfo,
10221022
"Keep the size of HTMLInputElement under 512 to avoid "
10231023
"performance regression!");
10241024

1025-
// We are in a type=text so we now we currenty need a TextControlState.
1026-
mInputData.mState = TextControlState::Construct(this);
1025+
// We are in a type=text but we create TextControlState lazily.
1026+
mInputData.mState = nullptr;
10271027

10281028
void* memory = mInputTypeMem;
10291029
mInputType = InputType::Create(this, mType, memory);
@@ -1053,7 +1053,8 @@ void HTMLInputElement::FreeData() {
10531053
if (!IsSingleLineTextControl(false)) {
10541054
free(mInputData.mValue);
10551055
mInputData.mValue = nullptr;
1056-
} else {
1056+
} else if (mInputData.mState) {
1057+
// XXX Passing nullptr to UnbindFromFrame doesn't do anything!
10571058
UnbindFromFrame(nullptr);
10581059
mInputData.mState->Destroy();
10591060
mInputData.mState = nullptr;
@@ -1065,11 +1066,22 @@ void HTMLInputElement::FreeData() {
10651066
}
10661067
}
10671068

1069+
void HTMLInputElement::EnsureEditorState() {
1070+
MOZ_ASSERT(IsSingleLineTextControl(false));
1071+
if (!mInputData.mState) {
1072+
mInputData.mState = TextControlState::Construct(this);
1073+
}
1074+
}
1075+
10681076
TextControlState* HTMLInputElement::GetEditorState() const {
10691077
if (!IsSingleLineTextControl(false)) {
10701078
return nullptr;
10711079
}
10721080

1081+
// We've postponed allocating TextControlState, doing that in a const
1082+
// method is fine.
1083+
const_cast<HTMLInputElement*>(this)->EnsureEditorState();
1084+
10731085
MOZ_ASSERT(mInputData.mState,
10741086
"Single line text controls need to have a state"
10751087
" associated with them");
@@ -1085,7 +1097,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLInputElement,
10851097
TextControlElement)
10861098
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mValidity)
10871099
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mControllers)
1088-
if (tmp->IsSingleLineTextControl(false)) {
1100+
if (tmp->IsSingleLineTextControl(false) && tmp->mInputData.mState) {
10891101
tmp->mInputData.mState->Traverse(cb);
10901102
}
10911103

@@ -1098,7 +1110,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLInputElement,
10981110
TextControlElement)
10991111
NS_IMPL_CYCLE_COLLECTION_UNLINK(mValidity)
11001112
NS_IMPL_CYCLE_COLLECTION_UNLINK(mControllers)
1101-
if (tmp->IsSingleLineTextControl(false)) {
1113+
if (tmp->IsSingleLineTextControl(false) && tmp->mInputData.mState) {
11021114
tmp->mInputData.mState->Unlink();
11031115
}
11041116

@@ -1578,7 +1590,12 @@ void HTMLInputElement::GetNonFileValueInternal(nsAString& aValue) const {
15781590
switch (GetValueMode()) {
15791591
case VALUE_MODE_VALUE:
15801592
if (IsSingleLineTextControl(false)) {
1581-
mInputData.mState->GetValue(aValue, true, /* aForDisplay = */ false);
1593+
if (mInputData.mState) {
1594+
mInputData.mState->GetValue(aValue, true, /* aForDisplay = */ false);
1595+
} else {
1596+
// Value hasn't been set yet.
1597+
aValue.Truncate();
1598+
}
15821599
} else if (!aValue.Assign(mInputData.mValue, fallible)) {
15831600
aValue.Truncate();
15841601
}
@@ -2702,6 +2719,7 @@ nsresult HTMLInputElement::SetValueInternal(
27022719
// of calling this method, you need to maintain SetUserInput() too. FYI:
27032720
// After calling SetValue(), the input type might have been
27042721
// modified so that mInputData may not store TextControlState.
2722+
EnsureEditorState();
27052723
if (!mInputData.mState->SetValue(
27062724
value, aOldValue,
27072725
forcePreserveUndoHistory
@@ -4455,7 +4473,7 @@ void HTMLInputElement::HandleTypeChange(FormControlType aNewType,
44554473

44564474
TextControlState::SelectionProperties sp;
44574475

4458-
if (GetEditorState()) {
4476+
if (IsSingleLineTextControl(false) && mInputData.mState) {
44594477
mInputData.mState->SyncUpSelectionPropertiesBeforeDestruction();
44604478
sp = mInputData.mState->GetSelectionProperties();
44614479
}

dom/html/HTMLInputElement.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1067,6 +1067,7 @@ class HTMLInputElement final : public TextControlElement,
10671067

10681068
MOZ_CAN_RUN_SCRIPT void FreeData();
10691069
TextControlState* GetEditorState() const;
1070+
void EnsureEditorState();
10701071

10711072
MOZ_CAN_RUN_SCRIPT TextEditor* GetTextEditorFromState();
10721073

0 commit comments

Comments
 (0)