[GTK] Add WebKitContextMenuItemType for paste as plaintext
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 18 May 2020 07:37:28 +0000 (07:37 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 18 May 2020 07:37:28 +0000 (07:37 +0000)
https://bugs.webkit.org/show_bug.cgi?id=177638

Patch by Carlos Garcia Campos <cgarcia@igalia.com> on 2020-05-18
Reviewed by Michael Catanzaro.

Source/WebCore:

Add paste as plain text context menu item for rich editable content.

* page/ContextMenuController.cpp:
(WebCore::ContextMenuController::contextMenuItemSelected):
(WebCore::ContextMenuController::populate):
(WebCore::ContextMenuController::checkOrEnableIfNeeded const):
* platform/ContextMenuItem.h:
* platform/LocalizedStrings.h:
* platform/gtk/LocalizedStringsGtk.cpp:
(WebCore::contextMenuItemTagPasteAsPlainText):

Source/WebKit:

Add WEBKIT_CONTEXT_MENU_ACTION_PASTE_AS_PLAIN_TEXT.

* Shared/API/glib/WebKitContextMenuActions.cpp:
(webkitContextMenuActionGetActionTag):
(webkitContextMenuActionGetForContextMenuItem):
(webkitContextMenuActionGetLabel):
* UIProcess/API/gtk/WebKitContextMenuActions.h:
* UIProcess/gtk/KeyBindingTranslator.cpp:

Tools:

Update default context menu test case to also test the context menu for rich editable content.

* TestWebKitAPI/Tests/WebKitGtk/TestContextMenu.cpp:
(prepareContextMenuTestView):
(testContextMenuDefaultMenu):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@261800 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/page/ContextMenuController.cpp
Source/WebCore/platform/ContextMenuItem.h
Source/WebCore/platform/LocalizedStrings.h
Source/WebCore/platform/gtk/LocalizedStringsGtk.cpp
Source/WebKit/ChangeLog
Source/WebKit/Shared/API/glib/WebKitContextMenuActions.cpp
Source/WebKit/UIProcess/API/gtk/WebKitContextMenuActions.h
Source/WebKit/UIProcess/gtk/KeyBindingTranslator.cpp
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WebKitGtk/TestContextMenu.cpp

index bf8d816..eab2ad8 100644 (file)
@@ -1,3 +1,21 @@
+2020-05-18  Carlos Garcia Campos  <cgarcia@igalia.com>
+
+        [GTK] Add WebKitContextMenuItemType for paste as plaintext
+        https://bugs.webkit.org/show_bug.cgi?id=177638
+
+        Reviewed by Michael Catanzaro.
+
+        Add paste as plain text context menu item for rich editable content.
+
+        * page/ContextMenuController.cpp:
+        (WebCore::ContextMenuController::contextMenuItemSelected):
+        (WebCore::ContextMenuController::populate):
+        (WebCore::ContextMenuController::checkOrEnableIfNeeded const):
+        * platform/ContextMenuItem.h:
+        * platform/LocalizedStrings.h:
+        * platform/gtk/LocalizedStringsGtk.cpp:
+        (WebCore::contextMenuItemTagPasteAsPlainText):
+
 2020-05-17  Simon Fraser  <simon.fraser@apple.com>
 
         Fix operator== and hash() for ExtendedColor
index f142041..dc8a628 100644 (file)
@@ -330,6 +330,9 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuAction action, co
         frame->editor().command("Paste").execute();
         break;
 #if PLATFORM(GTK)
+    case ContextMenuItemTagPasteAsPlainText:
+        frame->editor().command("PasteAsPlainText").execute();
+        break;
     case ContextMenuItemTagDelete:
         frame->editor().performDelete();
         break;
@@ -816,6 +819,7 @@ void ContextMenuController::populate()
     ContextMenuItem CutItem(ActionType, ContextMenuItemTagCut, contextMenuItemTagCut());
     ContextMenuItem PasteItem(ActionType, ContextMenuItemTagPaste, contextMenuItemTagPaste());
 #if PLATFORM(GTK)
+    ContextMenuItem PasteAsPlainTextItem(ActionType, ContextMenuItemTagPasteAsPlainText, contextMenuItemTagPasteAsPlainText());
     ContextMenuItem DeleteItem(ActionType, ContextMenuItemTagDelete, contextMenuItemTagDelete());
     ContextMenuItem SelectAllItem(ActionType, ContextMenuItemTagSelectAll, contextMenuItemTagSelectAll());
     ContextMenuItem InsertEmojiItem(ActionType, ContextMenuItemTagInsertEmoji, contextMenuItemTagInsertEmoji());
@@ -1053,6 +1057,8 @@ void ContextMenuController::populate()
         appendItem(CopyItem, m_contextMenu.get());
         appendItem(PasteItem, m_contextMenu.get());
 #if PLATFORM(GTK)
+        if (frame->editor().canEditRichly())
+            appendItem(PasteAsPlainTextItem, m_contextMenu.get());
         appendItem(DeleteItem, m_contextMenu.get());
         appendItem(*separatorItem(), m_contextMenu.get());
         appendItem(SelectAllItem, m_contextMenu.get());
@@ -1208,6 +1214,9 @@ void ContextMenuController::checkOrEnableIfNeeded(ContextMenuItem& item) const
             shouldEnable = frame->editor().canDHTMLPaste() || frame->editor().canPaste();
             break;
 #if PLATFORM(GTK)
+        case ContextMenuItemTagPasteAsPlainText:
+            shouldEnable = frame->editor().canDHTMLPaste() || frame->editor().canPaste();
+            break;
         case ContextMenuItemTagDelete:
             shouldEnable = frame->editor().canDelete();
             break;
index d633d23..a216c6c 100644 (file)
@@ -54,6 +54,7 @@ enum ContextMenuAction {
     ContextMenuItemTagCut,
     ContextMenuItemTagPaste,
 #if PLATFORM(GTK)
+    ContextMenuItemTagPasteAsPlainText,
     ContextMenuItemTagDelete,
     ContextMenuItemTagSelectAll,
     ContextMenuItemTagInputMethods,
index 0d3e17e..bca2af0 100644 (file)
@@ -70,6 +70,7 @@ namespace WebCore {
     String contextMenuItemTagCut();
     WEBCORE_EXPORT String contextMenuItemTagPaste();
 #if PLATFORM(GTK)
+    String contextMenuItemTagPasteAsPlainText();
     String contextMenuItemTagDelete();
     String contextMenuItemTagInputMethods();
     String contextMenuItemTagUnicode();
index 07b7f47..e5baccd 100644 (file)
@@ -88,6 +88,11 @@ String contextMenuItemTagEnterVideoFullscreen()
     return String::fromUTF8(_("Switch Video to _Fullscreen"));
 }
 
+String contextMenuItemTagPasteAsPlainText()
+{
+    return String::fromUTF8(_("Paste As Plain _Text"));
+}
+
 String contextMenuItemTagDelete()
 {
     return String::fromUTF8(_("_Delete"));
index 50a5ef5..0bc475f 100644 (file)
@@ -1,3 +1,19 @@
+2020-05-18  Carlos Garcia Campos  <cgarcia@igalia.com>
+
+        [GTK] Add WebKitContextMenuItemType for paste as plaintext
+        https://bugs.webkit.org/show_bug.cgi?id=177638
+
+        Reviewed by Michael Catanzaro.
+
+        Add WEBKIT_CONTEXT_MENU_ACTION_PASTE_AS_PLAIN_TEXT.
+
+        * Shared/API/glib/WebKitContextMenuActions.cpp:
+        (webkitContextMenuActionGetActionTag):
+        (webkitContextMenuActionGetForContextMenuItem):
+        (webkitContextMenuActionGetLabel):
+        * UIProcess/API/gtk/WebKitContextMenuActions.h:
+        * UIProcess/gtk/KeyBindingTranslator.cpp:
+
 2020-05-17  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         [GTK] Move to new Pasteboard API
index 2150e89..ae1b670 100644 (file)
@@ -79,6 +79,8 @@ ContextMenuAction webkitContextMenuActionGetActionTag(WebKitContextMenuAction ac
     case WEBKIT_CONTEXT_MENU_ACTION_PASTE:
         return ContextMenuItemTagPaste;
 #if PLATFORM(GTK)
+    case WEBKIT_CONTEXT_MENU_ACTION_PASTE_AS_PLAIN_TEXT:
+        return ContextMenuItemTagPasteAsPlainText;
     case WEBKIT_CONTEXT_MENU_ACTION_DELETE:
         return ContextMenuItemTagDelete;
     case WEBKIT_CONTEXT_MENU_ACTION_SELECT_ALL:
@@ -181,6 +183,8 @@ WebKitContextMenuAction webkitContextMenuActionGetForContextMenuItem(const WebKi
     case ContextMenuItemTagPaste:
         return WEBKIT_CONTEXT_MENU_ACTION_PASTE;
 #if PLATFORM(GTK)
+    case ContextMenuItemTagPasteAsPlainText:
+        return WEBKIT_CONTEXT_MENU_ACTION_PASTE_AS_PLAIN_TEXT;
     case ContextMenuItemTagDelete:
         return WEBKIT_CONTEXT_MENU_ACTION_DELETE;
     case ContextMenuItemTagSelectAll:
@@ -281,6 +285,8 @@ String webkitContextMenuActionGetLabel(WebKitContextMenuAction action)
     case WEBKIT_CONTEXT_MENU_ACTION_PASTE:
         return contextMenuItemTagPaste();
 #if PLATFORM(GTK)
+    case WEBKIT_CONTEXT_MENU_ACTION_PASTE_AS_PLAIN_TEXT:
+        return contextMenuItemTagPasteAsPlainText();
     case WEBKIT_CONTEXT_MENU_ACTION_DELETE:
         return contextMenuItemTagDelete();
     case WEBKIT_CONTEXT_MENU_ACTION_SELECT_ALL:
index 48c8fdd..4d63b8f 100644 (file)
@@ -75,6 +75,7 @@ G_BEGIN_DECLS
  * @WEBKIT_CONTEXT_MENU_ACTION_DOWNLOAD_VIDEO_TO_DISK: Download video to disk. Since 2.2
  * @WEBKIT_CONTEXT_MENU_ACTION_DOWNLOAD_AUDIO_TO_DISK: Download audio to disk. Since 2.2
  * @WEBKIT_CONTEXT_MENU_ACTION_INSERT_EMOJI: Insert an emoji. Since 2.26
+ * @WEBKIT_CONTEXT_MENU_ACTION_PASTE_AS_PLAIN_TEXT: Paste clipboard contents as plain text. Since 2.30
  * @WEBKIT_CONTEXT_MENU_ACTION_CUSTOM: Custom action defined by applications.
  *
  * Enum values used to denote the stock actions for
@@ -127,6 +128,7 @@ typedef enum {
     WEBKIT_CONTEXT_MENU_ACTION_DOWNLOAD_VIDEO_TO_DISK,
     WEBKIT_CONTEXT_MENU_ACTION_DOWNLOAD_AUDIO_TO_DISK,
     WEBKIT_CONTEXT_MENU_ACTION_INSERT_EMOJI,
+    WEBKIT_CONTEXT_MENU_ACTION_PASTE_AS_PLAIN_TEXT,
 
     WEBKIT_CONTEXT_MENU_ACTION_CUSTOM = 10000
 } WebKitContextMenuAction;
index 8723ee5..6be232e 100644 (file)
@@ -202,18 +202,19 @@ struct KeyCombinationEntry {
 };
 
 static const KeyCombinationEntry customKeyBindings[] = {
-    { GDK_KEY_b,         GDK_CONTROL_MASK, "ToggleBold"      },
-    { GDK_KEY_i,         GDK_CONTROL_MASK, "ToggleItalic"    },
-    { GDK_KEY_Escape,    0,                "Cancel"          },
-    { GDK_KEY_greater,   GDK_CONTROL_MASK, "Cancel"          },
-    { GDK_KEY_Tab,       0,                "InsertTab"       },
-    { GDK_KEY_Tab,       GDK_SHIFT_MASK,   "InsertBacktab"   },
-    { GDK_KEY_Return,    0,                "InsertNewLine"   },
-    { GDK_KEY_KP_Enter,  0,                "InsertNewLine"   },
-    { GDK_KEY_ISO_Enter, 0,                "InsertNewLine"   },
-    { GDK_KEY_Return,    GDK_SHIFT_MASK,   "InsertLineBreak" },
-    { GDK_KEY_KP_Enter,  GDK_SHIFT_MASK,   "InsertLineBreak" },
-    { GDK_KEY_ISO_Enter, GDK_SHIFT_MASK,   "InsertLineBreak" },
+    { GDK_KEY_b,         GDK_CONTROL_MASK,                  "ToggleBold"      },
+    { GDK_KEY_i,         GDK_CONTROL_MASK,                  "ToggleItalic"    },
+    { GDK_KEY_Escape,    0,                                 "Cancel"          },
+    { GDK_KEY_greater,   GDK_CONTROL_MASK,                  "Cancel"          },
+    { GDK_KEY_Tab,       0,                                 "InsertTab"       },
+    { GDK_KEY_Tab,       GDK_SHIFT_MASK,                    "InsertBacktab"   },
+    { GDK_KEY_Return,    0,                                 "InsertNewLine"   },
+    { GDK_KEY_KP_Enter,  0,                                 "InsertNewLine"   },
+    { GDK_KEY_ISO_Enter, 0,                                 "InsertNewLine"   },
+    { GDK_KEY_Return,    GDK_SHIFT_MASK,                    "InsertLineBreak" },
+    { GDK_KEY_KP_Enter,  GDK_SHIFT_MASK,                    "InsertLineBreak" },
+    { GDK_KEY_ISO_Enter, GDK_SHIFT_MASK,                    "InsertLineBreak" },
+    { GDK_KEY_V,         GDK_CONTROL_MASK | GDK_SHIFT_MASK, "PasteAsPlainText" },
 };
 
 static Vector<String> handleCustomKeyBindings(unsigned keyval, GdkModifierType state)
index b717349..57401b7 100644 (file)
@@ -1,3 +1,16 @@
+2020-05-18  Carlos Garcia Campos  <cgarcia@igalia.com>
+
+        [GTK] Add WebKitContextMenuItemType for paste as plaintext
+        https://bugs.webkit.org/show_bug.cgi?id=177638
+
+        Reviewed by Michael Catanzaro.
+
+        Update default context menu test case to also test the context menu for rich editable content.
+
+        * TestWebKitAPI/Tests/WebKitGtk/TestContextMenu.cpp:
+        (prepareContextMenuTestView):
+        (testContextMenuDefaultMenu):
+
 2020-05-17  Simon Fraser  <simon.fraser@apple.com>
 
         Fix operator== and hash() for ExtendedColor
index ad542e3..ac4fcf6 100644 (file)
@@ -337,6 +337,7 @@ public:
         Audio,
         VideoLive,
         Editable,
+        RichEditable,
         Selection
     };
 
@@ -459,6 +460,24 @@ public:
             iter = checkCurrentItemIsSeparatorAndGetNext(iter);
             iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_UNICODE, Visible | Enabled);
             break;
+        case RichEditable:
+            g_assert_false(webkit_hit_test_result_context_is_link(hitTestResult));
+            g_assert_false(webkit_hit_test_result_context_is_image(hitTestResult));
+            g_assert_false(webkit_hit_test_result_context_is_media(hitTestResult));
+            g_assert_true(webkit_hit_test_result_context_is_editable(hitTestResult));
+            g_assert_false(webkit_hit_test_result_context_is_selection(hitTestResult));
+            iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_CUT, Visible);
+            iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_COPY, Visible);
+            iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_PASTE, Visible | Enabled);
+            iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_PASTE_AS_PLAIN_TEXT, Visible | Enabled);
+            iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_DELETE, Visible);
+            iter = checkCurrentItemIsSeparatorAndGetNext(iter);
+            iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_SELECT_ALL, Visible | Enabled);
+            iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_INSERT_EMOJI, Visible | Enabled);
+            iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_FONT_MENU, Visible | Enabled);
+            iter = checkCurrentItemIsSeparatorAndGetNext(iter);
+            iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_UNICODE, Visible | Enabled);
+            break;
         case Selection:
             g_assert_false(webkit_hit_test_result_context_is_link(hitTestResult));
             g_assert_false(webkit_hit_test_result_context_is_image(hitTestResult));
@@ -496,7 +515,8 @@ static void prepareContextMenuTestView(ContextMenuDefaultTest* test)
         " <input style='position:absolute; left:1; top:30' size='10'></input>"
         " <video style='position:absolute; left:1; top:50' width='300' height='300' controls='controls' preload='none'><source src='silence.webm' type='video/webm' /></video>"
         " <audio style='position:absolute; left:1; top:60' width='50' height='20' controls='controls' preload='none'><source src='track.ogg' type='audio/ogg' /></audio>"
-        " <p style='position:absolute; left:1; top:90' id='text_to_select'>Lorem ipsum.</p>"
+        " <div contenteditable style='position:absolute; left:1; top: 90; height: 20px; width: 100px'></div>"
+        " <p style='position:absolute; left:1; top:110' id='text_to_select'>Lorem ipsum.</p>"
         " <script>"
         "  window.getSelection().removeAllRanges();"
         "  var select_range = document.createRange();"
@@ -517,7 +537,7 @@ static void testContextMenuDefaultMenu(ContextMenuDefaultTest* test, gconstpoint
     // Context menu for selection.
     // This test should always be the first because any other click removes the selection.
     test->m_expectedMenuType = ContextMenuDefaultTest::Selection;
-    test->showContextMenuAtPositionAndWaitUntilFinished(2, 115);
+    test->showContextMenuAtPositionAndWaitUntilFinished(2, 135);
 
     // Context menu for document.
     test->m_expectedMenuType = ContextMenuDefaultTest::Navigation;
@@ -550,6 +570,10 @@ static void testContextMenuDefaultMenu(ContextMenuDefaultTest* test, gconstpoint
     // Context menu for editable.
     test->m_expectedMenuType = ContextMenuDefaultTest::Editable;
     test->showContextMenuAtPositionAndWaitUntilFinished(5, 35);
+
+    // Context menu for rich editable.
+    test->m_expectedMenuType = ContextMenuDefaultTest::RichEditable;
+    test->showContextMenuAtPositionAndWaitUntilFinished(5, 95);
 }
 
 static void testPopupEventSignal(ContextMenuDefaultTest* test, gconstpointer)