diff --git a/content/html/content/src/nsTextEditorState.cpp b/content/html/content/src/nsTextEditorState.cpp
index 5181d7cf882..b2afb2e63a3 100644
--- a/content/html/content/src/nsTextEditorState.cpp
+++ b/content/html/content/src/nsTextEditorState.cpp
@@ -1122,6 +1122,26 @@ nsTextEditorState::BindToFrame(nsTextControlFrame* aFrame)
return NS_OK;
}
+struct PreDestroyer
+{
+ void Init(nsIEditor* aEditor)
+ {
+ mNewEditor = aEditor;
+ }
+ ~PreDestroyer()
+ {
+ if (mNewEditor) {
+ mNewEditor->PreDestroy(true);
+ }
+ }
+ void Swap(nsCOMPtr& aEditor)
+ {
+ return mNewEditor.swap(aEditor);
+ }
+private:
+ nsCOMPtr mNewEditor;
+};
+
nsresult
nsTextEditorState::PrepareEditor(const nsAString *aValue)
{
@@ -1168,12 +1188,14 @@ nsTextEditorState::PrepareEditor(const nsAString *aValue)
bool shouldInitializeEditor = false;
nsCOMPtr newEditor; // the editor that we might create
nsresult rv = NS_OK;
+ PreDestroyer preDestroyer;
if (!mEditor) {
shouldInitializeEditor = true;
// Create an editor
newEditor = do_CreateInstance(kTextEditorCID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
+ preDestroyer.Init(newEditor);
// Make sure we clear out the non-breaking space before we initialize the editor
rv = mBoundFrame->UpdateValueDisplay(false, true);
@@ -1302,7 +1324,7 @@ nsTextEditorState::PrepareEditor(const nsAString *aValue)
if (shouldInitializeEditor) {
// Hold on to the newly created editor
- mEditor = newEditor;
+ preDestroyer.Swap(mEditor);
}
// If we have a default value, insert it under the div we created
diff --git a/editor/libeditor/text/nsTextEditRules.cpp b/editor/libeditor/text/nsTextEditRules.cpp
index bda1d0f4230..0d7ba3a22e5 100644
--- a/editor/libeditor/text/nsTextEditRules.cpp
+++ b/editor/libeditor/text/nsTextEditRules.cpp
@@ -104,7 +104,7 @@ nsTextEditRules::Init(nsPlaintextEditor *aEditor)
mEditor = aEditor; // we hold a non-refcounted reference back to our editor
nsCOMPtr selection;
mEditor->GetSelection(getter_AddRefs(selection));
- NS_ASSERTION(selection, "editor cannot get selection");
+ NS_WARN_IF_FALSE(selection, "editor cannot get selection");
// Put in a magic br if needed. This method handles null selection,
// which should never happen anyway
diff --git a/layout/forms/nsTextControlFrame.cpp b/layout/forms/nsTextControlFrame.cpp
index c5d823939de..bdc3747402e 100644
--- a/layout/forms/nsTextControlFrame.cpp
+++ b/layout/forms/nsTextControlFrame.cpp
@@ -296,50 +296,53 @@ nsTextControlFrame::EnsureEditorInitialized()
// Make sure that editor init doesn't do things that would kill us off
// (especially off the script blockers it'll create for its DOM mutations).
- nsAutoScriptBlocker scriptBlocker;
+ {
+ nsAutoScriptBlocker scriptBlocker;
- // Time to mess with our security context... See comments in GetValue()
- // for why this is needed.
- nsCxPusher pusher;
- pusher.PushNull();
+ // Time to mess with our security context... See comments in GetValue()
+ // for why this is needed.
+ nsCxPusher pusher;
+ pusher.PushNull();
- // Make sure that we try to focus the content even if the method fails
- class EnsureSetFocus {
- public:
- explicit EnsureSetFocus(nsTextControlFrame* aFrame)
- : mFrame(aFrame) {}
- ~EnsureSetFocus() {
- if (nsContentUtils::IsFocusedContent(mFrame->GetContent()))
- mFrame->SetFocus(true, false);
- }
- private:
- nsTextControlFrame *mFrame;
- };
- EnsureSetFocus makeSureSetFocusHappens(this);
+ // Make sure that we try to focus the content even if the method fails
+ class EnsureSetFocus {
+ public:
+ explicit EnsureSetFocus(nsTextControlFrame* aFrame)
+ : mFrame(aFrame) {}
+ ~EnsureSetFocus() {
+ if (nsContentUtils::IsFocusedContent(mFrame->GetContent()))
+ mFrame->SetFocus(true, false);
+ }
+ private:
+ nsTextControlFrame *mFrame;
+ };
+ EnsureSetFocus makeSureSetFocusHappens(this);
#ifdef DEBUG
- // Make sure we are not being called again until we're finished.
- // If reentrancy happens, just pretend that we don't have an editor.
- const EditorInitializerEntryTracker tracker(*this);
- NS_ASSERTION(!tracker.EnteredMoreThanOnce(),
- "EnsureEditorInitialized has been called while a previous call was in progress");
+ // Make sure we are not being called again until we're finished.
+ // If reentrancy happens, just pretend that we don't have an editor.
+ const EditorInitializerEntryTracker tracker(*this);
+ NS_ASSERTION(!tracker.EnteredMoreThanOnce(),
+ "EnsureEditorInitialized has been called while a previous call was in progress");
#endif
- // Create an editor for the frame, if one doesn't already exist
- nsCOMPtr txtCtrl = do_QueryInterface(GetContent());
- NS_ASSERTION(txtCtrl, "Content not a text control element");
- nsresult rv = txtCtrl->CreateEditor();
- NS_ENSURE_SUCCESS(rv, rv);
+ // Create an editor for the frame, if one doesn't already exist
+ nsCOMPtr txtCtrl = do_QueryInterface(GetContent());
+ NS_ASSERTION(txtCtrl, "Content not a text control element");
+ nsresult rv = txtCtrl->CreateEditor();
+ NS_ENSURE_SUCCESS(rv, rv);
+ NS_ENSURE_STATE(weakFrame.IsAlive());
- // Turn on mUseEditor so that subsequent calls will use the
- // editor.
- mUseEditor = true;
+ // Turn on mUseEditor so that subsequent calls will use the
+ // editor.
+ mUseEditor = true;
- // Set the selection to the beginning of the text field.
- if (weakFrame.IsAlive()) {
- SetSelectionEndPoints(0, 0);
+ // Set the selection to the beginning of the text field.
+ if (weakFrame.IsAlive()) {
+ SetSelectionEndPoints(0, 0);
+ }
}
-
+ NS_ENSURE_STATE(weakFrame.IsAlive());
return NS_OK;
}
@@ -1089,8 +1092,10 @@ nsTextControlFrame::GetSelectionRange(int32_t* aSelectionStart,
return NS_OK;
}
- nsContentUtils::GetSelectionInTextControl(typedSel,
- GetRootNodeAndInitializeEditor(), *aSelectionStart, *aSelectionEnd);
+ mozilla::dom::Element* root = GetRootNodeAndInitializeEditor();
+ NS_ENSURE_STATE(root);
+ nsContentUtils::GetSelectionInTextControl(typedSel, root,
+ *aSelectionStart, *aSelectionEnd);
return NS_OK;
}