Bug 1501260 - Make HTMLEditRules::DocumentModifiedWorker() create bogus node via editor instance r=m_kato

HTMLEditRules::DocumentModifiedWorker() may be called asynchronously via
AddScriptRunnder. Therefore, this may not be in the stack while editor handles
an edit action. Then, HTMLEditRules cannot access edit action data which will
be put on the stack after fixing bug 1465702. So, it should do it after once
calling a method of editor instance (and editor instance should call back
proper HTMLEditRules method).

Differential Revision: https://phabricator.services.mozilla.com/D9536

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Masayuki Nakano 2018-10-25 05:55:04 +00:00
parent 06adc212d6
commit 51565faee9
6 changed files with 55 additions and 21 deletions

View File

@ -11388,12 +11388,16 @@ HTMLEditRules::DocumentModifiedWorker()
return;
}
Selection* selection = mHTMLEditor->GetSelection();
if (NS_WARN_IF(!selection)) {
return;
}
RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
htmlEditor->OnModifyDocument();
}
AutoSafeEditorData setData(*this, *mHTMLEditor, *selection);
void
HTMLEditRules::OnModifyDocument(Selection& aSelection)
{
MOZ_ASSERT(mHTMLEditor);
AutoSafeEditorData setData(*this, *mHTMLEditor, aSelection);
// DeleteNodeWithTransaction() below may cause a flush, which could destroy
// the editor

View File

@ -108,7 +108,11 @@ public:
EditSubActionInfo& aInfo,
nsresult aResult) override;
virtual bool DocumentIsEmpty() override;
virtual nsresult DocumentModified() override;
/**
* DocumentModified() is called when editor content is changed.
*/
MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult DocumentModified();
nsresult GetListState(bool* aMixed, bool* aOL, bool* aUL, bool* aDL);
nsresult GetListItemState(bool* aMixed, bool* aLI, bool* aDT, bool* aDD);
@ -145,6 +149,12 @@ public:
void StartToListenToEditSubActions() { mListenerEnabled = true; }
void EndListeningToEditSubActions() { mListenerEnabled = false; }
/**
* OnModifyDocument() is called when DocumentModifiedWorker() calls
* HTMLEditor::OnModifyDocument().
*/
MOZ_CAN_RUN_SCRIPT void OnModifyDocument(Selection& aSelection);
protected:
virtual ~HTMLEditRules();
@ -1316,7 +1326,11 @@ protected:
*/
MOZ_MUST_USE nsresult ChangeMarginStart(Element& aElement, bool aIncrease);
void DocumentModifiedWorker();
/**
* DocumentModifiedWorker() is called by DocumentModified() either
* synchronously or asynchronously.
*/
MOZ_CAN_RUN_SCRIPT void DocumentModifiedWorker();
/**
* InitStyleCacheArray() initializes aStyleCache for usable with

View File

@ -3521,9 +3521,10 @@ HTMLEditor::DoContentInserted(nsIContent* aChild,
// Ignore insertion of the bogus node
return;
}
// Protect the edit rules object from dying
RefPtr<TextEditRules> rules(mRules);
rules->DocumentModified();
RefPtr<HTMLEditRules> htmlRules = mRules->AsHTMLEditRules();
if (htmlRules) {
htmlRules->DocumentModified();
}
// Update spellcheck for only the newly-inserted node (bug 743819)
if (mInlineSpellChecker) {
@ -3564,9 +3565,11 @@ HTMLEditor::ContentRemoved(nsIContent* aChild,
// Ignore removal of the bogus node
return;
}
// Protect the edit rules object from dying
RefPtr<TextEditRules> rules(mRules);
rules->DocumentModified();
RefPtr<HTMLEditRules> htmlRules = mRules->AsHTMLEditRules();
if (htmlRules) {
htmlRules->DocumentModified();
}
}
}
@ -5222,4 +5225,18 @@ HTMLEditor::GetHTMLDocument() const
return doc->AsHTMLDocument();
}
void
HTMLEditor::OnModifyDocument()
{
MOZ_ASSERT(mRules);
RefPtr<Selection> selection = GetSelection();
if (NS_WARN_IF(!selection)) {
return;
}
RefPtr<HTMLEditRules> htmlRules = mRules->AsHTMLEditRules();
htmlRules->OnModifyDocument(*selection);
}
} // namespace mozilla

View File

@ -981,6 +981,13 @@ protected: // May be called by friends.
nsresult SetPositionToAbsolute(Element& aElement);
nsresult SetPositionToStatic(Element& aElement);
/**
* OnModifyDocument() is called when the editor is changed. This should
* be called only by HTMLEditRules::DocumentModifiedWorker() to call
* HTMLEditRules::OnModifyDocument().
*/
MOZ_CAN_RUN_SCRIPT void OnModifyDocument();
protected: // Called by helper classes.
virtual void
OnStartToHandleTopLevelEditSubAction(

View File

@ -1846,12 +1846,6 @@ TextEditRules::CreateBRInternal(
return CreateElementResult(brElement.forget());
}
nsresult
TextEditRules::DocumentModified()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
bool
TextEditRules::IsPasswordEditor() const
{

View File

@ -104,8 +104,6 @@ public:
*/
virtual bool DocumentIsEmpty();
virtual nsresult DocumentModified();
protected:
virtual ~TextEditRules();