Bug 1664411 - Factor out a condition to unconditionally enable clipboard events in some documents. r=masayuki
authorEmilio Cobos Álvarez <emilio@crisal.io>
Fri, 11 Sep 2020 11:08:35 +0000
changeset 548302 49039661a8071e4ab5995224c1cebc72163a5db2
parent 548301 9dd67fd23c9eb27ab2d6d0491296e82aa12a6631
child 548303 174a622bf334e32f911e97ca76c36b0a80d51f94
push id37776
push userbtara@mozilla.com
push dateFri, 11 Sep 2020 15:10:42 +0000
treeherdermozilla-central@b133e2d673e8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmasayuki
bugs1664411
milestone82.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1664411 - Factor out a condition to unconditionally enable clipboard events in some documents. r=masayuki This patch shouldn't introduce any behavior change. Differential Revision: https://phabricator.services.mozilla.com/D89834
dom/base/Document.cpp
dom/base/Document.h
dom/base/nsGlobalWindowCommands.cpp
editor/libeditor/HTMLEditorDataTransfer.cpp
editor/libeditor/TextEditor.cpp
editor/libeditor/TextEditor.h
editor/libeditor/TextEditorDataTransfer.cpp
--- a/dom/base/Document.cpp
+++ b/dom/base/Document.cpp
@@ -11785,16 +11785,20 @@ void Document::UnsuppressEventHandlingAn
       if (mPresShell) {
         nsRefreshDriver* rd = mPresShell->GetPresContext()->RefreshDriver();
         rd->RunDelayedEventsSoon();
       }
     }
   }
 }
 
+bool Document::AreClipboardCommandsUnconditionallyEnabled() const {
+  return IsHTMLOrXHTML() && !nsContentUtils::IsChromeDoc(this);
+}
+
 void Document::AddSuspendedChannelEventQueue(net::ChannelEventQueue* aQueue) {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(EventHandlingSuppressed());
   mSuspendedQueues.AppendElement(aQueue);
 }
 
 bool Document::SuspendPostMessageEvent(PostMessageEvent* aEvent) {
   MOZ_ASSERT(NS_IsMainThread());
--- a/dom/base/Document.h
+++ b/dom/base/Document.h
@@ -2709,16 +2709,23 @@ class Document : public nsINode,
 
   void DecreaseEventSuppression() {
     MOZ_ASSERT(mEventsSuppressed);
     --mEventsSuppressed;
     UpdateFrameRequestCallbackSchedulingState();
   }
 
   /**
+   * Some clipboard commands are unconditionally enabled on some documents, so
+   * as to always dispatch copy / paste events even though you'd normally not be
+   * able to copy.
+   */
+  bool AreClipboardCommandsUnconditionallyEnabled() const;
+
+  /**
    * Note a ChannelEventQueue which has been suspended on the document's behalf
    * to prevent XHRs from running content scripts while event handling is
    * suppressed. The document is responsible for resuming the queue after
    * event handling is unsuppressed.
    */
   void AddSuspendedChannelEventQueue(net::ChannelEventQueue* aQueue);
 
   /**
--- a/dom/base/nsGlobalWindowCommands.cpp
+++ b/dom/base/nsGlobalWindowCommands.cpp
@@ -482,17 +482,17 @@ nsresult nsClipboardCommand::IsCommandEn
     return NS_OK;
   }
 
   nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryInterface(aContext);
   NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
   RefPtr<dom::Document> doc = window->GetExtantDoc();
   NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
 
-  if (doc->IsHTMLOrXHTML() && !nsContentUtils::IsChromeDoc(doc)) {
+  if (doc->AreClipboardCommandsUnconditionallyEnabled()) {
     // In HTML and XHTML documents, we always want the cut, copy and paste
     // commands to be enabled, but if the document is chrome, let it control it.
     *outCmdEnabled = true;
   } else {
     // Cut isn't enabled in xul documents which use nsClipboardCommand
     if (strcmp(aCommandName, "cmd_copy") == 0) {
       *outCmdEnabled = nsCopySupport::CanCopy(doc);
     }
--- a/editor/libeditor/HTMLEditorDataTransfer.cpp
+++ b/editor/libeditor/HTMLEditorDataTransfer.cpp
@@ -2155,21 +2155,17 @@ nsresult HTMLEditor::PasteNoFormattingAs
 // are used by CanPaste() and CanPasteTransferable() below.
 
 static const char* textEditorFlavors[] = {kUnicodeMime};
 static const char* textHtmlEditorFlavors[] = {kUnicodeMime,   kHTMLMime,
                                               kJPEGImageMime, kJPGImageMime,
                                               kPNGImageMime,  kGIFImageMime};
 
 bool HTMLEditor::CanPaste(int32_t aClipboardType) const {
-  // Always enable the paste command when inside of a HTML or XHTML document,
-  // but if the document is chrome, let it control it.
-  Document* document = GetDocument();
-  if (document && document->IsHTMLOrXHTML() &&
-      !nsContentUtils::IsChromeDoc(document)) {
+  if (AreClipboardCommandsUnconditionallyEnabled()) {
     return true;
   }
 
   // can't paste if readonly
   if (!IsModifiable()) {
     return false;
   }
 
--- a/editor/libeditor/TextEditor.cpp
+++ b/editor/libeditor/TextEditor.cpp
@@ -1195,27 +1195,28 @@ nsresult TextEditor::CutAsAction(nsIPrin
   rv = DeleteSelectionAsSubAction(
       eNone, IsTextEditor() ? nsIEditor::eNoStrip : nsIEditor::eStrip);
   NS_WARNING_ASSERTION(
       NS_SUCCEEDED(rv),
       "EditorBase::DeleteSelectionAsSubAction(eNone) failed, but ignored");
   return EditorBase::ToGenericNSResult(rv);
 }
 
+bool TextEditor::AreClipboardCommandsUnconditionallyEnabled() const {
+  Document* document = GetDocument();
+  return document && document->AreClipboardCommandsUnconditionallyEnabled();
+}
+
 bool TextEditor::IsCutCommandEnabled() const {
   AutoEditActionDataSetter editActionData(*this, EditAction::eNotEditing);
   if (NS_WARN_IF(!editActionData.CanHandle())) {
     return false;
   }
 
-  // Cut is always enabled in HTML documents, but if the document is chrome,
-  // let it control it.
-  Document* document = GetDocument();
-  if (document && document->IsHTMLOrXHTML() &&
-      !nsContentUtils::IsChromeDoc(document)) {
+  if (AreClipboardCommandsUnconditionallyEnabled()) {
     return true;
   }
 
   return IsModifiable() && IsCopyToClipboardAllowedInternal();
 }
 
 NS_IMETHODIMP TextEditor::Copy() {
   AutoEditActionDataSetter editActionData(*this, EditAction::eCopy);
@@ -1231,21 +1232,17 @@ NS_IMETHODIMP TextEditor::Copy() {
 }
 
 bool TextEditor::IsCopyCommandEnabled() const {
   AutoEditActionDataSetter editActionData(*this, EditAction::eNotEditing);
   if (NS_WARN_IF(!editActionData.CanHandle())) {
     return false;
   }
 
-  // Copy is always enabled in HTML documents, but if the document is chrome,
-  // let it control it.
-  Document* document = GetDocument();
-  if (document && document->IsHTMLOrXHTML() &&
-      !nsContentUtils::IsChromeDoc(document)) {
+  if (AreClipboardCommandsUnconditionallyEnabled()) {
     return true;
   }
 
   return IsCopyToClipboardAllowedInternal();
 }
 
 bool TextEditor::CanDeleteSelection() const {
   AutoEditActionDataSetter editActionData(*this, EditAction::eNotEditing);
--- a/editor/libeditor/TextEditor.h
+++ b/editor/libeditor/TextEditor.h
@@ -82,16 +82,21 @@ class TextEditor : public EditorBase, pu
    *
    * @param aPrincipal          If you know current context is subject
    *                            principal or system principal, set it.
    *                            When nullptr, this checks it automatically.
    */
   MOZ_CAN_RUN_SCRIPT nsresult CutAsAction(nsIPrincipal* aPrincipal = nullptr);
 
   /**
+   * See Document::AreClipboardCommandsUnconditionallyEnabled.
+   */
+  bool AreClipboardCommandsUnconditionallyEnabled() const;
+
+  /**
    * IsCutCommandEnabled() returns whether cut command can be enabled or
    * disabled.  This always returns true if we're in non-chrome HTML/XHTML
    * document.  Otherwise, same as the result of `IsCopyToClipboardAllowed()`.
    */
   bool IsCutCommandEnabled() const;
 
   NS_IMETHOD Copy() override;
 
--- a/editor/libeditor/TextEditorDataTransfer.cpp
+++ b/editor/libeditor/TextEditorDataTransfer.cpp
@@ -659,20 +659,17 @@ nsresult TextEditor::PasteTransferableAs
 
   nsresult rv = InsertTextFromTransferable(aTransferable);
   NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
                        "TextEditor::InsertTextFromTransferable() failed");
   return EditorBase::ToGenericNSResult(rv);
 }
 
 bool TextEditor::CanPaste(int32_t aClipboardType) const {
-  // Always enable the paste command when inside of a HTML or XHTML document,
-  // but if the document is chrome, let it control it.
-  RefPtr<Document> doc = GetDocument();
-  if (doc && doc->IsHTMLOrXHTML() && !nsContentUtils::IsChromeDoc(doc)) {
+  if (AreClipboardCommandsUnconditionallyEnabled()) {
     return true;
   }
 
   // can't paste if readonly
   if (!IsModifiable()) {
     return false;
   }