summaryrefslogtreecommitdiffstats
path: root/webkit/glue/context_menu_client_impl.cc
diff options
context:
space:
mode:
authorinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-27 00:20:51 +0000
committerinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-27 00:20:51 +0000
commitf5b16fed647e941aa66933178da85db2860d639b (patch)
treef00e9856c04aad3b558a140955e7674add33f051 /webkit/glue/context_menu_client_impl.cc
parent920c091ac3ee15079194c82ae8a7a18215f3f23c (diff)
downloadchromium_src-f5b16fed647e941aa66933178da85db2860d639b.zip
chromium_src-f5b16fed647e941aa66933178da85db2860d639b.tar.gz
chromium_src-f5b16fed647e941aa66933178da85db2860d639b.tar.bz2
Add webkit to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/glue/context_menu_client_impl.cc')
-rw-r--r--webkit/glue/context_menu_client_impl.cc276
1 files changed, 276 insertions, 0 deletions
diff --git a/webkit/glue/context_menu_client_impl.cc b/webkit/glue/context_menu_client_impl.cc
new file mode 100644
index 0000000..c5227676
--- /dev/null
+++ b/webkit/glue/context_menu_client_impl.cc
@@ -0,0 +1,276 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "config.h"
+
+#pragma warning(push, 0)
+#include "ContextMenu.h"
+#include "Document.h"
+#include "DocumentLoader.h"
+#include "Editor.h"
+#include "FrameLoader.h"
+#include "FrameView.h"
+#include "HitTestResult.h"
+#include "KURL.h"
+#include "Widget.h"
+#pragma warning(pop)
+#undef LOG
+
+#include "webkit/glue/context_menu_client_impl.h"
+
+#include "base/string_util.h"
+#include "webkit/glue/context_node_types.h"
+#include "webkit/glue/glue_util.h"
+#include "webkit/glue/webdocumentloader_impl.h"
+#include "webkit/glue/webview_impl.h"
+
+#include "base/word_iterator.h"
+
+// Helper function to determine whether text is a single word or a sentence.
+static bool IsASingleWord(const std::wstring& text) {
+ WordIterator iter(text, WordIterator::BREAK_WORD);
+ int word_count = 0;
+ if (!iter.Init()) return false;
+ while (iter.Advance()) {
+ if (iter.IsWord()) {
+ word_count++;
+ if (word_count > 1) // More than one word.
+ return false;
+ }
+ }
+
+ // Check for 0 words.
+ if (!word_count)
+ return false;
+
+ // Has a single word.
+ return true;
+}
+
+// Helper function to get misspelled word on which context menu
+// is to be evolked. This function also sets the word on which context menu
+// has been evoked to be the selected word, as required.
+static std::wstring GetMisspelledWord(WebCore::ContextMenu* default_menu,
+ WebCore::Frame* selected_frame) {
+ std::wstring misspelled_word_string;
+
+ // First select from selectedText to check for multiple word selection.
+ misspelled_word_string = CollapseWhitespace(
+ webkit_glue::StringToStdWString(selected_frame->selectedText()),
+ false);
+
+ // Don't provide suggestions for multiple words.
+ if (!misspelled_word_string.empty() &&
+ !IsASingleWord(misspelled_word_string))
+ return L"";
+
+ // Expand around the click to see if we clicked a word.
+ WebCore::Selection selection;
+ WebCore::VisiblePosition pos(default_menu->hitTestResult().innerNode()->
+ renderer()->positionForPoint(default_menu->hitTestResult().
+ localPoint()));
+
+ if (pos.isNotNull()) {
+ selection = WebCore::Selection(pos);
+ selection.expandUsingGranularity(WebCore::WordGranularity);
+ }
+
+ if (selection.isRange()) {
+ selected_frame->setSelectionGranularity(WebCore::WordGranularity);
+ }
+
+ if (selected_frame->shouldChangeSelection(selection))
+ selected_frame->selectionController()->setSelection(selection);
+
+ misspelled_word_string = CollapseWhitespace(
+ webkit_glue::StringToStdWString(selected_frame->selectedText()),
+ false);
+
+ return misspelled_word_string;
+}
+
+ContextMenuClientImpl::~ContextMenuClientImpl() {
+}
+
+void ContextMenuClientImpl::contextMenuDestroyed() {
+ delete this;
+}
+
+// Figure out the URL of a page or subframe. Returns |page_type| as the type,
+// which indicates page or subframe, or ContextNode::NONE if the URL could not
+// be determined for some reason.
+static ContextNode::Type GetTypeAndURLFromFrame(WebCore::Frame* frame,
+ GURL* url,
+ ContextNode::Type page_type) {
+ ContextNode::Type type = ContextNode::NONE;
+ if (frame) {
+ WebCore::DocumentLoader* dl = frame->loader()->documentLoader();
+ if (dl) {
+ WebDataSource* ds = static_cast<WebDocumentLoaderImpl*>(dl)->
+ GetDataSource();
+ if (ds) {
+ type = page_type;
+ *url = ds->HasUnreachableURL() ? ds->GetUnreachableURL()
+ : ds->GetRequest().GetURL();
+ }
+ }
+ }
+ return type;
+}
+
+WebCore::PlatformMenuDescription
+ ContextMenuClientImpl::getCustomMenuFromDefaultItems(
+ WebCore::ContextMenu* default_menu) {
+ // Displaying the context menu in this function is a big hack as we don't
+ // have context, i.e. whether this is being invoked via a script or in
+ // response to user input (Mouse event WM_RBUTTONDOWN,
+ // Keyboard events KeyVK_APPS, Shift+F10). Check if this is being invoked
+ // in response to the above input events before popping up the context menu.
+ if (!webview_->context_menu_allowed())
+ return NULL;
+
+ WebCore::HitTestResult r = default_menu->hitTestResult();
+ WebCore::Frame* selected_frame = r.innerNonSharedNode()->document()->frame();
+
+ WebCore::IntPoint menu_point =
+ selected_frame->view()->contentsToWindow(r.point());
+
+ ContextNode::Type type = ContextNode::NONE;
+
+ // Links, Images and Image-Links take preference over all else.
+ WebCore::KURL link_url = r.absoluteLinkURL();
+ std::wstring link_url_string;
+ if (!link_url.isEmpty()) {
+ type = ContextNode::LINK;
+ }
+ WebCore::KURL image_url = r.absoluteImageURL();
+ std::wstring image_url_string;
+ if (!image_url.isEmpty()) {
+ type = ContextNode::IMAGE;
+ }
+ if (!image_url.isEmpty() && !link_url.isEmpty())
+ type = ContextNode::IMAGE_LINK;
+
+ // If it's not a link, an image or an image link, show a selection menu or a
+ // more generic page menu.
+ std::wstring selection_text_string;
+ std::wstring misspelled_word_string;
+ GURL frame_url;
+ GURL page_url;
+
+ // Send the frame and page URLs in any case.
+ ContextNode::Type frame_type = ContextNode::NONE;
+ ContextNode::Type page_type =
+ GetTypeAndURLFromFrame(webview_->main_frame()->frame(),
+ &page_url,
+ ContextNode::PAGE);
+ if (selected_frame != webview_->main_frame()->frame()) {
+ frame_type = GetTypeAndURLFromFrame(selected_frame,
+ &frame_url,
+ ContextNode::FRAME);
+ }
+
+ if (type == ContextNode::NONE) {
+ if (r.isContentEditable()) {
+ type = ContextNode::EDITABLE;
+ if (webview_->FocusedFrameNeedsSpellchecking()) {
+ misspelled_word_string = GetMisspelledWord(default_menu,
+ selected_frame);
+ }
+ } else if (r.isSelected()) {
+ type = ContextNode::SELECTION;
+ selection_text_string =
+ CollapseWhitespace(
+ webkit_glue::StringToStdWString(selected_frame->selectedText()),
+ false);
+ } else if (selected_frame != webview_->main_frame()->frame()) {
+ type = frame_type;
+ } else {
+ type = page_type;
+ }
+ }
+
+ int edit_flags = ContextNode::CAN_DO_NONE;
+ if (webview_->GetFocusedWebCoreFrame()->editor()->canUndo())
+ edit_flags |= ContextNode::CAN_UNDO;
+ if (webview_->GetFocusedWebCoreFrame()->editor()->canRedo())
+ edit_flags |= ContextNode::CAN_REDO;
+ if (webview_->GetFocusedWebCoreFrame()->editor()->canCut())
+ edit_flags |= ContextNode::CAN_CUT;
+ if (webview_->GetFocusedWebCoreFrame()->editor()->canCopy())
+ edit_flags |= ContextNode::CAN_COPY;
+ if (webview_->GetFocusedWebCoreFrame()->editor()->canPaste())
+ edit_flags |= ContextNode::CAN_PASTE;
+ if (webview_->GetFocusedWebCoreFrame()->editor()->canDelete())
+ edit_flags |= ContextNode::CAN_DELETE;
+ // We can always select all...
+ edit_flags |= ContextNode::CAN_SELECT_ALL;
+
+ WebViewDelegate* d = webview_->delegate();
+ if (d) {
+ d->ShowContextMenu(webview_,
+ type,
+ menu_point.x(),
+ menu_point.y(),
+ webkit_glue::KURLToGURL(link_url),
+ webkit_glue::KURLToGURL(image_url),
+ page_url,
+ frame_url,
+ selection_text_string,
+ misspelled_word_string,
+ edit_flags);
+ }
+ return NULL;
+}
+
+void ContextMenuClientImpl::contextMenuItemSelected(
+ WebCore::ContextMenuItem*, const WebCore::ContextMenu*) {
+}
+
+void ContextMenuClientImpl::downloadURL(const WebCore::KURL&) {
+}
+
+void ContextMenuClientImpl::copyImageToClipboard(const WebCore::HitTestResult&) {
+}
+
+void ContextMenuClientImpl::searchWithGoogle(const WebCore::Frame*) {
+}
+
+void ContextMenuClientImpl::lookUpInDictionary(WebCore::Frame*) {
+}
+
+void ContextMenuClientImpl::speak(const WebCore::String&) {
+}
+
+void ContextMenuClientImpl::stopSpeaking() {
+}
+
+bool ContextMenuClientImpl::shouldIncludeInspectElementItem() {
+ return false; // TODO(jackson): Eventually include the inspector context menu item
+}