Bug 1101392 - Part 2: Add a command that collapse selection to end after copying. r=roc
authorMorris Tseng <mtseng@mozilla.com>
Wed, 26 Nov 2014 23:06:00 +0100
changeset 244383 d59fef58d1ac2f336070602e7bfa50202a28eee3
parent 244382 f32ac17514553f657a83bde3be12e8f8ca0ef433
child 244384 1b10bab94f6e34a7835eb53ae5cb14a46ec19dcf
push id660
push userraliiev@mozilla.com
push dateWed, 18 Feb 2015 20:30:48 +0000
treeherdermozilla-release@49e493494178 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs1101392
milestone36.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 1101392 - Part 2: Add a command that collapse selection to end after copying. r=roc
dom/base/nsGlobalWindowCommands.cpp
dom/browser-element/BrowserElementChildPreload.js
editor/libeditor/nsEditorCommands.cpp
editor/libeditor/nsEditorCommands.h
editor/libeditor/nsEditorController.cpp
layout/base/TouchCaret.cpp
--- a/dom/base/nsGlobalWindowCommands.cpp
+++ b/dom/base/nsGlobalWindowCommands.cpp
@@ -24,16 +24,17 @@
 #include "nsIWebNavigation.h"
 #include "nsIContentViewerEdit.h"
 #include "nsIContentViewer.h"
 #include "nsFocusManager.h"
 #include "nsCopySupport.h"
 #include "nsIClipboard.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/BasicEvents.h"
+#include "mozilla/dom/Selection.h"
 
 #include "nsIClipboardDragDropHooks.h"
 #include "nsIClipboardDragDropHookList.h"
 
 using namespace mozilla;
 
 const char * const sSelectAllString = "cmd_selectAll";
 const char * const sSelectNoneString = "cmd_selectNone";
@@ -477,43 +478,53 @@ public:
 NS_IMPL_ISUPPORTS(nsClipboardCommand, nsIControllerCommand)
 
 nsresult
 nsClipboardCommand::IsCommandEnabled(const char* aCommandName, nsISupports *aContext, bool *outCmdEnabled)
 {
   NS_ENSURE_ARG_POINTER(outCmdEnabled);
   *outCmdEnabled = false;
 
-  if (strcmp(aCommandName, "cmd_copy"))
+  if (strcmp(aCommandName, "cmd_copy") &&
+      strcmp(aCommandName, "cmd_copyAndCollapseToEnd"))
     return NS_OK;
 
   nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aContext);
   NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
 
   nsCOMPtr<nsIDocument> doc = window->GetExtantDoc();
   *outCmdEnabled = nsCopySupport::CanCopy(doc);
   return NS_OK;
 }
 
 nsresult
 nsClipboardCommand::DoCommand(const char *aCommandName, nsISupports *aContext)
 {
-  if (strcmp(aCommandName, "cmd_copy"))
+  if (strcmp(aCommandName, "cmd_copy") &&
+      strcmp(aCommandName, "cmd_copyAndCollapseToEnd"))
     return NS_OK;
 
   nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aContext);
   NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
 
   nsIDocShell *docShell = window->GetDocShell();
   NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
 
   nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
   NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
 
   nsCopySupport::FireClipboardEvent(NS_COPY, nsIClipboard::kGlobalClipboard, presShell, nullptr);
+
+  if (!strcmp(aCommandName, "cmd_copyAndCollapseToEnd")) {
+    dom::Selection *sel =
+      presShell->GetCurrentSelection(nsISelectionController::SELECTION_NORMAL);
+    NS_ENSURE_TRUE(sel, NS_ERROR_FAILURE);
+    sel->CollapseToEnd();
+  }
+
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsClipboardCommand::GetCommandStateParams(const char *aCommandName,
                                               nsICommandParams *aParams, nsISupports *aCommandContext)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
@@ -1040,16 +1051,17 @@ nsWindowCommandRegistration::RegisterWin
   NS_REGISTER_NEXT_COMMAND(nsPhysicalSelectCommand, sSelectDownString);
   NS_REGISTER_NEXT_COMMAND(nsPhysicalSelectCommand, sSelectLeft2String);
   NS_REGISTER_NEXT_COMMAND(nsPhysicalSelectCommand, sSelectRight2String);
   NS_REGISTER_NEXT_COMMAND(nsPhysicalSelectCommand, sSelectUp2String);
   NS_REGISTER_LAST_COMMAND(nsPhysicalSelectCommand, sSelectDown2String);
 
   NS_REGISTER_ONE_COMMAND(nsClipboardCommand, "cmd_cut");
   NS_REGISTER_ONE_COMMAND(nsClipboardCommand, "cmd_copy");
+  NS_REGISTER_ONE_COMMAND(nsClipboardCommand, "cmd_copyAndCollapseToEnd");
   NS_REGISTER_ONE_COMMAND(nsClipboardCommand, "cmd_paste");
   NS_REGISTER_ONE_COMMAND(nsClipboardCopyLinkCommand, "cmd_copyLink");
   NS_REGISTER_FIRST_COMMAND(nsClipboardImageCommands, sCopyImageLocationString);
   NS_REGISTER_NEXT_COMMAND(nsClipboardImageCommands, sCopyImageContentsString);
   NS_REGISTER_LAST_COMMAND(nsClipboardImageCommands, sCopyImageString);
   NS_REGISTER_FIRST_COMMAND(nsClipboardSelectAllNoneCommands, sSelectAllString);
   NS_REGISTER_LAST_COMMAND(nsClipboardSelectAllNoneCommands, sSelectNoneString);
 
--- a/dom/browser-element/BrowserElementChildPreload.js
+++ b/dom/browser-element/BrowserElementChildPreload.js
@@ -54,17 +54,17 @@ const OBSERVED_EVENTS = [
   'ask-parent-to-exit-fullscreen',
   'ask-parent-to-rollback-fullscreen',
   'xpcom-shutdown',
   'activity-done'
 ];
 
 const COMMAND_MAP = {
   'cut': 'cmd_cut',
-  'copy': 'cmd_copy',
+  'copy': 'cmd_copyAndCollapseToEnd',
   'paste': 'cmd_paste',
   'selectall': 'cmd_selectAll'
 };
 
 /**
  * The BrowserElementChild implements one half of <iframe mozbrowser>.
  * (The other half is, unsurprisingly, BrowserElementParent.)
  *
--- a/editor/libeditor/nsEditorCommands.cpp
+++ b/editor/libeditor/nsEditorCommands.cpp
@@ -357,16 +357,70 @@ nsCopyOrDeleteCommand::GetCommandStatePa
                                              nsISupports *aCommandRefCon)
 {
   bool canUndo;
   IsCommandEnabled(aCommandName, aCommandRefCon, &canUndo);
   return aParams->SetBooleanValue(STATE_ENABLED, canUndo);
 }
 
 NS_IMETHODIMP
+nsCopyAndCollapseToEndCommand::IsCommandEnabled(const char *aCommandName,
+                                                nsISupports *aCommandRefCon,
+                                                bool *outCmdEnabled)
+{
+  NS_ENSURE_ARG_POINTER(outCmdEnabled);
+  nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
+  if (editor)
+    return editor->CanCopy(outCmdEnabled);
+
+  *outCmdEnabled = false;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsCopyAndCollapseToEndCommand::DoCommand(const char *aCommandName,
+                                         nsISupports *aCommandRefCon)
+{
+  nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
+  if (editor) {
+    nsresult rv = editor->Copy();
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+
+    nsCOMPtr<nsISelection> selection;
+    rv = editor->GetSelection(getter_AddRefs(selection));
+    if (NS_SUCCEEDED(rv) && selection) {
+      selection->CollapseToEnd();
+    }
+    return rv;
+  }
+
+  return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsCopyAndCollapseToEndCommand::DoCommandParams(const char *aCommandName,
+                                               nsICommandParams *aParams,
+                                               nsISupports *aCommandRefCon)
+{
+  return DoCommand(aCommandName, aCommandRefCon);
+}
+
+NS_IMETHODIMP
+nsCopyAndCollapseToEndCommand::GetCommandStateParams(
+  const char *aCommandName, nsICommandParams *aParams,
+  nsISupports *aCommandRefCon)
+{
+  bool canUndo;
+  IsCommandEnabled(aCommandName, aCommandRefCon, &canUndo);
+  return aParams->SetBooleanValue(STATE_ENABLED, canUndo);
+}
+
+NS_IMETHODIMP
 nsPasteCommand::IsCommandEnabled(const char *aCommandName,
                                  nsISupports *aCommandRefCon,
                                  bool *outCmdEnabled)
 {
   NS_ENSURE_ARG_POINTER(outCmdEnabled);
   nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
   if (editor) {
     bool isEditable = false;
--- a/editor/libeditor/nsEditorCommands.h
+++ b/editor/libeditor/nsEditorCommands.h
@@ -47,16 +47,17 @@ public:                                 
 NS_DECL_EDITOR_COMMAND(nsUndoCommand)
 NS_DECL_EDITOR_COMMAND(nsRedoCommand)
 NS_DECL_EDITOR_COMMAND(nsClearUndoCommand)
 
 NS_DECL_EDITOR_COMMAND(nsCutCommand)
 NS_DECL_EDITOR_COMMAND(nsCutOrDeleteCommand)
 NS_DECL_EDITOR_COMMAND(nsCopyCommand)
 NS_DECL_EDITOR_COMMAND(nsCopyOrDeleteCommand)
+NS_DECL_EDITOR_COMMAND(nsCopyAndCollapseToEndCommand)
 NS_DECL_EDITOR_COMMAND(nsPasteCommand)
 NS_DECL_EDITOR_COMMAND(nsPasteTransferableCommand)
 NS_DECL_EDITOR_COMMAND(nsSwitchTextDirectionCommand)
 NS_DECL_EDITOR_COMMAND(nsDeleteCommand)
 NS_DECL_EDITOR_COMMAND(nsSelectAllCommand)
 
 NS_DECL_EDITOR_COMMAND(nsSelectionMoveCommands)
 
--- a/editor/libeditor/nsEditorController.cpp
+++ b/editor/libeditor/nsEditorController.cpp
@@ -48,16 +48,18 @@ nsresult nsEditorController::RegisterEdi
   NS_REGISTER_ONE_COMMAND(nsUndoCommand, "cmd_undo");
   NS_REGISTER_ONE_COMMAND(nsRedoCommand, "cmd_redo");
   NS_REGISTER_ONE_COMMAND(nsClearUndoCommand, "cmd_clearUndo");
 
   NS_REGISTER_ONE_COMMAND(nsCutCommand, "cmd_cut");
   NS_REGISTER_ONE_COMMAND(nsCutOrDeleteCommand, "cmd_cutOrDelete");
   NS_REGISTER_ONE_COMMAND(nsCopyCommand, "cmd_copy");
   NS_REGISTER_ONE_COMMAND(nsCopyOrDeleteCommand, "cmd_copyOrDelete");
+  NS_REGISTER_ONE_COMMAND(nsCopyAndCollapseToEndCommand,
+                          "cmd_copyAndCollapseToEnd");
   NS_REGISTER_ONE_COMMAND(nsSelectAllCommand, "cmd_selectAll");
 
   NS_REGISTER_ONE_COMMAND(nsPasteCommand, "cmd_paste");
   NS_REGISTER_ONE_COMMAND(nsPasteTransferableCommand, "cmd_pasteTransferable");
 
   NS_REGISTER_ONE_COMMAND(nsSwitchTextDirectionCommand, "cmd_switchTextDirection");
 
   NS_REGISTER_FIRST_COMMAND(nsDeleteCommand, "cmd_delete");
--- a/layout/base/TouchCaret.cpp
+++ b/layout/base/TouchCaret.cpp
@@ -349,17 +349,20 @@ TouchCaret::NotifySelectionChanged(nsIDO
   // the caret is currently interested in , then there is nothing to do!
   if (aSel != caret->GetSelection()) {
     TOUCHCARET_LOG("Return for selection mismatch!");
     return NS_OK;
   }
 
   // Update touch caret position and visibility.
   // Hide touch caret while key event causes selection change.
-  if (aReason & nsISelectionListener::KEYPRESS_REASON) {
+  // Also hide touch caret when gecko or javascript collapse the selection.
+  if (aReason & nsISelectionListener::KEYPRESS_REASON ||
+      aReason & nsISelectionListener::COLLAPSETOSTART_REASON ||
+      aReason & nsISelectionListener::COLLAPSETOEND_REASON) {
     TOUCHCARET_LOG("KEYPRESS_REASON");
     SetVisibility(false);
   } else {
     SyncVisibilityWithCaret();
   }
 
   return NS_OK;
 }