mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-17 15:25:52 +00:00
Bug 1612477 - part 1: Make ComposerCommandsUpdater
not inherit nsIDocumentStateListener
r=m_kato
This patch makes `EditorBase::NotifyDocumentListeners()` notify `ComposerCommandsUpdater` via `HTMLEditor::mComposerCommandsUpdater` directly. Therefore, `ComposerCommandsUpdater` can stop inheriting `nsIDocumentStateListener`. Note that this patch also makes `ComposerCommandsUpdater::UpdateCommandGroup()` not take `nsAString` as its parameter because inlinning the `nsIDocumentStateListener` requires `ComposerCommandsUpdater.h` to include `nsAString.h`, but it's redundant and `UpdateCommandGroup()` just compares it with literal strings. Therefore, using `enum class` for specifying command group is faster. Differential Revision: https://phabricator.services.mozilla.com/D61357 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
b36c4e44b6
commit
cc2af30635
@ -9,7 +9,6 @@
|
||||
#include "mozilla/mozalloc.h" // for operator new
|
||||
#include "mozilla/TransactionManager.h" // for TransactionManager
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "nsAString.h"
|
||||
#include "nsCommandManager.h" // for nsCommandManager
|
||||
#include "nsComponentManagerUtils.h" // for do_CreateInstance
|
||||
#include "nsDebug.h" // for NS_ENSURE_TRUE, etc
|
||||
@ -40,11 +39,10 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(ComposerCommandsUpdater)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(ComposerCommandsUpdater)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(ComposerCommandsUpdater)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDocumentStateListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsITransactionListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
|
||||
NS_INTERFACE_MAP_ENTRY(nsINamed)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDocumentStateListener)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsITransactionListener)
|
||||
NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(ComposerCommandsUpdater)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
@ -55,58 +53,22 @@ NS_IMPL_CYCLE_COLLECTION(ComposerCommandsUpdater, mUpdateTimer, mDOMWindow,
|
||||
# pragma mark -
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP
|
||||
ComposerCommandsUpdater::NotifyDocumentCreated() {
|
||||
// Trigger an nsIObserve notification that the document has been created
|
||||
UpdateOneCommand("obs_documentCreated");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ComposerCommandsUpdater::NotifyDocumentWillBeDestroyed() {
|
||||
// cancel any outstanding update timer
|
||||
if (mUpdateTimer) {
|
||||
mUpdateTimer->Cancel();
|
||||
mUpdateTimer = nullptr;
|
||||
}
|
||||
|
||||
// We can't call this right now; it is too late in some cases and the window
|
||||
// is already partially destructed (e.g. JS objects may be gone).
|
||||
#if 0
|
||||
// Trigger an nsIObserve notification that the document will be destroyed
|
||||
UpdateOneCommand("obs_documentWillBeDestroyed");
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ComposerCommandsUpdater::NotifyDocumentStateChanged(bool aNowDirty) {
|
||||
// update document modified. We should have some other notifications for this
|
||||
// too.
|
||||
return UpdateDirtyState(aNowDirty);
|
||||
}
|
||||
|
||||
#if 0
|
||||
# pragma mark -
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP
|
||||
ComposerCommandsUpdater::WillDo(nsITransactionManager* aManager,
|
||||
nsITransaction* aTransaction,
|
||||
bool* aInterrupt) {
|
||||
NS_IMETHODIMP ComposerCommandsUpdater::WillDo(nsITransactionManager* aManager,
|
||||
nsITransaction* aTransaction,
|
||||
bool* aInterrupt) {
|
||||
*aInterrupt = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ComposerCommandsUpdater::DidDo(nsITransactionManager* aManager,
|
||||
nsITransaction* aTransaction,
|
||||
nsresult aDoResult) {
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
||||
NS_IMETHODIMP ComposerCommandsUpdater::DidDo(nsITransactionManager* aManager,
|
||||
nsITransaction* aTransaction,
|
||||
nsresult aDoResult) {
|
||||
// only need to update if the status of the Undo menu item changes.
|
||||
size_t undoCount = aManager->AsTransactionManager()->NumberOfUndoItems();
|
||||
if (undoCount == 1) {
|
||||
if (mFirstDoOfFirstUndo) {
|
||||
UpdateCommandGroup(NS_LITERAL_STRING("undo"));
|
||||
UpdateCommandGroup(CommandGroup::Undo);
|
||||
}
|
||||
mFirstDoOfFirstUndo = false;
|
||||
}
|
||||
@ -114,82 +76,73 @@ ComposerCommandsUpdater::DidDo(nsITransactionManager* aManager,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ComposerCommandsUpdater::WillUndo(nsITransactionManager* aManager,
|
||||
nsITransaction* aTransaction,
|
||||
bool* aInterrupt) {
|
||||
NS_IMETHODIMP ComposerCommandsUpdater::WillUndo(nsITransactionManager* aManager,
|
||||
nsITransaction* aTransaction,
|
||||
bool* aInterrupt) {
|
||||
*aInterrupt = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ComposerCommandsUpdater::DidUndo(nsITransactionManager* aManager,
|
||||
nsITransaction* aTransaction,
|
||||
nsresult aUndoResult) {
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
||||
NS_IMETHODIMP ComposerCommandsUpdater::DidUndo(nsITransactionManager* aManager,
|
||||
nsITransaction* aTransaction,
|
||||
nsresult aUndoResult) {
|
||||
size_t undoCount = aManager->AsTransactionManager()->NumberOfUndoItems();
|
||||
if (!undoCount) {
|
||||
mFirstDoOfFirstUndo = true; // reset the state for the next do
|
||||
}
|
||||
UpdateCommandGroup(NS_LITERAL_STRING("undo"));
|
||||
UpdateCommandGroup(CommandGroup::Undo);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ComposerCommandsUpdater::WillRedo(nsITransactionManager* aManager,
|
||||
nsITransaction* aTransaction,
|
||||
bool* aInterrupt) {
|
||||
NS_IMETHODIMP ComposerCommandsUpdater::WillRedo(nsITransactionManager* aManager,
|
||||
nsITransaction* aTransaction,
|
||||
bool* aInterrupt) {
|
||||
*aInterrupt = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ComposerCommandsUpdater::DidRedo(nsITransactionManager* aManager,
|
||||
nsITransaction* aTransaction,
|
||||
nsresult aRedoResult) {
|
||||
UpdateCommandGroup(NS_LITERAL_STRING("undo"));
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
||||
NS_IMETHODIMP ComposerCommandsUpdater::DidRedo(nsITransactionManager* aManager,
|
||||
nsITransaction* aTransaction,
|
||||
nsresult aRedoResult) {
|
||||
UpdateCommandGroup(CommandGroup::Undo);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ComposerCommandsUpdater::WillBeginBatch(nsITransactionManager* aManager,
|
||||
bool* aInterrupt) {
|
||||
NS_IMETHODIMP ComposerCommandsUpdater::WillBeginBatch(
|
||||
nsITransactionManager* aManager, bool* aInterrupt) {
|
||||
*aInterrupt = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ComposerCommandsUpdater::DidBeginBatch(nsITransactionManager* aManager,
|
||||
nsresult aResult) {
|
||||
NS_IMETHODIMP ComposerCommandsUpdater::DidBeginBatch(
|
||||
nsITransactionManager* aManager, nsresult aResult) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ComposerCommandsUpdater::WillEndBatch(nsITransactionManager* aManager,
|
||||
bool* aInterrupt) {
|
||||
NS_IMETHODIMP ComposerCommandsUpdater::WillEndBatch(
|
||||
nsITransactionManager* aManager, bool* aInterrupt) {
|
||||
*aInterrupt = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ComposerCommandsUpdater::DidEndBatch(nsITransactionManager* aManager,
|
||||
nsresult aResult) {
|
||||
NS_IMETHODIMP ComposerCommandsUpdater::DidEndBatch(
|
||||
nsITransactionManager* aManager, nsresult aResult) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ComposerCommandsUpdater::WillMerge(nsITransactionManager* aManager,
|
||||
nsITransaction* aTopTransaction,
|
||||
nsITransaction* aTransactionToMerge,
|
||||
bool* aInterrupt) {
|
||||
NS_IMETHODIMP ComposerCommandsUpdater::WillMerge(
|
||||
nsITransactionManager* aManager, nsITransaction* aTopTransaction,
|
||||
nsITransaction* aTransactionToMerge, bool* aInterrupt) {
|
||||
*aInterrupt = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ComposerCommandsUpdater::DidMerge(nsITransactionManager* aManager,
|
||||
nsITransaction* aTopTransaction,
|
||||
nsITransaction* aTransactionToMerge,
|
||||
bool aDidMerge, nsresult aMergeResult) {
|
||||
NS_IMETHODIMP ComposerCommandsUpdater::DidMerge(
|
||||
nsITransactionManager* aManager, nsITransaction* aTopTransaction,
|
||||
nsITransaction* aTransactionToMerge, bool aDidMerge,
|
||||
nsresult aMergeResult) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -205,90 +158,66 @@ void ComposerCommandsUpdater::Init(nsPIDOMWindowOuter& aDOMWindow) {
|
||||
nsresult ComposerCommandsUpdater::PrimeUpdateTimer() {
|
||||
if (!mUpdateTimer) {
|
||||
mUpdateTimer = NS_NewTimer();
|
||||
;
|
||||
NS_ENSURE_TRUE(mUpdateTimer, NS_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
const uint32_t kUpdateTimerDelay = 150;
|
||||
return mUpdateTimer->InitWithCallback(static_cast<nsITimerCallback*>(this),
|
||||
kUpdateTimerDelay,
|
||||
nsITimer::TYPE_ONE_SHOT);
|
||||
}
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
||||
void ComposerCommandsUpdater::TimerCallback() {
|
||||
// if the selection state has changed, update stuff
|
||||
bool isCollapsed = SelectionIsCollapsed();
|
||||
if (static_cast<int8_t>(isCollapsed) != mSelectionCollapsed) {
|
||||
UpdateCommandGroup(NS_LITERAL_STRING("select"));
|
||||
mSelectionCollapsed = isCollapsed;
|
||||
}
|
||||
|
||||
// isn't this redundant with the UpdateCommandGroup above?
|
||||
// can we just nuke the above call? or create a meta command group?
|
||||
UpdateCommandGroup(NS_LITERAL_STRING("style"));
|
||||
mSelectionCollapsed = SelectionIsCollapsed();
|
||||
UpdateCommandGroup(CommandGroup::Style);
|
||||
}
|
||||
|
||||
nsresult ComposerCommandsUpdater::UpdateDirtyState(bool aNowDirty) {
|
||||
if (mDirtyState != static_cast<int8_t>(aNowDirty)) {
|
||||
UpdateCommandGroup(NS_LITERAL_STRING("save"));
|
||||
UpdateCommandGroup(NS_LITERAL_STRING("undo"));
|
||||
mDirtyState = aNowDirty;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult ComposerCommandsUpdater::UpdateCommandGroup(
|
||||
const nsAString& aCommandGroup) {
|
||||
void ComposerCommandsUpdater::UpdateCommandGroup(CommandGroup aCommandGroup) {
|
||||
RefPtr<nsCommandManager> commandManager = GetCommandManager();
|
||||
NS_ENSURE_TRUE(commandManager, NS_ERROR_FAILURE);
|
||||
|
||||
if (aCommandGroup.EqualsLiteral("undo")) {
|
||||
commandManager->CommandStatusChanged("cmd_undo");
|
||||
commandManager->CommandStatusChanged("cmd_redo");
|
||||
return NS_OK;
|
||||
if (NS_WARN_IF(!commandManager)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aCommandGroup.EqualsLiteral("select") ||
|
||||
aCommandGroup.EqualsLiteral("style")) {
|
||||
commandManager->CommandStatusChanged("cmd_bold");
|
||||
commandManager->CommandStatusChanged("cmd_italic");
|
||||
commandManager->CommandStatusChanged("cmd_underline");
|
||||
commandManager->CommandStatusChanged("cmd_tt");
|
||||
switch (aCommandGroup) {
|
||||
case CommandGroup::Undo:
|
||||
commandManager->CommandStatusChanged("cmd_undo");
|
||||
commandManager->CommandStatusChanged("cmd_redo");
|
||||
return;
|
||||
case CommandGroup::Style:
|
||||
commandManager->CommandStatusChanged("cmd_bold");
|
||||
commandManager->CommandStatusChanged("cmd_italic");
|
||||
commandManager->CommandStatusChanged("cmd_underline");
|
||||
commandManager->CommandStatusChanged("cmd_tt");
|
||||
|
||||
commandManager->CommandStatusChanged("cmd_strikethrough");
|
||||
commandManager->CommandStatusChanged("cmd_superscript");
|
||||
commandManager->CommandStatusChanged("cmd_subscript");
|
||||
commandManager->CommandStatusChanged("cmd_nobreak");
|
||||
commandManager->CommandStatusChanged("cmd_strikethrough");
|
||||
commandManager->CommandStatusChanged("cmd_superscript");
|
||||
commandManager->CommandStatusChanged("cmd_subscript");
|
||||
commandManager->CommandStatusChanged("cmd_nobreak");
|
||||
|
||||
commandManager->CommandStatusChanged("cmd_em");
|
||||
commandManager->CommandStatusChanged("cmd_strong");
|
||||
commandManager->CommandStatusChanged("cmd_cite");
|
||||
commandManager->CommandStatusChanged("cmd_abbr");
|
||||
commandManager->CommandStatusChanged("cmd_acronym");
|
||||
commandManager->CommandStatusChanged("cmd_code");
|
||||
commandManager->CommandStatusChanged("cmd_samp");
|
||||
commandManager->CommandStatusChanged("cmd_var");
|
||||
commandManager->CommandStatusChanged("cmd_em");
|
||||
commandManager->CommandStatusChanged("cmd_strong");
|
||||
commandManager->CommandStatusChanged("cmd_cite");
|
||||
commandManager->CommandStatusChanged("cmd_abbr");
|
||||
commandManager->CommandStatusChanged("cmd_acronym");
|
||||
commandManager->CommandStatusChanged("cmd_code");
|
||||
commandManager->CommandStatusChanged("cmd_samp");
|
||||
commandManager->CommandStatusChanged("cmd_var");
|
||||
|
||||
commandManager->CommandStatusChanged("cmd_increaseFont");
|
||||
commandManager->CommandStatusChanged("cmd_decreaseFont");
|
||||
commandManager->CommandStatusChanged("cmd_increaseFont");
|
||||
commandManager->CommandStatusChanged("cmd_decreaseFont");
|
||||
|
||||
commandManager->CommandStatusChanged("cmd_paragraphState");
|
||||
commandManager->CommandStatusChanged("cmd_fontFace");
|
||||
commandManager->CommandStatusChanged("cmd_fontColor");
|
||||
commandManager->CommandStatusChanged("cmd_backgroundColor");
|
||||
commandManager->CommandStatusChanged("cmd_highlight");
|
||||
return NS_OK;
|
||||
commandManager->CommandStatusChanged("cmd_paragraphState");
|
||||
commandManager->CommandStatusChanged("cmd_fontFace");
|
||||
commandManager->CommandStatusChanged("cmd_fontColor");
|
||||
commandManager->CommandStatusChanged("cmd_backgroundColor");
|
||||
commandManager->CommandStatusChanged("cmd_highlight");
|
||||
return;
|
||||
case CommandGroup::Save:
|
||||
commandManager->CommandStatusChanged("cmd_setDocumentModified");
|
||||
commandManager->CommandStatusChanged("cmd_save");
|
||||
return;
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("New command group hasn't been implemented yet");
|
||||
}
|
||||
|
||||
if (aCommandGroup.EqualsLiteral("save")) {
|
||||
// save commands (most are not in C++)
|
||||
commandManager->CommandStatusChanged("cmd_setDocumentModified");
|
||||
commandManager->CommandStatusChanged("cmd_save");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult ComposerCommandsUpdater::UpdateOneCommand(const char* aCommand) {
|
||||
@ -318,8 +247,7 @@ nsCommandManager* ComposerCommandsUpdater::GetCommandManager() {
|
||||
return mDocShell->GetCommandManager();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ComposerCommandsUpdater::GetName(nsACString& aName) {
|
||||
NS_IMETHODIMP ComposerCommandsUpdater::GetName(nsACString& aName) {
|
||||
aName.AssignLiteral("ComposerCommandsUpdater");
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
#include "nsCOMPtr.h" // for already_AddRefed, nsCOMPtr
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsIDocumentStateListener.h"
|
||||
#include "nsINamed.h"
|
||||
#include "nsISupportsImpl.h" // for NS_DECL_ISUPPORTS
|
||||
#include "nsITimer.h" // for NS_DECL_NSITIMERCALLBACK, etc
|
||||
@ -24,8 +23,7 @@ class nsPIDOMWindowOuter;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class ComposerCommandsUpdater final : public nsIDocumentStateListener,
|
||||
public nsITransactionListener,
|
||||
class ComposerCommandsUpdater final : public nsITransactionListener,
|
||||
public nsITimerCallback,
|
||||
public nsINamed {
|
||||
public:
|
||||
@ -34,10 +32,7 @@ class ComposerCommandsUpdater final : public nsIDocumentStateListener,
|
||||
// nsISupports
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(ComposerCommandsUpdater,
|
||||
nsIDocumentStateListener)
|
||||
|
||||
// nsIDocumentStateListener
|
||||
NS_DECL_NSIDOCUMENTSTATELISTENER
|
||||
nsITransactionListener)
|
||||
|
||||
// nsITimerCallback
|
||||
NS_DECL_NSITIMERCALLBACK
|
||||
@ -55,6 +50,43 @@ class ComposerCommandsUpdater final : public nsIDocumentStateListener,
|
||||
*/
|
||||
void OnSelectionChange() { PrimeUpdateTimer(); }
|
||||
|
||||
/**
|
||||
* OnHTMLEditorCreated() is called when `HTMLEditor` is created and
|
||||
* initialized.
|
||||
*/
|
||||
MOZ_CAN_RUN_SCRIPT void OnHTMLEditorCreated() {
|
||||
UpdateOneCommand("obs_documentCreated");
|
||||
}
|
||||
|
||||
/**
|
||||
* OnBeforeHTMLEditorDestroyed() is called when `HTMLEditor` is being
|
||||
* destroyed.
|
||||
*/
|
||||
MOZ_CAN_RUN_SCRIPT void OnBeforeHTMLEditorDestroyed() {
|
||||
// cancel any outstanding update timer
|
||||
if (mUpdateTimer) {
|
||||
mUpdateTimer->Cancel();
|
||||
mUpdateTimer = nullptr;
|
||||
}
|
||||
|
||||
// We can't notify the command manager of this right now; it is too late in
|
||||
// some cases and the window is already partially destructed (e.g. JS
|
||||
// objects may be gone).
|
||||
}
|
||||
|
||||
/**
|
||||
* OnHTMLEditorDirtyStateChanged() is called when dirty state of `HTMLEditor`
|
||||
* is changed form or to "dirty".
|
||||
*/
|
||||
MOZ_CAN_RUN_SCRIPT void OnHTMLEditorDirtyStateChanged(bool aNowDirty) {
|
||||
if (mDirtyState == static_cast<int8_t>(aNowDirty)) {
|
||||
return;
|
||||
}
|
||||
UpdateCommandGroup(CommandGroup::Save);
|
||||
UpdateCommandGroup(CommandGroup::Undo);
|
||||
mDirtyState = aNowDirty;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~ComposerCommandsUpdater();
|
||||
|
||||
@ -65,9 +97,13 @@ class ComposerCommandsUpdater final : public nsIDocumentStateListener,
|
||||
};
|
||||
|
||||
bool SelectionIsCollapsed();
|
||||
nsresult UpdateDirtyState(bool aNowDirty);
|
||||
nsresult UpdateOneCommand(const char* aCommand);
|
||||
nsresult UpdateCommandGroup(const nsAString& aCommandGroup);
|
||||
MOZ_CAN_RUN_SCRIPT nsresult UpdateOneCommand(const char* aCommand);
|
||||
enum class CommandGroup {
|
||||
Save,
|
||||
Style,
|
||||
Undo,
|
||||
};
|
||||
MOZ_CAN_RUN_SCRIPT void UpdateCommandGroup(CommandGroup aCommandGroup);
|
||||
|
||||
nsCommandManager* GetCommandManager();
|
||||
|
||||
|
@ -335,7 +335,7 @@ nsresult nsEditingSession::SetupEditorOnWindow(nsPIDOMWindowOuter& aWindow) {
|
||||
|
||||
if (mEditorStatus != eEditorCreationInProgress) {
|
||||
RefPtr<ComposerCommandsUpdater> updater = mComposerCommandsUpdater;
|
||||
updater->NotifyDocumentCreated();
|
||||
updater->OnHTMLEditorCreated();
|
||||
|
||||
// At this point we have made a final decision that we don't support
|
||||
// editing the current document. This is an internal failure state, but
|
||||
@ -411,8 +411,7 @@ nsresult nsEditingSession::SetupEditorOnWindow(nsPIDOMWindowOuter& aWindow) {
|
||||
|
||||
// Set up as a doc state listener
|
||||
// Important! We must have this to broadcast the "obs_documentCreated" message
|
||||
rv = htmlEditor->AddDocumentStateListener(mComposerCommandsUpdater);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
htmlEditor->SetComposerCommandsUpdater(mComposerCommandsUpdater);
|
||||
|
||||
rv = htmlEditor->Init(*doc, nullptr /* root content */, nullptr, mEditorFlags,
|
||||
EmptyString());
|
||||
@ -423,8 +422,6 @@ nsresult nsEditingSession::SetupEditorOnWindow(nsPIDOMWindowOuter& aWindow) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
htmlEditor->SetComposerCommandsUpdater(mComposerCommandsUpdater);
|
||||
|
||||
// and as a transaction listener
|
||||
MOZ_ASSERT(mComposerCommandsUpdater);
|
||||
DebugOnly<bool> addedTransactionListener =
|
||||
@ -452,7 +449,6 @@ void nsEditingSession::RemoveListenersAndControllers(
|
||||
|
||||
// Remove all the listeners
|
||||
aHTMLEditor->SetComposerCommandsUpdater(nullptr);
|
||||
aHTMLEditor->RemoveDocumentStateListener(mComposerCommandsUpdater);
|
||||
DebugOnly<bool> removedTransactionListener =
|
||||
aHTMLEditor->RemoveTransactionListener(*mComposerCommandsUpdater);
|
||||
NS_WARNING_ASSERTION(removedTransactionListener,
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "PlaceholderTransaction.h" // for PlaceholderTransaction
|
||||
#include "SplitNodeTransaction.h" // for SplitNodeTransaction
|
||||
#include "mozilla/CheckedInt.h" // for CheckedInt
|
||||
#include "mozilla/ComposerCommandsUpdater.h" // for ComposerCommandsUpdater
|
||||
#include "mozilla/ComputedStyle.h" // for ComputedStyle
|
||||
#include "mozilla/CSSEditUtils.h" // for CSSEditUtils
|
||||
#include "mozilla/EditAction.h" // for EditSubAction
|
||||
@ -2883,37 +2884,44 @@ nsINode* EditorBase::GetFirstEditableNode(nsINode* aRoot) {
|
||||
|
||||
nsresult EditorBase::NotifyDocumentListeners(
|
||||
TDocumentListenerNotification aNotificationType) {
|
||||
if (!mDocStateListeners.Length()) {
|
||||
// Maybe there just aren't any.
|
||||
RefPtr<ComposerCommandsUpdater> composerCommandsUpdate =
|
||||
AsHTMLEditor() ? AsHTMLEditor()->mComposerCommandsUpdater : nullptr;
|
||||
if (!mDocStateListeners.Length() && !composerCommandsUpdate) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
AutoDocumentStateListenerArray listeners(mDocStateListeners);
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
switch (aNotificationType) {
|
||||
case eDocumentCreated:
|
||||
if (composerCommandsUpdate) {
|
||||
composerCommandsUpdate->OnHTMLEditorCreated();
|
||||
}
|
||||
for (auto& listener : listeners) {
|
||||
rv = listener->NotifyDocumentCreated();
|
||||
if (NS_FAILED(rv)) {
|
||||
break;
|
||||
nsresult rv = listener->NotifyDocumentCreated();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
break;
|
||||
return NS_OK;
|
||||
|
||||
case eDocumentToBeDestroyed:
|
||||
if (composerCommandsUpdate) {
|
||||
composerCommandsUpdate->OnBeforeHTMLEditorDestroyed();
|
||||
}
|
||||
for (auto& listener : listeners) {
|
||||
rv = listener->NotifyDocumentWillBeDestroyed();
|
||||
if (NS_FAILED(rv)) {
|
||||
break;
|
||||
nsresult rv = listener->NotifyDocumentWillBeDestroyed();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
break;
|
||||
return NS_OK;
|
||||
|
||||
case eDocumentStateChanged: {
|
||||
bool docIsDirty;
|
||||
rv = GetDocumentModified(&docIsDirty);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsresult rv = GetDocumentModified(&docIsDirty);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (static_cast<int8_t>(docIsDirty) == mDocDirtyState) {
|
||||
return NS_OK;
|
||||
@ -2921,19 +2929,21 @@ nsresult EditorBase::NotifyDocumentListeners(
|
||||
|
||||
mDocDirtyState = docIsDirty;
|
||||
|
||||
if (composerCommandsUpdate) {
|
||||
composerCommandsUpdate->OnHTMLEditorDirtyStateChanged(mDocDirtyState);
|
||||
}
|
||||
for (auto& listener : listeners) {
|
||||
rv = listener->NotifyDocumentStateChanged(mDocDirtyState);
|
||||
if (NS_FAILED(rv)) {
|
||||
break;
|
||||
nsresult rv = listener->NotifyDocumentStateChanged(mDocDirtyState);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
break;
|
||||
return NS_OK;
|
||||
}
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("Unknown notification");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult EditorBase::SetTextNodeWithoutTransaction(const nsAString& aString,
|
||||
|
@ -2839,9 +2839,8 @@ class EditorBase : public nsIEditor,
|
||||
AutoEditorObserverArray;
|
||||
AutoEditorObserverArray mEditorObservers;
|
||||
// Listen to overall doc state (dirty or not, just created, etc.).
|
||||
// Document state listener is currently used by EditingSession and
|
||||
// BlueGriffon so that reserving only one is enough (although, this is not
|
||||
// necessary for TextEditor).
|
||||
// Document state listener is currently used by FinderHighlighter and
|
||||
// BlueGriffon so that reserving only one is enough.
|
||||
typedef AutoTArray<OwningNonNull<nsIDocumentStateListener>, 1>
|
||||
AutoDocumentStateListenerArray;
|
||||
AutoDocumentStateListenerArray mDocStateListeners;
|
||||
|
Loading…
Reference in New Issue
Block a user