refactor: rename the atom directory to shell
This commit is contained in:
parent
4575a4aae3
commit
d7f07e8a80
631 changed files with 0 additions and 0 deletions
23
shell/common/native_mate_converters/accelerator_converter.cc
Normal file
23
shell/common/native_mate_converters/accelerator_converter.cc
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/common/native_mate_converters/accelerator_converter.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/ui/accelerator_util.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
// static
|
||||
bool Converter<ui::Accelerator>::FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
ui::Accelerator* out) {
|
||||
std::string keycode;
|
||||
if (!ConvertFromV8(isolate, val, &keycode))
|
||||
return false;
|
||||
return accelerator_util::StringToAccelerator(keycode, out);
|
||||
}
|
||||
|
||||
} // namespace mate
|
25
shell/common/native_mate_converters/accelerator_converter.h
Normal file
25
shell/common/native_mate_converters/accelerator_converter.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
// Copyright (c) 2014 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_ACCELERATOR_CONVERTER_H_
|
||||
#define ATOM_COMMON_NATIVE_MATE_CONVERTERS_ACCELERATOR_CONVERTER_H_
|
||||
|
||||
#include "native_mate/converter.h"
|
||||
|
||||
namespace ui {
|
||||
class Accelerator;
|
||||
}
|
||||
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
struct Converter<ui::Accelerator> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
ui::Accelerator* out);
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
#endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_ACCELERATOR_CONVERTER_H_
|
530
shell/common/native_mate_converters/blink_converter.cc
Normal file
530
shell/common/native_mate_converters/blink_converter.cc
Normal file
|
@ -0,0 +1,530 @@
|
|||
// Copyright (c) 2015 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/common/native_mate_converters/blink_converter.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/common/keyboard_util.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "content/public/browser/native_web_keyboard_event.h"
|
||||
#include "gin/converter.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "third_party/blink/public/platform/web_input_event.h"
|
||||
#include "third_party/blink/public/platform/web_mouse_event.h"
|
||||
#include "third_party/blink/public/platform/web_mouse_wheel_event.h"
|
||||
#include "third_party/blink/public/web/web_device_emulation_params.h"
|
||||
#include "ui/base/clipboard/clipboard.h"
|
||||
#include "ui/events/keycodes/dom/keycode_converter.h"
|
||||
#include "ui/events/keycodes/keyboard_code_conversion.h"
|
||||
|
||||
namespace {
|
||||
|
||||
template <typename T>
|
||||
int VectorToBitArray(const std::vector<T>& vec) {
|
||||
int bits = 0;
|
||||
for (const T& item : vec)
|
||||
bits |= item;
|
||||
return bits;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
struct Converter<base::char16> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Handle<v8::Value> val,
|
||||
base::char16* out) {
|
||||
base::string16 code = base::UTF8ToUTF16(gin::V8ToString(isolate, val));
|
||||
if (code.length() != 1)
|
||||
return false;
|
||||
*out = code[0];
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<blink::WebInputEvent::Type> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Handle<v8::Value> val,
|
||||
blink::WebInputEvent::Type* out) {
|
||||
std::string type = base::ToLowerASCII(gin::V8ToString(isolate, val));
|
||||
if (type == "mousedown")
|
||||
*out = blink::WebInputEvent::kMouseDown;
|
||||
else if (type == "mouseup")
|
||||
*out = blink::WebInputEvent::kMouseUp;
|
||||
else if (type == "mousemove")
|
||||
*out = blink::WebInputEvent::kMouseMove;
|
||||
else if (type == "mouseenter")
|
||||
*out = blink::WebInputEvent::kMouseEnter;
|
||||
else if (type == "mouseleave")
|
||||
*out = blink::WebInputEvent::kMouseLeave;
|
||||
else if (type == "contextmenu")
|
||||
*out = blink::WebInputEvent::kContextMenu;
|
||||
else if (type == "mousewheel")
|
||||
*out = blink::WebInputEvent::kMouseWheel;
|
||||
else if (type == "keydown")
|
||||
*out = blink::WebInputEvent::kRawKeyDown;
|
||||
else if (type == "keyup")
|
||||
*out = blink::WebInputEvent::kKeyUp;
|
||||
else if (type == "char")
|
||||
*out = blink::WebInputEvent::kChar;
|
||||
else if (type == "touchstart")
|
||||
*out = blink::WebInputEvent::kTouchStart;
|
||||
else if (type == "touchmove")
|
||||
*out = blink::WebInputEvent::kTouchMove;
|
||||
else if (type == "touchend")
|
||||
*out = blink::WebInputEvent::kTouchEnd;
|
||||
else if (type == "touchcancel")
|
||||
*out = blink::WebInputEvent::kTouchCancel;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<blink::WebMouseEvent::Button> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Handle<v8::Value> val,
|
||||
blink::WebMouseEvent::Button* out) {
|
||||
std::string button = base::ToLowerASCII(gin::V8ToString(isolate, val));
|
||||
if (button == "left")
|
||||
*out = blink::WebMouseEvent::Button::kLeft;
|
||||
else if (button == "middle")
|
||||
*out = blink::WebMouseEvent::Button::kMiddle;
|
||||
else if (button == "right")
|
||||
*out = blink::WebMouseEvent::Button::kRight;
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<blink::WebInputEvent::Modifiers> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Handle<v8::Value> val,
|
||||
blink::WebInputEvent::Modifiers* out) {
|
||||
std::string modifier = base::ToLowerASCII(gin::V8ToString(isolate, val));
|
||||
if (modifier == "shift")
|
||||
*out = blink::WebInputEvent::kShiftKey;
|
||||
else if (modifier == "control" || modifier == "ctrl")
|
||||
*out = blink::WebInputEvent::kControlKey;
|
||||
else if (modifier == "alt")
|
||||
*out = blink::WebInputEvent::kAltKey;
|
||||
else if (modifier == "meta" || modifier == "command" || modifier == "cmd")
|
||||
*out = blink::WebInputEvent::kMetaKey;
|
||||
else if (modifier == "iskeypad")
|
||||
*out = blink::WebInputEvent::kIsKeyPad;
|
||||
else if (modifier == "isautorepeat")
|
||||
*out = blink::WebInputEvent::kIsAutoRepeat;
|
||||
else if (modifier == "leftbuttondown")
|
||||
*out = blink::WebInputEvent::kLeftButtonDown;
|
||||
else if (modifier == "middlebuttondown")
|
||||
*out = blink::WebInputEvent::kMiddleButtonDown;
|
||||
else if (modifier == "rightbuttondown")
|
||||
*out = blink::WebInputEvent::kRightButtonDown;
|
||||
else if (modifier == "capslock")
|
||||
*out = blink::WebInputEvent::kCapsLockOn;
|
||||
else if (modifier == "numlock")
|
||||
*out = blink::WebInputEvent::kNumLockOn;
|
||||
else if (modifier == "left")
|
||||
*out = blink::WebInputEvent::kIsLeft;
|
||||
else if (modifier == "right")
|
||||
*out = blink::WebInputEvent::kIsRight;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
blink::WebInputEvent::Type GetWebInputEventType(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val) {
|
||||
blink::WebInputEvent::Type type = blink::WebInputEvent::kUndefined;
|
||||
mate::Dictionary dict;
|
||||
ConvertFromV8(isolate, val, &dict) && dict.Get("type", &type);
|
||||
return type;
|
||||
}
|
||||
|
||||
bool Converter<blink::WebInputEvent>::FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
blink::WebInputEvent* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
blink::WebInputEvent::Type type;
|
||||
if (!dict.Get("type", &type))
|
||||
return false;
|
||||
out->SetType(type);
|
||||
std::vector<blink::WebInputEvent::Modifiers> modifiers;
|
||||
if (dict.Get("modifiers", &modifiers))
|
||||
out->SetModifiers(VectorToBitArray(modifiers));
|
||||
out->SetTimeStamp(base::TimeTicks::Now());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Converter<blink::WebKeyboardEvent>::FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
blink::WebKeyboardEvent* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
if (!ConvertFromV8(isolate, val, static_cast<blink::WebInputEvent*>(out)))
|
||||
return false;
|
||||
|
||||
std::string str;
|
||||
if (!dict.Get("keyCode", &str))
|
||||
return false;
|
||||
|
||||
bool shifted = false;
|
||||
ui::KeyboardCode keyCode = atom::KeyboardCodeFromStr(str, &shifted);
|
||||
out->windows_key_code = keyCode;
|
||||
if (shifted)
|
||||
out->SetModifiers(out->GetModifiers() | blink::WebInputEvent::kShiftKey);
|
||||
|
||||
ui::DomCode domCode = ui::UsLayoutKeyboardCodeToDomCode(keyCode);
|
||||
out->dom_code = static_cast<int>(domCode);
|
||||
|
||||
ui::DomKey domKey;
|
||||
ui::KeyboardCode dummy_code;
|
||||
int flags = atom::WebEventModifiersToEventFlags(out->GetModifiers());
|
||||
if (ui::DomCodeToUsLayoutDomKey(domCode, flags, &domKey, &dummy_code))
|
||||
out->dom_key = static_cast<int>(domKey);
|
||||
|
||||
if ((out->GetType() == blink::WebInputEvent::kChar ||
|
||||
out->GetType() == blink::WebInputEvent::kRawKeyDown)) {
|
||||
// Make sure to not read beyond the buffer in case some bad code doesn't
|
||||
// NULL-terminate it (this is called from plugins).
|
||||
size_t text_length_cap = blink::WebKeyboardEvent::kTextLengthCap;
|
||||
base::string16 text16 = base::UTF8ToUTF16(str);
|
||||
|
||||
memset(out->text, 0, text_length_cap);
|
||||
memset(out->unmodified_text, 0, text_length_cap);
|
||||
for (size_t i = 0; i < std::min(text_length_cap, text16.size()); ++i) {
|
||||
out->text[i] = text16[i];
|
||||
out->unmodified_text[i] = text16[i];
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Converter<content::NativeWebKeyboardEvent>::FromV8(
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
content::NativeWebKeyboardEvent* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
if (!ConvertFromV8(isolate, val, static_cast<blink::WebKeyboardEvent*>(out)))
|
||||
return false;
|
||||
dict.Get("skipInBrowser", &out->skip_in_browser);
|
||||
return true;
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Converter<content::NativeWebKeyboardEvent>::ToV8(
|
||||
v8::Isolate* isolate,
|
||||
const content::NativeWebKeyboardEvent& in) {
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
|
||||
|
||||
if (in.GetType() == blink::WebInputEvent::Type::kRawKeyDown)
|
||||
dict.Set("type", "keyDown");
|
||||
else if (in.GetType() == blink::WebInputEvent::Type::kKeyUp)
|
||||
dict.Set("type", "keyUp");
|
||||
dict.Set("key", ui::KeycodeConverter::DomKeyToKeyString(in.dom_key));
|
||||
dict.Set("code", ui::KeycodeConverter::DomCodeToCodeString(
|
||||
static_cast<ui::DomCode>(in.dom_code)));
|
||||
|
||||
using Modifiers = blink::WebInputEvent::Modifiers;
|
||||
dict.Set("isAutoRepeat", (in.GetModifiers() & Modifiers::kIsAutoRepeat) != 0);
|
||||
dict.Set("shift", (in.GetModifiers() & Modifiers::kShiftKey) != 0);
|
||||
dict.Set("control", (in.GetModifiers() & Modifiers::kControlKey) != 0);
|
||||
dict.Set("alt", (in.GetModifiers() & Modifiers::kAltKey) != 0);
|
||||
dict.Set("meta", (in.GetModifiers() & Modifiers::kMetaKey) != 0);
|
||||
|
||||
return dict.GetHandle();
|
||||
}
|
||||
|
||||
bool Converter<blink::WebMouseEvent>::FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
blink::WebMouseEvent* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
if (!ConvertFromV8(isolate, val, static_cast<blink::WebInputEvent*>(out)))
|
||||
return false;
|
||||
|
||||
float x = 0.f;
|
||||
float y = 0.f;
|
||||
if (!dict.Get("x", &x) || !dict.Get("y", &y))
|
||||
return false;
|
||||
out->SetPositionInWidget(x, y);
|
||||
|
||||
if (!dict.Get("button", &out->button))
|
||||
out->button = blink::WebMouseEvent::Button::kLeft;
|
||||
|
||||
float global_x = 0.f;
|
||||
float global_y = 0.f;
|
||||
dict.Get("globalX", &global_x);
|
||||
dict.Get("globalY", &global_y);
|
||||
out->SetPositionInScreen(global_x, global_y);
|
||||
|
||||
dict.Get("movementX", &out->movement_x);
|
||||
dict.Get("movementY", &out->movement_y);
|
||||
dict.Get("clickCount", &out->click_count);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Converter<blink::WebMouseWheelEvent>::FromV8(
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
blink::WebMouseWheelEvent* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
if (!ConvertFromV8(isolate, val, static_cast<blink::WebMouseEvent*>(out)))
|
||||
return false;
|
||||
dict.Get("deltaX", &out->delta_x);
|
||||
dict.Get("deltaY", &out->delta_y);
|
||||
dict.Get("wheelTicksX", &out->wheel_ticks_x);
|
||||
dict.Get("wheelTicksY", &out->wheel_ticks_y);
|
||||
dict.Get("accelerationRatioX", &out->acceleration_ratio_x);
|
||||
dict.Get("accelerationRatioY", &out->acceleration_ratio_y);
|
||||
dict.Get("hasPreciseScrollingDeltas", &out->has_precise_scrolling_deltas);
|
||||
|
||||
#if defined(USE_AURA)
|
||||
// Matches the behavior of ui/events/blink/web_input_event_traits.cc:
|
||||
bool can_scroll = true;
|
||||
if (dict.Get("canScroll", &can_scroll) && !can_scroll) {
|
||||
out->has_precise_scrolling_deltas = false;
|
||||
out->SetModifiers(out->GetModifiers() & ~blink::WebInputEvent::kControlKey);
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Converter<blink::WebFloatPoint>::FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
blink::WebFloatPoint* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
return dict.Get("x", &out->x) && dict.Get("y", &out->y);
|
||||
}
|
||||
|
||||
template <>
|
||||
struct Converter<base::Optional<blink::WebPoint>> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
base::Optional<blink::WebPoint>* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
blink::WebPoint point;
|
||||
bool success = dict.Get("x", &point.x) && dict.Get("y", &point.y);
|
||||
if (!success)
|
||||
return false;
|
||||
out->emplace(point);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
bool Converter<blink::WebSize>::FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
blink::WebSize* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
return dict.Get("width", &out->width) && dict.Get("height", &out->height);
|
||||
}
|
||||
|
||||
bool Converter<blink::WebDeviceEmulationParams>::FromV8(
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
blink::WebDeviceEmulationParams* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
|
||||
std::string screen_position;
|
||||
if (dict.Get("screenPosition", &screen_position)) {
|
||||
screen_position = base::ToLowerASCII(screen_position);
|
||||
if (screen_position == "mobile")
|
||||
out->screen_position = blink::WebDeviceEmulationParams::kMobile;
|
||||
else if (screen_position == "desktop")
|
||||
out->screen_position = blink::WebDeviceEmulationParams::kDesktop;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
dict.Get("screenSize", &out->screen_size);
|
||||
dict.Get("viewPosition", &out->view_position);
|
||||
dict.Get("deviceScaleFactor", &out->device_scale_factor);
|
||||
dict.Get("viewSize", &out->view_size);
|
||||
dict.Get("scale", &out->scale);
|
||||
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::kMediaTypeImage:
|
||||
return mate::StringToV8(isolate, "image");
|
||||
case blink::WebContextMenuData::kMediaTypeVideo:
|
||||
return mate::StringToV8(isolate, "video");
|
||||
case blink::WebContextMenuData::kMediaTypeAudio:
|
||||
return mate::StringToV8(isolate, "audio");
|
||||
case blink::WebContextMenuData::kMediaTypeCanvas:
|
||||
return mate::StringToV8(isolate, "canvas");
|
||||
case blink::WebContextMenuData::kMediaTypeFile:
|
||||
return mate::StringToV8(isolate, "file");
|
||||
case blink::WebContextMenuData::kMediaTypePlugin:
|
||||
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::kInputFieldTypePlainText:
|
||||
return mate::StringToV8(isolate, "plainText");
|
||||
case blink::WebContextMenuData::kInputFieldTypePassword:
|
||||
return mate::StringToV8(isolate, "password");
|
||||
case blink::WebContextMenuData::kInputFieldTypeOther:
|
||||
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::kCanUndo));
|
||||
dict.Set("canRedo", !!(editFlags & blink::WebContextMenuData::kCanRedo));
|
||||
dict.Set("canCut", !!(editFlags & blink::WebContextMenuData::kCanCut));
|
||||
dict.Set("canCopy", !!(editFlags & blink::WebContextMenuData::kCanCopy));
|
||||
|
||||
bool pasteFlag = false;
|
||||
if (editFlags & blink::WebContextMenuData::kCanPaste) {
|
||||
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::kCanDelete));
|
||||
dict.Set("canSelectAll",
|
||||
!!(editFlags & blink::WebContextMenuData::kCanSelectAll));
|
||||
|
||||
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::kMediaInError));
|
||||
dict.Set("isPaused",
|
||||
!!(mediaFlags & blink::WebContextMenuData::kMediaPaused));
|
||||
dict.Set("isMuted", !!(mediaFlags & blink::WebContextMenuData::kMediaMuted));
|
||||
dict.Set("hasAudio",
|
||||
!!(mediaFlags & blink::WebContextMenuData::kMediaHasAudio));
|
||||
dict.Set("isLooping",
|
||||
(mediaFlags & blink::WebContextMenuData::kMediaLoop) != 0);
|
||||
dict.Set("isControlsVisible",
|
||||
(mediaFlags & blink::WebContextMenuData::kMediaControls) != 0);
|
||||
dict.Set("canToggleControls",
|
||||
!!(mediaFlags & blink::WebContextMenuData::kMediaCanToggleControls));
|
||||
dict.Set("canRotate",
|
||||
!!(mediaFlags & blink::WebContextMenuData::kMediaCanRotate));
|
||||
return mate::ConvertToV8(isolate, dict);
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Converter<blink::WebCache::ResourceTypeStat>::ToV8(
|
||||
v8::Isolate* isolate,
|
||||
const blink::WebCache::ResourceTypeStat& stat) {
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
|
||||
dict.Set("count", static_cast<uint32_t>(stat.count));
|
||||
dict.Set("size", static_cast<double>(stat.size));
|
||||
dict.Set("liveSize", static_cast<double>(stat.decoded_size));
|
||||
return dict.GetHandle();
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Converter<blink::WebCache::ResourceTypeStats>::ToV8(
|
||||
v8::Isolate* isolate,
|
||||
const blink::WebCache::ResourceTypeStats& stats) {
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
|
||||
dict.Set("images", stats.images);
|
||||
dict.Set("scripts", stats.scripts);
|
||||
dict.Set("cssStyleSheets", stats.css_style_sheets);
|
||||
dict.Set("xslStyleSheets", stats.xsl_style_sheets);
|
||||
dict.Set("fonts", stats.fonts);
|
||||
dict.Set("other", stats.other);
|
||||
return dict.GetHandle();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Local<v8::Value> Converter<network::mojom::ReferrerPolicy>::ToV8(
|
||||
v8::Isolate* isolate,
|
||||
const network::mojom::ReferrerPolicy& in) {
|
||||
switch (in) {
|
||||
case network::mojom::ReferrerPolicy::kDefault:
|
||||
return mate::StringToV8(isolate, "default");
|
||||
case network::mojom::ReferrerPolicy::kAlways:
|
||||
return mate::StringToV8(isolate, "unsafe-url");
|
||||
case network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade:
|
||||
return mate::StringToV8(isolate, "no-referrer-when-downgrade");
|
||||
case network::mojom::ReferrerPolicy::kNever:
|
||||
return mate::StringToV8(isolate, "no-referrer");
|
||||
case network::mojom::ReferrerPolicy::kOrigin:
|
||||
return mate::StringToV8(isolate, "origin");
|
||||
case network::mojom::ReferrerPolicy::
|
||||
kNoReferrerWhenDowngradeOriginWhenCrossOrigin:
|
||||
return mate::StringToV8(isolate, "strict-origin-when-cross-origin");
|
||||
case network::mojom::ReferrerPolicy::kSameOrigin:
|
||||
return mate::StringToV8(isolate, "same-origin");
|
||||
case network::mojom::ReferrerPolicy::kStrictOrigin:
|
||||
return mate::StringToV8(isolate, "strict-origin");
|
||||
default:
|
||||
return mate::StringToV8(isolate, "no-referrer");
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
bool Converter<network::mojom::ReferrerPolicy>::FromV8(
|
||||
v8::Isolate* isolate,
|
||||
v8::Handle<v8::Value> val,
|
||||
network::mojom::ReferrerPolicy* out) {
|
||||
std::string policy = base::ToLowerASCII(gin::V8ToString(isolate, val));
|
||||
if (policy == "default")
|
||||
*out = network::mojom::ReferrerPolicy::kDefault;
|
||||
else if (policy == "unsafe-url")
|
||||
*out = network::mojom::ReferrerPolicy::kAlways;
|
||||
else if (policy == "no-referrer-when-downgrade")
|
||||
*out = network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade;
|
||||
else if (policy == "no-referrer")
|
||||
*out = network::mojom::ReferrerPolicy::kNever;
|
||||
else if (policy == "origin")
|
||||
*out = network::mojom::ReferrerPolicy::kOrigin;
|
||||
else if (policy == "strict-origin-when-cross-origin")
|
||||
*out = network::mojom::ReferrerPolicy::
|
||||
kNoReferrerWhenDowngradeOriginWhenCrossOrigin;
|
||||
else if (policy == "same-origin")
|
||||
*out = network::mojom::ReferrerPolicy::kSameOrigin;
|
||||
else if (policy == "strict-origin")
|
||||
*out = network::mojom::ReferrerPolicy::kStrictOrigin;
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace mate
|
139
shell/common/native_mate_converters/blink_converter.h
Normal file
139
shell/common/native_mate_converters/blink_converter.h
Normal file
|
@ -0,0 +1,139 @@
|
|||
// Copyright (c) 2015 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_BLINK_CONVERTER_H_
|
||||
#define ATOM_COMMON_NATIVE_MATE_CONVERTERS_BLINK_CONVERTER_H_
|
||||
|
||||
#include "native_mate/converter.h"
|
||||
#include "third_party/blink/public/platform/web_cache.h"
|
||||
#include "third_party/blink/public/platform/web_input_event.h"
|
||||
#include "third_party/blink/public/web/web_context_menu_data.h"
|
||||
|
||||
namespace blink {
|
||||
class WebMouseEvent;
|
||||
class WebMouseWheelEvent;
|
||||
class WebKeyboardEvent;
|
||||
struct WebDeviceEmulationParams;
|
||||
struct WebFloatPoint;
|
||||
struct WebPoint;
|
||||
struct WebSize;
|
||||
} // namespace blink
|
||||
|
||||
namespace content {
|
||||
struct NativeWebKeyboardEvent;
|
||||
}
|
||||
|
||||
namespace mate {
|
||||
|
||||
blink::WebInputEvent::Type GetWebInputEventType(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val);
|
||||
|
||||
template <>
|
||||
struct Converter<blink::WebInputEvent> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
blink::WebInputEvent* out);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<blink::WebKeyboardEvent> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
blink::WebKeyboardEvent* out);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<content::NativeWebKeyboardEvent> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
content::NativeWebKeyboardEvent* out);
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const content::NativeWebKeyboardEvent& in);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<blink::WebMouseEvent> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
blink::WebMouseEvent* out);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<blink::WebMouseWheelEvent> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
blink::WebMouseWheelEvent* out);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<blink::WebFloatPoint> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
blink::WebFloatPoint* out);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<blink::WebPoint> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
blink::WebPoint* out);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<blink::WebSize> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
blink::WebSize* out);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<blink::WebDeviceEmulationParams> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
blink::WebDeviceEmulationParams* 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);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<blink::WebCache::ResourceTypeStat> {
|
||||
static v8::Local<v8::Value> ToV8(
|
||||
v8::Isolate* isolate,
|
||||
const blink::WebCache::ResourceTypeStat& stat);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<blink::WebCache::ResourceTypeStats> {
|
||||
static v8::Local<v8::Value> ToV8(
|
||||
v8::Isolate* isolate,
|
||||
const blink::WebCache::ResourceTypeStats& stats);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<network::mojom::ReferrerPolicy> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const network::mojom::ReferrerPolicy& in);
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
network::mojom::ReferrerPolicy* out);
|
||||
};
|
||||
|
||||
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_
|
163
shell/common/native_mate_converters/callback.cc
Normal file
163
shell/common/native_mate_converters/callback.cc
Normal file
|
@ -0,0 +1,163 @@
|
|||
// Copyright (c) 2015 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "base/stl_util.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace mate {
|
||||
|
||||
namespace internal {
|
||||
|
||||
namespace {
|
||||
|
||||
struct TranslaterHolder {
|
||||
explicit TranslaterHolder(v8::Isolate* isolate)
|
||||
: handle(isolate, v8::External::New(isolate, this)) {
|
||||
handle.SetWeak(this, &GC, v8::WeakCallbackType::kFinalizer);
|
||||
}
|
||||
~TranslaterHolder() {
|
||||
if (!handle.IsEmpty()) {
|
||||
handle.ClearWeak();
|
||||
handle.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
static void GC(const v8::WeakCallbackInfo<TranslaterHolder>& data) {
|
||||
delete data.GetParameter();
|
||||
}
|
||||
|
||||
v8::Global<v8::External> handle;
|
||||
Translater translater;
|
||||
};
|
||||
|
||||
// Cached JavaScript version of |CallTranslater|.
|
||||
v8::Persistent<v8::FunctionTemplate> g_call_translater;
|
||||
|
||||
void CallTranslater(v8::Local<v8::External> external,
|
||||
v8::Local<v8::Object> state,
|
||||
mate::Arguments* args) {
|
||||
// Whether the callback should only be called for once.
|
||||
v8::Isolate* isolate = args->isolate();
|
||||
auto context = isolate->GetCurrentContext();
|
||||
bool one_time =
|
||||
state->Has(context, mate::StringToSymbol(isolate, "oneTime")).ToChecked();
|
||||
|
||||
// Check if the callback has already been called.
|
||||
if (one_time) {
|
||||
auto called_symbol = mate::StringToSymbol(isolate, "called");
|
||||
if (state->Has(context, called_symbol).ToChecked()) {
|
||||
args->ThrowError("callback can only be called for once");
|
||||
return;
|
||||
} else {
|
||||
state->Set(context, called_symbol, v8::Boolean::New(isolate, true))
|
||||
.ToChecked();
|
||||
}
|
||||
}
|
||||
|
||||
TranslaterHolder* holder = static_cast<TranslaterHolder*>(external->Value());
|
||||
holder->translater.Run(args);
|
||||
|
||||
// Free immediately for one-time callback.
|
||||
if (one_time)
|
||||
delete holder;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// Destroy the class on UI thread when possible.
|
||||
struct DeleteOnUIThread {
|
||||
template <typename T>
|
||||
static void Destruct(const T* x) {
|
||||
if (Locker::IsBrowserProcess() &&
|
||||
!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
|
||||
BrowserThread::DeleteSoon(BrowserThread::UI, FROM_HERE, x);
|
||||
} else {
|
||||
delete x;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Like v8::Global, but ref-counted.
|
||||
template <typename T>
|
||||
class RefCountedGlobal
|
||||
: public base::RefCountedThreadSafe<RefCountedGlobal<T>, DeleteOnUIThread> {
|
||||
public:
|
||||
RefCountedGlobal(v8::Isolate* isolate, v8::Local<v8::Value> value)
|
||||
: handle_(isolate, v8::Local<T>::Cast(value)) {}
|
||||
|
||||
bool IsAlive() const { return !handle_.IsEmpty(); }
|
||||
|
||||
v8::Local<T> NewHandle(v8::Isolate* isolate) const {
|
||||
return v8::Local<T>::New(isolate, handle_);
|
||||
}
|
||||
|
||||
private:
|
||||
v8::Global<T> handle_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(RefCountedGlobal);
|
||||
};
|
||||
|
||||
SafeV8Function::SafeV8Function(v8::Isolate* isolate, v8::Local<v8::Value> value)
|
||||
: v8_function_(new RefCountedGlobal<v8::Function>(isolate, value)) {}
|
||||
|
||||
SafeV8Function::SafeV8Function(const SafeV8Function& other)
|
||||
: v8_function_(other.v8_function_) {}
|
||||
|
||||
SafeV8Function::~SafeV8Function() {}
|
||||
|
||||
bool SafeV8Function::IsAlive() const {
|
||||
return v8_function_.get() && v8_function_->IsAlive();
|
||||
}
|
||||
|
||||
v8::Local<v8::Function> SafeV8Function::NewHandle(v8::Isolate* isolate) const {
|
||||
return v8_function_->NewHandle(isolate);
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> CreateFunctionFromTranslater(v8::Isolate* isolate,
|
||||
const Translater& translater,
|
||||
bool one_time) {
|
||||
// The FunctionTemplate is cached.
|
||||
if (g_call_translater.IsEmpty())
|
||||
g_call_translater.Reset(isolate,
|
||||
mate::CreateFunctionTemplate(
|
||||
isolate, base::BindRepeating(&CallTranslater)));
|
||||
|
||||
v8::Local<v8::FunctionTemplate> call_translater =
|
||||
v8::Local<v8::FunctionTemplate>::New(isolate, g_call_translater);
|
||||
auto* holder = new TranslaterHolder(isolate);
|
||||
holder->translater = translater;
|
||||
Dictionary state = mate::Dictionary::CreateEmpty(isolate);
|
||||
if (one_time)
|
||||
state.Set("oneTime", true);
|
||||
auto context = isolate->GetCurrentContext();
|
||||
return BindFunctionWith(
|
||||
isolate, context, call_translater->GetFunction(context).ToLocalChecked(),
|
||||
holder->handle.Get(isolate), state.GetHandle());
|
||||
}
|
||||
|
||||
// func.bind(func, arg1).
|
||||
// NB(zcbenz): Using C++11 version crashes VS.
|
||||
v8::Local<v8::Value> BindFunctionWith(v8::Isolate* isolate,
|
||||
v8::Local<v8::Context> context,
|
||||
v8::Local<v8::Function> func,
|
||||
v8::Local<v8::Value> arg1,
|
||||
v8::Local<v8::Value> arg2) {
|
||||
v8::MaybeLocal<v8::Value> bind =
|
||||
func->Get(context, mate::StringToV8(isolate, "bind"));
|
||||
CHECK(!bind.IsEmpty());
|
||||
v8::Local<v8::Function> bind_func =
|
||||
v8::Local<v8::Function>::Cast(bind.ToLocalChecked());
|
||||
v8::Local<v8::Value> converted[] = {func, arg1, arg2};
|
||||
return bind_func->Call(context, func, base::size(converted), converted)
|
||||
.ToLocalChecked();
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} // namespace mate
|
181
shell/common/native_mate_converters/callback.h
Normal file
181
shell/common/native_mate_converters/callback.h
Normal file
|
@ -0,0 +1,181 @@
|
|||
// Copyright (c) 2015 GitHub, Inc. All rights reserved.
|
||||
// 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_CALLBACK_H_
|
||||
#define ATOM_COMMON_NATIVE_MATE_CONVERTERS_CALLBACK_H_
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/common/api/locker.h"
|
||||
#include "base/bind.h"
|
||||
#include "base/callback.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "base/message_loop/message_loop.h"
|
||||
#include "native_mate/function_template.h"
|
||||
#include "native_mate/scoped_persistent.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
namespace internal {
|
||||
|
||||
template <typename T>
|
||||
class RefCountedGlobal;
|
||||
|
||||
// Manages the V8 function with RAII.
|
||||
class SafeV8Function {
|
||||
public:
|
||||
SafeV8Function(v8::Isolate* isolate, v8::Local<v8::Value> value);
|
||||
SafeV8Function(const SafeV8Function& other);
|
||||
~SafeV8Function();
|
||||
|
||||
bool IsAlive() const;
|
||||
v8::Local<v8::Function> NewHandle(v8::Isolate* isolate) const;
|
||||
|
||||
private:
|
||||
scoped_refptr<RefCountedGlobal<v8::Function>> v8_function_;
|
||||
};
|
||||
|
||||
// Helper to invoke a V8 function with C++ parameters.
|
||||
template <typename Sig>
|
||||
struct V8FunctionInvoker {};
|
||||
|
||||
template <typename... ArgTypes>
|
||||
struct V8FunctionInvoker<v8::Local<v8::Value>(ArgTypes...)> {
|
||||
static v8::Local<v8::Value> Go(v8::Isolate* isolate,
|
||||
const SafeV8Function& function,
|
||||
ArgTypes... raw) {
|
||||
Locker locker(isolate);
|
||||
v8::EscapableHandleScope handle_scope(isolate);
|
||||
if (!function.IsAlive())
|
||||
return v8::Null(isolate);
|
||||
v8::MicrotasksScope script_scope(isolate,
|
||||
v8::MicrotasksScope::kRunMicrotasks);
|
||||
v8::Local<v8::Function> holder = function.NewHandle(isolate);
|
||||
v8::Local<v8::Context> context = holder->CreationContext();
|
||||
v8::Context::Scope context_scope(context);
|
||||
std::vector<v8::Local<v8::Value>> args{
|
||||
ConvertToV8(isolate, std::forward<ArgTypes>(raw))...};
|
||||
v8::MaybeLocal<v8::Value> ret = holder->Call(
|
||||
context, holder, args.size(), args.empty() ? nullptr : &args.front());
|
||||
if (ret.IsEmpty())
|
||||
return v8::Undefined(isolate);
|
||||
else
|
||||
return handle_scope.Escape(ret.ToLocalChecked());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename... ArgTypes>
|
||||
struct V8FunctionInvoker<void(ArgTypes...)> {
|
||||
static void Go(v8::Isolate* isolate,
|
||||
const SafeV8Function& function,
|
||||
ArgTypes... raw) {
|
||||
Locker locker(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
if (!function.IsAlive())
|
||||
return;
|
||||
v8::MicrotasksScope script_scope(isolate,
|
||||
v8::MicrotasksScope::kRunMicrotasks);
|
||||
v8::Local<v8::Function> holder = function.NewHandle(isolate);
|
||||
v8::Local<v8::Context> context = holder->CreationContext();
|
||||
v8::Context::Scope context_scope(context);
|
||||
std::vector<v8::Local<v8::Value>> args{
|
||||
ConvertToV8(isolate, std::forward<ArgTypes>(raw))...};
|
||||
holder
|
||||
->Call(context, holder, args.size(),
|
||||
args.empty() ? nullptr : &args.front())
|
||||
.IsEmpty();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ReturnType, typename... ArgTypes>
|
||||
struct V8FunctionInvoker<ReturnType(ArgTypes...)> {
|
||||
static ReturnType Go(v8::Isolate* isolate,
|
||||
const SafeV8Function& function,
|
||||
ArgTypes... raw) {
|
||||
Locker locker(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
ReturnType ret = ReturnType();
|
||||
if (!function.IsAlive())
|
||||
return ret;
|
||||
v8::MicrotasksScope script_scope(isolate,
|
||||
v8::MicrotasksScope::kRunMicrotasks);
|
||||
v8::Local<v8::Function> holder = function.NewHandle(isolate);
|
||||
v8::Local<v8::Context> context = holder->CreationContext();
|
||||
v8::Context::Scope context_scope(context);
|
||||
std::vector<v8::Local<v8::Value>> args{
|
||||
ConvertToV8(isolate, std::forward<ArgTypes>(raw))...};
|
||||
v8::Local<v8::Value> result;
|
||||
auto maybe_result = holder->Call(context, holder, args.size(),
|
||||
args.empty() ? nullptr : &args.front());
|
||||
if (maybe_result.ToLocal(&result))
|
||||
Converter<ReturnType>::FromV8(isolate, result, &ret);
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
// Helper to pass a C++ funtion to JavaScript.
|
||||
using Translater = base::Callback<void(Arguments* args)>;
|
||||
v8::Local<v8::Value> CreateFunctionFromTranslater(v8::Isolate* isolate,
|
||||
const Translater& translater,
|
||||
bool one_time);
|
||||
v8::Local<v8::Value> BindFunctionWith(v8::Isolate* isolate,
|
||||
v8::Local<v8::Context> context,
|
||||
v8::Local<v8::Function> func,
|
||||
v8::Local<v8::Value> arg1,
|
||||
v8::Local<v8::Value> arg2);
|
||||
|
||||
// Calls callback with Arguments.
|
||||
template <typename Sig>
|
||||
struct NativeFunctionInvoker {};
|
||||
|
||||
template <typename ReturnType, typename... ArgTypes>
|
||||
struct NativeFunctionInvoker<ReturnType(ArgTypes...)> {
|
||||
static void Go(base::Callback<ReturnType(ArgTypes...)> val, Arguments* args) {
|
||||
using Indices = typename IndicesGenerator<sizeof...(ArgTypes)>::type;
|
||||
Invoker<Indices, ArgTypes...> invoker(args, 0);
|
||||
if (invoker.IsOK())
|
||||
invoker.DispatchToCallback(val);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template <typename Sig>
|
||||
struct Converter<base::RepeatingCallback<Sig>> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const base::RepeatingCallback<Sig>& val) {
|
||||
// We don't use CreateFunctionTemplate here because it creates a new
|
||||
// FunctionTemplate everytime, which is cached by V8 and causes leaks.
|
||||
internal::Translater translater =
|
||||
base::Bind(&internal::NativeFunctionInvoker<Sig>::Go, val);
|
||||
// To avoid memory leak, we ensure that the callback can only be called
|
||||
// for once.
|
||||
return internal::CreateFunctionFromTranslater(isolate, translater, true);
|
||||
}
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
base::RepeatingCallback<Sig>* out) {
|
||||
if (!val->IsFunction())
|
||||
return false;
|
||||
|
||||
*out = base::BindRepeating(&internal::V8FunctionInvoker<Sig>::Go, isolate,
|
||||
internal::SafeV8Function(isolate, val));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// Convert a callback to V8 without the call number limitation, this can easily
|
||||
// cause memory leaks so use it with caution.
|
||||
template <typename Sig>
|
||||
v8::Local<v8::Value> CallbackToV8(v8::Isolate* isolate,
|
||||
const base::Callback<Sig>& val) {
|
||||
internal::Translater translater =
|
||||
base::Bind(&internal::NativeFunctionInvoker<Sig>::Go, val);
|
||||
return internal::CreateFunctionFromTranslater(isolate, translater, false);
|
||||
}
|
||||
|
||||
} // namespace mate
|
||||
|
||||
#endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_CALLBACK_H_
|
251
shell/common/native_mate_converters/content_converter.cc
Normal file
251
shell/common/native_mate_converters/content_converter.cc
Normal file
|
@ -0,0 +1,251 @@
|
|||
// Copyright (c) 2015 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/common/native_mate_converters/content_converter.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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 "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "content/public/common/context_menu_params.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
namespace {
|
||||
|
||||
void ExecuteCommand(content::WebContents* web_contents,
|
||||
int action,
|
||||
const content::CustomContextMenuContext& context) {
|
||||
web_contents->ExecuteCustomContextMenuCommand(action, context);
|
||||
}
|
||||
|
||||
// Forward declaration for nested recursive call.
|
||||
v8::Local<v8::Value> MenuToV8(v8::Isolate* isolate,
|
||||
content::WebContents* web_contents,
|
||||
const content::CustomContextMenuContext& context,
|
||||
const std::vector<content::MenuItem>& menu);
|
||||
|
||||
v8::Local<v8::Value> MenuItemToV8(
|
||||
v8::Isolate* isolate,
|
||||
content::WebContents* web_contents,
|
||||
const content::CustomContextMenuContext& context,
|
||||
const content::MenuItem& item) {
|
||||
mate::Dictionary v8_item = mate::Dictionary::CreateEmpty(isolate);
|
||||
switch (item.type) {
|
||||
case content::MenuItem::CHECKABLE_OPTION:
|
||||
case content::MenuItem::GROUP:
|
||||
v8_item.Set("checked", item.checked);
|
||||
FALLTHROUGH;
|
||||
case content::MenuItem::OPTION:
|
||||
case content::MenuItem::SUBMENU:
|
||||
v8_item.Set("label", item.label);
|
||||
v8_item.Set("enabled", item.enabled);
|
||||
FALLTHROUGH;
|
||||
default:
|
||||
v8_item.Set("type", item.type);
|
||||
}
|
||||
if (item.type == content::MenuItem::SUBMENU)
|
||||
v8_item.Set("submenu",
|
||||
MenuToV8(isolate, web_contents, context, item.submenu));
|
||||
else if (item.action > 0)
|
||||
v8_item.Set("click", base::BindRepeating(ExecuteCommand, web_contents,
|
||||
item.action, context));
|
||||
return v8_item.GetHandle();
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> MenuToV8(v8::Isolate* isolate,
|
||||
content::WebContents* web_contents,
|
||||
const content::CustomContextMenuContext& context,
|
||||
const std::vector<content::MenuItem>& menu) {
|
||||
std::vector<v8::Local<v8::Value>> v8_menu;
|
||||
for (const auto& menu_item : menu)
|
||||
v8_menu.push_back(MenuItemToV8(isolate, web_contents, context, menu_item));
|
||||
return mate::ConvertToV8(isolate, v8_menu);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace mate {
|
||||
|
||||
// static
|
||||
v8::Local<v8::Value> Converter<content::MenuItem::Type>::ToV8(
|
||||
v8::Isolate* isolate,
|
||||
const content::MenuItem::Type& val) {
|
||||
switch (val) {
|
||||
case content::MenuItem::CHECKABLE_OPTION:
|
||||
return StringToV8(isolate, "checkbox");
|
||||
case content::MenuItem::GROUP:
|
||||
return StringToV8(isolate, "radio");
|
||||
case content::MenuItem::SEPARATOR:
|
||||
return StringToV8(isolate, "separator");
|
||||
case content::MenuItem::SUBMENU:
|
||||
return StringToV8(isolate, "submenu");
|
||||
case content::MenuItem::OPTION:
|
||||
default:
|
||||
return StringToV8(isolate, "normal");
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Local<v8::Value> Converter<ContextMenuParamsWithWebContents>::ToV8(
|
||||
v8::Isolate* isolate,
|
||||
const ContextMenuParamsWithWebContents& val) {
|
||||
const auto& params = val.first;
|
||||
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));
|
||||
bool has_image_contents =
|
||||
(params.media_type == blink::WebContextMenuData::kMediaTypeImage) &&
|
||||
params.has_image_contents;
|
||||
dict.Set("hasImageContents", 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));
|
||||
return mate::ConvertToV8(isolate, dict);
|
||||
}
|
||||
|
||||
// static
|
||||
bool Converter<blink::mojom::PermissionStatus>::FromV8(
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
blink::mojom::PermissionStatus* out) {
|
||||
bool result;
|
||||
if (!ConvertFromV8(isolate, val, &result))
|
||||
return false;
|
||||
|
||||
if (result)
|
||||
*out = blink::mojom::PermissionStatus::GRANTED;
|
||||
else
|
||||
*out = blink::mojom::PermissionStatus::DENIED;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Local<v8::Value> Converter<content::PermissionType>::ToV8(
|
||||
v8::Isolate* isolate,
|
||||
const content::PermissionType& val) {
|
||||
using PermissionType = atom::WebContentsPermissionHelper::PermissionType;
|
||||
switch (val) {
|
||||
case content::PermissionType::MIDI_SYSEX:
|
||||
return StringToV8(isolate, "midiSysex");
|
||||
case content::PermissionType::NOTIFICATIONS:
|
||||
return StringToV8(isolate, "notifications");
|
||||
case content::PermissionType::GEOLOCATION:
|
||||
return StringToV8(isolate, "geolocation");
|
||||
case content::PermissionType::AUDIO_CAPTURE:
|
||||
case content::PermissionType::VIDEO_CAPTURE:
|
||||
return StringToV8(isolate, "media");
|
||||
case content::PermissionType::PROTECTED_MEDIA_IDENTIFIER:
|
||||
return StringToV8(isolate, "mediaKeySystem");
|
||||
case content::PermissionType::MIDI:
|
||||
return StringToV8(isolate, "midi");
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (val == static_cast<content::PermissionType>(PermissionType::POINTER_LOCK))
|
||||
return StringToV8(isolate, "pointerLock");
|
||||
else if (val ==
|
||||
static_cast<content::PermissionType>(PermissionType::FULLSCREEN))
|
||||
return StringToV8(isolate, "fullscreen");
|
||||
else if (val ==
|
||||
static_cast<content::PermissionType>(PermissionType::OPEN_EXTERNAL))
|
||||
return StringToV8(isolate, "openExternal");
|
||||
|
||||
return StringToV8(isolate, "unknown");
|
||||
}
|
||||
|
||||
// static
|
||||
bool Converter<content::StopFindAction>::FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
content::StopFindAction* out) {
|
||||
std::string action;
|
||||
if (!ConvertFromV8(isolate, val, &action))
|
||||
return false;
|
||||
|
||||
if (action == "clearSelection")
|
||||
*out = content::STOP_FIND_ACTION_CLEAR_SELECTION;
|
||||
else if (action == "keepSelection")
|
||||
*out = content::STOP_FIND_ACTION_KEEP_SELECTION;
|
||||
else if (action == "activateSelection")
|
||||
*out = content::STOP_FIND_ACTION_ACTIVATE_SELECTION;
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Local<v8::Value> Converter<content::WebContents*>::ToV8(
|
||||
v8::Isolate* isolate,
|
||||
content::WebContents* val) {
|
||||
if (!val)
|
||||
return v8::Null(isolate);
|
||||
return atom::api::WebContents::FromOrCreate(isolate, val).ToV8();
|
||||
}
|
||||
|
||||
// static
|
||||
bool Converter<content::WebContents*>::FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
content::WebContents** out) {
|
||||
atom::api::WebContents* web_contents = nullptr;
|
||||
if (!ConvertFromV8(isolate, val, &web_contents) || !web_contents)
|
||||
return false;
|
||||
|
||||
*out = web_contents->web_contents();
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Local<v8::Value> Converter<content::Referrer>::ToV8(
|
||||
v8::Isolate* isolate,
|
||||
const content::Referrer& val) {
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
|
||||
dict.Set("url", ConvertToV8(isolate, val.url));
|
||||
dict.Set("policy", ConvertToV8(isolate, val.policy));
|
||||
return mate::ConvertToV8(isolate, dict);
|
||||
}
|
||||
|
||||
// static
|
||||
bool Converter<content::Referrer>::FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
content::Referrer* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
|
||||
if (!dict.Get("url", &out->url))
|
||||
return false;
|
||||
|
||||
if (!dict.Get("policy", &out->policy))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace mate
|
79
shell/common/native_mate_converters/content_converter.h
Normal file
79
shell/common/native_mate_converters/content_converter.h
Normal file
|
@ -0,0 +1,79 @@
|
|||
// Copyright (c) 2015 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_CONTENT_CONVERTER_H_
|
||||
#define ATOM_COMMON_NATIVE_MATE_CONVERTERS_CONTENT_CONVERTER_H_
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "content/public/browser/permission_type.h"
|
||||
#include "content/public/common/menu_item.h"
|
||||
#include "content/public/common/referrer.h"
|
||||
#include "content/public/common/stop_find_action.h"
|
||||
#include "native_mate/converter.h"
|
||||
#include "third_party/blink/public/mojom/permissions/permission_status.mojom.h"
|
||||
|
||||
namespace content {
|
||||
struct ContextMenuParams;
|
||||
class WebContents;
|
||||
} // namespace content
|
||||
|
||||
using ContextMenuParamsWithWebContents =
|
||||
std::pair<content::ContextMenuParams, content::WebContents*>;
|
||||
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
struct Converter<content::MenuItem::Type> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const content::MenuItem::Type& val);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<ContextMenuParamsWithWebContents> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const ContextMenuParamsWithWebContents& val);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<blink::mojom::PermissionStatus> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
blink::mojom::PermissionStatus* out);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<content::PermissionType> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const content::PermissionType& val);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<content::StopFindAction> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
content::StopFindAction* out);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<content::WebContents*> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
content::WebContents* val);
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
content::WebContents** out);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<content::Referrer> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const content::Referrer& val);
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
content::Referrer* out);
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
#endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_CONTENT_CONVERTER_H_
|
76
shell/common/native_mate_converters/file_dialog_converter.cc
Normal file
76
shell/common/native_mate_converters/file_dialog_converter.cc
Normal file
|
@ -0,0 +1,76 @@
|
|||
// Copyright (c) 2015 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/common/native_mate_converters/file_dialog_converter.h"
|
||||
|
||||
#include "atom/browser/api/atom_api_browser_window.h"
|
||||
#include "atom/browser/ui/file_dialog.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
bool Converter<file_dialog::Filter>::FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
file_dialog::Filter* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
if (!dict.Get("name", &(out->first)))
|
||||
return false;
|
||||
if (!dict.Get("extensions", &(out->second)))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Converter<file_dialog::Filter>::ToV8(
|
||||
v8::Isolate* isolate,
|
||||
const file_dialog::Filter& in) {
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
|
||||
|
||||
dict.Set("name", in.first);
|
||||
dict.Set("extensions", in.second);
|
||||
|
||||
return dict.GetHandle();
|
||||
}
|
||||
|
||||
bool Converter<file_dialog::DialogSettings>::FromV8(
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
file_dialog::DialogSettings* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
dict.Get("window", &(out->parent_window));
|
||||
dict.Get("title", &(out->title));
|
||||
dict.Get("message", &(out->message));
|
||||
dict.Get("buttonLabel", &(out->button_label));
|
||||
dict.Get("nameFieldLabel", &(out->name_field_label));
|
||||
dict.Get("defaultPath", &(out->default_path));
|
||||
dict.Get("filters", &(out->filters));
|
||||
dict.Get("properties", &(out->properties));
|
||||
dict.Get("showsTagField", &(out->shows_tag_field));
|
||||
dict.Get("securityScopedBookmarks", &(out->security_scoped_bookmarks));
|
||||
return true;
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Converter<file_dialog::DialogSettings>::ToV8(
|
||||
v8::Isolate* isolate,
|
||||
const file_dialog::DialogSettings& in) {
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
|
||||
|
||||
dict.Set("window", atom::api::BrowserWindow::From(isolate, in.parent_window));
|
||||
dict.Set("title", in.title);
|
||||
dict.Set("message", in.message);
|
||||
dict.Set("buttonLabel", in.button_label);
|
||||
dict.Set("nameFieldLabel", in.name_field_label);
|
||||
dict.Set("defaultPath", in.default_path);
|
||||
dict.Set("filters", in.filters);
|
||||
dict.Set("showsTagField", in.shows_tag_field);
|
||||
dict.Set("securityScopedBookmarks", in.security_scoped_bookmarks);
|
||||
|
||||
return dict.GetHandle();
|
||||
}
|
||||
|
||||
} // namespace mate
|
33
shell/common/native_mate_converters/file_dialog_converter.h
Normal file
33
shell/common/native_mate_converters/file_dialog_converter.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
// Copyright (c) 2014 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_FILE_DIALOG_CONVERTER_H_
|
||||
#define ATOM_COMMON_NATIVE_MATE_CONVERTERS_FILE_DIALOG_CONVERTER_H_
|
||||
|
||||
#include "atom/browser/ui/file_dialog.h"
|
||||
#include "native_mate/converter.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
struct Converter<file_dialog::Filter> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const file_dialog::Filter& in);
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
file_dialog::Filter* out);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<file_dialog::DialogSettings> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const file_dialog::DialogSettings& in);
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
file_dialog::DialogSettings* out);
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
#endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_FILE_DIALOG_CONVERTER_H_
|
57
shell/common/native_mate_converters/file_path_converter.h
Normal file
57
shell/common/native_mate_converters/file_path_converter.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
// Copyright (c) 2014 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_FILE_PATH_CONVERTER_H_
|
||||
#define ATOM_COMMON_NATIVE_MATE_CONVERTERS_FILE_PATH_CONVERTER_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
#include "base/files/file_path.h"
|
||||
|
||||
namespace gin {
|
||||
|
||||
template <>
|
||||
struct Converter<base::FilePath> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const base::FilePath& val) {
|
||||
return Converter<base::FilePath::StringType>::ToV8(isolate, val.value());
|
||||
}
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
base::FilePath* out) {
|
||||
if (val->IsNull())
|
||||
return true;
|
||||
|
||||
base::FilePath::StringType path;
|
||||
if (Converter<base::FilePath::StringType>::FromV8(isolate, val, &path)) {
|
||||
*out = base::FilePath(path);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace gin
|
||||
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
struct Converter<base::FilePath> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const base::FilePath& val) {
|
||||
return gin::Converter<base::FilePath::StringType>::ToV8(isolate,
|
||||
val.value());
|
||||
}
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
base::FilePath* out) {
|
||||
return gin::Converter<base::FilePath>::FromV8(isolate, val, out);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
#endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_FILE_PATH_CONVERTER_H_
|
161
shell/common/native_mate_converters/gfx_converter.cc
Normal file
161
shell/common/native_mate_converters/gfx_converter.cc
Normal file
|
@ -0,0 +1,161 @@
|
|||
// Copyright (c) 2015 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "ui/display/display.h"
|
||||
#include "ui/display/screen.h"
|
||||
#include "ui/gfx/geometry/point.h"
|
||||
#include "ui/gfx/geometry/rect.h"
|
||||
#include "ui/gfx/geometry/size.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
v8::Local<v8::Value> Converter<gfx::Point>::ToV8(v8::Isolate* isolate,
|
||||
const gfx::Point& val) {
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
|
||||
dict.SetHidden("simple", true);
|
||||
dict.Set("x", val.x());
|
||||
dict.Set("y", val.y());
|
||||
return dict.GetHandle();
|
||||
}
|
||||
|
||||
bool Converter<gfx::Point>::FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
gfx::Point* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
double x, y;
|
||||
if (!dict.Get("x", &x) || !dict.Get("y", &y))
|
||||
return false;
|
||||
*out = gfx::Point(static_cast<int>(std::round(x)),
|
||||
static_cast<int>(std::round(y)));
|
||||
return true;
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Converter<gfx::PointF>::ToV8(v8::Isolate* isolate,
|
||||
const gfx::PointF& val) {
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
|
||||
dict.SetHidden("simple", true);
|
||||
dict.Set("x", val.x());
|
||||
dict.Set("y", val.y());
|
||||
return dict.GetHandle();
|
||||
}
|
||||
|
||||
bool Converter<gfx::PointF>::FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
gfx::PointF* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
float x, y;
|
||||
if (!dict.Get("x", &x) || !dict.Get("y", &y))
|
||||
return false;
|
||||
*out = gfx::PointF(x, y);
|
||||
return true;
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Converter<gfx::Size>::ToV8(v8::Isolate* isolate,
|
||||
const gfx::Size& val) {
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
|
||||
dict.SetHidden("simple", true);
|
||||
dict.Set("width", val.width());
|
||||
dict.Set("height", val.height());
|
||||
return dict.GetHandle();
|
||||
}
|
||||
|
||||
bool Converter<gfx::Size>::FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
gfx::Size* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
int width, height;
|
||||
if (!dict.Get("width", &width) || !dict.Get("height", &height))
|
||||
return false;
|
||||
*out = gfx::Size(width, height);
|
||||
return true;
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Converter<gfx::Rect>::ToV8(v8::Isolate* isolate,
|
||||
const gfx::Rect& val) {
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
|
||||
dict.SetHidden("simple", true);
|
||||
dict.Set("x", val.x());
|
||||
dict.Set("y", val.y());
|
||||
dict.Set("width", val.width());
|
||||
dict.Set("height", val.height());
|
||||
return dict.GetHandle();
|
||||
}
|
||||
|
||||
bool Converter<gfx::Rect>::FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
gfx::Rect* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
int x, y, width, height;
|
||||
if (!dict.Get("x", &x) || !dict.Get("y", &y) || !dict.Get("width", &width) ||
|
||||
!dict.Get("height", &height))
|
||||
return false;
|
||||
*out = gfx::Rect(x, y, width, height);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <>
|
||||
struct Converter<display::Display::AccelerometerSupport> {
|
||||
static v8::Local<v8::Value> ToV8(
|
||||
v8::Isolate* isolate,
|
||||
const display::Display::AccelerometerSupport& val) {
|
||||
switch (val) {
|
||||
case display::Display::AccelerometerSupport::AVAILABLE:
|
||||
return StringToV8(isolate, "available");
|
||||
case display::Display::AccelerometerSupport::UNAVAILABLE:
|
||||
return StringToV8(isolate, "unavailable");
|
||||
default:
|
||||
return StringToV8(isolate, "unknown");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<display::Display::TouchSupport> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const display::Display::TouchSupport& val) {
|
||||
switch (val) {
|
||||
case display::Display::TouchSupport::AVAILABLE:
|
||||
return StringToV8(isolate, "available");
|
||||
case display::Display::TouchSupport::UNAVAILABLE:
|
||||
return StringToV8(isolate, "unavailable");
|
||||
default:
|
||||
return StringToV8(isolate, "unknown");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
v8::Local<v8::Value> Converter<display::Display>::ToV8(
|
||||
v8::Isolate* isolate,
|
||||
const display::Display& val) {
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
|
||||
dict.SetHidden("simple", true);
|
||||
dict.Set("id", val.id());
|
||||
dict.Set("bounds", val.bounds());
|
||||
dict.Set("workArea", val.work_area());
|
||||
dict.Set("accelerometerSupport", val.accelerometer_support());
|
||||
dict.Set("monochrome", val.is_monochrome());
|
||||
dict.Set("colorDepth", val.color_depth());
|
||||
dict.Set("colorSpace", val.color_space().ToString());
|
||||
dict.Set("depthPerComponent", val.depth_per_component());
|
||||
dict.Set("size", val.size());
|
||||
dict.Set("workAreaSize", val.work_area_size());
|
||||
dict.Set("scaleFactor", val.device_scale_factor());
|
||||
dict.Set("rotation", val.RotationAsDegree());
|
||||
dict.Set("internal", val.IsInternal());
|
||||
dict.Set("touchSupport", val.touch_support());
|
||||
return dict.GetHandle();
|
||||
}
|
||||
|
||||
} // namespace mate
|
67
shell/common/native_mate_converters/gfx_converter.h
Normal file
67
shell/common/native_mate_converters/gfx_converter.h
Normal file
|
@ -0,0 +1,67 @@
|
|||
// Copyright (c) 2014 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_GFX_CONVERTER_H_
|
||||
#define ATOM_COMMON_NATIVE_MATE_CONVERTERS_GFX_CONVERTER_H_
|
||||
|
||||
#include "native_mate/converter.h"
|
||||
#include "ui/gfx/geometry/point_f.h"
|
||||
|
||||
namespace display {
|
||||
class Display;
|
||||
}
|
||||
|
||||
namespace gfx {
|
||||
class Point;
|
||||
class Size;
|
||||
class Rect;
|
||||
} // namespace gfx
|
||||
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
struct Converter<gfx::Point> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate, const gfx::Point& val);
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
gfx::Point* out);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<gfx::PointF> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const gfx::PointF& val);
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
gfx::PointF* out);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<gfx::Size> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate, const gfx::Size& val);
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
gfx::Size* out);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<gfx::Rect> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate, const gfx::Rect& val);
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
gfx::Rect* out);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<display::Display> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const display::Display& val);
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
display::Display* out);
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
#endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_GFX_CONVERTER_H_
|
35
shell/common/native_mate_converters/gurl_converter.h
Normal file
35
shell/common/native_mate_converters/gurl_converter.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
// Copyright (c) 2014 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_GURL_CONVERTER_H_
|
||||
#define ATOM_COMMON_NATIVE_MATE_CONVERTERS_GURL_CONVERTER_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "native_mate/converter.h"
|
||||
#include "url/gurl.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
struct Converter<GURL> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate, const GURL& val) {
|
||||
return ConvertToV8(isolate, val.spec());
|
||||
}
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
GURL* out) {
|
||||
std::string url;
|
||||
if (Converter<std::string>::FromV8(isolate, val, &url)) {
|
||||
*out = GURL(url);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
#endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_GURL_CONVERTER_H_
|
43
shell/common/native_mate_converters/image_converter.cc
Normal file
43
shell/common/native_mate_converters/image_converter.cc
Normal file
|
@ -0,0 +1,43 @@
|
|||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/common/native_mate_converters/image_converter.h"
|
||||
|
||||
#include "atom/common/api/atom_api_native_image.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "ui/gfx/image/image_skia.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
bool Converter<gfx::ImageSkia>::FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
gfx::ImageSkia* out) {
|
||||
gfx::Image image;
|
||||
if (!ConvertFromV8(isolate, val, &image))
|
||||
return false;
|
||||
|
||||
*out = image.AsImageSkia();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Converter<gfx::Image>::FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
gfx::Image* out) {
|
||||
if (val->IsNull())
|
||||
return true;
|
||||
|
||||
Handle<atom::api::NativeImage> native_image;
|
||||
if (!ConvertFromV8(isolate, val, &native_image))
|
||||
return false;
|
||||
|
||||
*out = native_image->image();
|
||||
return true;
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Converter<gfx::Image>::ToV8(v8::Isolate* isolate,
|
||||
const gfx::Image& val) {
|
||||
return ConvertToV8(isolate, atom::api::NativeImage::Create(isolate, val));
|
||||
}
|
||||
|
||||
} // namespace mate
|
34
shell/common/native_mate_converters/image_converter.h
Normal file
34
shell/common/native_mate_converters/image_converter.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
// Copyright (c) 2014 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_IMAGE_CONVERTER_H_
|
||||
#define ATOM_COMMON_NATIVE_MATE_CONVERTERS_IMAGE_CONVERTER_H_
|
||||
|
||||
#include "native_mate/converter.h"
|
||||
|
||||
namespace gfx {
|
||||
class Image;
|
||||
class ImageSkia;
|
||||
} // namespace gfx
|
||||
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
struct Converter<gfx::ImageSkia> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
gfx::ImageSkia* out);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<gfx::Image> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
gfx::Image* out);
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate, const gfx::Image& val);
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
#endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_IMAGE_CONVERTER_H_
|
70
shell/common/native_mate_converters/map_converter.h
Normal file
70
shell/common/native_mate_converters/map_converter.h
Normal file
|
@ -0,0 +1,70 @@
|
|||
// Copyright (c) 2019 Slack Technologies, 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_MAP_CONVERTER_H_
|
||||
#define ATOM_COMMON_NATIVE_MATE_CONVERTERS_MAP_CONVERTER_H_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "gin/converter.h"
|
||||
|
||||
namespace gin {
|
||||
|
||||
template <typename T>
|
||||
struct Converter<std::map<std::string, T>> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
std::map<std::string, T>* out) {
|
||||
if (!val->IsObject())
|
||||
return false;
|
||||
|
||||
v8::Local<v8::Context> context = isolate->GetCurrentContext();
|
||||
v8::Local<v8::Object> dict = val->ToObject(context).ToLocalChecked();
|
||||
v8::Local<v8::Array> keys =
|
||||
dict->GetOwnPropertyNames(context).ToLocalChecked();
|
||||
for (uint32_t i = 0; i < keys->Length(); ++i) {
|
||||
v8::Local<v8::Value> key = keys->Get(context, i).ToLocalChecked();
|
||||
T value;
|
||||
if (Converter<T>::FromV8(
|
||||
isolate, dict->Get(context, key).ToLocalChecked(), &value))
|
||||
(*out)[gin::V8ToString(isolate, key)] = std::move(value);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const std::map<std::string, T>& val) {
|
||||
v8::Local<v8::Object> result = v8::Object::New(isolate);
|
||||
auto context = isolate->GetCurrentContext();
|
||||
for (auto i = val.begin(); i != val.end(); i++) {
|
||||
result
|
||||
->Set(context, Converter<T>::ToV8(isolate, i->first),
|
||||
Converter<T>::ToV8(isolate, i->second))
|
||||
.Check();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace gin
|
||||
|
||||
namespace mate {
|
||||
|
||||
template <typename T>
|
||||
struct Converter<std::map<std::string, T>> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
std::map<std::string, T>* out) {
|
||||
return gin::Converter<std::map<std::string, T>>::FromV8(isolate, val, out);
|
||||
}
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const std::map<std::string, T>& val) {
|
||||
return gin::Converter<std::map<std::string, T>>::ToV8(isolate, val);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
#endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_MAP_CONVERTER_H_
|
38
shell/common/native_mate_converters/message_box_converter.cc
Normal file
38
shell/common/native_mate_converters/message_box_converter.cc
Normal file
|
@ -0,0 +1,38 @@
|
|||
// Copyright (c) 2015 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/common/native_mate_converters/message_box_converter.h"
|
||||
|
||||
#include "atom/browser/api/atom_api_browser_window.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "atom/common/native_mate_converters/image_converter.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
bool Converter<atom::MessageBoxSettings>::FromV8(
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
atom::MessageBoxSettings* out) {
|
||||
mate::Dictionary dict;
|
||||
int type = 0;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
dict.Get("window", &out->parent_window);
|
||||
dict.Get("type", &type);
|
||||
out->type = static_cast<atom::MessageBoxType>(type);
|
||||
dict.Get("buttons", &out->buttons);
|
||||
dict.Get("defaultId", &out->default_id);
|
||||
dict.Get("cancelId", &out->cancel_id);
|
||||
dict.Get("options", &out->options);
|
||||
dict.Get("title", &out->title);
|
||||
dict.Get("message", &out->message);
|
||||
dict.Get("detail", &out->detail);
|
||||
dict.Get("checkboxLabel", &out->checkbox_label);
|
||||
dict.Get("checkboxChecked", &out->checkbox_checked);
|
||||
dict.Get("icon", &out->icon);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace mate
|
22
shell/common/native_mate_converters/message_box_converter.h
Normal file
22
shell/common/native_mate_converters/message_box_converter.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
// Copyright (c) 2019 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_MESSAGE_BOX_CONVERTER_H_
|
||||
#define ATOM_COMMON_NATIVE_MATE_CONVERTERS_MESSAGE_BOX_CONVERTER_H_
|
||||
|
||||
#include "atom/browser/ui/message_box.h"
|
||||
#include "native_mate/converter.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
struct Converter<atom::MessageBoxSettings> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
atom::MessageBoxSettings* out);
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
#endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_MESSAGE_BOX_CONVERTER_H_
|
324
shell/common/native_mate_converters/net_converter.cc
Normal file
324
shell/common/native_mate_converters/net_converter.cc
Normal file
|
@ -0,0 +1,324 @@
|
|||
// Copyright (c) 2015 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/common/native_mate_converters/net_converter.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/values.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "net/base/upload_bytes_element_reader.h"
|
||||
#include "net/base/upload_data_stream.h"
|
||||
#include "net/base/upload_element_reader.h"
|
||||
#include "net/base/upload_file_element_reader.h"
|
||||
#include "net/cert/x509_certificate.h"
|
||||
#include "net/cert/x509_util.h"
|
||||
#include "net/http/http_response_headers.h"
|
||||
#include "net/url_request/url_request.h"
|
||||
#include "services/network/public/cpp/resource_request.h"
|
||||
#include "storage/browser/blob/upload_blob_element_reader.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
namespace {
|
||||
|
||||
bool CertFromData(const std::string& data,
|
||||
scoped_refptr<net::X509Certificate>* out) {
|
||||
auto cert_list = net::X509Certificate::CreateCertificateListFromBytes(
|
||||
data.c_str(), data.length(),
|
||||
net::X509Certificate::FORMAT_SINGLE_CERTIFICATE);
|
||||
if (cert_list.empty())
|
||||
return false;
|
||||
|
||||
auto leaf_cert = cert_list.front();
|
||||
if (!leaf_cert)
|
||||
return false;
|
||||
|
||||
*out = leaf_cert;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
v8::Local<v8::Value> Converter<net::AuthChallengeInfo>::ToV8(
|
||||
v8::Isolate* isolate,
|
||||
const net::AuthChallengeInfo& val) {
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
|
||||
dict.Set("isProxy", val.is_proxy);
|
||||
dict.Set("scheme", val.scheme);
|
||||
dict.Set("host", val.challenger.host());
|
||||
dict.Set("port", static_cast<uint32_t>(val.challenger.port()));
|
||||
dict.Set("realm", val.realm);
|
||||
return mate::ConvertToV8(isolate, dict);
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Local<v8::Value> Converter<scoped_refptr<net::X509Certificate>>::ToV8(
|
||||
v8::Isolate* isolate,
|
||||
const scoped_refptr<net::X509Certificate>& val) {
|
||||
mate::Dictionary dict(isolate, v8::Object::New(isolate));
|
||||
std::string encoded_data;
|
||||
net::X509Certificate::GetPEMEncoded(val->cert_buffer(), &encoded_data);
|
||||
|
||||
dict.Set("data", encoded_data);
|
||||
dict.Set("issuer", val->issuer());
|
||||
dict.Set("issuerName", val->issuer().GetDisplayName());
|
||||
dict.Set("subject", val->subject());
|
||||
dict.Set("subjectName", val->subject().GetDisplayName());
|
||||
dict.Set("serialNumber", base::HexEncode(val->serial_number().data(),
|
||||
val->serial_number().size()));
|
||||
dict.Set("validStart", val->valid_start().ToDoubleT());
|
||||
dict.Set("validExpiry", val->valid_expiry().ToDoubleT());
|
||||
dict.Set("fingerprint",
|
||||
net::HashValue(val->CalculateFingerprint256(val->cert_buffer()))
|
||||
.ToString());
|
||||
|
||||
const auto& intermediate_buffers = val->intermediate_buffers();
|
||||
if (!intermediate_buffers.empty()) {
|
||||
std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> issuer_intermediates;
|
||||
issuer_intermediates.reserve(intermediate_buffers.size() - 1);
|
||||
for (size_t i = 1; i < intermediate_buffers.size(); ++i) {
|
||||
issuer_intermediates.push_back(
|
||||
bssl::UpRef(intermediate_buffers[i].get()));
|
||||
}
|
||||
const scoped_refptr<net::X509Certificate>& issuer_cert =
|
||||
net::X509Certificate::CreateFromBuffer(
|
||||
bssl::UpRef(intermediate_buffers[0].get()),
|
||||
std::move(issuer_intermediates));
|
||||
dict.Set("issuerCert", issuer_cert);
|
||||
}
|
||||
|
||||
return dict.GetHandle();
|
||||
}
|
||||
|
||||
bool Converter<scoped_refptr<net::X509Certificate>>::FromV8(
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
scoped_refptr<net::X509Certificate>* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
|
||||
std::string data;
|
||||
dict.Get("data", &data);
|
||||
scoped_refptr<net::X509Certificate> leaf_cert;
|
||||
if (!CertFromData(data, &leaf_cert))
|
||||
return false;
|
||||
|
||||
scoped_refptr<net::X509Certificate> issuer_cert;
|
||||
if (dict.Get("issuerCert", &issuer_cert)) {
|
||||
std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
|
||||
intermediates.push_back(bssl::UpRef(issuer_cert->cert_buffer()));
|
||||
auto cert = net::X509Certificate::CreateFromBuffer(
|
||||
bssl::UpRef(leaf_cert->cert_buffer()), std::move(intermediates));
|
||||
if (!cert)
|
||||
return false;
|
||||
|
||||
*out = cert;
|
||||
} else {
|
||||
*out = leaf_cert;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Local<v8::Value> Converter<net::CertPrincipal>::ToV8(
|
||||
v8::Isolate* isolate,
|
||||
const net::CertPrincipal& val) {
|
||||
mate::Dictionary dict(isolate, v8::Object::New(isolate));
|
||||
|
||||
dict.Set("commonName", val.common_name);
|
||||
dict.Set("organizations", val.organization_names);
|
||||
dict.Set("organizationUnits", val.organization_unit_names);
|
||||
dict.Set("locality", val.locality_name);
|
||||
dict.Set("state", val.state_or_province_name);
|
||||
dict.Set("country", val.country_name);
|
||||
|
||||
return dict.GetHandle();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Local<v8::Value> Converter<net::HttpResponseHeaders*>::ToV8(
|
||||
v8::Isolate* isolate,
|
||||
net::HttpResponseHeaders* headers) {
|
||||
base::DictionaryValue response_headers;
|
||||
if (headers) {
|
||||
size_t iter = 0;
|
||||
std::string key;
|
||||
std::string value;
|
||||
while (headers->EnumerateHeaderLines(&iter, &key, &value)) {
|
||||
key = base::ToLowerASCII(key);
|
||||
if (response_headers.FindKey(key)) {
|
||||
base::ListValue* values = nullptr;
|
||||
if (response_headers.GetList(key, &values))
|
||||
values->AppendString(value);
|
||||
} else {
|
||||
auto values = std::make_unique<base::ListValue>();
|
||||
values->AppendString(value);
|
||||
response_headers.Set(key, std::move(values));
|
||||
}
|
||||
}
|
||||
}
|
||||
return ConvertToV8(isolate, response_headers);
|
||||
}
|
||||
|
||||
bool Converter<net::HttpResponseHeaders*>::FromV8(
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
net::HttpResponseHeaders* out) {
|
||||
if (!val->IsObject()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto addHeaderFromValue = [&isolate, &out](
|
||||
const std::string& key,
|
||||
const v8::Local<v8::Value>& localVal) {
|
||||
auto context = isolate->GetCurrentContext();
|
||||
v8::Local<v8::String> localStrVal;
|
||||
if (!localVal->ToString(context).ToLocal(&localStrVal)) {
|
||||
return false;
|
||||
}
|
||||
std::string value;
|
||||
mate::ConvertFromV8(isolate, localStrVal, &value);
|
||||
out->AddHeader(key + ": " + value);
|
||||
return true;
|
||||
};
|
||||
|
||||
auto context = isolate->GetCurrentContext();
|
||||
auto headers = v8::Local<v8::Object>::Cast(val);
|
||||
auto keys = headers->GetOwnPropertyNames(context).ToLocalChecked();
|
||||
for (uint32_t i = 0; i < keys->Length(); i++) {
|
||||
v8::Local<v8::Value> keyVal;
|
||||
if (!keys->Get(context, i).ToLocal(&keyVal)) {
|
||||
return false;
|
||||
}
|
||||
std::string key;
|
||||
mate::ConvertFromV8(isolate, keyVal, &key);
|
||||
|
||||
auto localVal = headers->Get(context, keyVal).ToLocalChecked();
|
||||
if (localVal->IsArray()) {
|
||||
auto values = v8::Local<v8::Array>::Cast(localVal);
|
||||
for (uint32_t j = 0; j < values->Length(); j++) {
|
||||
if (!addHeaderFromValue(key,
|
||||
values->Get(context, j).ToLocalChecked())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!addHeaderFromValue(key, localVal)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Local<v8::Value> Converter<network::ResourceRequest>::ToV8(
|
||||
v8::Isolate* isolate,
|
||||
const network::ResourceRequest& val) {
|
||||
mate::Dictionary dict(isolate, v8::Object::New(isolate));
|
||||
dict.Set("method", val.method);
|
||||
dict.Set("url", val.url.spec());
|
||||
dict.Set("referrer", val.referrer.spec());
|
||||
mate::Dictionary headers(isolate, v8::Object::New(isolate));
|
||||
for (net::HttpRequestHeaders::Iterator it(val.headers); it.GetNext();)
|
||||
headers.Set(it.name(), it.value());
|
||||
dict.Set("headers", headers);
|
||||
if (val.request_body) {
|
||||
const auto& elements = *val.request_body->elements();
|
||||
v8::Local<v8::Array> arr = v8::Array::New(isolate, elements.size());
|
||||
for (size_t i = 0; i < elements.size(); ++i) {
|
||||
const auto& element = elements[i];
|
||||
mate::Dictionary upload_data(isolate, v8::Object::New(isolate));
|
||||
switch (element.type()) {
|
||||
case network::mojom::DataElementType::kFile:
|
||||
upload_data.Set("file", element.path().value());
|
||||
break;
|
||||
case network::mojom::DataElementType::kBytes:
|
||||
upload_data.Set("bytes", node::Buffer::Copy(isolate, element.bytes(),
|
||||
element.length())
|
||||
.ToLocalChecked());
|
||||
break;
|
||||
case network::mojom::DataElementType::kBlob:
|
||||
upload_data.Set("blobUUID", element.blob_uuid());
|
||||
break;
|
||||
default:
|
||||
NOTREACHED() << "Found unsupported data element";
|
||||
}
|
||||
arr->Set(isolate->GetCurrentContext(), static_cast<uint32_t>(i),
|
||||
upload_data.GetHandle())
|
||||
.Check();
|
||||
}
|
||||
dict.Set("uploadData", arr);
|
||||
}
|
||||
return dict.GetHandle();
|
||||
}
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace atom {
|
||||
|
||||
void FillRequestDetails(base::DictionaryValue* details,
|
||||
const net::URLRequest* request) {
|
||||
details->SetString("method", request->method());
|
||||
std::string url;
|
||||
if (!request->url_chain().empty())
|
||||
url = request->url().spec();
|
||||
details->SetKey("url", base::Value(url));
|
||||
details->SetString("referrer", request->referrer());
|
||||
auto list = std::make_unique<base::ListValue>();
|
||||
GetUploadData(list.get(), request);
|
||||
if (!list->empty())
|
||||
details->Set("uploadData", std::move(list));
|
||||
auto headers_value = std::make_unique<base::DictionaryValue>();
|
||||
for (net::HttpRequestHeaders::Iterator it(request->extra_request_headers());
|
||||
it.GetNext();) {
|
||||
headers_value->SetString(it.name(), it.value());
|
||||
}
|
||||
details->Set("headers", std::move(headers_value));
|
||||
}
|
||||
|
||||
void GetUploadData(base::ListValue* upload_data_list,
|
||||
const net::URLRequest* request) {
|
||||
const net::UploadDataStream* upload_data = request->get_upload();
|
||||
if (!upload_data)
|
||||
return;
|
||||
const std::vector<std::unique_ptr<net::UploadElementReader>>* readers =
|
||||
upload_data->GetElementReaders();
|
||||
for (const auto& reader : *readers) {
|
||||
auto upload_data_dict = std::make_unique<base::DictionaryValue>();
|
||||
if (reader->AsBytesReader()) {
|
||||
const net::UploadBytesElementReader* bytes_reader =
|
||||
reader->AsBytesReader();
|
||||
auto bytes = std::make_unique<base::Value>(
|
||||
std::vector<char>(bytes_reader->bytes(),
|
||||
bytes_reader->bytes() + bytes_reader->length()));
|
||||
upload_data_dict->Set("bytes", std::move(bytes));
|
||||
} else if (reader->AsFileReader()) {
|
||||
const net::UploadFileElementReader* file_reader = reader->AsFileReader();
|
||||
auto file_path = file_reader->path().AsUTF8Unsafe();
|
||||
upload_data_dict->SetKey("file", base::Value(file_path));
|
||||
} else {
|
||||
const storage::UploadBlobElementReader* blob_reader =
|
||||
static_cast<storage::UploadBlobElementReader*>(reader.get());
|
||||
upload_data_dict->SetString("blobUUID", blob_reader->uuid());
|
||||
}
|
||||
upload_data_list->Append(std::move(upload_data_dict));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace atom
|
80
shell/common/native_mate_converters/net_converter.h
Normal file
80
shell/common/native_mate_converters/net_converter.h
Normal file
|
@ -0,0 +1,80 @@
|
|||
// Copyright (c) 2015 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_NET_CONVERTER_H_
|
||||
#define ATOM_COMMON_NATIVE_MATE_CONVERTERS_NET_CONVERTER_H_
|
||||
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "native_mate/converter.h"
|
||||
|
||||
namespace base {
|
||||
class DictionaryValue;
|
||||
class ListValue;
|
||||
} // namespace base
|
||||
|
||||
namespace net {
|
||||
class AuthChallengeInfo;
|
||||
class URLRequest;
|
||||
class X509Certificate;
|
||||
class HttpResponseHeaders;
|
||||
struct CertPrincipal;
|
||||
} // namespace net
|
||||
|
||||
namespace network {
|
||||
struct ResourceRequest;
|
||||
}
|
||||
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
struct Converter<net::AuthChallengeInfo> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const net::AuthChallengeInfo& val);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<scoped_refptr<net::X509Certificate>> {
|
||||
static v8::Local<v8::Value> ToV8(
|
||||
v8::Isolate* isolate,
|
||||
const scoped_refptr<net::X509Certificate>& val);
|
||||
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
scoped_refptr<net::X509Certificate>* out);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<net::CertPrincipal> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const net::CertPrincipal& val);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<net::HttpResponseHeaders*> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
net::HttpResponseHeaders* headers);
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
net::HttpResponseHeaders* out);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<network::ResourceRequest> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const network::ResourceRequest& val);
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace atom {
|
||||
|
||||
void FillRequestDetails(base::DictionaryValue* details,
|
||||
const net::URLRequest* request);
|
||||
|
||||
void GetUploadData(base::ListValue* upload_data_list,
|
||||
const net::URLRequest* request);
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_NET_CONVERTER_H_
|
94
shell/common/native_mate_converters/network_converter.cc
Normal file
94
shell/common/native_mate_converters/network_converter.cc
Normal file
|
@ -0,0 +1,94 @@
|
|||
// Copyright (c) 2018 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/common/native_mate_converters/network_converter.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "base/numerics/safe_conversions.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "services/network/public/cpp/resource_request_body.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
// static
|
||||
v8::Local<v8::Value>
|
||||
Converter<scoped_refptr<network::ResourceRequestBody>>::ToV8(
|
||||
v8::Isolate* isolate,
|
||||
const scoped_refptr<network::ResourceRequestBody>& val) {
|
||||
if (!val)
|
||||
return v8::Null(isolate);
|
||||
auto list = std::make_unique<base::ListValue>();
|
||||
for (const auto& element : *(val->elements())) {
|
||||
auto post_data_dict = std::make_unique<base::DictionaryValue>();
|
||||
auto type = element.type();
|
||||
if (type == network::mojom::DataElementType::kBytes) {
|
||||
auto bytes = std::make_unique<base::Value>(std::vector<char>(
|
||||
element.bytes(), element.bytes() + (element.length())));
|
||||
post_data_dict->SetString("type", "rawData");
|
||||
post_data_dict->Set("bytes", std::move(bytes));
|
||||
} else if (type == network::mojom::DataElementType::kFile) {
|
||||
post_data_dict->SetString("type", "file");
|
||||
post_data_dict->SetKey("filePath",
|
||||
base::Value(element.path().AsUTF8Unsafe()));
|
||||
post_data_dict->SetInteger("offset", static_cast<int>(element.offset()));
|
||||
post_data_dict->SetInteger("length", static_cast<int>(element.length()));
|
||||
post_data_dict->SetDouble(
|
||||
"modificationTime", element.expected_modification_time().ToDoubleT());
|
||||
} else if (type == network::mojom::DataElementType::kBlob) {
|
||||
post_data_dict->SetString("type", "blob");
|
||||
post_data_dict->SetString("blobUUID", element.blob_uuid());
|
||||
}
|
||||
list->Append(std::move(post_data_dict));
|
||||
}
|
||||
return ConvertToV8(isolate, *list);
|
||||
}
|
||||
|
||||
// static
|
||||
bool Converter<scoped_refptr<network::ResourceRequestBody>>::FromV8(
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
scoped_refptr<network::ResourceRequestBody>* out) {
|
||||
auto list = std::make_unique<base::ListValue>();
|
||||
if (!ConvertFromV8(isolate, val, list.get()))
|
||||
return false;
|
||||
*out = new network::ResourceRequestBody();
|
||||
for (size_t i = 0; i < list->GetSize(); ++i) {
|
||||
base::DictionaryValue* dict = nullptr;
|
||||
std::string type;
|
||||
if (!list->GetDictionary(i, &dict))
|
||||
return false;
|
||||
dict->GetString("type", &type);
|
||||
if (type == "rawData") {
|
||||
base::Value* bytes = nullptr;
|
||||
dict->GetBinary("bytes", &bytes);
|
||||
(*out)->AppendBytes(
|
||||
reinterpret_cast<const char*>(bytes->GetBlob().data()),
|
||||
base::checked_cast<int>(bytes->GetBlob().size()));
|
||||
} else if (type == "file") {
|
||||
std::string file;
|
||||
int offset = 0, length = -1;
|
||||
double modification_time = 0.0;
|
||||
dict->GetStringWithoutPathExpansion("filePath", &file);
|
||||
dict->GetInteger("offset", &offset);
|
||||
dict->GetInteger("file", &length);
|
||||
dict->GetDouble("modificationTime", &modification_time);
|
||||
(*out)->AppendFileRange(base::FilePath::FromUTF8Unsafe(file),
|
||||
static_cast<uint64_t>(offset),
|
||||
static_cast<uint64_t>(length),
|
||||
base::Time::FromDoubleT(modification_time));
|
||||
} else if (type == "blob") {
|
||||
std::string uuid;
|
||||
dict->GetString("blobUUID", &uuid);
|
||||
(*out)->AppendBlob(uuid);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace mate
|
29
shell/common/native_mate_converters/network_converter.h
Normal file
29
shell/common/native_mate_converters/network_converter.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
// Copyright (c) 2018 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_NETWORK_CONVERTER_H_
|
||||
#define ATOM_COMMON_NATIVE_MATE_CONVERTERS_NETWORK_CONVERTER_H_
|
||||
|
||||
#include "base/memory/scoped_refptr.h"
|
||||
#include "native_mate/converter.h"
|
||||
|
||||
namespace network {
|
||||
class ResourceRequestBody;
|
||||
}
|
||||
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
struct Converter<scoped_refptr<network::ResourceRequestBody>> {
|
||||
static v8::Local<v8::Value> ToV8(
|
||||
v8::Isolate* isolate,
|
||||
const scoped_refptr<network::ResourceRequestBody>& val);
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
scoped_refptr<network::ResourceRequestBody>* out);
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
#endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_NETWORK_CONVERTER_H_
|
87
shell/common/native_mate_converters/once_callback.h
Normal file
87
shell/common/native_mate_converters/once_callback.h
Normal file
|
@ -0,0 +1,87 @@
|
|||
// Copyright (c) 2019 GitHub, Inc. All rights reserved.
|
||||
// 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_ONCE_CALLBACK_H_
|
||||
#define ATOM_COMMON_NATIVE_MATE_CONVERTERS_ONCE_CALLBACK_H_
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Manages the OnceCallback with ref-couting.
|
||||
template <typename Sig>
|
||||
class RefCountedOnceCallback
|
||||
: public base::RefCounted<RefCountedOnceCallback<Sig>> {
|
||||
public:
|
||||
explicit RefCountedOnceCallback(base::OnceCallback<Sig> callback)
|
||||
: callback_(std::move(callback)) {}
|
||||
|
||||
base::OnceCallback<Sig> GetCallback() { return std::move(callback_); }
|
||||
|
||||
private:
|
||||
friend class base::RefCounted<RefCountedOnceCallback<Sig>>;
|
||||
~RefCountedOnceCallback() = default;
|
||||
|
||||
base::OnceCallback<Sig> callback_;
|
||||
};
|
||||
|
||||
// Invokes the OnceCallback.
|
||||
template <typename Sig>
|
||||
struct InvokeOnceCallback {};
|
||||
|
||||
template <typename... ArgTypes>
|
||||
struct InvokeOnceCallback<void(ArgTypes...)> {
|
||||
static void Go(
|
||||
scoped_refptr<RefCountedOnceCallback<void(ArgTypes...)>> holder,
|
||||
ArgTypes... args) {
|
||||
base::OnceCallback<void(ArgTypes...)> callback = holder->GetCallback();
|
||||
DCHECK(!callback.is_null());
|
||||
std::move(callback).Run(std::move(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ReturnType, typename... ArgTypes>
|
||||
struct InvokeOnceCallback<ReturnType(ArgTypes...)> {
|
||||
static ReturnType Go(
|
||||
scoped_refptr<RefCountedOnceCallback<ReturnType(ArgTypes...)>> holder,
|
||||
ArgTypes... args) {
|
||||
base::OnceCallback<void(ArgTypes...)> callback = holder->GetCallback();
|
||||
DCHECK(!callback.is_null());
|
||||
return std::move(callback).Run(std::move(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template <typename Sig>
|
||||
struct Converter<base::OnceCallback<Sig>> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
base::OnceCallback<Sig> val) {
|
||||
// Reuse the converter of base::RepeatingCallback by storing the callback
|
||||
// with a RefCounted.
|
||||
auto holder = base::MakeRefCounted<internal::RefCountedOnceCallback<Sig>>(
|
||||
std::move(val));
|
||||
return Converter<base::RepeatingCallback<Sig>>::ToV8(
|
||||
isolate,
|
||||
base::BindRepeating(&internal::InvokeOnceCallback<Sig>::Go, holder));
|
||||
}
|
||||
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
base::OnceCallback<Sig>* out) {
|
||||
if (!val->IsFunction())
|
||||
return false;
|
||||
*out = base::BindOnce(&internal::V8FunctionInvoker<Sig>::Go, isolate,
|
||||
internal::SafeV8Function(isolate, val));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
#endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_ONCE_CALLBACK_H_
|
64
shell/common/native_mate_converters/string16_converter.h
Normal file
64
shell/common/native_mate_converters/string16_converter.h
Normal file
|
@ -0,0 +1,64 @@
|
|||
// Copyright (c) 2014 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_STRING16_CONVERTER_H_
|
||||
#define ATOM_COMMON_NATIVE_MATE_CONVERTERS_STRING16_CONVERTER_H_
|
||||
|
||||
#include "base/strings/string16.h"
|
||||
#include "gin/converter.h"
|
||||
#include "native_mate/converter.h"
|
||||
|
||||
namespace gin {
|
||||
|
||||
template <>
|
||||
struct Converter<base::string16> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const base::string16& val) {
|
||||
return v8::String::NewFromTwoByte(
|
||||
isolate, reinterpret_cast<const uint16_t*>(val.data()),
|
||||
v8::NewStringType::kNormal, val.size())
|
||||
.ToLocalChecked();
|
||||
}
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
base::string16* out) {
|
||||
if (!val->IsString())
|
||||
return false;
|
||||
|
||||
v8::String::Value s(isolate, val);
|
||||
out->assign(reinterpret_cast<const base::char16*>(*s), s.length());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
inline v8::Local<v8::String> StringToV8(v8::Isolate* isolate,
|
||||
const base::string16& input) {
|
||||
return ConvertToV8(isolate, input).As<v8::String>();
|
||||
}
|
||||
|
||||
} // namespace gin
|
||||
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
struct Converter<base::string16> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const base::string16& val) {
|
||||
return gin::Converter<base::string16>::ToV8(isolate, val);
|
||||
}
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
base::string16* out) {
|
||||
return gin::Converter<base::string16>::FromV8(isolate, val, out);
|
||||
}
|
||||
};
|
||||
|
||||
inline v8::Local<v8::String> StringToV8(v8::Isolate* isolate,
|
||||
const base::string16& input) {
|
||||
return ConvertToV8(isolate, input).As<v8::String>();
|
||||
}
|
||||
|
||||
} // namespace mate
|
||||
|
||||
#endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_STRING16_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, "touchMenu");
|
||||
default:
|
||||
return mate::StringToV8(isolate, "none");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
#endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_UI_BASE_TYPES_CONVERTER_H_
|
517
shell/common/native_mate_converters/v8_value_converter.cc
Normal file
517
shell/common/native_mate_converters/v8_value_converter.cc
Normal file
|
@ -0,0 +1,517 @@
|
|||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/common/native_mate_converters/v8_value_converter.h"
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/values.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
#include "atom/common/node_bindings.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
const int kMaxRecursionDepth = 100;
|
||||
|
||||
} // namespace
|
||||
|
||||
// The state of a call to FromV8Value.
|
||||
class V8ValueConverter::FromV8ValueState {
|
||||
public:
|
||||
// Level scope which updates the current depth of some FromV8ValueState.
|
||||
class Level {
|
||||
public:
|
||||
explicit Level(FromV8ValueState* state) : state_(state) {
|
||||
state_->max_recursion_depth_--;
|
||||
}
|
||||
~Level() { state_->max_recursion_depth_++; }
|
||||
|
||||
private:
|
||||
FromV8ValueState* state_;
|
||||
};
|
||||
|
||||
FromV8ValueState() : max_recursion_depth_(kMaxRecursionDepth) {}
|
||||
|
||||
// If |handle| is not in |unique_map_|, then add it to |unique_map_| and
|
||||
// return true.
|
||||
//
|
||||
// Otherwise do nothing and return false. Here "A is unique" means that no
|
||||
// other handle B in the map points to the same object as A. Note that A can
|
||||
// be unique even if there already is another handle with the same identity
|
||||
// hash (key) in the map, because two objects can have the same hash.
|
||||
bool AddToUniquenessCheck(v8::Local<v8::Object> handle) {
|
||||
int hash;
|
||||
auto iter = GetIteratorInMap(handle, &hash);
|
||||
if (iter != unique_map_.end())
|
||||
return false;
|
||||
|
||||
unique_map_.insert(std::make_pair(hash, handle));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RemoveFromUniquenessCheck(v8::Local<v8::Object> handle) {
|
||||
int unused_hash;
|
||||
auto iter = GetIteratorInMap(handle, &unused_hash);
|
||||
if (iter == unique_map_.end())
|
||||
return false;
|
||||
unique_map_.erase(iter);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HasReachedMaxRecursionDepth() { return max_recursion_depth_ < 0; }
|
||||
|
||||
private:
|
||||
using HashToHandleMap = std::multimap<int, v8::Local<v8::Object>>;
|
||||
using Iterator = HashToHandleMap::const_iterator;
|
||||
|
||||
Iterator GetIteratorInMap(v8::Local<v8::Object> handle, int* hash) {
|
||||
*hash = handle->GetIdentityHash();
|
||||
// We only compare using == with handles to objects with the same identity
|
||||
// hash. Different hash obviously means different objects, but two objects
|
||||
// in a couple of thousands could have the same identity hash.
|
||||
std::pair<Iterator, Iterator> range = unique_map_.equal_range(*hash);
|
||||
for (auto it = range.first; it != range.second; ++it) {
|
||||
// Operator == for handles actually compares the underlying objects.
|
||||
if (it->second == handle)
|
||||
return it;
|
||||
}
|
||||
// Not found.
|
||||
return unique_map_.end();
|
||||
}
|
||||
|
||||
HashToHandleMap unique_map_;
|
||||
|
||||
int max_recursion_depth_;
|
||||
};
|
||||
|
||||
// A class to ensure that objects/arrays that are being converted by
|
||||
// this V8ValueConverterImpl do not have cycles.
|
||||
//
|
||||
// An example of cycle: var v = {}; v = {key: v};
|
||||
// Not an example of cycle: var v = {}; a = [v, v]; or w = {a: v, b: v};
|
||||
class V8ValueConverter::ScopedUniquenessGuard {
|
||||
public:
|
||||
ScopedUniquenessGuard(V8ValueConverter::FromV8ValueState* state,
|
||||
v8::Local<v8::Object> value)
|
||||
: state_(state),
|
||||
value_(value),
|
||||
is_valid_(state_->AddToUniquenessCheck(value_)) {}
|
||||
~ScopedUniquenessGuard() {
|
||||
if (is_valid_) {
|
||||
bool removed = state_->RemoveFromUniquenessCheck(value_);
|
||||
DCHECK(removed);
|
||||
}
|
||||
}
|
||||
|
||||
bool is_valid() const { return is_valid_; }
|
||||
|
||||
private:
|
||||
typedef std::multimap<int, v8::Local<v8::Object>> HashToHandleMap;
|
||||
V8ValueConverter::FromV8ValueState* state_;
|
||||
v8::Local<v8::Object> value_;
|
||||
bool is_valid_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ScopedUniquenessGuard);
|
||||
};
|
||||
|
||||
V8ValueConverter::V8ValueConverter() {}
|
||||
|
||||
void V8ValueConverter::SetRegExpAllowed(bool val) {
|
||||
reg_exp_allowed_ = val;
|
||||
}
|
||||
|
||||
void V8ValueConverter::SetFunctionAllowed(bool val) {
|
||||
function_allowed_ = val;
|
||||
}
|
||||
|
||||
void V8ValueConverter::SetStripNullFromObjects(bool val) {
|
||||
strip_null_from_objects_ = val;
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> V8ValueConverter::ToV8Value(
|
||||
const base::Value* value,
|
||||
v8::Local<v8::Context> context) const {
|
||||
v8::Context::Scope context_scope(context);
|
||||
v8::EscapableHandleScope handle_scope(context->GetIsolate());
|
||||
return handle_scope.Escape(ToV8ValueImpl(context->GetIsolate(), value));
|
||||
}
|
||||
|
||||
std::unique_ptr<base::Value> V8ValueConverter::FromV8Value(
|
||||
v8::Local<v8::Value> val,
|
||||
v8::Local<v8::Context> context) const {
|
||||
v8::Context::Scope context_scope(context);
|
||||
v8::HandleScope handle_scope(context->GetIsolate());
|
||||
FromV8ValueState state;
|
||||
return FromV8ValueImpl(&state, val, context->GetIsolate());
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> V8ValueConverter::ToV8ValueImpl(
|
||||
v8::Isolate* isolate,
|
||||
const base::Value* value) const {
|
||||
switch (value->type()) {
|
||||
case base::Value::Type::NONE:
|
||||
return v8::Null(isolate);
|
||||
|
||||
case base::Value::Type::BOOLEAN: {
|
||||
bool val = value->GetBool();
|
||||
return v8::Boolean::New(isolate, val);
|
||||
}
|
||||
|
||||
case base::Value::Type::INTEGER: {
|
||||
int val = value->GetInt();
|
||||
return v8::Integer::New(isolate, val);
|
||||
}
|
||||
|
||||
case base::Value::Type::DOUBLE: {
|
||||
double val = value->GetDouble();
|
||||
return v8::Number::New(isolate, val);
|
||||
}
|
||||
|
||||
case base::Value::Type::STRING: {
|
||||
std::string val = value->GetString();
|
||||
return v8::String::NewFromUtf8(isolate, val.c_str(),
|
||||
v8::NewStringType::kNormal, val.length())
|
||||
.ToLocalChecked();
|
||||
}
|
||||
|
||||
case base::Value::Type::LIST:
|
||||
return ToV8Array(isolate, static_cast<const base::ListValue*>(value));
|
||||
|
||||
case base::Value::Type::DICTIONARY:
|
||||
return ToV8Object(isolate,
|
||||
static_cast<const base::DictionaryValue*>(value));
|
||||
|
||||
case base::Value::Type::BINARY:
|
||||
return ToArrayBuffer(isolate, static_cast<const base::Value*>(value));
|
||||
|
||||
default:
|
||||
LOG(ERROR) << "Unexpected value type: " << value->type();
|
||||
return v8::Null(isolate);
|
||||
}
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> V8ValueConverter::ToV8Array(
|
||||
v8::Isolate* isolate,
|
||||
const base::ListValue* val) const {
|
||||
v8::Local<v8::Array> result(v8::Array::New(isolate, val->GetSize()));
|
||||
auto context = isolate->GetCurrentContext();
|
||||
|
||||
for (size_t i = 0; i < val->GetSize(); ++i) {
|
||||
const base::Value* child = nullptr;
|
||||
val->Get(i, &child);
|
||||
|
||||
v8::Local<v8::Value> child_v8 = ToV8ValueImpl(isolate, child);
|
||||
|
||||
v8::TryCatch try_catch(isolate);
|
||||
result->Set(context, static_cast<uint32_t>(i), child_v8).Check();
|
||||
if (try_catch.HasCaught())
|
||||
LOG(ERROR) << "Setter for index " << i << " threw an exception.";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> V8ValueConverter::ToV8Object(
|
||||
v8::Isolate* isolate,
|
||||
const base::DictionaryValue* val) const {
|
||||
mate::Dictionary result = mate::Dictionary::CreateEmpty(isolate);
|
||||
result.SetHidden("simple", true);
|
||||
|
||||
for (base::DictionaryValue::Iterator iter(*val); !iter.IsAtEnd();
|
||||
iter.Advance()) {
|
||||
const std::string& key = iter.key();
|
||||
v8::Local<v8::Value> child_v8 = ToV8ValueImpl(isolate, &iter.value());
|
||||
|
||||
v8::TryCatch try_catch(isolate);
|
||||
result.Set(key, child_v8);
|
||||
if (try_catch.HasCaught()) {
|
||||
LOG(ERROR) << "Setter for property " << key.c_str() << " threw an "
|
||||
<< "exception.";
|
||||
}
|
||||
}
|
||||
|
||||
return result.GetHandle();
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> V8ValueConverter::ToArrayBuffer(
|
||||
v8::Isolate* isolate,
|
||||
const base::Value* value) const {
|
||||
const auto* data = reinterpret_cast<const char*>(value->GetBlob().data());
|
||||
size_t length = value->GetBlob().size();
|
||||
|
||||
if (NodeBindings::IsInitialized()) {
|
||||
return node::Buffer::Copy(isolate, data, length).ToLocalChecked();
|
||||
}
|
||||
|
||||
if (length > node::Buffer::kMaxLength) {
|
||||
return v8::Local<v8::Object>();
|
||||
}
|
||||
auto context = isolate->GetCurrentContext();
|
||||
auto array_buffer = v8::ArrayBuffer::New(isolate, length);
|
||||
memcpy(array_buffer->GetContents().Data(), data, length);
|
||||
// From this point, if something goes wrong(can't find Buffer class for
|
||||
// example) we'll simply return a Uint8Array based on the created ArrayBuffer.
|
||||
// This can happen if no preload script was specified to the renderer.
|
||||
mate::Dictionary global(isolate, context->Global());
|
||||
v8::Local<v8::Value> buffer_value;
|
||||
|
||||
// Get the Buffer class stored as a hidden value in the global object. We'll
|
||||
// use it return a browserified Buffer.
|
||||
if (!global.GetHidden("Buffer", &buffer_value) ||
|
||||
!buffer_value->IsFunction()) {
|
||||
return v8::Uint8Array::New(array_buffer, 0, length);
|
||||
}
|
||||
|
||||
mate::Dictionary buffer_class(
|
||||
isolate,
|
||||
buffer_value->ToObject(isolate->GetCurrentContext()).ToLocalChecked());
|
||||
v8::Local<v8::Value> from_value;
|
||||
if (!buffer_class.Get("from", &from_value) || !from_value->IsFunction()) {
|
||||
return v8::Uint8Array::New(array_buffer, 0, length);
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> args[] = {array_buffer};
|
||||
auto func = v8::Local<v8::Function>::Cast(from_value);
|
||||
auto result = func->Call(context, v8::Null(isolate), 1, args);
|
||||
if (!result.IsEmpty()) {
|
||||
return result.ToLocalChecked();
|
||||
}
|
||||
|
||||
return v8::Uint8Array::New(array_buffer, 0, length);
|
||||
}
|
||||
|
||||
std::unique_ptr<base::Value> V8ValueConverter::FromV8ValueImpl(
|
||||
FromV8ValueState* state,
|
||||
v8::Local<v8::Value> val,
|
||||
v8::Isolate* isolate) const {
|
||||
FromV8ValueState::Level state_level(state);
|
||||
if (state->HasReachedMaxRecursionDepth())
|
||||
return nullptr;
|
||||
|
||||
if (val->IsExternal())
|
||||
return std::make_unique<base::Value>();
|
||||
|
||||
if (val->IsNull())
|
||||
return std::make_unique<base::Value>();
|
||||
|
||||
auto context = isolate->GetCurrentContext();
|
||||
|
||||
if (val->IsBoolean())
|
||||
return std::make_unique<base::Value>(val->ToBoolean(isolate)->Value());
|
||||
|
||||
if (val->IsInt32())
|
||||
return std::make_unique<base::Value>(val.As<v8::Int32>()->Value());
|
||||
|
||||
if (val->IsNumber()) {
|
||||
double val_as_double = val.As<v8::Number>()->Value();
|
||||
if (!std::isfinite(val_as_double))
|
||||
return nullptr;
|
||||
return std::make_unique<base::Value>(val_as_double);
|
||||
}
|
||||
|
||||
if (val->IsString()) {
|
||||
v8::String::Utf8Value utf8(isolate, val);
|
||||
return std::make_unique<base::Value>(std::string(*utf8, utf8.length()));
|
||||
}
|
||||
|
||||
if (val->IsUndefined())
|
||||
// JSON.stringify ignores undefined.
|
||||
return nullptr;
|
||||
|
||||
if (val->IsDate()) {
|
||||
v8::Date* date = v8::Date::Cast(*val);
|
||||
v8::Local<v8::Value> toISOString =
|
||||
date->Get(context, v8::String::NewFromUtf8(isolate, "toISOString",
|
||||
v8::NewStringType::kNormal)
|
||||
.ToLocalChecked())
|
||||
.ToLocalChecked();
|
||||
if (toISOString->IsFunction()) {
|
||||
v8::MaybeLocal<v8::Value> result =
|
||||
toISOString.As<v8::Function>()->Call(context, val, 0, nullptr);
|
||||
if (!result.IsEmpty()) {
|
||||
v8::String::Utf8Value utf8(isolate, result.ToLocalChecked());
|
||||
return std::make_unique<base::Value>(std::string(*utf8, utf8.length()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (val->IsRegExp()) {
|
||||
if (!reg_exp_allowed_)
|
||||
// JSON.stringify converts to an object.
|
||||
return FromV8Object(val.As<v8::Object>(), state, isolate);
|
||||
return std::make_unique<base::Value>(*v8::String::Utf8Value(isolate, val));
|
||||
}
|
||||
|
||||
// v8::Value doesn't have a ToArray() method for some reason.
|
||||
if (val->IsArray())
|
||||
return FromV8Array(val.As<v8::Array>(), state, isolate);
|
||||
|
||||
if (val->IsFunction()) {
|
||||
if (!function_allowed_)
|
||||
// JSON.stringify refuses to convert function(){}.
|
||||
return nullptr;
|
||||
return FromV8Object(val.As<v8::Object>(), state, isolate);
|
||||
}
|
||||
|
||||
if (node::Buffer::HasInstance(val)) {
|
||||
return FromNodeBuffer(val, state, isolate);
|
||||
}
|
||||
|
||||
if (val->IsObject()) {
|
||||
return FromV8Object(val.As<v8::Object>(), state, isolate);
|
||||
}
|
||||
|
||||
LOG(ERROR) << "Unexpected v8 value type encountered.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<base::Value> V8ValueConverter::FromV8Array(
|
||||
v8::Local<v8::Array> val,
|
||||
FromV8ValueState* state,
|
||||
v8::Isolate* isolate) const {
|
||||
ScopedUniquenessGuard uniqueness_guard(state, val);
|
||||
if (!uniqueness_guard.is_valid())
|
||||
return std::make_unique<base::Value>();
|
||||
|
||||
std::unique_ptr<v8::Context::Scope> scope;
|
||||
// If val was created in a different context than our current one, change to
|
||||
// that context, but change back after val is converted.
|
||||
if (!val->CreationContext().IsEmpty() &&
|
||||
val->CreationContext() != isolate->GetCurrentContext())
|
||||
scope.reset(new v8::Context::Scope(val->CreationContext()));
|
||||
|
||||
std::unique_ptr<base::ListValue> result(new base::ListValue());
|
||||
|
||||
// Only fields with integer keys are carried over to the ListValue.
|
||||
for (uint32_t i = 0; i < val->Length(); ++i) {
|
||||
v8::TryCatch try_catch(isolate);
|
||||
v8::Local<v8::Value> child_v8;
|
||||
v8::MaybeLocal<v8::Value> maybe_child =
|
||||
val->Get(isolate->GetCurrentContext(), i);
|
||||
if (try_catch.HasCaught() || !maybe_child.ToLocal(&child_v8)) {
|
||||
LOG(ERROR) << "Getter for index " << i << " threw an exception.";
|
||||
child_v8 = v8::Null(isolate);
|
||||
}
|
||||
|
||||
if (!val->HasRealIndexedProperty(isolate->GetCurrentContext(), i)
|
||||
.FromMaybe(false)) {
|
||||
result->Append(std::make_unique<base::Value>());
|
||||
continue;
|
||||
}
|
||||
|
||||
std::unique_ptr<base::Value> child =
|
||||
FromV8ValueImpl(state, child_v8, isolate);
|
||||
if (child)
|
||||
result->Append(std::move(child));
|
||||
else
|
||||
// JSON.stringify puts null in places where values don't serialize, for
|
||||
// example undefined and functions. Emulate that behavior.
|
||||
result->Append(std::make_unique<base::Value>());
|
||||
}
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
std::unique_ptr<base::Value> V8ValueConverter::FromNodeBuffer(
|
||||
v8::Local<v8::Value> value,
|
||||
FromV8ValueState* state,
|
||||
v8::Isolate* isolate) const {
|
||||
std::vector<char> buffer(
|
||||
node::Buffer::Data(value),
|
||||
node::Buffer::Data(value) + node::Buffer::Length(value));
|
||||
return std::make_unique<base::Value>(std::move(buffer));
|
||||
}
|
||||
|
||||
std::unique_ptr<base::Value> V8ValueConverter::FromV8Object(
|
||||
v8::Local<v8::Object> val,
|
||||
FromV8ValueState* state,
|
||||
v8::Isolate* isolate) const {
|
||||
ScopedUniquenessGuard uniqueness_guard(state, val);
|
||||
if (!uniqueness_guard.is_valid())
|
||||
return std::make_unique<base::Value>();
|
||||
|
||||
std::unique_ptr<v8::Context::Scope> scope;
|
||||
// If val was created in a different context than our current one, change to
|
||||
// that context, but change back after val is converted.
|
||||
if (!val->CreationContext().IsEmpty() &&
|
||||
val->CreationContext() != isolate->GetCurrentContext())
|
||||
scope.reset(new v8::Context::Scope(val->CreationContext()));
|
||||
|
||||
auto result = std::make_unique<base::DictionaryValue>();
|
||||
v8::Local<v8::Array> property_names;
|
||||
if (!val->GetOwnPropertyNames(isolate->GetCurrentContext())
|
||||
.ToLocal(&property_names)) {
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < property_names->Length(); ++i) {
|
||||
v8::Local<v8::Value> key =
|
||||
property_names->Get(isolate->GetCurrentContext(), i).ToLocalChecked();
|
||||
|
||||
// Extend this test to cover more types as necessary and if sensible.
|
||||
if (!key->IsString() && !key->IsNumber()) {
|
||||
NOTREACHED() << "Key \"" << *v8::String::Utf8Value(isolate, key)
|
||||
<< "\" "
|
||||
"is neither a string nor a number";
|
||||
continue;
|
||||
}
|
||||
|
||||
v8::String::Utf8Value name_utf8(isolate, key);
|
||||
|
||||
v8::TryCatch try_catch(isolate);
|
||||
v8::Local<v8::Value> child_v8;
|
||||
v8::MaybeLocal<v8::Value> maybe_child =
|
||||
val->Get(isolate->GetCurrentContext(), key);
|
||||
if (try_catch.HasCaught() || !maybe_child.ToLocal(&child_v8)) {
|
||||
LOG(ERROR) << "Getter for property " << *name_utf8
|
||||
<< " threw an exception.";
|
||||
child_v8 = v8::Null(isolate);
|
||||
}
|
||||
|
||||
std::unique_ptr<base::Value> child =
|
||||
FromV8ValueImpl(state, child_v8, isolate);
|
||||
if (!child)
|
||||
// JSON.stringify skips properties whose values don't serialize, for
|
||||
// example undefined and functions. Emulate that behavior.
|
||||
continue;
|
||||
|
||||
// Strip null if asked (and since undefined is turned into null, undefined
|
||||
// too). The use case for supporting this is JSON-schema support,
|
||||
// specifically for extensions, where "optional" JSON properties may be
|
||||
// represented as null, yet due to buggy legacy code elsewhere isn't
|
||||
// treated as such (potentially causing crashes). For example, the
|
||||
// "tabs.create" function takes an object as its first argument with an
|
||||
// optional "windowId" property.
|
||||
//
|
||||
// Given just
|
||||
//
|
||||
// tabs.create({})
|
||||
//
|
||||
// this will work as expected on code that only checks for the existence of
|
||||
// a "windowId" property (such as that legacy code). However given
|
||||
//
|
||||
// tabs.create({windowId: null})
|
||||
//
|
||||
// there *is* a "windowId" property, but since it should be an int, code
|
||||
// on the browser which doesn't additionally check for null will fail.
|
||||
// We can avoid all bugs related to this by stripping null.
|
||||
if (strip_null_from_objects_ && child->is_none())
|
||||
continue;
|
||||
|
||||
result->SetWithoutPathExpansion(std::string(*name_utf8, name_utf8.length()),
|
||||
std::move(child));
|
||||
}
|
||||
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
} // namespace atom
|
77
shell/common/native_mate_converters/v8_value_converter.h
Normal file
77
shell/common/native_mate_converters/v8_value_converter.h
Normal file
|
@ -0,0 +1,77 @@
|
|||
// Copyright (c) 2013 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_V8_VALUE_CONVERTER_H_
|
||||
#define ATOM_COMMON_NATIVE_MATE_CONVERTERS_V8_VALUE_CONVERTER_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "base/compiler_specific.h"
|
||||
#include "base/macros.h"
|
||||
#include "v8/include/v8.h"
|
||||
|
||||
namespace base {
|
||||
class DictionaryValue;
|
||||
class ListValue;
|
||||
class Value;
|
||||
} // namespace base
|
||||
|
||||
namespace atom {
|
||||
|
||||
class V8ValueConverter {
|
||||
public:
|
||||
V8ValueConverter();
|
||||
|
||||
void SetRegExpAllowed(bool val);
|
||||
void SetFunctionAllowed(bool val);
|
||||
void SetStripNullFromObjects(bool val);
|
||||
v8::Local<v8::Value> ToV8Value(const base::Value* value,
|
||||
v8::Local<v8::Context> context) const;
|
||||
std::unique_ptr<base::Value> FromV8Value(
|
||||
v8::Local<v8::Value> value,
|
||||
v8::Local<v8::Context> context) const;
|
||||
|
||||
private:
|
||||
class FromV8ValueState;
|
||||
class ScopedUniquenessGuard;
|
||||
|
||||
v8::Local<v8::Value> ToV8ValueImpl(v8::Isolate* isolate,
|
||||
const base::Value* value) const;
|
||||
v8::Local<v8::Value> ToV8Array(v8::Isolate* isolate,
|
||||
const base::ListValue* list) const;
|
||||
v8::Local<v8::Value> ToV8Object(
|
||||
v8::Isolate* isolate,
|
||||
const base::DictionaryValue* dictionary) const;
|
||||
v8::Local<v8::Value> ToArrayBuffer(v8::Isolate* isolate,
|
||||
const base::Value* value) const;
|
||||
|
||||
std::unique_ptr<base::Value> FromV8ValueImpl(FromV8ValueState* state,
|
||||
v8::Local<v8::Value> value,
|
||||
v8::Isolate* isolate) const;
|
||||
std::unique_ptr<base::Value> FromV8Array(v8::Local<v8::Array> array,
|
||||
FromV8ValueState* state,
|
||||
v8::Isolate* isolate) const;
|
||||
std::unique_ptr<base::Value> FromNodeBuffer(v8::Local<v8::Value> value,
|
||||
FromV8ValueState* state,
|
||||
v8::Isolate* isolate) const;
|
||||
std::unique_ptr<base::Value> FromV8Object(v8::Local<v8::Object> object,
|
||||
FromV8ValueState* state,
|
||||
v8::Isolate* isolate) const;
|
||||
|
||||
// If true, we will convert RegExp JavaScript objects to string.
|
||||
bool reg_exp_allowed_ = false;
|
||||
|
||||
// If true, we will convert Function JavaScript objects to dictionaries.
|
||||
bool function_allowed_ = false;
|
||||
|
||||
// If true, undefined and null values are ignored when converting v8 objects
|
||||
// into Values.
|
||||
bool strip_null_from_objects_ = false;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(V8ValueConverter);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_V8_VALUE_CONVERTER_H_
|
76
shell/common/native_mate_converters/value_converter.cc
Normal file
76
shell/common/native_mate_converters/value_converter.cc
Normal file
|
@ -0,0 +1,76 @@
|
|||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "atom/common/native_mate_converters/v8_value_converter.h"
|
||||
#include "base/values.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
bool Converter<base::DictionaryValue>::FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
base::DictionaryValue* out) {
|
||||
atom::V8ValueConverter converter;
|
||||
std::unique_ptr<base::Value> value(
|
||||
converter.FromV8Value(val, isolate->GetCurrentContext()));
|
||||
if (value && value->is_dict()) {
|
||||
out->Swap(static_cast<base::DictionaryValue*>(value.get()));
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Converter<base::DictionaryValue>::ToV8(
|
||||
v8::Isolate* isolate,
|
||||
const base::DictionaryValue& val) {
|
||||
atom::V8ValueConverter converter;
|
||||
return converter.ToV8Value(&val, isolate->GetCurrentContext());
|
||||
}
|
||||
|
||||
bool Converter<base::Value>::FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
base::Value* out) {
|
||||
atom::V8ValueConverter converter;
|
||||
std::unique_ptr<base::Value> value(
|
||||
converter.FromV8Value(val, isolate->GetCurrentContext()));
|
||||
if (value) {
|
||||
*out = value->Clone();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Converter<base::Value>::ToV8(v8::Isolate* isolate,
|
||||
const base::Value& val) {
|
||||
atom::V8ValueConverter converter;
|
||||
return converter.ToV8Value(&val, isolate->GetCurrentContext());
|
||||
}
|
||||
|
||||
bool Converter<base::ListValue>::FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
base::ListValue* out) {
|
||||
atom::V8ValueConverter converter;
|
||||
std::unique_ptr<base::Value> value(
|
||||
converter.FromV8Value(val, isolate->GetCurrentContext()));
|
||||
if (value->is_list()) {
|
||||
out->Swap(static_cast<base::ListValue*>(value.get()));
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Converter<base::ListValue>::ToV8(
|
||||
v8::Isolate* isolate,
|
||||
const base::ListValue& val) {
|
||||
atom::V8ValueConverter converter;
|
||||
return converter.ToV8Value(&val, isolate->GetCurrentContext());
|
||||
}
|
||||
|
||||
} // namespace mate
|
47
shell/common/native_mate_converters/value_converter.h
Normal file
47
shell/common/native_mate_converters/value_converter.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
// Copyright (c) 2014 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_VALUE_CONVERTER_H_
|
||||
#define ATOM_COMMON_NATIVE_MATE_CONVERTERS_VALUE_CONVERTER_H_
|
||||
|
||||
#include "native_mate/converter.h"
|
||||
|
||||
namespace base {
|
||||
class DictionaryValue;
|
||||
class ListValue;
|
||||
class Value;
|
||||
} // namespace base
|
||||
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
struct Converter<base::DictionaryValue> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
base::DictionaryValue* out);
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const base::DictionaryValue& val);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<base::Value> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
base::Value* out);
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const base::Value& val);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<base::ListValue> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
base::ListValue* out);
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const base::ListValue& val);
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
#endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_VALUE_CONVERTER_H_
|
Loading…
Add table
Add a link
Reference in a new issue