Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose the 'context-menu' event. #5379

Merged
merged 3 commits into from May 5, 2016
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 6 additions & 4 deletions atom/browser/api/atom_api_web_contents.cc
Expand Up @@ -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;
}

Expand Down
88 changes: 88 additions & 0 deletions atom/common/native_mate_converters/blink_converter.cc
Expand Up @@ -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 {

Expand Down Expand Up @@ -296,4 +297,91 @@ bool Converter<blink::WebFindOptions>::FromV8(
return true;
}

// static
v8::Local<v8::Value> Converter<blink::WebContextMenuData::MediaType>::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<v8::Value> Converter<blink::WebContextMenuData::InputFieldType>::ToV8(
v8::Isolate* isolate,
const blink::WebContextMenuData::InputFieldType& in) {
switch (in) {
case blink::WebContextMenuData::InputFieldTypePlainText:
return mate::StringToV8(isolate, "plain-text");
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<v8::Value> 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<base::string16> 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<v8::Value> 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
17 changes: 17 additions & 0 deletions atom/common/native_mate_converters/blink_converter.h
Expand Up @@ -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;
Expand Down Expand Up @@ -87,6 +88,22 @@ struct Converter<blink::WebFindOptions> {
blink::WebFindOptions* out);
};

template<>
struct Converter<blink::WebContextMenuData::MediaType> {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
const blink::WebContextMenuData::MediaType& in);
};

template<>
struct Converter<blink::WebContextMenuData::InputFieldType> {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
const blink::WebContextMenuData::InputFieldType& in);
};

v8::Local<v8::Value> EditFlagsToV8(v8::Isolate* isolate, int editFlags);

v8::Local<v8::Value> MediaFlagsToV8(v8::Isolate* isolate, int mediaFlags);

} // namespace mate

#endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_BLINK_CONVERTER_H_
20 changes: 20 additions & 0 deletions atom/common/native_mate_converters/content_converter.cc
Expand Up @@ -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"
Expand Down Expand Up @@ -94,6 +97,23 @@ v8::Local<v8::Value> Converter<ContextMenuParamsWithWebContents>::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));
Expand Down
34 changes: 34 additions & 0 deletions 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<ui::MenuSourceType> {
static v8::Local<v8::Value> 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, "touch-menu");
default:
return mate::StringToV8(isolate, "none");
}
}
};

} // namespace mate

#endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_UI_BASE_TYPES_CONVERTER_H_
57 changes: 57 additions & 0 deletions docs/api/web-contents.md
Expand Up @@ -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`, `plain-text`,
`password`, `other`.
* `menuSourceType` String - Input source that invoked the context menu.
Can be `none`, `mouse`, `keyboard`, `touch`, `touch-menu`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer to use touchMenu and plainText instead of touch-menu and plain-text, the former follows the style of other APIs, like the dialog.showOpenDialog and webContents.sendInputEvent.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good, I wasn't too sure on the style to use there.


Emitted when there is a new context menu that needs to be handled.

## Instance Methods

The `webContents` object has the following instance methods:
Expand Down
1 change: 1 addition & 0 deletions filenames.gypi
Expand Up @@ -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',
Expand Down