mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 12:51:06 +00:00
9fd1e2d108
Now, nobody (including comm-central) uses `nsITransactionListener` interface. This patch also optimizes the notifying methods of `HTMLEditor` from `TransactionManager` to make them safer and simpler. The `HTMLEditor`'s methods can drop some arguments, but I'd like to keep them to make new listeners in the future handle them easier and safer, but the `ComposerCommandsUpdater` does not require them. This is the reason why the difference of the methods' arguments. Depends on D145664 Differential Revision: https://phabricator.services.mozilla.com/D145667
200 lines
6.5 KiB
C++
200 lines
6.5 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "mozilla/ComposerCommandsUpdater.h"
|
|
|
|
#include "mozilla/mozalloc.h" // for operator new
|
|
#include "mozilla/TransactionManager.h" // for TransactionManager
|
|
#include "mozilla/dom/Selection.h"
|
|
#include "nsCommandManager.h" // for nsCommandManager
|
|
#include "nsComponentManagerUtils.h" // for do_CreateInstance
|
|
#include "nsDebug.h" // for NS_ENSURE_TRUE, etc
|
|
#include "nsDocShell.h" // for nsIDocShell
|
|
#include "nsError.h" // for NS_OK, NS_ERROR_FAILURE, etc
|
|
#include "nsID.h" // for NS_GET_IID, etc
|
|
#include "nsIInterfaceRequestorUtils.h" // for do_GetInterface
|
|
#include "nsLiteralString.h" // for NS_LITERAL_STRING
|
|
#include "nsPIDOMWindow.h" // for nsPIDOMWindow
|
|
|
|
class nsITransaction;
|
|
|
|
namespace mozilla {
|
|
|
|
ComposerCommandsUpdater::ComposerCommandsUpdater()
|
|
: mDirtyState(eStateUninitialized),
|
|
mSelectionCollapsed(eStateUninitialized),
|
|
mFirstDoOfFirstUndo(true) {}
|
|
|
|
ComposerCommandsUpdater::~ComposerCommandsUpdater() {
|
|
// cancel any outstanding update timer
|
|
if (mUpdateTimer) {
|
|
mUpdateTimer->Cancel();
|
|
}
|
|
}
|
|
|
|
NS_IMPL_CYCLE_COLLECTING_ADDREF(ComposerCommandsUpdater)
|
|
NS_IMPL_CYCLE_COLLECTING_RELEASE(ComposerCommandsUpdater)
|
|
|
|
NS_INTERFACE_MAP_BEGIN(ComposerCommandsUpdater)
|
|
NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
|
|
NS_INTERFACE_MAP_ENTRY(nsINamed)
|
|
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsITimerCallback)
|
|
NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(ComposerCommandsUpdater)
|
|
NS_INTERFACE_MAP_END
|
|
|
|
NS_IMPL_CYCLE_COLLECTION(ComposerCommandsUpdater, mUpdateTimer, mDOMWindow,
|
|
mDocShell)
|
|
|
|
#if 0
|
|
# pragma mark -
|
|
#endif
|
|
|
|
void ComposerCommandsUpdater::DidDoTransaction(
|
|
TransactionManager& aTransactionManager) {
|
|
// only need to update if the status of the Undo menu item changes.
|
|
if (aTransactionManager.NumberOfUndoItems() == 1) {
|
|
if (mFirstDoOfFirstUndo) {
|
|
UpdateCommandGroup(CommandGroup::Undo);
|
|
}
|
|
mFirstDoOfFirstUndo = false;
|
|
}
|
|
}
|
|
|
|
void ComposerCommandsUpdater::DidUndoTransaction(
|
|
TransactionManager& aTransactionManager) {
|
|
if (!aTransactionManager.NumberOfUndoItems()) {
|
|
mFirstDoOfFirstUndo = true; // reset the state for the next do
|
|
}
|
|
UpdateCommandGroup(CommandGroup::Undo);
|
|
}
|
|
|
|
void ComposerCommandsUpdater::DidRedoTransaction(
|
|
TransactionManager& aTransactionManager) {
|
|
UpdateCommandGroup(CommandGroup::Undo);
|
|
}
|
|
|
|
#if 0
|
|
# pragma mark -
|
|
#endif
|
|
|
|
void ComposerCommandsUpdater::Init(nsPIDOMWindowOuter& aDOMWindow) {
|
|
mDOMWindow = &aDOMWindow;
|
|
mDocShell = aDOMWindow.GetDocShell();
|
|
}
|
|
|
|
nsresult ComposerCommandsUpdater::PrimeUpdateTimer() {
|
|
if (!mUpdateTimer) {
|
|
mUpdateTimer = NS_NewTimer();
|
|
}
|
|
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() {
|
|
mSelectionCollapsed = SelectionIsCollapsed();
|
|
UpdateCommandGroup(CommandGroup::Style);
|
|
}
|
|
|
|
void ComposerCommandsUpdater::UpdateCommandGroup(CommandGroup aCommandGroup) {
|
|
RefPtr<nsCommandManager> commandManager = GetCommandManager();
|
|
if (NS_WARN_IF(!commandManager)) {
|
|
return;
|
|
}
|
|
|
|
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_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_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");
|
|
}
|
|
}
|
|
|
|
nsresult ComposerCommandsUpdater::UpdateOneCommand(const char* aCommand) {
|
|
RefPtr<nsCommandManager> commandManager = GetCommandManager();
|
|
NS_ENSURE_TRUE(commandManager, NS_ERROR_FAILURE);
|
|
commandManager->CommandStatusChanged(aCommand);
|
|
return NS_OK;
|
|
}
|
|
|
|
bool ComposerCommandsUpdater::SelectionIsCollapsed() {
|
|
if (NS_WARN_IF(!mDOMWindow)) {
|
|
return true;
|
|
}
|
|
|
|
RefPtr<dom::Selection> domSelection = mDOMWindow->GetSelection();
|
|
if (NS_WARN_IF(!domSelection)) {
|
|
return false;
|
|
}
|
|
|
|
return domSelection->IsCollapsed();
|
|
}
|
|
|
|
nsCommandManager* ComposerCommandsUpdater::GetCommandManager() {
|
|
if (NS_WARN_IF(!mDocShell)) {
|
|
return nullptr;
|
|
}
|
|
return mDocShell->GetCommandManager();
|
|
}
|
|
|
|
NS_IMETHODIMP ComposerCommandsUpdater::GetName(nsACString& aName) {
|
|
aName.AssignLiteral("ComposerCommandsUpdater");
|
|
return NS_OK;
|
|
}
|
|
|
|
#if 0
|
|
# pragma mark -
|
|
#endif
|
|
|
|
nsresult ComposerCommandsUpdater::Notify(nsITimer* aTimer) {
|
|
NS_ASSERTION(aTimer == mUpdateTimer.get(), "Hey, this ain't my timer!");
|
|
TimerCallback();
|
|
return NS_OK;
|
|
}
|
|
|
|
#if 0
|
|
# pragma mark -
|
|
#endif
|
|
|
|
} // namespace mozilla
|