mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 802985, PreDestroy editor, r=ehsan
This commit is contained in:
parent
e86cd8818c
commit
efe22ceaf9
@ -1122,6 +1122,26 @@ nsTextEditorState::BindToFrame(nsTextControlFrame* aFrame)
|
|||||||
return NS_OK;
|
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
|
nsresult
|
||||||
nsTextEditorState::PrepareEditor(const nsAString *aValue)
|
nsTextEditorState::PrepareEditor(const nsAString *aValue)
|
||||||
{
|
{
|
||||||
@ -1168,12 +1188,14 @@ nsTextEditorState::PrepareEditor(const nsAString *aValue)
|
|||||||
bool shouldInitializeEditor = false;
|
bool shouldInitializeEditor = false;
|
||||||
nsCOMPtr<nsIEditor> newEditor; // the editor that we might create
|
nsCOMPtr<nsIEditor> newEditor; // the editor that we might create
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
|
PreDestroyer preDestroyer;
|
||||||
if (!mEditor) {
|
if (!mEditor) {
|
||||||
shouldInitializeEditor = true;
|
shouldInitializeEditor = true;
|
||||||
|
|
||||||
// Create an editor
|
// Create an editor
|
||||||
newEditor = do_CreateInstance(kTextEditorCID, &rv);
|
newEditor = do_CreateInstance(kTextEditorCID, &rv);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
preDestroyer.Init(newEditor);
|
||||||
|
|
||||||
// Make sure we clear out the non-breaking space before we initialize the editor
|
// Make sure we clear out the non-breaking space before we initialize the editor
|
||||||
rv = mBoundFrame->UpdateValueDisplay(false, true);
|
rv = mBoundFrame->UpdateValueDisplay(false, true);
|
||||||
@ -1302,7 +1324,7 @@ nsTextEditorState::PrepareEditor(const nsAString *aValue)
|
|||||||
|
|
||||||
if (shouldInitializeEditor) {
|
if (shouldInitializeEditor) {
|
||||||
// Hold on to the newly created editor
|
// 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
|
// 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
|
mEditor = aEditor; // we hold a non-refcounted reference back to our editor
|
||||||
nsCOMPtr<nsISelection> selection;
|
nsCOMPtr<nsISelection> selection;
|
||||||
mEditor->GetSelection(getter_AddRefs(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,
|
// Put in a magic br if needed. This method handles null selection,
|
||||||
// which should never happen anyway
|
// which should never happen anyway
|
||||||
|
@ -296,50 +296,53 @@ nsTextControlFrame::EnsureEditorInitialized()
|
|||||||
|
|
||||||
// Make sure that editor init doesn't do things that would kill us off
|
// 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).
|
// (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()
|
// Time to mess with our security context... See comments in GetValue()
|
||||||
// for why this is needed.
|
// for why this is needed.
|
||||||
nsCxPusher pusher;
|
nsCxPusher pusher;
|
||||||
pusher.PushNull();
|
pusher.PushNull();
|
||||||
|
|
||||||
// Make sure that we try to focus the content even if the method fails
|
// Make sure that we try to focus the content even if the method fails
|
||||||
class EnsureSetFocus {
|
class EnsureSetFocus {
|
||||||
public:
|
public:
|
||||||
explicit EnsureSetFocus(nsTextControlFrame* aFrame)
|
explicit EnsureSetFocus(nsTextControlFrame* aFrame)
|
||||||
: mFrame(aFrame) {}
|
: mFrame(aFrame) {}
|
||||||
~EnsureSetFocus() {
|
~EnsureSetFocus() {
|
||||||
if (nsContentUtils::IsFocusedContent(mFrame->GetContent()))
|
if (nsContentUtils::IsFocusedContent(mFrame->GetContent()))
|
||||||
mFrame->SetFocus(true, false);
|
mFrame->SetFocus(true, false);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
nsTextControlFrame *mFrame;
|
nsTextControlFrame *mFrame;
|
||||||
};
|
};
|
||||||
EnsureSetFocus makeSureSetFocusHappens(this);
|
EnsureSetFocus makeSureSetFocusHappens(this);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
// Make sure we are not being called again until we're finished.
|
// Make sure we are not being called again until we're finished.
|
||||||
// If reentrancy happens, just pretend that we don't have an editor.
|
// If reentrancy happens, just pretend that we don't have an editor.
|
||||||
const EditorInitializerEntryTracker tracker(*this);
|
const EditorInitializerEntryTracker tracker(*this);
|
||||||
NS_ASSERTION(!tracker.EnteredMoreThanOnce(),
|
NS_ASSERTION(!tracker.EnteredMoreThanOnce(),
|
||||||
"EnsureEditorInitialized has been called while a previous call was in progress");
|
"EnsureEditorInitialized has been called while a previous call was in progress");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Create an editor for the frame, if one doesn't already exist
|
// Create an editor for the frame, if one doesn't already exist
|
||||||
nsCOMPtr<nsITextControlElement> txtCtrl = do_QueryInterface(GetContent());
|
nsCOMPtr<nsITextControlElement> txtCtrl = do_QueryInterface(GetContent());
|
||||||
NS_ASSERTION(txtCtrl, "Content not a text control element");
|
NS_ASSERTION(txtCtrl, "Content not a text control element");
|
||||||
nsresult rv = txtCtrl->CreateEditor();
|
nsresult rv = txtCtrl->CreateEditor();
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
NS_ENSURE_STATE(weakFrame.IsAlive());
|
||||||
|
|
||||||
// Turn on mUseEditor so that subsequent calls will use the
|
// Turn on mUseEditor so that subsequent calls will use the
|
||||||
// editor.
|
// editor.
|
||||||
mUseEditor = true;
|
mUseEditor = true;
|
||||||
|
|
||||||
// Set the selection to the beginning of the text field.
|
// Set the selection to the beginning of the text field.
|
||||||
if (weakFrame.IsAlive()) {
|
if (weakFrame.IsAlive()) {
|
||||||
SetSelectionEndPoints(0, 0);
|
SetSelectionEndPoints(0, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
NS_ENSURE_STATE(weakFrame.IsAlive());
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1089,8 +1092,10 @@ nsTextControlFrame::GetSelectionRange(int32_t* aSelectionStart,
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsContentUtils::GetSelectionInTextControl(typedSel,
|
mozilla::dom::Element* root = GetRootNodeAndInitializeEditor();
|
||||||
GetRootNodeAndInitializeEditor(), *aSelectionStart, *aSelectionEnd);
|
NS_ENSURE_STATE(root);
|
||||||
|
nsContentUtils::GetSelectionInTextControl(typedSel, root,
|
||||||
|
*aSelectionStart, *aSelectionEnd);
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user