mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
Bug 1692673 - Avoid enabling Cut/Copy menu commands in text editor context when there's no selection, unless a listener is present. r=masayuki
Differential Revision: https://phabricator.services.mozilla.com/D107480
This commit is contained in:
parent
ba2a3835f3
commit
91adcd2694
@ -1248,7 +1248,7 @@ NS_IMETHODIMP EditorBase::CanCut(bool* aCanCut) {
|
||||
if (NS_WARN_IF(!aCanCut)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
*aCanCut = AsTextEditor()->IsCutCommandEnabled();
|
||||
*aCanCut = MOZ_KnownLive(AsTextEditor())->IsCutCommandEnabled();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1258,7 +1258,7 @@ NS_IMETHODIMP EditorBase::CanCopy(bool* aCanCopy) {
|
||||
if (NS_WARN_IF(!aCanCopy)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
*aCanCopy = AsTextEditor()->IsCopyCommandEnabled();
|
||||
*aCanCopy = MOZ_KnownLive(AsTextEditor())->IsCopyCommandEnabled();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -13,9 +13,11 @@
|
||||
#include "PlaceholderTransaction.h"
|
||||
#include "gfxFontUtils.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/ContentEvents.h"
|
||||
#include "mozilla/ContentIterator.h"
|
||||
#include "mozilla/EditAction.h"
|
||||
#include "mozilla/EditorDOMPoint.h"
|
||||
#include "mozilla/EventDispatcher.h"
|
||||
#include "mozilla/HTMLEditor.h"
|
||||
#include "mozilla/IMEStateManager.h"
|
||||
#include "mozilla/LookAndFeel.h"
|
||||
@ -54,6 +56,7 @@
|
||||
#include "nsIWeakReferenceUtils.h"
|
||||
#include "nsNameSpaceManager.h"
|
||||
#include "nsLiteralString.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsString.h"
|
||||
@ -1214,17 +1217,64 @@ bool TextEditor::AreClipboardCommandsUnconditionallyEnabled() const {
|
||||
return document && document->AreClipboardCommandsUnconditionallyEnabled();
|
||||
}
|
||||
|
||||
bool TextEditor::CheckForClipboardCommandListener(
|
||||
nsAtom* aCommand, EventMessage aEventMessage) const {
|
||||
RefPtr<Document> document = GetDocument();
|
||||
if (!document) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We exclude XUL and chrome docs here to maintain current behavior where
|
||||
// in these cases the editor element alone is expected to handle clipboard
|
||||
// command availability.
|
||||
if (!document->AreClipboardCommandsUnconditionallyEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// So in web content documents, "unconditionally" enabled Cut/Copy are not
|
||||
// really unconditional; they're enabled if there is a listener that wants
|
||||
// to handle them. What they're not conditional on here is whether there is
|
||||
// currently a selection in the editor.
|
||||
RefPtr<PresShell> presShell = document->GetObservingPresShell();
|
||||
if (!presShell) {
|
||||
return false;
|
||||
}
|
||||
RefPtr<nsPresContext> presContext = presShell->GetPresContext();
|
||||
if (!presContext) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPtr<EventTarget> et = GetDOMEventTarget();
|
||||
while (et) {
|
||||
EventListenerManager* elm = et->GetOrCreateListenerManager();
|
||||
if (elm && elm->HasListenersFor(aCommand)) {
|
||||
return true;
|
||||
}
|
||||
InternalClipboardEvent event(true, aEventMessage);
|
||||
EventChainPreVisitor visitor(presContext, &event, nullptr,
|
||||
nsEventStatus_eIgnore, false, et);
|
||||
et->GetEventTargetParent(visitor);
|
||||
et = visitor.GetParentTarget();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TextEditor::IsCutCommandEnabled() const {
|
||||
AutoEditActionDataSetter editActionData(*this, EditAction::eNotEditing);
|
||||
if (NS_WARN_IF(!editActionData.CanHandle())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (AreClipboardCommandsUnconditionallyEnabled()) {
|
||||
if (IsModifiable() && IsCopyToClipboardAllowedInternal()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return IsModifiable() && IsCopyToClipboardAllowedInternal();
|
||||
// If there's an event listener for "cut", we always enable the command
|
||||
// as we don't really know what the listener may want to do in response.
|
||||
// We look up the event target chain for a possible listener on a parent
|
||||
// in addition to checking the immediate target.
|
||||
return CheckForClipboardCommandListener(nsGkAtoms::oncut, eCut);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP TextEditor::Copy() {
|
||||
@ -1246,11 +1296,12 @@ bool TextEditor::IsCopyCommandEnabled() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (AreClipboardCommandsUnconditionallyEnabled()) {
|
||||
if (IsCopyToClipboardAllowedInternal()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return IsCopyToClipboardAllowedInternal();
|
||||
// Like "cut", always enable "copy" if there's a listener.
|
||||
return CheckForClipboardCommandListener(nsGkAtoms::oncopy, eCopy);
|
||||
}
|
||||
|
||||
bool TextEditor::CanDeleteSelection() const {
|
||||
|
@ -96,7 +96,7 @@ class TextEditor : public EditorBase, public nsITimerCallback, public nsINamed {
|
||||
* disabled. This always returns true if we're in non-chrome HTML/XHTML
|
||||
* document. Otherwise, same as the result of `IsCopyToClipboardAllowed()`.
|
||||
*/
|
||||
bool IsCutCommandEnabled() const;
|
||||
MOZ_CAN_RUN_SCRIPT bool IsCutCommandEnabled() const;
|
||||
|
||||
NS_IMETHOD Copy() override;
|
||||
|
||||
@ -105,7 +105,7 @@ class TextEditor : public EditorBase, public nsITimerCallback, public nsINamed {
|
||||
* This always returns true if we're in non-chrome HTML/XHTML document.
|
||||
* Otherwise, same as the result of `IsCopyToClipboardAllowed()`.
|
||||
*/
|
||||
bool IsCopyCommandEnabled() const;
|
||||
MOZ_CAN_RUN_SCRIPT bool IsCopyCommandEnabled() const;
|
||||
|
||||
/**
|
||||
* IsCopyToClipboardAllowed() returns true if the selected content can
|
||||
@ -786,6 +786,13 @@ class TextEditor : public EditorBase, public nsITimerCallback, public nsINamed {
|
||||
bool aNotify,
|
||||
bool aForceStartMasking);
|
||||
|
||||
/**
|
||||
* Helper for Is{Cut|Copy}CommandEnabled.
|
||||
* Look for a listener for the given command, including up the target chain.
|
||||
*/
|
||||
MOZ_CAN_RUN_SCRIPT bool CheckForClipboardCommandListener(
|
||||
nsAtom* aCommand, EventMessage aEventMessage) const;
|
||||
|
||||
protected:
|
||||
mutable nsCOMPtr<nsIDocumentEncoder> mCachedDocumentEncoder;
|
||||
|
||||
|
@ -328,6 +328,7 @@ interface nsIEditor : nsISupports
|
||||
* HTML/XHTML document.
|
||||
* FYI: Current user in script is only BlueGriffon.
|
||||
*/
|
||||
[can_run_script]
|
||||
boolean canCut();
|
||||
|
||||
/** copy the currently selected text, putting it into the OS clipboard
|
||||
@ -344,6 +345,7 @@ interface nsIEditor : nsISupports
|
||||
* HTML/XHTML document.
|
||||
* FYI: Current user in script is only BlueGriffon.
|
||||
*/
|
||||
[can_run_script]
|
||||
boolean canCopy();
|
||||
|
||||
/** paste the text in the OS clipboard at the cursor position, replacing
|
||||
|
Loading…
Reference in New Issue
Block a user