зеркало из https://github.com/mozilla/gecko-dev.git
Bug 802985, PreDestroy editor, r=ehsan , a=lsblakk
--HG-- extra : rebase_source : 224d67b3a3c108cf1d1822d2e1cdd2d1757137a0
This commit is contained in:
Родитель
0cf77fada8
Коммит
a0d6cab071
|
@ -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<nsIEditor>& aEditor)
|
||||
{
|
||||
return mNewEditor.swap(aEditor);
|
||||
}
|
||||
private:
|
||||
nsCOMPtr<nsIEditor> mNewEditor;
|
||||
};
|
||||
|
||||
nsresult
|
||||
nsTextEditorState::PrepareEditor(const nsAString *aValue)
|
||||
{
|
||||
|
@ -1168,12 +1188,14 @@ nsTextEditorState::PrepareEditor(const nsAString *aValue)
|
|||
bool shouldInitializeEditor = false;
|
||||
nsCOMPtr<nsIEditor> 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
|
||||
|
|
|
@ -104,7 +104,7 @@ nsTextEditRules::Init(nsPlaintextEditor *aEditor)
|
|||
mEditor = aEditor; // we hold a non-refcounted reference back to our editor
|
||||
nsCOMPtr<nsISelection> 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
|
||||
|
|
|
@ -305,50 +305,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<nsITextControlElement> 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<nsITextControlElement> 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;
|
||||
}
|
||||
|
||||
|
@ -1098,8 +1101,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;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче