content_converter.cc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. // Copyright (c) 2015 GitHub, Inc.
  2. // Use of this source code is governed by the MIT license that can be
  3. // found in the LICENSE file.
  4. #include "atom/common/native_mate_converters/content_converter.h"
  5. #include <string>
  6. #include <vector>
  7. #include "atom/browser/api/atom_api_web_contents.h"
  8. #include "atom/browser/web_contents_permission_helper.h"
  9. #include "atom/common/native_mate_converters/blink_converter.h"
  10. #include "atom/common/native_mate_converters/callback.h"
  11. #include "atom/common/native_mate_converters/gurl_converter.h"
  12. #include "atom/common/native_mate_converters/string16_converter.h"
  13. #include "atom/common/native_mate_converters/ui_base_types_converter.h"
  14. #include "atom/common/native_mate_converters/value_converter.h"
  15. #include "content/public/browser/web_contents.h"
  16. #include "content/public/common/context_menu_params.h"
  17. #include "content/public/common/resource_request_body.h"
  18. #include "native_mate/dictionary.h"
  19. using content::ResourceRequestBody;
  20. namespace {
  21. void ExecuteCommand(content::WebContents* web_contents,
  22. int action,
  23. const content::CustomContextMenuContext& context) {
  24. web_contents->ExecuteCustomContextMenuCommand(action, context);
  25. }
  26. // Forward declaration for nested recursive call.
  27. v8::Local<v8::Value> MenuToV8(v8::Isolate* isolate,
  28. content::WebContents* web_contents,
  29. const content::CustomContextMenuContext& context,
  30. const std::vector<content::MenuItem>& menu);
  31. v8::Local<v8::Value> MenuItemToV8(
  32. v8::Isolate* isolate,
  33. content::WebContents* web_contents,
  34. const content::CustomContextMenuContext& context,
  35. const content::MenuItem& item) {
  36. mate::Dictionary v8_item = mate::Dictionary::CreateEmpty(isolate);
  37. switch (item.type) {
  38. case content::MenuItem::CHECKABLE_OPTION:
  39. case content::MenuItem::GROUP:
  40. v8_item.Set("checked", item.checked);
  41. case content::MenuItem::OPTION:
  42. case content::MenuItem::SUBMENU:
  43. v8_item.Set("label", item.label);
  44. v8_item.Set("enabled", item.enabled);
  45. default:
  46. v8_item.Set("type", item.type);
  47. }
  48. if (item.type == content::MenuItem::SUBMENU)
  49. v8_item.Set("submenu",
  50. MenuToV8(isolate, web_contents, context, item.submenu));
  51. else if (item.action > 0)
  52. v8_item.Set("click",
  53. base::Bind(ExecuteCommand, web_contents, item.action, context));
  54. return v8_item.GetHandle();
  55. }
  56. v8::Local<v8::Value> MenuToV8(v8::Isolate* isolate,
  57. content::WebContents* web_contents,
  58. const content::CustomContextMenuContext& context,
  59. const std::vector<content::MenuItem>& menu) {
  60. std::vector<v8::Local<v8::Value>> v8_menu;
  61. for (const auto& menu_item : menu)
  62. v8_menu.push_back(MenuItemToV8(isolate, web_contents, context, menu_item));
  63. return mate::ConvertToV8(isolate, v8_menu);
  64. }
  65. } // namespace
  66. namespace mate {
  67. // static
  68. v8::Local<v8::Value> Converter<content::MenuItem::Type>::ToV8(
  69. v8::Isolate* isolate,
  70. const content::MenuItem::Type& val) {
  71. switch (val) {
  72. case content::MenuItem::CHECKABLE_OPTION:
  73. return StringToV8(isolate, "checkbox");
  74. case content::MenuItem::GROUP:
  75. return StringToV8(isolate, "radio");
  76. case content::MenuItem::SEPARATOR:
  77. return StringToV8(isolate, "separator");
  78. case content::MenuItem::SUBMENU:
  79. return StringToV8(isolate, "submenu");
  80. case content::MenuItem::OPTION:
  81. default:
  82. return StringToV8(isolate, "normal");
  83. }
  84. }
  85. // static
  86. v8::Local<v8::Value> Converter<ContextMenuParamsWithWebContents>::ToV8(
  87. v8::Isolate* isolate,
  88. const ContextMenuParamsWithWebContents& val) {
  89. const auto& params = val.first;
  90. mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
  91. dict.Set("x", params.x);
  92. dict.Set("y", params.y);
  93. dict.Set("linkURL", params.link_url);
  94. dict.Set("linkText", params.link_text);
  95. dict.Set("pageURL", params.page_url);
  96. dict.Set("frameURL", params.frame_url);
  97. dict.Set("srcURL", params.src_url);
  98. dict.Set("mediaType", params.media_type);
  99. dict.Set("mediaFlags", MediaFlagsToV8(isolate, params.media_flags));
  100. bool has_image_contents =
  101. (params.media_type == blink::WebContextMenuData::kMediaTypeImage) &&
  102. params.has_image_contents;
  103. dict.Set("hasImageContents", has_image_contents);
  104. dict.Set("isEditable", params.is_editable);
  105. dict.Set("editFlags", EditFlagsToV8(isolate, params.edit_flags));
  106. dict.Set("selectionText", params.selection_text);
  107. dict.Set("titleText", params.title_text);
  108. dict.Set("misspelledWord", params.misspelled_word);
  109. dict.Set("frameCharset", params.frame_charset);
  110. dict.Set("inputFieldType", params.input_field_type);
  111. dict.Set("menuSourceType", params.source_type);
  112. if (params.custom_context.is_pepper_menu)
  113. dict.Set("menu", MenuToV8(isolate, val.second, params.custom_context,
  114. params.custom_items));
  115. return mate::ConvertToV8(isolate, dict);
  116. }
  117. // static
  118. bool Converter<blink::mojom::PermissionStatus>::FromV8(
  119. v8::Isolate* isolate,
  120. v8::Local<v8::Value> val,
  121. blink::mojom::PermissionStatus* out) {
  122. bool result;
  123. if (!ConvertFromV8(isolate, val, &result))
  124. return false;
  125. if (result)
  126. *out = blink::mojom::PermissionStatus::GRANTED;
  127. else
  128. *out = blink::mojom::PermissionStatus::DENIED;
  129. return true;
  130. }
  131. // static
  132. v8::Local<v8::Value> Converter<content::PermissionType>::ToV8(
  133. v8::Isolate* isolate,
  134. const content::PermissionType& val) {
  135. using PermissionType = atom::WebContentsPermissionHelper::PermissionType;
  136. switch (val) {
  137. case content::PermissionType::MIDI_SYSEX:
  138. return StringToV8(isolate, "midiSysex");
  139. case content::PermissionType::PUSH_MESSAGING:
  140. return StringToV8(isolate, "pushMessaging");
  141. case content::PermissionType::NOTIFICATIONS:
  142. return StringToV8(isolate, "notifications");
  143. case content::PermissionType::GEOLOCATION:
  144. return StringToV8(isolate, "geolocation");
  145. case content::PermissionType::AUDIO_CAPTURE:
  146. case content::PermissionType::VIDEO_CAPTURE:
  147. return StringToV8(isolate, "media");
  148. case content::PermissionType::PROTECTED_MEDIA_IDENTIFIER:
  149. return StringToV8(isolate, "mediaKeySystem");
  150. case content::PermissionType::MIDI:
  151. return StringToV8(isolate, "midi");
  152. default:
  153. break;
  154. }
  155. if (val == static_cast<content::PermissionType>(PermissionType::POINTER_LOCK))
  156. return StringToV8(isolate, "pointerLock");
  157. else if (val ==
  158. static_cast<content::PermissionType>(PermissionType::FULLSCREEN))
  159. return StringToV8(isolate, "fullscreen");
  160. else if (val ==
  161. static_cast<content::PermissionType>(PermissionType::OPEN_EXTERNAL))
  162. return StringToV8(isolate, "openExternal");
  163. return StringToV8(isolate, "unknown");
  164. }
  165. // static
  166. bool Converter<content::StopFindAction>::FromV8(v8::Isolate* isolate,
  167. v8::Local<v8::Value> val,
  168. content::StopFindAction* out) {
  169. std::string action;
  170. if (!ConvertFromV8(isolate, val, &action))
  171. return false;
  172. if (action == "clearSelection")
  173. *out = content::STOP_FIND_ACTION_CLEAR_SELECTION;
  174. else if (action == "keepSelection")
  175. *out = content::STOP_FIND_ACTION_KEEP_SELECTION;
  176. else if (action == "activateSelection")
  177. *out = content::STOP_FIND_ACTION_ACTIVATE_SELECTION;
  178. else
  179. return false;
  180. return true;
  181. }
  182. // static
  183. v8::Local<v8::Value> Converter<scoped_refptr<ResourceRequestBody>>::ToV8(
  184. v8::Isolate* isolate,
  185. const scoped_refptr<ResourceRequestBody>& val) {
  186. if (!val)
  187. return v8::Null(isolate);
  188. std::unique_ptr<base::ListValue> list(new base::ListValue);
  189. for (const auto& element : *(val->elements())) {
  190. std::unique_ptr<base::DictionaryValue> post_data_dict(
  191. new base::DictionaryValue);
  192. auto type = element.type();
  193. if (type == ResourceRequestBody::Element::TYPE_BYTES) {
  194. std::unique_ptr<base::Value> bytes(base::Value::CreateWithCopiedBuffer(
  195. element.bytes(), static_cast<size_t>(element.length())));
  196. post_data_dict->SetString("type", "rawData");
  197. post_data_dict->Set("bytes", std::move(bytes));
  198. } else if (type == ResourceRequestBody::Element::TYPE_FILE) {
  199. post_data_dict->SetString("type", "file");
  200. post_data_dict->SetKey("filePath",
  201. base::Value(element.path().AsUTF8Unsafe()));
  202. post_data_dict->SetInteger("offset", static_cast<int>(element.offset()));
  203. post_data_dict->SetInteger("length", static_cast<int>(element.length()));
  204. post_data_dict->SetDouble(
  205. "modificationTime", element.expected_modification_time().ToDoubleT());
  206. } else if (type == ResourceRequestBody::Element::TYPE_FILE_FILESYSTEM) {
  207. post_data_dict->SetString("type", "fileSystem");
  208. post_data_dict->SetKey("fileSystemURL",
  209. base::Value(element.filesystem_url().spec()));
  210. post_data_dict->SetInteger("offset", static_cast<int>(element.offset()));
  211. post_data_dict->SetInteger("length", static_cast<int>(element.length()));
  212. post_data_dict->SetDouble(
  213. "modificationTime", element.expected_modification_time().ToDoubleT());
  214. } else if (type == ResourceRequestBody::Element::TYPE_BLOB) {
  215. post_data_dict->SetString("type", "blob");
  216. post_data_dict->SetString("blobUUID", element.blob_uuid());
  217. }
  218. list->Append(std::move(post_data_dict));
  219. }
  220. return ConvertToV8(isolate, *list);
  221. }
  222. // static
  223. bool Converter<scoped_refptr<ResourceRequestBody>>::FromV8(
  224. v8::Isolate* isolate,
  225. v8::Local<v8::Value> val,
  226. scoped_refptr<ResourceRequestBody>* out) {
  227. std::unique_ptr<base::ListValue> list(new base::ListValue);
  228. if (!ConvertFromV8(isolate, val, list.get()))
  229. return false;
  230. *out = new content::ResourceRequestBody();
  231. for (size_t i = 0; i < list->GetSize(); ++i) {
  232. base::DictionaryValue* dict = nullptr;
  233. std::string type;
  234. if (!list->GetDictionary(i, &dict))
  235. return false;
  236. dict->GetString("type", &type);
  237. if (type == "rawData") {
  238. base::Value* bytes = nullptr;
  239. dict->GetBinary("bytes", &bytes);
  240. (*out)->AppendBytes(bytes->GetBlob().data(), bytes->GetBlob().size());
  241. } else if (type == "file") {
  242. std::string file;
  243. int offset = 0, length = -1;
  244. double modification_time = 0.0;
  245. dict->GetStringWithoutPathExpansion("filePath", &file);
  246. dict->GetInteger("offset", &offset);
  247. dict->GetInteger("file", &length);
  248. dict->GetDouble("modificationTime", &modification_time);
  249. (*out)->AppendFileRange(base::FilePath::FromUTF8Unsafe(file),
  250. static_cast<uint64_t>(offset),
  251. static_cast<uint64_t>(length),
  252. base::Time::FromDoubleT(modification_time));
  253. } else if (type == "fileSystem") {
  254. std::string file_system_url;
  255. int offset = 0, length = -1;
  256. double modification_time = 0.0;
  257. dict->GetStringWithoutPathExpansion("fileSystemURL", &file_system_url);
  258. dict->GetInteger("offset", &offset);
  259. dict->GetInteger("file", &length);
  260. dict->GetDouble("modificationTime", &modification_time);
  261. (*out)->AppendFileSystemFileRange(
  262. GURL(file_system_url), static_cast<uint64_t>(offset),
  263. static_cast<uint64_t>(length),
  264. base::Time::FromDoubleT(modification_time));
  265. } else if (type == "blob") {
  266. std::string uuid;
  267. dict->GetString("blobUUID", &uuid);
  268. (*out)->AppendBlob(uuid);
  269. }
  270. }
  271. return true;
  272. }
  273. // static
  274. v8::Local<v8::Value> Converter<content::WebContents*>::ToV8(
  275. v8::Isolate* isolate,
  276. content::WebContents* val) {
  277. if (!val)
  278. return v8::Null(isolate);
  279. return atom::api::WebContents::CreateFrom(isolate, val).ToV8();
  280. }
  281. // static
  282. bool Converter<content::WebContents*>::FromV8(v8::Isolate* isolate,
  283. v8::Local<v8::Value> val,
  284. content::WebContents** out) {
  285. atom::api::WebContents* web_contents = nullptr;
  286. if (!ConvertFromV8(isolate, val, &web_contents) || !web_contents)
  287. return false;
  288. *out = web_contents->web_contents();
  289. return true;
  290. }
  291. // static
  292. v8::Local<v8::Value> Converter<content::Referrer>::ToV8(
  293. v8::Isolate* isolate,
  294. const content::Referrer& val) {
  295. mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
  296. dict.Set("url", ConvertToV8(isolate, val.url));
  297. dict.Set("policy", ConvertToV8(isolate, val.policy));
  298. return mate::ConvertToV8(isolate, dict);
  299. }
  300. // static
  301. bool Converter<content::Referrer>::FromV8(v8::Isolate* isolate,
  302. v8::Local<v8::Value> val,
  303. content::Referrer* out) {
  304. mate::Dictionary dict;
  305. if (!ConvertFromV8(isolate, val, &dict))
  306. return false;
  307. if (!dict.Get("url", &out->url))
  308. return false;
  309. if (!dict.Get("policy", &out->policy))
  310. return false;
  311. return true;
  312. }
  313. } // namespace mate