diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index a48277490b00..7785808f3693 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -440,11 +440,13 @@ void WebContents::RendererResponsive(content::WebContents* source) { } bool WebContents::HandleContextMenu(const content::ContextMenuParams& params) { - if (!params.custom_context.is_pepper_menu) - return false; + if (params.custom_context.is_pepper_menu) { + Emit("pepper-context-menu", std::make_pair(params, web_contents())); + web_contents()->NotifyContextMenuClosed(params.custom_context); + } else { + Emit("context-menu", std::make_pair(params, web_contents())); + } - Emit("pepper-context-menu", std::make_pair(params, web_contents())); - web_contents()->NotifyContextMenuClosed(params.custom_context); return true; } diff --git a/atom/common/native_mate_converters/blink_converter.cc b/atom/common/native_mate_converters/blink_converter.cc index c58f830eb02e..0ae73e9825c8 100644 --- a/atom/common/native_mate_converters/blink_converter.cc +++ b/atom/common/native_mate_converters/blink_converter.cc @@ -15,6 +15,7 @@ #include "third_party/WebKit/public/web/WebDeviceEmulationParams.h" #include "third_party/WebKit/public/web/WebFindOptions.h" #include "third_party/WebKit/public/web/WebInputEvent.h" +#include "ui/base/clipboard/clipboard.h" namespace { @@ -296,4 +297,91 @@ bool Converter::FromV8( return true; } +// static +v8::Local Converter::ToV8( + v8::Isolate* isolate, const blink::WebContextMenuData::MediaType& in) { + switch (in) { + case blink::WebContextMenuData::MediaTypeImage: + return mate::StringToV8(isolate, "image"); + case blink::WebContextMenuData::MediaTypeVideo: + return mate::StringToV8(isolate, "video"); + case blink::WebContextMenuData::MediaTypeAudio: + return mate::StringToV8(isolate, "audio"); + case blink::WebContextMenuData::MediaTypeCanvas: + return mate::StringToV8(isolate, "canvas"); + case blink::WebContextMenuData::MediaTypeFile: + return mate::StringToV8(isolate, "file"); + case blink::WebContextMenuData::MediaTypePlugin: + return mate::StringToV8(isolate, "plugin"); + default: + return mate::StringToV8(isolate, "none"); + } +} + +// static +v8::Local Converter::ToV8( + v8::Isolate* isolate, + const blink::WebContextMenuData::InputFieldType& in) { + switch (in) { + case blink::WebContextMenuData::InputFieldTypePlainText: + return mate::StringToV8(isolate, "plainText"); + case blink::WebContextMenuData::InputFieldTypePassword: + return mate::StringToV8(isolate, "password"); + case blink::WebContextMenuData::InputFieldTypeOther: + return mate::StringToV8(isolate, "other"); + default: + return mate::StringToV8(isolate, "none"); + } +} + +v8::Local EditFlagsToV8(v8::Isolate* isolate, int editFlags) { + mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate); + dict.Set("canUndo", + !!(editFlags & blink::WebContextMenuData::CanUndo)); + dict.Set("canRedo", + !!(editFlags & blink::WebContextMenuData::CanRedo)); + dict.Set("canCut", + !!(editFlags & blink::WebContextMenuData::CanCut)); + dict.Set("canCopy", + !!(editFlags & blink::WebContextMenuData::CanCopy)); + + bool pasteFlag = false; + if (editFlags & blink::WebContextMenuData::CanPaste) { + std::vector types; + bool ignore; + ui::Clipboard::GetForCurrentThread()->ReadAvailableTypes( + ui::CLIPBOARD_TYPE_COPY_PASTE, &types, &ignore); + pasteFlag = !types.empty(); + } + dict.Set("canPaste", pasteFlag); + + dict.Set("canDelete", + !!(editFlags & blink::WebContextMenuData::CanDelete)); + dict.Set("canSelectAll", + !!(editFlags & blink::WebContextMenuData::CanSelectAll)); + + return mate::ConvertToV8(isolate, dict); +} + +v8::Local MediaFlagsToV8(v8::Isolate* isolate, int mediaFlags) { + mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate); + dict.Set("inError", + !!(mediaFlags & blink::WebContextMenuData::MediaInError)); + dict.Set("isPaused", + !!(mediaFlags & blink::WebContextMenuData::MediaPaused)); + dict.Set("isMuted", + !!(mediaFlags & blink::WebContextMenuData::MediaMuted)); + dict.Set("hasAudio", + !!(mediaFlags & blink::WebContextMenuData::MediaHasAudio)); + dict.Set("isLooping", + (mediaFlags & blink::WebContextMenuData::MediaLoop) != 0); + dict.Set("isControlsVisible", + (mediaFlags & blink::WebContextMenuData::MediaControls) != 0); + dict.Set("canToggleControls", + !!(mediaFlags & blink::WebContextMenuData::MediaCanToggleControls)); + dict.Set("canRotate", + !!(mediaFlags & blink::WebContextMenuData::MediaCanRotate)); + return mate::ConvertToV8(isolate, dict); +} + } // namespace mate diff --git a/atom/common/native_mate_converters/blink_converter.h b/atom/common/native_mate_converters/blink_converter.h index 6a3601929214..514c6ab680c7 100644 --- a/atom/common/native_mate_converters/blink_converter.h +++ b/atom/common/native_mate_converters/blink_converter.h @@ -6,6 +6,7 @@ #define ATOM_COMMON_NATIVE_MATE_CONVERTERS_BLINK_CONVERTER_H_ #include "native_mate/converter.h" +#include "third_party/WebKit/public/web/WebContextMenuData.h" namespace blink { class WebInputEvent; @@ -87,6 +88,22 @@ struct Converter { blink::WebFindOptions* out); }; +template<> +struct Converter { + static v8::Local ToV8(v8::Isolate* isolate, + const blink::WebContextMenuData::MediaType& in); +}; + +template<> +struct Converter { + static v8::Local ToV8(v8::Isolate* isolate, + const blink::WebContextMenuData::InputFieldType& in); +}; + +v8::Local EditFlagsToV8(v8::Isolate* isolate, int editFlags); + +v8::Local MediaFlagsToV8(v8::Isolate* isolate, int mediaFlags); + } // namespace mate #endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_BLINK_CONVERTER_H_ diff --git a/atom/common/native_mate_converters/content_converter.cc b/atom/common/native_mate_converters/content_converter.cc index 154dcf88ce37..5589c5a84af2 100644 --- a/atom/common/native_mate_converters/content_converter.cc +++ b/atom/common/native_mate_converters/content_converter.cc @@ -9,8 +9,11 @@ #include "atom/browser/api/atom_api_web_contents.h" #include "atom/browser/web_contents_permission_helper.h" +#include "atom/common/native_mate_converters/blink_converter.h" #include "atom/common/native_mate_converters/callback.h" +#include "atom/common/native_mate_converters/gurl_converter.h" #include "atom/common/native_mate_converters/string16_converter.h" +#include "atom/common/native_mate_converters/ui_base_types_converter.h" #include "content/public/browser/web_contents.h" #include "content/public/common/context_menu_params.h" #include "native_mate/dictionary.h" @@ -94,6 +97,23 @@ v8::Local Converter::ToV8( mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate); dict.Set("x", params.x); dict.Set("y", params.y); + dict.Set("linkURL", params.link_url); + dict.Set("linkText", params.link_text); + dict.Set("pageURL", params.page_url); + dict.Set("frameURL", params.frame_url); + dict.Set("srcURL", params.src_url); + dict.Set("mediaType", params.media_type); + dict.Set("mediaFlags", MediaFlagsToV8(isolate, params.media_flags)); + dict.Set("hasImageContents", params.has_image_contents); + dict.Set("isEditable", params.is_editable); + dict.Set("editFlags", EditFlagsToV8(isolate, params.edit_flags)); + dict.Set("selectionText", params.selection_text); + dict.Set("titleText", params.title_text); + dict.Set("misspelledWord", params.misspelled_word); + dict.Set("frameCharset", params.frame_charset); + dict.Set("inputFieldType", params.input_field_type); + dict.Set("menuSourceType", params.source_type); + if (params.custom_context.is_pepper_menu) dict.Set("menu", MenuToV8(isolate, val.second, params.custom_context, params.custom_items)); diff --git a/atom/common/native_mate_converters/ui_base_types_converter.h b/atom/common/native_mate_converters/ui_base_types_converter.h new file mode 100644 index 000000000000..ad3390566c88 --- /dev/null +++ b/atom/common/native_mate_converters/ui_base_types_converter.h @@ -0,0 +1,34 @@ +// Copyright (c) 2016 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_COMMON_NATIVE_MATE_CONVERTERS_UI_BASE_TYPES_CONVERTER_H_ +#define ATOM_COMMON_NATIVE_MATE_CONVERTERS_UI_BASE_TYPES_CONVERTER_H_ + +#include "native_mate/converter.h" +#include "ui/base/ui_base_types.h" + +namespace mate { + +template<> +struct Converter { + static v8::Local ToV8(v8::Isolate* isolate, + const ui::MenuSourceType& in) { + switch (in) { + case ui::MENU_SOURCE_MOUSE: + return mate::StringToV8(isolate, "mouse"); + case ui::MENU_SOURCE_KEYBOARD: + return mate::StringToV8(isolate, "keyboard"); + case ui::MENU_SOURCE_TOUCH: + return mate::StringToV8(isolate, "touch"); + case ui::MENU_SOURCE_TOUCH_EDIT_MENU: + return mate::StringToV8(isolate, "touchMenu"); + default: + return mate::StringToV8(isolate, "none"); + } + } +}; + +} // namespace mate + +#endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_UI_BASE_TYPES_CONVERTER_H_ diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 4576e77ddf91..3d4a83cf1fc1 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -308,6 +308,63 @@ If the `type` parameter is `custom`, the `image` parameter will hold the custom cursor image in a `NativeImage`, and the `scale` will hold scaling information for the image. +### Event: 'context-menu' + +Returns: + +* `event` Event +* `params` Object + * `x` Integer - x coodinate + * `y` Integer - y coodinate + * `linkURL` String - URL of the link that encloses the node the context menu +was invoked on. + * `linkText` String - Text associated with the link. May be an empty +string if the contents of the link are an image. + * `pageURL` String - URL of the top level page that the context menu was +invoked on. + * `frameURL` String - URL of the subframe that the context menu was invoked +on. + * `srcURL` String - Source URL for the element that the context menu +was invoked on. Elements with source URLs are images, audio and video. + * `mediaType` String - Type of the node the context menu was invoked on. Can +be `none`, `image`, `audio`, `video`, `canvas`, `file` or `plugin`. + * `mediaFlags` Object - Parameters for the media element the context menu was +invoked on. + * `inError` - Boolean + * `isPaused` - Boolean + * `isMuted` - Boolean + * `hasAudio` - Boolean + * `isLooping` - Boolean + * `isControlsVisible` - Boolean + * `canToggleControls` - Boolean + * `canRotate` - Boolean + * `hasImageContent` Boolean - Wether the context menu was invoked on an image +which has non-empty contents. + * `isEditable` Boolean - Wether the context is editable. + * `editFlags` Object - These flags indicate wether the renderer believes it is +able to perform the corresponding action. + * `canUndo` - Boolean + * `canRedo` - Boolean + * `canCut` - Boolean + * `canCopy` - Boolean + * `canPaste` - Boolean + * `canDelete` - Boolean + * `canSelectAll` - Boolean + * `selectionText` String - Text of the selection that the context menu was +invoked on. + * `titleText` String - Title or alt text of the selection that the context +was invoked on. + * `misspelledWord` String - The misspelled word under the cursor, if any. + * `frameCharset` String - The character encoding of the frame on which the +menu was invoked. + * `inputFieldType` String - If the context menu was invoked on an input +field, the type of that field. Possible values are `none`, `plainText`, +`password`, `other`. + * `menuSourceType` String - Input source that invoked the context menu. +Can be `none`, `mouse`, `keyboard`, `touch`, `touchMenu`. + +Emitted when there is a new context menu that needs to be handled. + ## Instance Methods The `webContents` object has the following instance methods: diff --git a/filenames.gypi b/filenames.gypi index 1c2139497567..3ad66e7fafc3 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -362,6 +362,7 @@ 'atom/common/native_mate_converters/net_converter.cc', 'atom/common/native_mate_converters/net_converter.h', 'atom/common/native_mate_converters/string16_converter.h', + 'atom/common/native_mate_converters/ui_base_types_converter.h', 'atom/common/native_mate_converters/v8_value_converter.cc', 'atom/common/native_mate_converters/v8_value_converter.h', 'atom/common/native_mate_converters/value_converter.cc',