[WK2] selection does not disappear after coping the text
[framework/web/webkit-efl.git] / Source / WebCore / page / ContextMenuController.cpp
old mode 100755 (executable)
new mode 100644 (file)
index e9334d9..fd8952a
 #include "NavigationAction.h"
 #include "Node.h"
 #include "Page.h"
-#include "RenderLayer.h"
+#include "PlatformEvent.h"
 #include "RenderObject.h"
 #include "ReplaceSelectionCommand.h"
 #include "ResourceRequest.h"
 #include "Settings.h"
 #include "TextIterator.h"
+#include "TypingCommand.h"
 #include "UserTypingGestureIndicator.h"
 #include "WindowFeatures.h"
 #include "markup.h"
 #include <wtf/unicode/Unicode.h>
 
+#if PLATFORM(GTK)
+#include <wtf/gobject/GOwnPtr.h>
+#endif
+
 using namespace WTF;
 using namespace Unicode;
 
@@ -84,7 +89,7 @@ ContextMenuController::ContextMenuController(Page* page, ContextMenuClient* clie
 
 ContextMenuController::~ContextMenuController()
 {
-#if ENABLE(TIZEN_CONTEXT_MENU) && ENABLE(TIZEN_WEBKIT_EFL_DRT)
+#if ENABLE(TIZEN_CONTEXT_MENU)
     //this fixes a bug which occured when WebKit was shut down if a context menu was active
     //then ContextMenuController destructor was calling:
     //- first m_client->contextMenuDestroyed which destroyed the m_client object explicitly and then
@@ -99,6 +104,11 @@ ContextMenuController::~ContextMenuController()
     m_client->contextMenuDestroyed();
 }
 
+PassOwnPtr<ContextMenuController> ContextMenuController::create(Page* page, ContextMenuClient* client)
+{
+    return adoptPtr(new ContextMenuController(page, client));
+}
+
 void ContextMenuController::clearContextMenu()
 {
     m_contextMenu.clear();
@@ -118,6 +128,11 @@ void ContextMenuController::handleContextMenuEvent(Event* event)
     showContextMenu(event);
 }
 
+static PassOwnPtr<ContextMenuItem> separatorItem()
+{
+    return adoptPtr(new ContextMenuItem(SeparatorType, ContextMenuItemTagNoAction, String()));
+}
+
 void ContextMenuController::showContextMenu(Event* event, PassRefPtr<ContextMenuProvider> menuProvider)
 {
     m_menuProvider = menuProvider;
@@ -129,6 +144,10 @@ void ContextMenuController::showContextMenu(Event* event, PassRefPtr<ContextMenu
     }
 
     m_menuProvider->populateContextMenu(m_contextMenu.get());
+    if (m_hitTestResult.isSelected()) {
+        appendItem(*separatorItem(), m_contextMenu.get());
+        populate();
+    }
     showContextMenu(event);
 }
 
@@ -175,13 +194,24 @@ static void openNewWindow(const KURL& urlToLoad, Frame* frame)
 {
     if (Page* oldPage = frame->page()) {
         FrameLoadRequest request(frame->document()->securityOrigin(), ResourceRequest(urlToLoad, frame->loader()->outgoingReferrer()));
-        if (Page* newPage = oldPage->chrome()->createWindow(frame, request, WindowFeatures(), NavigationAction())) {
-            newPage->mainFrame()->loader()->loadFrameRequest(request, false, false, 0, 0, SendReferrer);   
+        if (Page* newPage = oldPage->chrome()->createWindow(frame, request, WindowFeatures(), NavigationAction(request.resourceRequest()))) {
+            newPage->mainFrame()->loader()->loadFrameRequest(request, false, false, 0, 0, MaybeSendReferrer);
             newPage->chrome()->show();
         }
     }
 }
 
+#if PLATFORM(GTK)
+static void insertUnicodeCharacter(UChar character, Frame* frame)
+{
+    String text(&character, 1);
+    if (!frame->editor()->shouldInsertText(text, frame->selection()->toNormalizedRange().get(), EditorInsertActionTyped))
+        return;
+
+    TypingCommand::insertText(frame->document(), text, 0, TypingCommand::TextCompositionNone);
+}
+#endif
+
 void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
 {
     ASSERT(item->type() == ActionType || item->type() == CheckableActionType);
@@ -201,6 +231,18 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
     if (!frame)
         return;
 
+#if ENABLE(TIZEN_WEBKIT_PASTEBOARD)
+    if (Page* page = frame->page()) {
+        if (item->action() == ContextMenuItemTagCopyLinkToClipboard
+            || item->action() == ContextMenuItemTagCopyImageToClipboard
+            || item->action() == ContextMenuItemTagCopyImageUrlToClipboard
+            || item->action() == ContextMenuItemTagCopyMediaLinkToClipboard
+            || item->action() == ContextMenuItemTagCopy
+            || item->action() == ContextMenuItemTagCut)
+            Pasteboard::generalPasteboard()->setPage(page);
+    }
+#endif
+
     switch (item->action()) {
     case ContextMenuItemTagOpenLinkInNewWindow:
         openNewWindow(m_hitTestResult.absoluteLinkURL(), frame);
@@ -217,13 +259,13 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
         break;
     case ContextMenuItemTagDownloadImageToDisk:
         // FIXME: Some day we should be able to do this from within WebCore.
-#if ENABLE(TIZEN_SAVE_IMAGE)
+#if ENABLE(TIZEN_INSTALL_CONTENT)
         m_client->saveAsImage(m_contextMenu.get(), frame, m_hitTestResult.absoluteImageURL());
 #else
         m_client->downloadURL(m_hitTestResult.absoluteImageURL());
 #endif
         break;
-#if ENABLE(TIZEN_SAVE_IMAGE)
+#if ENABLE(TIZEN_INSTALL_CONTENT)
     case ContextMenuItemTagSendImageViaEmail:
         m_client->sendImageViaEmail(m_contextMenu.get(), frame, m_hitTestResult.absoluteImageURL());
        break;
@@ -236,16 +278,11 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
         // For now, call into the client. This is temporary!
         frame->editor()->copyImage(m_hitTestResult);
         break;
-#if PLATFORM(QT) || PLATFORM(GTK)
+#if PLATFORM(QT) || PLATFORM(GTK) || PLATFORM(EFL)
     case ContextMenuItemTagCopyImageUrlToClipboard:
         frame->editor()->copyURL(m_hitTestResult.absoluteImageURL(), m_hitTestResult.textContent());
         break;
 #endif
-#if ENABLE(TIZEN_COPY_IMAGE_LOCATION)
-    case ContextMenuItemTagCopyImageLocationToClipboard:
-        frame->editor()->copyURL(m_hitTestResult.absoluteImageURL(), m_hitTestResult.textContent());
-        break;
-#endif
     case ContextMenuItemTagOpenMediaInNewWindow:
         openNewWindow(m_hitTestResult.absoluteMediaURL(), frame);
         break;
@@ -275,9 +312,14 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
             openNewWindow(loader->url(), frame);
         break;
     }
-    case ContextMenuItemTagCopy:
+    case ContextMenuItemTagCopy: {
         frame->editor()->copy();
+#if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
+        if (frame->selection())
+            frame->editor()->command("Unselect").execute();
+#endif
         break;
+    }
     case ContextMenuItemTagGoBack:
         if (Page* page = frame->page())
             page->backForward()->goBackOrForward(-1);
@@ -302,16 +344,43 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
     case ContextMenuItemTagDelete:
         frame->editor()->performDelete();
         break;
+    case ContextMenuItemTagUnicodeInsertLRMMark:
+        insertUnicodeCharacter(leftToRightMark, frame);
+        break;
+    case ContextMenuItemTagUnicodeInsertRLMMark:
+        insertUnicodeCharacter(rightToLeftMark, frame);
+        break;
+    case ContextMenuItemTagUnicodeInsertLREMark:
+        insertUnicodeCharacter(leftToRightEmbed, frame);
+        break;
+    case ContextMenuItemTagUnicodeInsertRLEMark:
+        insertUnicodeCharacter(rightToLeftEmbed, frame);
+        break;
+    case ContextMenuItemTagUnicodeInsertLROMark:
+        insertUnicodeCharacter(leftToRightOverride, frame);
+        break;
+    case ContextMenuItemTagUnicodeInsertRLOMark:
+        insertUnicodeCharacter(rightToLeftOverride, frame);
+        break;
+    case ContextMenuItemTagUnicodeInsertPDFMark:
+        insertUnicodeCharacter(popDirectionalFormatting, frame);
+        break;
+    case ContextMenuItemTagUnicodeInsertZWSMark:
+        insertUnicodeCharacter(zeroWidthSpace, frame);
+        break;
+    case ContextMenuItemTagUnicodeInsertZWJMark:
+        insertUnicodeCharacter(zeroWidthJoiner, frame);
+        break;
+    case ContextMenuItemTagUnicodeInsertZWNJMark:
+        insertUnicodeCharacter(zeroWidthNonJoiner, frame);
+        break;
 #endif
-#if PLATFORM(GTK) || PLATFORM(QT)
+#if PLATFORM(GTK) || PLATFORM(QT) || PLATFORM(EFL)
     case ContextMenuItemTagSelectAll:
         frame->editor()->command("SelectAll").execute();
         break;
 #endif
 #if ENABLE(TIZEN_CONTEXT_MENU_SELECT)
-    case ContextMenuItemTagSelectAll:
-        frame->editor()->command("SelectAll").execute();
-        break;
     case ContextMenuItemTagSelectWord:
         frame->editor()->command("SelectWord").execute();
         break;
@@ -340,7 +409,7 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
         break;
     case ContextMenuItemTagOpenLink:
         if (Frame* targetFrame = m_hitTestResult.targetFrame())
-            targetFrame->loader()->loadFrameRequest(FrameLoadRequest(frame->document()->securityOrigin(), ResourceRequest(m_hitTestResult.absoluteLinkURL(), frame->loader()->outgoingReferrer())), false, false, 0, 0, SendReferrer);
+            targetFrame->loader()->loadFrameRequest(FrameLoadRequest(frame->document()->securityOrigin(), ResourceRequest(m_hitTestResult.absoluteLinkURL(), frame->loader()->outgoingReferrer())), false, false, 0, 0, MaybeSendReferrer);
         else
             openNewWindow(m_hitTestResult.absoluteLinkURL(), frame);
         break;
@@ -470,11 +539,6 @@ void ContextMenuController::appendItem(ContextMenuItem& menuItem, ContextMenu* p
         parentMenu->appendItem(menuItem);
 }
 
-static PassOwnPtr<ContextMenuItem> separatorItem()
-{
-    return adoptPtr(new ContextMenuItem(SeparatorType, ContextMenuItemTagNoAction, String()));
-}
-
 void ContextMenuController::createAndAppendFontSubMenu(ContextMenuItem& fontMenuItem)
 {
     ContextMenu fontMenu;
@@ -561,7 +625,38 @@ void ContextMenuController::createAndAppendSpeechSubMenu(ContextMenuItem& speech
 
 #endif
  
-#if !PLATFORM(GTK)
+#if PLATFORM(GTK)
+
+void ContextMenuController::createAndAppendUnicodeSubMenu(ContextMenuItem& unicodeMenuItem)
+{
+    ContextMenu unicodeMenu;
+
+    ContextMenuItem leftToRightMarkMenuItem(ActionType, ContextMenuItemTagUnicodeInsertLRMMark, contextMenuItemTagUnicodeInsertLRMMark());
+    ContextMenuItem rightToLeftMarkMenuItem(ActionType, ContextMenuItemTagUnicodeInsertRLMMark, contextMenuItemTagUnicodeInsertRLMMark());
+    ContextMenuItem leftToRightEmbedMenuItem(ActionType, ContextMenuItemTagUnicodeInsertLREMark, contextMenuItemTagUnicodeInsertLREMark());
+    ContextMenuItem rightToLeftEmbedMenuItem(ActionType, ContextMenuItemTagUnicodeInsertRLEMark, contextMenuItemTagUnicodeInsertRLEMark());
+    ContextMenuItem leftToRightOverrideMenuItem(ActionType, ContextMenuItemTagUnicodeInsertLROMark, contextMenuItemTagUnicodeInsertLROMark());
+    ContextMenuItem rightToLeftOverrideMenuItem(ActionType, ContextMenuItemTagUnicodeInsertRLOMark, contextMenuItemTagUnicodeInsertRLOMark());
+    ContextMenuItem popDirectionalFormattingMenuItem(ActionType, ContextMenuItemTagUnicodeInsertPDFMark, contextMenuItemTagUnicodeInsertPDFMark());
+    ContextMenuItem zeroWidthSpaceMenuItem(ActionType, ContextMenuItemTagUnicodeInsertZWSMark, contextMenuItemTagUnicodeInsertZWSMark());
+    ContextMenuItem zeroWidthJoinerMenuItem(ActionType, ContextMenuItemTagUnicodeInsertZWJMark, contextMenuItemTagUnicodeInsertZWJMark());
+    ContextMenuItem zeroWidthNonJoinerMenuItem(ActionType, ContextMenuItemTagUnicodeInsertZWNJMark, contextMenuItemTagUnicodeInsertZWNJMark());
+
+    appendItem(leftToRightMarkMenuItem, &unicodeMenu);
+    appendItem(rightToLeftMarkMenuItem, &unicodeMenu);
+    appendItem(leftToRightEmbedMenuItem, &unicodeMenu);
+    appendItem(rightToLeftEmbedMenuItem, &unicodeMenu);
+    appendItem(leftToRightOverrideMenuItem, &unicodeMenu);
+    appendItem(rightToLeftOverrideMenuItem, &unicodeMenu);
+    appendItem(popDirectionalFormattingMenuItem, &unicodeMenu);
+    appendItem(zeroWidthSpaceMenuItem, &unicodeMenu);
+    appendItem(zeroWidthJoinerMenuItem, &unicodeMenu);
+    appendItem(zeroWidthNonJoinerMenuItem, &unicodeMenu);
+
+    unicodeMenuItem.setSubMenu(&unicodeMenu);
+}
+
+#else
 
 void ContextMenuController::createAndAppendWritingDirectionSubMenu(ContextMenuItem& writingDirectionMenuItem)
 {
@@ -673,7 +768,7 @@ void ContextMenuController::populate()
         contextMenuItemTagDownloadImageToDisk());
     ContextMenuItem CopyImageItem(ActionType, ContextMenuItemTagCopyImageToClipboard, 
         contextMenuItemTagCopyImageToClipboard());
-#if PLATFORM(QT) || PLATFORM(GTK)
+#if PLATFORM(QT) || PLATFORM(GTK) || PLATFORM(EFL)
     ContextMenuItem CopyImageUrlItem(ActionType, ContextMenuItemTagCopyImageUrlToClipboard, 
         contextMenuItemTagCopyImageUrlToClipboard());
 #endif
@@ -717,11 +812,10 @@ void ContextMenuController::populate()
 #if PLATFORM(GTK)
     ContextMenuItem DeleteItem(ActionType, ContextMenuItemTagDelete, contextMenuItemTagDelete());
 #endif
-#if PLATFORM(GTK) || PLATFORM(QT)
+#if PLATFORM(GTK) || PLATFORM(QT) || PLATFORM(EFL)
     ContextMenuItem SelectAllItem(ActionType, ContextMenuItemTagSelectAll, contextMenuItemTagSelectAll());
 #endif
 #if ENABLE(TIZEN_CONTEXT_MENU_SELECT)
-    ContextMenuItem SelectAllItem(ActionType, ContextMenuItemTagSelectAll, contextMenuItemTagSelectAll());
     ContextMenuItem SelectWordItem(ActionType, ContextMenuItemTagSelectWord, contextMenuItemTagSelectWord());
 #endif
 
@@ -740,6 +834,15 @@ void ContextMenuController::populate()
         FrameLoader* loader = frame->loader();
         KURL linkURL = m_hitTestResult.absoluteLinkURL();
         if (!linkURL.isEmpty()) {
+#if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
+            if (m_hitTestResult.isSelected()) {
+                if (selectionContainsPossibleWord(frame)) {
+                    appendItem(SearchWebItem, m_contextMenu.get());
+                }
+                appendItem(CopyItem, m_contextMenu.get());
+                return;
+            }
+#endif
 #if ENABLE(TIZEN_DOWNLOAD_LINK_FILTER)
             if (loader->client()->canHandleRequest(ResourceRequest(linkURL)) &&
                (linkURL.protocolIs("http") || linkURL.protocolIs("https") || linkURL.protocolIs("ftp") || linkURL.protocolIs("ftps"))) {
@@ -766,7 +869,7 @@ void ContextMenuController::populate()
             appendItem(DownloadImageItem, m_contextMenu.get());
             if (imageURL.isLocalFile() || m_hitTestResult.image())
                 appendItem(CopyImageItem, m_contextMenu.get());
-#if PLATFORM(QT) || PLATFORM(GTK)
+#if PLATFORM(QT) || PLATFORM(GTK) || PLATFORM(EFL)
             appendItem(CopyImageUrlItem, m_contextMenu.get());
 #endif
         }
@@ -938,19 +1041,36 @@ void ContextMenuController::populate()
 #endif
         }
 
+#if ENABLE(TIZEN_CONTEXT_MENU_WEBKIT_2)
+        if (m_hitTestResult.isSelected()) {
+            appendItem(CutItem, m_contextMenu.get());
+            appendItem(CopyItem, m_contextMenu.get());
+        }
+#else
         appendItem(CutItem, m_contextMenu.get());
         appendItem(CopyItem, m_contextMenu.get());
+#endif
         appendItem(PasteItem, m_contextMenu.get());
 #if PLATFORM(GTK)
         appendItem(DeleteItem, m_contextMenu.get());
         appendItem(*separatorItem(), m_contextMenu.get());
 #endif
-#if PLATFORM(GTK) || PLATFORM(QT)
-        appendItem(SelectAllItem, m_contextMenu.get());
+#if ENABLE(TIZEN_CONTEXT_MENU_WEBKIT_2)
+        if (frame->selection()) {
+            Node* baseNode = frame->selection()->base().containerNode();
+            if (baseNode && baseNode->isTextNode()) {
+                if (!(baseNode->textContent().isEmpty())) {
+#endif
+#if PLATFORM(GTK) || PLATFORM(QT) || PLATFORM(EFL)
+                    appendItem(SelectAllItem, m_contextMenu.get());
 #endif
 #if ENABLE(TIZEN_CONTEXT_MENU_SELECT)
-        appendItem(SelectWordItem, m_contextMenu.get());
-        appendItem(SelectAllItem, m_contextMenu.get());
+                    appendItem(SelectWordItem, m_contextMenu.get());
+#endif
+#if ENABLE(TIZEN_CONTEXT_MENU_WEBKIT_2)
+                }
+            }
+        }
 #endif
 
         if (!inPasswordField) {
@@ -993,7 +1113,15 @@ void ContextMenuController::populate()
             createAndAppendSpeechSubMenu(SpeechMenuItem);
             appendItem(SpeechMenuItem, m_contextMenu.get());
 #endif
-#if !PLATFORM(GTK)
+#if PLATFORM(GTK)
+            EditorClient* client = frame->editor()->client();
+            if (client && client->shouldShowUnicodeMenu()) {
+                ContextMenuItem UnicodeMenuItem(SubmenuType, ContextMenuItemTagUnicode, contextMenuItemTagUnicode());
+                createAndAppendUnicodeSubMenu(UnicodeMenuItem);
+                appendItem(*separatorItem(), m_contextMenu.get());
+                appendItem(UnicodeMenuItem, m_contextMenu.get());
+            }
+#else
             ContextMenuItem WritingDirectionMenuItem(SubmenuType, ContextMenuItemTagWritingDirectionMenu, 
                 contextMenuItemTagWritingDirectionMenu());
 #if !ENABLE(TIZEN_CONTEXT_MENU_TEMPORARY_FIX)
@@ -1036,7 +1164,12 @@ void ContextMenuController::addInspectElementItem()
         return;
 
     ContextMenuItem InspectElementItem(ActionType, ContextMenuItemTagInspectElement, contextMenuItemTagInspectElement());
-    appendItem(*separatorItem(), m_contextMenu.get());
+#if USE(CROSS_PLATFORM_CONTEXT_MENUS)
+    if (!m_contextMenu->items().isEmpty())
+#else
+    if (m_contextMenu->itemCount())
+#endif
+        appendItem(*separatorItem(), m_contextMenu.get());
     appendItem(InspectElementItem, m_contextMenu.get());
 }
 #endif // ENABLE(INSPECTOR)
@@ -1104,7 +1237,6 @@ void ContextMenuController::checkOrEnableIfNeeded(ContextMenuItem& item) const
             shouldEnable = frame->editor()->canDHTMLPaste() || frame->editor()->canPaste();
             break;
 #if ENABLE(TIZEN_CONTEXT_MENU_SELECT)
-        case ContextMenuItemTagSelectAll:
         case ContextMenuItemTagSelectWord:
             shouldEnable = frame->editor()->canSelectRange();
             break;
@@ -1113,9 +1245,23 @@ void ContextMenuController::checkOrEnableIfNeeded(ContextMenuItem& item) const
         case ContextMenuItemTagDelete:
             shouldEnable = frame->editor()->canDelete();
             break;
-        case ContextMenuItemTagSelectAll:
         case ContextMenuItemTagInputMethods:
         case ContextMenuItemTagUnicode:
+        case ContextMenuItemTagUnicodeInsertLRMMark:
+        case ContextMenuItemTagUnicodeInsertRLMMark:
+        case ContextMenuItemTagUnicodeInsertLREMark:
+        case ContextMenuItemTagUnicodeInsertRLEMark:
+        case ContextMenuItemTagUnicodeInsertLROMark:
+        case ContextMenuItemTagUnicodeInsertRLOMark:
+        case ContextMenuItemTagUnicodeInsertPDFMark:
+        case ContextMenuItemTagUnicodeInsertZWSMark:
+        case ContextMenuItemTagUnicodeInsertZWJMark:
+        case ContextMenuItemTagUnicodeInsertZWNJMark:
+            shouldEnable = true;
+            break;
+#endif
+#if PLATFORM(GTK) || PLATFORM(EFL)
+        case ContextMenuItemTagSelectAll:
             shouldEnable = true;
             break;
 #endif
@@ -1244,10 +1390,7 @@ void ContextMenuController::checkOrEnableIfNeeded(ContextMenuItem& item) const
         case ContextMenuItemTagOpenImageInNewWindow:
         case ContextMenuItemTagDownloadImageToDisk:
         case ContextMenuItemTagCopyImageToClipboard:
-#if ENABLE(TIZEN_COPY_IMAGE_LOCATION)
-        case ContextMenuItemTagCopyImageLocationToClipboard:
-#endif
-#if PLATFORM(QT) || PLATFORM(GTK)
+#if PLATFORM(QT) || PLATFORM(GTK) || PLATFORM(EFL)
         case ContextMenuItemTagCopyImageUrlToClipboard:
 #endif
             break;
@@ -1323,6 +1466,17 @@ void ContextMenuController::checkOrEnableIfNeeded(ContextMenuItem& item) const
     item.setEnabled(shouldEnable);
 }
 
+#if USE(ACCESSIBILITY_CONTEXT_MENUS)
+void ContextMenuController::showContextMenuAt(Frame* frame, const IntPoint& clickPoint)
+{
+    // Simulate a click in the middle of the accessibility object.
+    PlatformMouseEvent mouseEvent(clickPoint, clickPoint, RightButton, PlatformEvent::MousePressed, 1, false, false, false, false, currentTime());
+    bool handled = frame->eventHandler()->sendContextMenuEvent(mouseEvent);
+    if (handled && client())
+        client()->showContextMenu();
+}
+#endif
+
 } // namespace WebCore
 
 #endif // ENABLE(CONTEXT_MENUS)