atom_api_web_contents.cc 73 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157
  1. // Copyright (c) 2014 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/browser/api/atom_api_web_contents.h"
  5. #include <set>
  6. #include <string>
  7. // We have problems with redefinition of ssize_t between node.h and
  8. // port_chromium.h, and the latter was introduced by leveldb.mojom.h.
  9. // The best solution is to not include content/browser/frame_host/ headers
  10. // and node.h in the same file, but for now I'm just working around the
  11. // problem.
  12. #if defined(OS_WIN)
  13. #define COMPONENTS_SERVICES_LEVELDB_PUBLIC_INTERFACES_LEVELDB_MOJOM_H_
  14. #define COMPONENTS_LEVELDB_PUBLIC_INTERFACES_LEVELDB_MOJOM_H_
  15. #endif
  16. #include "atom/browser/api/atom_api_browser_window.h"
  17. #include "atom/browser/api/atom_api_debugger.h"
  18. #include "atom/browser/api/atom_api_session.h"
  19. #include "atom/browser/atom_browser_client.h"
  20. #include "atom/browser/atom_browser_context.h"
  21. #include "atom/browser/atom_browser_main_parts.h"
  22. #include "atom/browser/atom_javascript_dialog_manager.h"
  23. #include "atom/browser/child_web_contents_tracker.h"
  24. #include "atom/browser/lib/bluetooth_chooser.h"
  25. #include "atom/browser/native_window.h"
  26. #include "atom/browser/net/atom_network_delegate.h"
  27. #if defined(ENABLE_OSR)
  28. #include "atom/browser/osr/osr_output_device.h"
  29. #include "atom/browser/osr/osr_render_widget_host_view.h"
  30. #include "atom/browser/osr/osr_web_contents_view.h"
  31. #endif
  32. #include "atom/browser/ui/drag_util.h"
  33. #include "atom/browser/web_contents_permission_helper.h"
  34. #include "atom/browser/web_contents_preferences.h"
  35. #include "atom/browser/web_contents_zoom_controller.h"
  36. #include "atom/browser/web_view_guest_delegate.h"
  37. #include "atom/common/api/api_messages.h"
  38. #include "atom/common/api/atom_api_native_image.h"
  39. #include "atom/common/api/event_emitter_caller.h"
  40. #include "atom/common/color_util.h"
  41. #include "atom/common/mouse_util.h"
  42. #include "atom/common/native_mate_converters/blink_converter.h"
  43. #include "atom/common/native_mate_converters/callback.h"
  44. #include "atom/common/native_mate_converters/content_converter.h"
  45. #include "atom/common/native_mate_converters/file_path_converter.h"
  46. #include "atom/common/native_mate_converters/gfx_converter.h"
  47. #include "atom/common/native_mate_converters/gurl_converter.h"
  48. #include "atom/common/native_mate_converters/image_converter.h"
  49. #include "atom/common/native_mate_converters/net_converter.h"
  50. #include "atom/common/native_mate_converters/string16_converter.h"
  51. #include "atom/common/native_mate_converters/value_converter.h"
  52. #include "atom/common/options_switches.h"
  53. #include "base/message_loop/message_loop.h"
  54. #include "base/process/process_handle.h"
  55. #include "base/strings/utf_string_conversions.h"
  56. #include "base/threading/thread_task_runner_handle.h"
  57. #include "base/values.h"
  58. #include "brightray/browser/inspectable_web_contents.h"
  59. #include "brightray/browser/inspectable_web_contents_view.h"
  60. #include "chrome/browser/browser_process.h"
  61. #include "chrome/browser/printing/print_preview_message_handler.h"
  62. #include "chrome/browser/printing/print_view_manager_basic.h"
  63. #include "chrome/browser/ssl/security_state_tab_helper.h"
  64. #include "content/browser/frame_host/frame_tree_node.h"
  65. #include "content/browser/frame_host/render_frame_host_manager.h"
  66. #include "content/browser/renderer_host/render_widget_host_impl.h"
  67. #include "content/browser/renderer_host/render_widget_host_view_base.h"
  68. #include "content/common/view_messages.h"
  69. #include "content/public/browser/child_process_security_policy.h"
  70. #include "content/public/browser/favicon_status.h"
  71. #include "content/public/browser/native_web_keyboard_event.h"
  72. #include "content/public/browser/navigation_details.h"
  73. #include "content/public/browser/navigation_entry.h"
  74. #include "content/public/browser/navigation_handle.h"
  75. #include "content/public/browser/plugin_service.h"
  76. #include "content/public/browser/render_frame_host.h"
  77. #include "content/public/browser/render_process_host.h"
  78. #include "content/public/browser/render_view_host.h"
  79. #include "content/public/browser/render_widget_host.h"
  80. #include "content/public/browser/render_widget_host_view.h"
  81. #include "content/public/browser/resource_request_details.h"
  82. #include "content/public/browser/service_worker_context.h"
  83. #include "content/public/browser/site_instance.h"
  84. #include "content/public/browser/storage_partition.h"
  85. #include "content/public/browser/web_contents.h"
  86. #include "content/public/common/context_menu_params.h"
  87. #include "native_mate/converter.h"
  88. #include "native_mate/dictionary.h"
  89. #include "native_mate/object_template_builder.h"
  90. #include "net/url_request/url_request_context.h"
  91. #include "third_party/WebKit/public/platform/WebInputEvent.h"
  92. #include "third_party/WebKit/public/web/WebFindOptions.h"
  93. #include "ui/display/screen.h"
  94. #include "ui/events/base_event_utils.h"
  95. #include "ui/latency/latency_info.h"
  96. #if !defined(OS_MACOSX)
  97. #include "ui/aura/window.h"
  98. #endif
  99. #if defined(OS_LINUX) || defined(OS_WIN)
  100. #include "content/public/common/renderer_preferences.h"
  101. #include "ui/gfx/font_render_params.h"
  102. #endif
  103. #include "atom/common/node_includes.h"
  104. namespace {
  105. struct PrintSettings {
  106. bool silent;
  107. bool print_background;
  108. base::string16 device_name;
  109. };
  110. } // namespace
  111. namespace mate {
  112. template <>
  113. struct Converter<atom::SetSizeParams> {
  114. static bool FromV8(v8::Isolate* isolate,
  115. v8::Local<v8::Value> val,
  116. atom::SetSizeParams* out) {
  117. mate::Dictionary params;
  118. if (!ConvertFromV8(isolate, val, &params))
  119. return false;
  120. bool autosize;
  121. if (params.Get("enableAutoSize", &autosize))
  122. out->enable_auto_size.reset(new bool(true));
  123. gfx::Size size;
  124. if (params.Get("min", &size))
  125. out->min_size.reset(new gfx::Size(size));
  126. if (params.Get("max", &size))
  127. out->max_size.reset(new gfx::Size(size));
  128. if (params.Get("normal", &size))
  129. out->normal_size.reset(new gfx::Size(size));
  130. return true;
  131. }
  132. };
  133. template <>
  134. struct Converter<PrintSettings> {
  135. static bool FromV8(v8::Isolate* isolate,
  136. v8::Local<v8::Value> val,
  137. PrintSettings* out) {
  138. mate::Dictionary dict;
  139. if (!ConvertFromV8(isolate, val, &dict))
  140. return false;
  141. dict.Get("silent", &(out->silent));
  142. dict.Get("printBackground", &(out->print_background));
  143. dict.Get("deviceName", &(out->device_name));
  144. return true;
  145. }
  146. };
  147. template <>
  148. struct Converter<printing::PrinterBasicInfo> {
  149. static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
  150. const printing::PrinterBasicInfo& val) {
  151. mate::Dictionary dict(isolate, v8::Object::New(isolate));
  152. dict.Set("name", val.printer_name);
  153. dict.Set("description", val.printer_description);
  154. dict.Set("status", val.printer_status);
  155. dict.Set("isDefault", val.is_default ? true : false);
  156. dict.Set("options", val.options);
  157. return dict.GetHandle();
  158. }
  159. };
  160. template <>
  161. struct Converter<WindowOpenDisposition> {
  162. static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
  163. WindowOpenDisposition val) {
  164. std::string disposition = "other";
  165. switch (val) {
  166. case WindowOpenDisposition::CURRENT_TAB:
  167. disposition = "default";
  168. break;
  169. case WindowOpenDisposition::NEW_FOREGROUND_TAB:
  170. disposition = "foreground-tab";
  171. break;
  172. case WindowOpenDisposition::NEW_BACKGROUND_TAB:
  173. disposition = "background-tab";
  174. break;
  175. case WindowOpenDisposition::NEW_POPUP:
  176. case WindowOpenDisposition::NEW_WINDOW:
  177. disposition = "new-window";
  178. break;
  179. case WindowOpenDisposition::SAVE_TO_DISK:
  180. disposition = "save-to-disk";
  181. break;
  182. default:
  183. break;
  184. }
  185. return mate::ConvertToV8(isolate, disposition);
  186. }
  187. };
  188. template <>
  189. struct Converter<content::SavePageType> {
  190. static bool FromV8(v8::Isolate* isolate,
  191. v8::Local<v8::Value> val,
  192. content::SavePageType* out) {
  193. std::string save_type;
  194. if (!ConvertFromV8(isolate, val, &save_type))
  195. return false;
  196. save_type = base::ToLowerASCII(save_type);
  197. if (save_type == "htmlonly") {
  198. *out = content::SAVE_PAGE_TYPE_AS_ONLY_HTML;
  199. } else if (save_type == "htmlcomplete") {
  200. *out = content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML;
  201. } else if (save_type == "mhtml") {
  202. *out = content::SAVE_PAGE_TYPE_AS_MHTML;
  203. } else {
  204. return false;
  205. }
  206. return true;
  207. }
  208. };
  209. template <>
  210. struct Converter<atom::api::WebContents::Type> {
  211. static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
  212. atom::api::WebContents::Type val) {
  213. using Type = atom::api::WebContents::Type;
  214. std::string type = "";
  215. switch (val) {
  216. case Type::BACKGROUND_PAGE:
  217. type = "backgroundPage";
  218. break;
  219. case Type::BROWSER_WINDOW:
  220. type = "window";
  221. break;
  222. case Type::BROWSER_VIEW:
  223. type = "browserView";
  224. break;
  225. case Type::REMOTE:
  226. type = "remote";
  227. break;
  228. case Type::WEB_VIEW:
  229. type = "webview";
  230. break;
  231. case Type::OFF_SCREEN:
  232. type = "offscreen";
  233. break;
  234. default:
  235. break;
  236. }
  237. return mate::ConvertToV8(isolate, type);
  238. }
  239. static bool FromV8(v8::Isolate* isolate,
  240. v8::Local<v8::Value> val,
  241. atom::api::WebContents::Type* out) {
  242. using Type = atom::api::WebContents::Type;
  243. std::string type;
  244. if (!ConvertFromV8(isolate, val, &type))
  245. return false;
  246. if (type == "backgroundPage") {
  247. *out = Type::BACKGROUND_PAGE;
  248. } else if (type == "browserView") {
  249. *out = Type::BROWSER_VIEW;
  250. } else if (type == "webview") {
  251. *out = Type::WEB_VIEW;
  252. #if defined(ENABLE_OSR)
  253. } else if (type == "offscreen") {
  254. *out = Type::OFF_SCREEN;
  255. #endif
  256. } else {
  257. return false;
  258. }
  259. return true;
  260. }
  261. };
  262. } // namespace mate
  263. namespace atom {
  264. namespace api {
  265. namespace {
  266. content::ServiceWorkerContext* GetServiceWorkerContext(
  267. const content::WebContents* web_contents) {
  268. auto* context = web_contents->GetBrowserContext();
  269. auto* site_instance = web_contents->GetSiteInstance();
  270. if (!context || !site_instance)
  271. return nullptr;
  272. auto* storage_partition =
  273. content::BrowserContext::GetStoragePartition(context, site_instance);
  274. if (!storage_partition)
  275. return nullptr;
  276. return storage_partition->GetServiceWorkerContext();
  277. }
  278. // Called when CapturePage is done.
  279. void OnCapturePageDone(const base::Callback<void(const gfx::Image&)>& callback,
  280. const SkBitmap& bitmap,
  281. content::ReadbackResponse response) {
  282. // Hack to enable transparency in captured image
  283. // TODO(nitsakh) Remove hack once fixed in chromium
  284. const_cast<SkBitmap&>(bitmap).setAlphaType(kPremul_SkAlphaType);
  285. callback.Run(gfx::Image::CreateFrom1xBitmap(bitmap));
  286. }
  287. } // namespace
  288. struct WebContents::FrameDispatchHelper {
  289. WebContents* api_web_contents;
  290. content::RenderFrameHost* rfh;
  291. bool Send(IPC::Message* msg) { return rfh->Send(msg); }
  292. void OnSetTemporaryZoomLevel(double level, IPC::Message* reply_msg) {
  293. api_web_contents->OnSetTemporaryZoomLevel(rfh, level, reply_msg);
  294. }
  295. void OnGetZoomLevel(IPC::Message* reply_msg) {
  296. api_web_contents->OnGetZoomLevel(rfh, reply_msg);
  297. }
  298. void OnRendererMessageSync(const base::string16& channel,
  299. const base::ListValue& args,
  300. IPC::Message* message) {
  301. api_web_contents->OnRendererMessageSync(rfh, channel, args, message);
  302. }
  303. };
  304. WebContents::WebContents(v8::Isolate* isolate,
  305. content::WebContents* web_contents,
  306. Type type)
  307. : content::WebContentsObserver(web_contents), type_(type) {
  308. const mate::Dictionary options = mate::Dictionary::CreateEmpty(isolate);
  309. if (type == REMOTE) {
  310. web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent());
  311. Init(isolate);
  312. AttachAsUserData(web_contents);
  313. InitZoomController(web_contents, options);
  314. } else {
  315. auto session = Session::CreateFrom(isolate, GetBrowserContext());
  316. session_.Reset(isolate, session.ToV8());
  317. InitWithSessionAndOptions(isolate, web_contents, session, options);
  318. }
  319. }
  320. WebContents::WebContents(v8::Isolate* isolate,
  321. const mate::Dictionary& options) {
  322. // Read options.
  323. options.Get("backgroundThrottling", &background_throttling_);
  324. // FIXME(zcbenz): We should read "type" parameter for better design, but
  325. // on Windows we have encountered a compiler bug that if we read "type"
  326. // from |options| and then set |type_|, a memory corruption will happen
  327. // and Electron will soon crash.
  328. // Remvoe this after we upgraded to use VS 2015 Update 3.
  329. bool b = false;
  330. if (options.Get("isGuest", &b) && b)
  331. type_ = WEB_VIEW;
  332. else if (options.Get("isBackgroundPage", &b) && b)
  333. type_ = BACKGROUND_PAGE;
  334. else if (options.Get("isBrowserView", &b) && b)
  335. type_ = BROWSER_VIEW;
  336. #if defined(ENABLE_OSR)
  337. else if (options.Get(options::kOffscreen, &b) && b)
  338. type_ = OFF_SCREEN;
  339. #endif
  340. // Init embedder earlier
  341. options.Get("embedder", &embedder_);
  342. // Whether to enable DevTools.
  343. options.Get("devTools", &enable_devtools_);
  344. // Obtain the session.
  345. std::string partition;
  346. mate::Handle<api::Session> session;
  347. if (options.Get("session", &session) && !session.IsEmpty()) {
  348. } else if (options.Get("partition", &partition)) {
  349. session = Session::FromPartition(isolate, partition);
  350. } else {
  351. // Use the default session if not specified.
  352. session = Session::FromPartition(isolate, "");
  353. }
  354. session_.Reset(isolate, session.ToV8());
  355. content::WebContents* web_contents;
  356. if (IsGuest()) {
  357. scoped_refptr<content::SiteInstance> site_instance =
  358. content::SiteInstance::CreateForURL(session->browser_context(),
  359. GURL("chrome-guest://fake-host"));
  360. content::WebContents::CreateParams params(session->browser_context(),
  361. site_instance);
  362. guest_delegate_.reset(new WebViewGuestDelegate);
  363. params.guest_delegate = guest_delegate_.get();
  364. #if defined(ENABLE_OSR)
  365. if (embedder_ && embedder_->IsOffScreen()) {
  366. auto* view = new OffScreenWebContentsView(
  367. false, base::Bind(&WebContents::OnPaint, base::Unretained(this)));
  368. params.view = view;
  369. params.delegate_view = view;
  370. web_contents = content::WebContents::Create(params);
  371. view->SetWebContents(web_contents);
  372. } else {
  373. #endif
  374. web_contents = content::WebContents::Create(params);
  375. #if defined(ENABLE_OSR)
  376. }
  377. } else if (IsOffScreen()) {
  378. bool transparent = false;
  379. options.Get("transparent", &transparent);
  380. content::WebContents::CreateParams params(session->browser_context());
  381. auto* view = new OffScreenWebContentsView(
  382. transparent, base::Bind(&WebContents::OnPaint, base::Unretained(this)));
  383. params.view = view;
  384. params.delegate_view = view;
  385. web_contents = content::WebContents::Create(params);
  386. view->SetWebContents(web_contents);
  387. #endif
  388. } else {
  389. content::WebContents::CreateParams params(session->browser_context());
  390. web_contents = content::WebContents::Create(params);
  391. }
  392. InitWithSessionAndOptions(isolate, web_contents, session, options);
  393. }
  394. void WebContents::InitZoomController(content::WebContents* web_contents,
  395. const mate::Dictionary& options) {
  396. WebContentsZoomController::CreateForWebContents(web_contents);
  397. zoom_controller_ = WebContentsZoomController::FromWebContents(web_contents);
  398. double zoom_factor;
  399. if (options.Get(options::kZoomFactor, &zoom_factor))
  400. zoom_controller_->SetDefaultZoomFactor(zoom_factor);
  401. }
  402. void WebContents::InitWithSessionAndOptions(v8::Isolate* isolate,
  403. content::WebContents* web_contents,
  404. mate::Handle<api::Session> session,
  405. const mate::Dictionary& options) {
  406. Observe(web_contents);
  407. InitWithWebContents(web_contents, session->browser_context());
  408. managed_web_contents()->GetView()->SetDelegate(this);
  409. auto* prefs = web_contents->GetMutableRendererPrefs();
  410. prefs->accept_languages = g_browser_process->GetApplicationLocale();
  411. #if defined(OS_LINUX) || defined(OS_WIN)
  412. // Update font settings.
  413. CR_DEFINE_STATIC_LOCAL(
  414. const gfx::FontRenderParams, params,
  415. (gfx::GetFontRenderParams(gfx::FontRenderParamsQuery(), nullptr)));
  416. prefs->should_antialias_text = params.antialiasing;
  417. prefs->use_subpixel_positioning = params.subpixel_positioning;
  418. prefs->hinting = params.hinting;
  419. prefs->use_autohinter = params.autohinter;
  420. prefs->use_bitmaps = params.use_bitmaps;
  421. prefs->subpixel_rendering = params.subpixel_rendering;
  422. #endif
  423. // Save the preferences in C++.
  424. new WebContentsPreferences(web_contents, options);
  425. // Initialize permission helper.
  426. WebContentsPermissionHelper::CreateForWebContents(web_contents);
  427. // Initialize security state client.
  428. SecurityStateTabHelper::CreateForWebContents(web_contents);
  429. // Initialize zoom controller.
  430. InitZoomController(web_contents, options);
  431. web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent());
  432. if (IsGuest()) {
  433. guest_delegate_->Initialize(this);
  434. NativeWindow* owner_window = nullptr;
  435. if (embedder_) {
  436. // New WebContents's owner_window is the embedder's owner_window.
  437. auto* relay =
  438. NativeWindowRelay::FromWebContents(embedder_->web_contents());
  439. if (relay)
  440. owner_window = relay->window.get();
  441. }
  442. if (owner_window)
  443. SetOwnerWindow(owner_window);
  444. }
  445. Init(isolate);
  446. AttachAsUserData(web_contents);
  447. }
  448. WebContents::~WebContents() {
  449. // The destroy() is called.
  450. if (managed_web_contents()) {
  451. managed_web_contents()->GetView()->SetDelegate(nullptr);
  452. // For webview we need to tell content module to do some cleanup work before
  453. // destroying it.
  454. if (type_ == WEB_VIEW)
  455. guest_delegate_->Destroy();
  456. RenderViewDeleted(web_contents()->GetRenderViewHost());
  457. if (type_ == WEB_VIEW) {
  458. DestroyWebContents(false /* async */);
  459. } else {
  460. if (type_ == BROWSER_WINDOW && owner_window()) {
  461. for (ExtendedWebContentsObserver& observer : observers_)
  462. observer.OnCloseContents();
  463. } else {
  464. DestroyWebContents(true /* async */);
  465. }
  466. // The WebContentsDestroyed will not be called automatically because we
  467. // destroy the webContents in the next tick. So we have to manually
  468. // call it here to make sure "destroyed" event is emitted.
  469. WebContentsDestroyed();
  470. }
  471. }
  472. }
  473. void WebContents::DestroyWebContents(bool async) {
  474. // This event is only for internal use, which is emitted when WebContents is
  475. // being destroyed.
  476. Emit("will-destroy");
  477. ResetManagedWebContents(async);
  478. }
  479. bool WebContents::DidAddMessageToConsole(content::WebContents* source,
  480. int32_t level,
  481. const base::string16& message,
  482. int32_t line_no,
  483. const base::string16& source_id) {
  484. return Emit("console-message", level, message, line_no, source_id);
  485. }
  486. void WebContents::OnCreateWindow(
  487. const GURL& target_url,
  488. const content::Referrer& referrer,
  489. const std::string& frame_name,
  490. WindowOpenDisposition disposition,
  491. const std::vector<std::string>& features,
  492. const scoped_refptr<content::ResourceRequestBody>& body) {
  493. if (type_ == BROWSER_WINDOW || type_ == OFF_SCREEN)
  494. Emit("-new-window", target_url, frame_name, disposition, features, body,
  495. referrer);
  496. else
  497. Emit("new-window", target_url, frame_name, disposition, features);
  498. }
  499. void WebContents::WebContentsCreated(content::WebContents* source_contents,
  500. int opener_render_process_id,
  501. int opener_render_frame_id,
  502. const std::string& frame_name,
  503. const GURL& target_url,
  504. content::WebContents* new_contents) {
  505. v8::Locker locker(isolate());
  506. v8::HandleScope handle_scope(isolate());
  507. auto api_web_contents = CreateFrom(isolate(), new_contents, BROWSER_WINDOW);
  508. Emit("-web-contents-created", api_web_contents, target_url, frame_name);
  509. }
  510. void WebContents::AddNewContents(content::WebContents* source,
  511. content::WebContents* new_contents,
  512. WindowOpenDisposition disposition,
  513. const gfx::Rect& initial_rect,
  514. bool user_gesture,
  515. bool* was_blocked) {
  516. new ChildWebContentsTracker(new_contents);
  517. v8::Locker locker(isolate());
  518. v8::HandleScope handle_scope(isolate());
  519. auto api_web_contents = CreateFrom(isolate(), new_contents);
  520. if (Emit("-add-new-contents", api_web_contents, disposition, user_gesture,
  521. initial_rect.x(), initial_rect.y(), initial_rect.width(),
  522. initial_rect.height())) {
  523. api_web_contents->DestroyWebContents(true /* async */);
  524. }
  525. }
  526. content::WebContents* WebContents::OpenURLFromTab(
  527. content::WebContents* source,
  528. const content::OpenURLParams& params) {
  529. if (params.disposition != WindowOpenDisposition::CURRENT_TAB) {
  530. if (type_ == BROWSER_WINDOW || type_ == OFF_SCREEN)
  531. Emit("-new-window", params.url, "", params.disposition);
  532. else
  533. Emit("new-window", params.url, "", params.disposition);
  534. return nullptr;
  535. }
  536. // Give user a chance to cancel navigation.
  537. if (Emit("will-navigate", params.url))
  538. return nullptr;
  539. // Don't load the URL if the web contents was marked as destroyed from a
  540. // will-navigate event listener
  541. if (IsDestroyed())
  542. return nullptr;
  543. return CommonWebContentsDelegate::OpenURLFromTab(source, params);
  544. }
  545. void WebContents::BeforeUnloadFired(content::WebContents* tab,
  546. bool proceed,
  547. bool* proceed_to_fire_unload) {
  548. if (type_ == BROWSER_WINDOW || type_ == OFF_SCREEN)
  549. *proceed_to_fire_unload = proceed;
  550. else
  551. *proceed_to_fire_unload = true;
  552. }
  553. void WebContents::MoveContents(content::WebContents* source,
  554. const gfx::Rect& pos) {
  555. Emit("move", pos);
  556. }
  557. void WebContents::CloseContents(content::WebContents* source) {
  558. Emit("close");
  559. #if defined(TOOLKIT_VIEWS) && !defined(OS_MACOSX)
  560. HideAutofillPopup();
  561. #endif
  562. if (managed_web_contents())
  563. managed_web_contents()->GetView()->SetDelegate(nullptr);
  564. for (ExtendedWebContentsObserver& observer : observers_)
  565. observer.OnCloseContents();
  566. }
  567. void WebContents::ActivateContents(content::WebContents* source) {
  568. Emit("activate");
  569. }
  570. void WebContents::UpdateTargetURL(content::WebContents* source,
  571. const GURL& url) {
  572. Emit("update-target-url", url);
  573. }
  574. bool WebContents::IsPopupOrPanel(const content::WebContents* source) const {
  575. return type_ == BROWSER_WINDOW;
  576. }
  577. void WebContents::HandleKeyboardEvent(
  578. content::WebContents* source,
  579. const content::NativeWebKeyboardEvent& event) {
  580. if (type_ == WEB_VIEW && embedder_) {
  581. // Send the unhandled keyboard events back to the embedder.
  582. embedder_->HandleKeyboardEvent(source, event);
  583. } else {
  584. // Go to the default keyboard handling.
  585. CommonWebContentsDelegate::HandleKeyboardEvent(source, event);
  586. }
  587. }
  588. content::KeyboardEventProcessingResult WebContents::PreHandleKeyboardEvent(
  589. content::WebContents* source,
  590. const content::NativeWebKeyboardEvent& event) {
  591. if (event.GetType() == blink::WebInputEvent::Type::kRawKeyDown ||
  592. event.GetType() == blink::WebInputEvent::Type::kKeyUp) {
  593. bool prevent_default = Emit("before-input-event", event);
  594. if (prevent_default) {
  595. return content::KeyboardEventProcessingResult::HANDLED;
  596. }
  597. }
  598. return content::KeyboardEventProcessingResult::NOT_HANDLED;
  599. }
  600. void WebContents::EnterFullscreenModeForTab(content::WebContents* source,
  601. const GURL& origin) {
  602. auto* permission_helper =
  603. WebContentsPermissionHelper::FromWebContents(source);
  604. auto callback = base::Bind(&WebContents::OnEnterFullscreenModeForTab,
  605. base::Unretained(this), source, origin);
  606. permission_helper->RequestFullscreenPermission(callback);
  607. }
  608. void WebContents::OnEnterFullscreenModeForTab(content::WebContents* source,
  609. const GURL& origin,
  610. bool allowed) {
  611. if (!allowed)
  612. return;
  613. CommonWebContentsDelegate::EnterFullscreenModeForTab(source, origin);
  614. Emit("enter-html-full-screen");
  615. }
  616. void WebContents::ExitFullscreenModeForTab(content::WebContents* source) {
  617. CommonWebContentsDelegate::ExitFullscreenModeForTab(source);
  618. Emit("leave-html-full-screen");
  619. }
  620. void WebContents::RendererUnresponsive(
  621. content::WebContents* source,
  622. const content::WebContentsUnresponsiveState& unresponsive_state) {
  623. Emit("unresponsive");
  624. }
  625. void WebContents::RendererResponsive(content::WebContents* source) {
  626. Emit("responsive");
  627. for (ExtendedWebContentsObserver& observer : observers_)
  628. observer.OnRendererResponsive();
  629. }
  630. bool WebContents::HandleContextMenu(const content::ContextMenuParams& params) {
  631. if (params.custom_context.is_pepper_menu) {
  632. Emit("pepper-context-menu", std::make_pair(params, web_contents()),
  633. base::Bind(&content::WebContents::NotifyContextMenuClosed,
  634. base::Unretained(web_contents()), params.custom_context));
  635. } else {
  636. Emit("context-menu", std::make_pair(params, web_contents()));
  637. }
  638. return true;
  639. }
  640. bool WebContents::OnGoToEntryOffset(int offset) {
  641. GoToOffset(offset);
  642. return false;
  643. }
  644. void WebContents::FindReply(content::WebContents* web_contents,
  645. int request_id,
  646. int number_of_matches,
  647. const gfx::Rect& selection_rect,
  648. int active_match_ordinal,
  649. bool final_update) {
  650. if (!final_update)
  651. return;
  652. v8::Locker locker(isolate());
  653. v8::HandleScope handle_scope(isolate());
  654. mate::Dictionary result = mate::Dictionary::CreateEmpty(isolate());
  655. result.Set("requestId", request_id);
  656. result.Set("matches", number_of_matches);
  657. result.Set("selectionArea", selection_rect);
  658. result.Set("activeMatchOrdinal", active_match_ordinal);
  659. result.Set("finalUpdate", final_update); // Deprecate after 2.0
  660. Emit("found-in-page", result);
  661. }
  662. bool WebContents::CheckMediaAccessPermission(content::WebContents* web_contents,
  663. const GURL& security_origin,
  664. content::MediaStreamType type) {
  665. return true;
  666. }
  667. void WebContents::RequestMediaAccessPermission(
  668. content::WebContents* web_contents,
  669. const content::MediaStreamRequest& request,
  670. const content::MediaResponseCallback& callback) {
  671. auto* permission_helper =
  672. WebContentsPermissionHelper::FromWebContents(web_contents);
  673. permission_helper->RequestMediaAccessPermission(request, callback);
  674. }
  675. void WebContents::RequestToLockMouse(content::WebContents* web_contents,
  676. bool user_gesture,
  677. bool last_unlocked_by_target) {
  678. auto* permission_helper =
  679. WebContentsPermissionHelper::FromWebContents(web_contents);
  680. permission_helper->RequestPointerLockPermission(user_gesture);
  681. }
  682. std::unique_ptr<content::BluetoothChooser> WebContents::RunBluetoothChooser(
  683. content::RenderFrameHost* frame,
  684. const content::BluetoothChooser::EventHandler& event_handler) {
  685. std::unique_ptr<BluetoothChooser> bluetooth_chooser(
  686. new BluetoothChooser(this, event_handler));
  687. return std::move(bluetooth_chooser);
  688. }
  689. content::JavaScriptDialogManager* WebContents::GetJavaScriptDialogManager(
  690. content::WebContents* source) {
  691. if (!dialog_manager_)
  692. dialog_manager_.reset(new AtomJavaScriptDialogManager(this));
  693. return dialog_manager_.get();
  694. }
  695. void WebContents::BeforeUnloadFired(const base::TimeTicks& proceed_time) {
  696. // Do nothing, we override this method just to avoid compilation error since
  697. // there are two virtual functions named BeforeUnloadFired.
  698. }
  699. void WebContents::RenderViewCreated(content::RenderViewHost* render_view_host) {
  700. auto* const impl = content::RenderWidgetHostImpl::FromID(
  701. render_view_host->GetProcess()->GetID(),
  702. render_view_host->GetRoutingID());
  703. if (impl)
  704. impl->disable_hidden_ = !background_throttling_;
  705. }
  706. void WebContents::RenderViewDeleted(content::RenderViewHost* render_view_host) {
  707. Emit("render-view-deleted", render_view_host->GetProcess()->GetID());
  708. }
  709. void WebContents::RenderProcessGone(base::TerminationStatus status) {
  710. Emit("crashed", status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED);
  711. }
  712. void WebContents::PluginCrashed(const base::FilePath& plugin_path,
  713. base::ProcessId plugin_pid) {
  714. content::WebPluginInfo info;
  715. auto* plugin_service = content::PluginService::GetInstance();
  716. plugin_service->GetPluginInfoByPath(plugin_path, &info);
  717. Emit("plugin-crashed", info.name, info.version);
  718. }
  719. void WebContents::MediaStartedPlaying(const MediaPlayerInfo& video_type,
  720. const MediaPlayerId& id) {
  721. Emit("media-started-playing");
  722. }
  723. void WebContents::MediaStoppedPlaying(const MediaPlayerInfo& video_type,
  724. const MediaPlayerId& id) {
  725. Emit("media-paused");
  726. }
  727. void WebContents::DidChangeThemeColor(SkColor theme_color) {
  728. if (theme_color != SK_ColorTRANSPARENT) {
  729. Emit("did-change-theme-color", atom::ToRGBHex(theme_color));
  730. } else {
  731. Emit("did-change-theme-color", nullptr);
  732. }
  733. }
  734. void WebContents::DocumentLoadedInFrame(
  735. content::RenderFrameHost* render_frame_host) {
  736. if (!render_frame_host->GetParent())
  737. Emit("dom-ready");
  738. }
  739. void WebContents::DidFinishLoad(content::RenderFrameHost* render_frame_host,
  740. const GURL& validated_url) {
  741. bool is_main_frame = !render_frame_host->GetParent();
  742. int frame_process_id = render_frame_host->GetProcess()->GetID();
  743. int frame_routing_id = render_frame_host->GetRoutingID();
  744. Emit("did-frame-finish-load", is_main_frame, frame_process_id,
  745. frame_routing_id);
  746. if (is_main_frame)
  747. Emit("did-finish-load");
  748. }
  749. void WebContents::DidFailLoad(content::RenderFrameHost* render_frame_host,
  750. const GURL& url,
  751. int error_code,
  752. const base::string16& error_description) {
  753. bool is_main_frame = !render_frame_host->GetParent();
  754. int frame_process_id = render_frame_host->GetProcess()->GetID();
  755. int frame_routing_id = render_frame_host->GetRoutingID();
  756. Emit("did-fail-load", error_code, error_description, url, is_main_frame,
  757. frame_process_id, frame_routing_id);
  758. }
  759. void WebContents::DidStartLoading() {
  760. Emit("did-start-loading");
  761. }
  762. void WebContents::DidStopLoading() {
  763. Emit("did-stop-loading");
  764. }
  765. void WebContents::DidGetResourceResponseStart(
  766. const content::ResourceRequestDetails& details) {
  767. // Plznavigate is using blob URLs to deliver the body
  768. // of the main resource to the renderer process. This
  769. // gets better in the future with kNavigationMojoResponse
  770. // feature, which replaces this mechanism with Mojo Datapipe.
  771. if (details.url.SchemeIsBlob() &&
  772. (details.resource_type == content::RESOURCE_TYPE_MAIN_FRAME ||
  773. details.resource_type == content::RESOURCE_TYPE_SUB_FRAME))
  774. return;
  775. Emit("-did-get-response-details", details.socket_address.IsEmpty(),
  776. details.url, details.original_url, details.http_response_code,
  777. details.method, details.referrer, details.headers.get(),
  778. ResourceTypeToString(details.resource_type));
  779. }
  780. void WebContents::DidGetRedirectForResourceRequest(
  781. const content::ResourceRedirectDetails& details) {
  782. Emit("-did-get-redirect-request", details.url, details.new_url,
  783. (details.resource_type == content::RESOURCE_TYPE_MAIN_FRAME),
  784. details.http_response_code, details.method, details.referrer,
  785. details.headers.get());
  786. }
  787. void WebContents::DidStartNavigation(
  788. content::NavigationHandle* navigation_handle) {
  789. bool is_main_frame = navigation_handle->IsInMainFrame();
  790. int frame_tree_node_id = navigation_handle->GetFrameTreeNodeId();
  791. content::FrameTreeNode* frame_tree_node =
  792. content::FrameTreeNode::GloballyFindByID(frame_tree_node_id);
  793. content::RenderFrameHostManager* render_manager =
  794. frame_tree_node->render_manager();
  795. content::RenderFrameHost* frame_host = nullptr;
  796. if (render_manager) {
  797. frame_host = render_manager->speculative_frame_host();
  798. if (!frame_host)
  799. frame_host = render_manager->current_frame_host();
  800. }
  801. int frame_process_id = -1, frame_routing_id = -1;
  802. if (frame_host) {
  803. frame_process_id = frame_host->GetProcess()->GetID();
  804. frame_routing_id = frame_host->GetRoutingID();
  805. }
  806. bool is_same_document = navigation_handle->IsSameDocument();
  807. auto url = navigation_handle->GetURL();
  808. Emit("did-start-navigation", url, is_same_document, is_main_frame,
  809. frame_process_id, frame_routing_id);
  810. }
  811. void WebContents::DidFinishNavigation(
  812. content::NavigationHandle* navigation_handle) {
  813. if (!navigation_handle->HasCommitted())
  814. return;
  815. bool is_main_frame = navigation_handle->IsInMainFrame();
  816. content::RenderFrameHost* frame_host =
  817. navigation_handle->GetRenderFrameHost();
  818. int frame_process_id = -1, frame_routing_id = -1;
  819. if (frame_host) {
  820. frame_process_id = frame_host->GetProcess()->GetID();
  821. frame_routing_id = frame_host->GetRoutingID();
  822. }
  823. if (!navigation_handle->IsErrorPage()) {
  824. auto url = navigation_handle->GetURL();
  825. bool is_same_document = navigation_handle->IsSameDocument();
  826. if (is_same_document) {
  827. Emit("did-navigate-in-page", url, is_main_frame, frame_process_id,
  828. frame_routing_id);
  829. } else {
  830. const net::HttpResponseHeaders* http_response =
  831. navigation_handle->GetResponseHeaders();
  832. std::string http_status_text;
  833. int http_response_code = -1;
  834. if (http_response) {
  835. http_status_text = http_response->GetStatusText();
  836. http_response_code = http_response->response_code();
  837. }
  838. Emit("did-frame-navigate", url, http_response_code, http_status_text,
  839. is_main_frame, frame_process_id, frame_routing_id);
  840. if (is_main_frame) {
  841. Emit("did-navigate", url, http_response_code, http_status_text);
  842. }
  843. }
  844. } else {
  845. auto url = navigation_handle->GetURL();
  846. int code = navigation_handle->GetNetErrorCode();
  847. auto description = net::ErrorToShortString(code);
  848. Emit("did-fail-provisional-load", code, description, url, is_main_frame,
  849. frame_process_id, frame_routing_id);
  850. // Do not emit "did-fail-load" for canceled requests.
  851. if (code != net::ERR_ABORTED)
  852. Emit("did-fail-load", code, description, url, is_main_frame,
  853. frame_process_id, frame_routing_id);
  854. }
  855. }
  856. void WebContents::TitleWasSet(content::NavigationEntry* entry) {
  857. base::string16 final_title;
  858. bool explicit_set = true;
  859. if (entry) {
  860. auto title = entry->GetTitle();
  861. auto url = entry->GetURL();
  862. if (url.SchemeIsFile() && title.empty()) {
  863. final_title = base::UTF8ToUTF16(url.ExtractFileName());
  864. explicit_set = false;
  865. } else {
  866. final_title = title;
  867. }
  868. }
  869. Emit("page-title-updated", final_title, explicit_set);
  870. }
  871. void WebContents::DidUpdateFaviconURL(
  872. const std::vector<content::FaviconURL>& urls) {
  873. std::set<GURL> unique_urls;
  874. for (const auto& iter : urls) {
  875. if (iter.icon_type != content::FaviconURL::IconType::kFavicon)
  876. continue;
  877. const GURL& url = iter.icon_url;
  878. if (url.is_valid())
  879. unique_urls.insert(url);
  880. }
  881. Emit("page-favicon-updated", unique_urls);
  882. }
  883. void WebContents::DevToolsReloadPage() {
  884. Emit("devtools-reload-page");
  885. }
  886. void WebContents::DevToolsFocused() {
  887. Emit("devtools-focused");
  888. }
  889. void WebContents::DevToolsOpened() {
  890. v8::Locker locker(isolate());
  891. v8::HandleScope handle_scope(isolate());
  892. auto handle = WebContents::CreateFrom(
  893. isolate(), managed_web_contents()->GetDevToolsWebContents());
  894. devtools_web_contents_.Reset(isolate(), handle.ToV8());
  895. // Set inspected tabID.
  896. base::Value tab_id(ID());
  897. managed_web_contents()->CallClientFunction("DevToolsAPI.setInspectedTabId",
  898. &tab_id, nullptr, nullptr);
  899. // Inherit owner window in devtools when it doesn't have one.
  900. auto* devtools = managed_web_contents()->GetDevToolsWebContents();
  901. bool has_window = devtools->GetUserData(NativeWindowRelay::UserDataKey());
  902. if (owner_window() && !has_window)
  903. handle->SetOwnerWindow(devtools, owner_window());
  904. Emit("devtools-opened");
  905. }
  906. void WebContents::DevToolsClosed() {
  907. v8::Locker locker(isolate());
  908. v8::HandleScope handle_scope(isolate());
  909. devtools_web_contents_.Reset();
  910. Emit("devtools-closed");
  911. }
  912. #if defined(TOOLKIT_VIEWS) && !defined(OS_MACOSX)
  913. void WebContents::ShowAutofillPopup(content::RenderFrameHost* frame_host,
  914. const gfx::RectF& bounds,
  915. const std::vector<base::string16>& values,
  916. const std::vector<base::string16>& labels) {
  917. bool offscreen = IsOffScreen() || (embedder_ && embedder_->IsOffScreen());
  918. CommonWebContentsDelegate::ShowAutofillPopup(offscreen, frame_host, bounds,
  919. values, labels);
  920. }
  921. #endif
  922. bool WebContents::OnMessageReceived(const IPC::Message& message) {
  923. bool handled = true;
  924. IPC_BEGIN_MESSAGE_MAP(WebContents, message)
  925. IPC_MESSAGE_HANDLER_CODE(ViewHostMsg_SetCursor, OnCursorChange,
  926. handled = false)
  927. IPC_MESSAGE_UNHANDLED(handled = false)
  928. IPC_END_MESSAGE_MAP()
  929. return handled;
  930. }
  931. bool WebContents::OnMessageReceived(const IPC::Message& message,
  932. content::RenderFrameHost* frame_host) {
  933. bool handled = true;
  934. FrameDispatchHelper helper = {this, frame_host};
  935. IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(WebContents, message, frame_host)
  936. IPC_MESSAGE_HANDLER(AtomFrameHostMsg_Message, OnRendererMessage)
  937. IPC_MESSAGE_FORWARD_DELAY_REPLY(AtomFrameHostMsg_Message_Sync, &helper,
  938. FrameDispatchHelper::OnRendererMessageSync)
  939. IPC_MESSAGE_FORWARD_DELAY_REPLY(
  940. AtomFrameHostMsg_SetTemporaryZoomLevel, &helper,
  941. FrameDispatchHelper::OnSetTemporaryZoomLevel)
  942. IPC_MESSAGE_FORWARD_DELAY_REPLY(AtomFrameHostMsg_GetZoomLevel, &helper,
  943. FrameDispatchHelper::OnGetZoomLevel)
  944. #if defined(TOOLKIT_VIEWS) && !defined(OS_MACOSX)
  945. IPC_MESSAGE_HANDLER(AtomAutofillFrameHostMsg_ShowPopup, ShowAutofillPopup)
  946. IPC_MESSAGE_HANDLER(AtomAutofillFrameHostMsg_HidePopup, HideAutofillPopup)
  947. #endif
  948. IPC_MESSAGE_UNHANDLED(handled = false)
  949. IPC_END_MESSAGE_MAP()
  950. return handled;
  951. }
  952. // There are three ways of destroying a webContents:
  953. // 1. call webContents.destroy();
  954. // 2. garbage collection;
  955. // 3. user closes the window of webContents;
  956. // For webview only #1 will happen, for BrowserWindow both #1 and #3 may
  957. // happen. The #2 should never happen for webContents, because webview is
  958. // managed by GuestViewManager, and BrowserWindow's webContents is managed
  959. // by api::BrowserWindow.
  960. // For #1, the destructor will do the cleanup work and we only need to make
  961. // sure "destroyed" event is emitted. For #3, the content::WebContents will
  962. // be destroyed on close, and WebContentsDestroyed would be called for it, so
  963. // we need to make sure the api::WebContents is also deleted.
  964. void WebContents::WebContentsDestroyed() {
  965. // Cleanup relationships with other parts.
  966. RemoveFromWeakMap();
  967. // We can not call Destroy here because we need to call Emit first, but we
  968. // also do not want any method to be used, so just mark as destroyed here.
  969. MarkDestroyed();
  970. Emit("destroyed");
  971. // Destroy the native class in next tick.
  972. base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, GetDestroyClosure());
  973. }
  974. void WebContents::NavigationEntryCommitted(
  975. const content::LoadCommittedDetails& details) {
  976. Emit("navigation-entry-commited", details.entry->GetURL(),
  977. details.is_same_document, details.did_replace_entry);
  978. }
  979. int64_t WebContents::GetIDForContents(content::WebContents* web_contents) {
  980. int64_t process_id = web_contents->GetMainFrame()->GetProcess()->GetID();
  981. int64_t routing_id = web_contents->GetMainFrame()->GetRoutingID();
  982. int64_t rv = (process_id << 32) + routing_id;
  983. return rv;
  984. }
  985. int64_t WebContents::GetID() const {
  986. return WebContents::GetIDForContents(web_contents());
  987. }
  988. int WebContents::GetProcessID() const {
  989. return web_contents()->GetMainFrame()->GetProcess()->GetID();
  990. }
  991. base::ProcessId WebContents::GetOSProcessID() const {
  992. auto process_handle =
  993. web_contents()->GetMainFrame()->GetProcess()->GetHandle();
  994. return base::GetProcId(process_handle);
  995. }
  996. WebContents::Type WebContents::GetType() const {
  997. return type_;
  998. }
  999. bool WebContents::Equal(const WebContents* web_contents) const {
  1000. return GetID() == web_contents->GetID();
  1001. }
  1002. void WebContents::LoadURL(const GURL& url, const mate::Dictionary& options) {
  1003. if (!url.is_valid() || url.spec().size() > url::kMaxURLChars) {
  1004. Emit("did-fail-load", static_cast<int>(net::ERR_INVALID_URL),
  1005. net::ErrorToShortString(net::ERR_INVALID_URL),
  1006. url.possibly_invalid_spec(), true);
  1007. return;
  1008. }
  1009. if (guest_delegate_ && !guest_delegate_->IsAttached()) {
  1010. return;
  1011. }
  1012. content::NavigationController::LoadURLParams params(url);
  1013. if (!options.Get("httpReferrer", &params.referrer)) {
  1014. GURL http_referrer;
  1015. if (options.Get("httpReferrer", &http_referrer))
  1016. params.referrer = content::Referrer(http_referrer.GetAsReferrer(),
  1017. blink::kWebReferrerPolicyDefault);
  1018. }
  1019. std::string user_agent;
  1020. if (options.Get("userAgent", &user_agent))
  1021. web_contents()->SetUserAgentOverride(user_agent);
  1022. std::string extra_headers;
  1023. if (options.Get("extraHeaders", &extra_headers))
  1024. params.extra_headers = extra_headers;
  1025. scoped_refptr<content::ResourceRequestBody> body;
  1026. if (options.Get("postData", &body)) {
  1027. params.post_data = body;
  1028. params.load_type = content::NavigationController::LOAD_TYPE_HTTP_POST;
  1029. }
  1030. GURL base_url_for_data_url;
  1031. if (options.Get("baseURLForDataURL", &base_url_for_data_url)) {
  1032. params.base_url_for_data_url = base_url_for_data_url;
  1033. params.load_type = content::NavigationController::LOAD_TYPE_DATA;
  1034. }
  1035. params.transition_type = ui::PAGE_TRANSITION_TYPED;
  1036. params.should_clear_history_list = true;
  1037. params.override_user_agent = content::NavigationController::UA_OVERRIDE_TRUE;
  1038. web_contents()->GetController().LoadURLWithParams(params);
  1039. // Set the background color of RenderWidgetHostView.
  1040. // We have to call it right after LoadURL because the RenderViewHost is only
  1041. // created after loading a page.
  1042. auto* const view = web_contents()->GetRenderWidgetHostView();
  1043. if (view) {
  1044. auto* web_preferences = WebContentsPreferences::From(web_contents());
  1045. std::string color_name;
  1046. if (web_preferences->dict()->GetString(options::kBackgroundColor,
  1047. &color_name)) {
  1048. view->SetBackgroundColor(ParseHexColor(color_name));
  1049. } else {
  1050. view->SetBackgroundColor(SK_ColorTRANSPARENT);
  1051. }
  1052. }
  1053. }
  1054. void WebContents::DownloadURL(const GURL& url) {
  1055. auto* browser_context = web_contents()->GetBrowserContext();
  1056. auto* download_manager =
  1057. content::BrowserContext::GetDownloadManager(browser_context);
  1058. download_manager->DownloadUrl(
  1059. content::DownloadUrlParameters::CreateForWebContentsMainFrame(
  1060. web_contents(), url, NO_TRAFFIC_ANNOTATION_YET));
  1061. }
  1062. GURL WebContents::GetURL() const {
  1063. return web_contents()->GetURL();
  1064. }
  1065. base::string16 WebContents::GetTitle() const {
  1066. return web_contents()->GetTitle();
  1067. }
  1068. bool WebContents::IsLoading() const {
  1069. return web_contents()->IsLoading();
  1070. }
  1071. bool WebContents::IsLoadingMainFrame() const {
  1072. return web_contents()->IsLoadingToDifferentDocument();
  1073. }
  1074. bool WebContents::IsWaitingForResponse() const {
  1075. return web_contents()->IsWaitingForResponse();
  1076. }
  1077. void WebContents::Stop() {
  1078. web_contents()->Stop();
  1079. }
  1080. void WebContents::GoBack() {
  1081. atom::AtomBrowserClient::SuppressRendererProcessRestartForOnce();
  1082. web_contents()->GetController().GoBack();
  1083. }
  1084. void WebContents::GoForward() {
  1085. atom::AtomBrowserClient::SuppressRendererProcessRestartForOnce();
  1086. web_contents()->GetController().GoForward();
  1087. }
  1088. void WebContents::GoToOffset(int offset) {
  1089. atom::AtomBrowserClient::SuppressRendererProcessRestartForOnce();
  1090. web_contents()->GetController().GoToOffset(offset);
  1091. }
  1092. const std::string WebContents::GetWebRTCIPHandlingPolicy() const {
  1093. return web_contents()->GetMutableRendererPrefs()->webrtc_ip_handling_policy;
  1094. }
  1095. void WebContents::SetWebRTCIPHandlingPolicy(
  1096. const std::string& webrtc_ip_handling_policy) {
  1097. if (GetWebRTCIPHandlingPolicy() == webrtc_ip_handling_policy)
  1098. return;
  1099. web_contents()->GetMutableRendererPrefs()->webrtc_ip_handling_policy =
  1100. webrtc_ip_handling_policy;
  1101. content::RenderViewHost* host = web_contents()->GetRenderViewHost();
  1102. if (host)
  1103. host->SyncRendererPrefs();
  1104. }
  1105. bool WebContents::IsCrashed() const {
  1106. return web_contents()->IsCrashed();
  1107. }
  1108. void WebContents::SetUserAgent(const std::string& user_agent,
  1109. mate::Arguments* args) {
  1110. web_contents()->SetUserAgentOverride(user_agent);
  1111. }
  1112. std::string WebContents::GetUserAgent() {
  1113. return web_contents()->GetUserAgentOverride();
  1114. }
  1115. bool WebContents::SavePage(const base::FilePath& full_file_path,
  1116. const content::SavePageType& save_type,
  1117. const SavePageHandler::SavePageCallback& callback) {
  1118. auto* handler = new SavePageHandler(web_contents(), callback);
  1119. return handler->Handle(full_file_path, save_type);
  1120. }
  1121. void WebContents::OpenDevTools(mate::Arguments* args) {
  1122. if (type_ == REMOTE)
  1123. return;
  1124. if (!enable_devtools_)
  1125. return;
  1126. std::string state;
  1127. if (type_ == WEB_VIEW || !owner_window()) {
  1128. state = "detach";
  1129. }
  1130. if (args && args->Length() == 1) {
  1131. mate::Dictionary options;
  1132. if (args->GetNext(&options)) {
  1133. options.Get("mode", &state);
  1134. }
  1135. }
  1136. managed_web_contents()->SetDockState(state);
  1137. managed_web_contents()->ShowDevTools();
  1138. }
  1139. void WebContents::CloseDevTools() {
  1140. if (type_ == REMOTE)
  1141. return;
  1142. managed_web_contents()->CloseDevTools();
  1143. }
  1144. bool WebContents::IsDevToolsOpened() {
  1145. if (type_ == REMOTE)
  1146. return false;
  1147. return managed_web_contents()->IsDevToolsViewShowing();
  1148. }
  1149. bool WebContents::IsDevToolsFocused() {
  1150. if (type_ == REMOTE)
  1151. return false;
  1152. return managed_web_contents()->GetView()->IsDevToolsViewFocused();
  1153. }
  1154. void WebContents::EnableDeviceEmulation(
  1155. const blink::WebDeviceEmulationParams& params) {
  1156. if (type_ == REMOTE)
  1157. return;
  1158. auto* frame_host = web_contents()->GetMainFrame();
  1159. if (frame_host) {
  1160. auto* widget_host =
  1161. frame_host ? frame_host->GetView()->GetRenderWidgetHost() : nullptr;
  1162. if (!widget_host)
  1163. return;
  1164. widget_host->Send(
  1165. new ViewMsg_EnableDeviceEmulation(widget_host->GetRoutingID(), params));
  1166. }
  1167. }
  1168. void WebContents::DisableDeviceEmulation() {
  1169. if (type_ == REMOTE)
  1170. return;
  1171. auto* frame_host = web_contents()->GetMainFrame();
  1172. if (frame_host) {
  1173. auto* widget_host =
  1174. frame_host ? frame_host->GetView()->GetRenderWidgetHost() : nullptr;
  1175. if (!widget_host)
  1176. return;
  1177. widget_host->Send(
  1178. new ViewMsg_DisableDeviceEmulation(widget_host->GetRoutingID()));
  1179. }
  1180. }
  1181. void WebContents::ToggleDevTools() {
  1182. if (IsDevToolsOpened())
  1183. CloseDevTools();
  1184. else
  1185. OpenDevTools(nullptr);
  1186. }
  1187. void WebContents::InspectElement(int x, int y) {
  1188. if (type_ == REMOTE)
  1189. return;
  1190. if (!enable_devtools_)
  1191. return;
  1192. if (!managed_web_contents()->GetDevToolsWebContents())
  1193. OpenDevTools(nullptr);
  1194. managed_web_contents()->InspectElement(x, y);
  1195. }
  1196. void WebContents::InspectServiceWorker() {
  1197. if (type_ == REMOTE)
  1198. return;
  1199. if (!enable_devtools_)
  1200. return;
  1201. for (const auto& agent_host : content::DevToolsAgentHost::GetOrCreateAll()) {
  1202. if (agent_host->GetType() ==
  1203. content::DevToolsAgentHost::kTypeServiceWorker) {
  1204. OpenDevTools(nullptr);
  1205. managed_web_contents()->AttachTo(agent_host);
  1206. break;
  1207. }
  1208. }
  1209. }
  1210. void WebContents::HasServiceWorker(const base::Callback<void(bool)>& callback) {
  1211. auto* context = GetServiceWorkerContext(web_contents());
  1212. if (!context)
  1213. return;
  1214. struct WrappedCallback {
  1215. base::Callback<void(bool)> callback_;
  1216. explicit WrappedCallback(const base::Callback<void(bool)>& callback)
  1217. : callback_(callback) {}
  1218. void Run(content::ServiceWorkerCapability capability) {
  1219. callback_.Run(capability !=
  1220. content::ServiceWorkerCapability::NO_SERVICE_WORKER);
  1221. delete this;
  1222. }
  1223. };
  1224. auto* wrapped_callback = new WrappedCallback(callback);
  1225. context->CheckHasServiceWorker(
  1226. web_contents()->GetLastCommittedURL(), GURL::EmptyGURL(),
  1227. base::BindOnce(&WrappedCallback::Run,
  1228. base::Unretained(wrapped_callback)));
  1229. }
  1230. void WebContents::UnregisterServiceWorker(
  1231. const base::Callback<void(bool)>& callback) {
  1232. auto* context = GetServiceWorkerContext(web_contents());
  1233. if (!context)
  1234. return;
  1235. context->UnregisterServiceWorker(web_contents()->GetLastCommittedURL(),
  1236. callback);
  1237. }
  1238. void WebContents::SetIgnoreMenuShortcuts(bool ignore) {
  1239. set_ignore_menu_shortcuts(ignore);
  1240. }
  1241. void WebContents::SetAudioMuted(bool muted) {
  1242. web_contents()->SetAudioMuted(muted);
  1243. }
  1244. bool WebContents::IsAudioMuted() {
  1245. return web_contents()->IsAudioMuted();
  1246. }
  1247. void WebContents::Print(mate::Arguments* args) {
  1248. PrintSettings settings = {false, false, base::string16()};
  1249. if (args->Length() >= 1 && !args->GetNext(&settings)) {
  1250. args->ThrowError();
  1251. return;
  1252. }
  1253. auto* print_view_manager_basic_ptr =
  1254. printing::PrintViewManagerBasic::FromWebContents(web_contents());
  1255. if (args->Length() == 2) {
  1256. base::Callback<void(bool)> callback;
  1257. if (!args->GetNext(&callback)) {
  1258. args->ThrowError();
  1259. return;
  1260. }
  1261. print_view_manager_basic_ptr->SetCallback(callback);
  1262. }
  1263. print_view_manager_basic_ptr->PrintNow(
  1264. web_contents()->GetMainFrame(), settings.silent,
  1265. settings.print_background, settings.device_name);
  1266. }
  1267. std::vector<printing::PrinterBasicInfo> WebContents::GetPrinterList() {
  1268. std::vector<printing::PrinterBasicInfo> printers;
  1269. auto print_backend = printing::PrintBackend::CreateInstance(nullptr);
  1270. base::ThreadRestrictions::ScopedAllowIO allow_io;
  1271. print_backend->EnumeratePrinters(&printers);
  1272. return printers;
  1273. }
  1274. void WebContents::PrintToPDF(const base::DictionaryValue& setting,
  1275. const PrintToPDFCallback& callback) {
  1276. printing::PrintPreviewMessageHandler::FromWebContents(web_contents())
  1277. ->PrintToPDF(setting, callback);
  1278. }
  1279. void WebContents::AddWorkSpace(mate::Arguments* args,
  1280. const base::FilePath& path) {
  1281. if (path.empty()) {
  1282. args->ThrowError("path cannot be empty");
  1283. return;
  1284. }
  1285. DevToolsAddFileSystem(path);
  1286. }
  1287. void WebContents::RemoveWorkSpace(mate::Arguments* args,
  1288. const base::FilePath& path) {
  1289. if (path.empty()) {
  1290. args->ThrowError("path cannot be empty");
  1291. return;
  1292. }
  1293. DevToolsRemoveFileSystem(path);
  1294. }
  1295. void WebContents::Undo() {
  1296. web_contents()->Undo();
  1297. }
  1298. void WebContents::Redo() {
  1299. web_contents()->Redo();
  1300. }
  1301. void WebContents::Cut() {
  1302. web_contents()->Cut();
  1303. }
  1304. void WebContents::Copy() {
  1305. web_contents()->Copy();
  1306. }
  1307. void WebContents::Paste() {
  1308. web_contents()->Paste();
  1309. }
  1310. void WebContents::PasteAndMatchStyle() {
  1311. web_contents()->PasteAndMatchStyle();
  1312. }
  1313. void WebContents::Delete() {
  1314. web_contents()->Delete();
  1315. }
  1316. void WebContents::SelectAll() {
  1317. web_contents()->SelectAll();
  1318. }
  1319. void WebContents::Unselect() {
  1320. web_contents()->CollapseSelection();
  1321. }
  1322. void WebContents::Replace(const base::string16& word) {
  1323. web_contents()->Replace(word);
  1324. }
  1325. void WebContents::ReplaceMisspelling(const base::string16& word) {
  1326. web_contents()->ReplaceMisspelling(word);
  1327. }
  1328. uint32_t WebContents::FindInPage(mate::Arguments* args) {
  1329. uint32_t request_id = GetNextRequestId();
  1330. base::string16 search_text;
  1331. blink::WebFindOptions options;
  1332. if (!args->GetNext(&search_text) || search_text.empty()) {
  1333. args->ThrowError("Must provide a non-empty search content");
  1334. return 0;
  1335. }
  1336. args->GetNext(&options);
  1337. web_contents()->Find(request_id, search_text, options);
  1338. return request_id;
  1339. }
  1340. void WebContents::StopFindInPage(content::StopFindAction action) {
  1341. web_contents()->StopFinding(action);
  1342. }
  1343. void WebContents::ShowDefinitionForSelection() {
  1344. #if defined(OS_MACOSX)
  1345. auto* const view = web_contents()->GetRenderWidgetHostView();
  1346. if (view)
  1347. view->ShowDefinitionForSelection();
  1348. #endif
  1349. }
  1350. void WebContents::CopyImageAt(int x, int y) {
  1351. auto* const host = web_contents()->GetMainFrame();
  1352. if (host)
  1353. host->CopyImageAt(x, y);
  1354. }
  1355. void WebContents::Focus() {
  1356. web_contents()->Focus();
  1357. }
  1358. #if !defined(OS_MACOSX)
  1359. bool WebContents::IsFocused() const {
  1360. auto* view = web_contents()->GetRenderWidgetHostView();
  1361. if (!view)
  1362. return false;
  1363. if (GetType() != BACKGROUND_PAGE) {
  1364. auto* window = web_contents()->GetNativeView()->GetToplevelWindow();
  1365. if (window && !window->IsVisible())
  1366. return false;
  1367. }
  1368. return view->HasFocus();
  1369. }
  1370. #endif
  1371. void WebContents::TabTraverse(bool reverse) {
  1372. web_contents()->FocusThroughTabTraversal(reverse);
  1373. }
  1374. bool WebContents::SendIPCMessage(bool all_frames,
  1375. const base::string16& channel,
  1376. const base::ListValue& args) {
  1377. auto* frame_host = web_contents()->GetMainFrame();
  1378. if (frame_host) {
  1379. return frame_host->Send(new AtomFrameMsg_Message(
  1380. frame_host->GetRoutingID(), all_frames, channel, args));
  1381. }
  1382. return false;
  1383. }
  1384. void WebContents::SendInputEvent(v8::Isolate* isolate,
  1385. v8::Local<v8::Value> input_event) {
  1386. auto* const view = static_cast<content::RenderWidgetHostViewBase*>(
  1387. web_contents()->GetRenderWidgetHostView());
  1388. if (!view)
  1389. return;
  1390. blink::WebInputEvent::Type type =
  1391. mate::GetWebInputEventType(isolate, input_event);
  1392. if (blink::WebInputEvent::IsMouseEventType(type)) {
  1393. blink::WebMouseEvent mouse_event;
  1394. if (mate::ConvertFromV8(isolate, input_event, &mouse_event)) {
  1395. view->ProcessMouseEvent(mouse_event, ui::LatencyInfo());
  1396. return;
  1397. }
  1398. } else if (blink::WebInputEvent::IsKeyboardEventType(type)) {
  1399. content::NativeWebKeyboardEvent keyboard_event(
  1400. blink::WebKeyboardEvent::kRawKeyDown,
  1401. blink::WebInputEvent::kNoModifiers, ui::EventTimeForNow());
  1402. if (mate::ConvertFromV8(isolate, input_event, &keyboard_event)) {
  1403. view->ProcessKeyboardEvent(keyboard_event, ui::LatencyInfo());
  1404. return;
  1405. }
  1406. } else if (type == blink::WebInputEvent::kMouseWheel) {
  1407. blink::WebMouseWheelEvent mouse_wheel_event;
  1408. if (mate::ConvertFromV8(isolate, input_event, &mouse_wheel_event)) {
  1409. view->ProcessMouseWheelEvent(mouse_wheel_event, ui::LatencyInfo());
  1410. return;
  1411. }
  1412. }
  1413. isolate->ThrowException(
  1414. v8::Exception::Error(mate::StringToV8(isolate, "Invalid event object")));
  1415. }
  1416. void WebContents::BeginFrameSubscription(mate::Arguments* args) {
  1417. bool only_dirty = false;
  1418. FrameSubscriber::FrameCaptureCallback callback;
  1419. args->GetNext(&only_dirty);
  1420. if (!args->GetNext(&callback)) {
  1421. args->ThrowError();
  1422. return;
  1423. }
  1424. auto* const view = web_contents()->GetRenderWidgetHostView();
  1425. if (view) {
  1426. std::unique_ptr<FrameSubscriber> frame_subscriber(
  1427. new FrameSubscriber(isolate(), view, callback, only_dirty));
  1428. view->BeginFrameSubscription(std::move(frame_subscriber));
  1429. }
  1430. }
  1431. void WebContents::EndFrameSubscription() {
  1432. auto* const view = web_contents()->GetRenderWidgetHostView();
  1433. if (view)
  1434. view->EndFrameSubscription();
  1435. }
  1436. void WebContents::StartDrag(const mate::Dictionary& item,
  1437. mate::Arguments* args) {
  1438. base::FilePath file;
  1439. std::vector<base::FilePath> files;
  1440. if (!item.Get("files", &files) && item.Get("file", &file)) {
  1441. files.push_back(file);
  1442. }
  1443. mate::Handle<NativeImage> icon;
  1444. if (!item.Get("icon", &icon) && !file.empty()) {
  1445. // TODO(zcbenz): Set default icon from file.
  1446. }
  1447. // Error checking.
  1448. if (icon.IsEmpty()) {
  1449. args->ThrowError("Must specify 'icon' option");
  1450. return;
  1451. }
  1452. #if defined(OS_MACOSX)
  1453. // NSWindow.dragImage requires a non-empty NSImage
  1454. if (icon->image().IsEmpty()) {
  1455. args->ThrowError("Must specify non-empty 'icon' option");
  1456. return;
  1457. }
  1458. #endif
  1459. // Start dragging.
  1460. if (!files.empty()) {
  1461. base::MessageLoop::ScopedNestableTaskAllower allow(
  1462. base::MessageLoop::current());
  1463. DragFileItems(files, icon->image(), web_contents()->GetNativeView());
  1464. } else {
  1465. args->ThrowError("Must specify either 'file' or 'files' option");
  1466. }
  1467. }
  1468. void WebContents::CapturePage(mate::Arguments* args) {
  1469. gfx::Rect rect;
  1470. base::Callback<void(const gfx::Image&)> callback;
  1471. if (!(args->Length() == 1 && args->GetNext(&callback)) &&
  1472. !(args->Length() == 2 && args->GetNext(&rect) &&
  1473. args->GetNext(&callback))) {
  1474. args->ThrowError();
  1475. return;
  1476. }
  1477. auto* const view = web_contents()->GetRenderWidgetHostView();
  1478. if (!view) {
  1479. callback.Run(gfx::Image());
  1480. return;
  1481. }
  1482. // Capture full page if user doesn't specify a |rect|.
  1483. const gfx::Size view_size =
  1484. rect.IsEmpty() ? view->GetViewBounds().size() : rect.size();
  1485. // By default, the requested bitmap size is the view size in screen
  1486. // coordinates. However, if there's more pixel detail available on the
  1487. // current system, increase the requested bitmap size to capture it all.
  1488. gfx::Size bitmap_size = view_size;
  1489. const gfx::NativeView native_view = view->GetNativeView();
  1490. const float scale = display::Screen::GetScreen()
  1491. ->GetDisplayNearestView(native_view)
  1492. .device_scale_factor();
  1493. if (scale > 1.0f)
  1494. bitmap_size = gfx::ScaleToCeiledSize(view_size, scale);
  1495. view->CopyFromSurface(gfx::Rect(rect.origin(), view_size), bitmap_size,
  1496. base::Bind(&OnCapturePageDone, callback),
  1497. kBGRA_8888_SkColorType);
  1498. }
  1499. void WebContents::OnCursorChange(const content::WebCursor& cursor) {
  1500. content::CursorInfo info;
  1501. cursor.GetCursorInfo(&info);
  1502. if (cursor.IsCustom()) {
  1503. Emit("cursor-changed", CursorTypeToString(info),
  1504. gfx::Image::CreateFrom1xBitmap(info.custom_image),
  1505. info.image_scale_factor,
  1506. gfx::Size(info.custom_image.width(), info.custom_image.height()),
  1507. info.hotspot);
  1508. } else {
  1509. Emit("cursor-changed", CursorTypeToString(info));
  1510. }
  1511. }
  1512. void WebContents::SetSize(const SetSizeParams& params) {
  1513. if (guest_delegate_)
  1514. guest_delegate_->SetSize(params);
  1515. }
  1516. bool WebContents::IsGuest() const {
  1517. return type_ == WEB_VIEW;
  1518. }
  1519. bool WebContents::IsOffScreen() const {
  1520. #if defined(ENABLE_OSR)
  1521. return type_ == OFF_SCREEN;
  1522. #else
  1523. return false;
  1524. #endif
  1525. }
  1526. void WebContents::OnPaint(const gfx::Rect& dirty_rect, const SkBitmap& bitmap) {
  1527. Emit("paint", dirty_rect, gfx::Image::CreateFrom1xBitmap(bitmap));
  1528. }
  1529. void WebContents::StartPainting() {
  1530. if (!IsOffScreen())
  1531. return;
  1532. #if defined(ENABLE_OSR)
  1533. auto* osr_wcv = GetOffScreenWebContentsView();
  1534. if (osr_wcv)
  1535. osr_wcv->SetPainting(true);
  1536. #endif
  1537. }
  1538. void WebContents::StopPainting() {
  1539. if (!IsOffScreen())
  1540. return;
  1541. #if defined(ENABLE_OSR)
  1542. auto* osr_wcv = GetOffScreenWebContentsView();
  1543. if (osr_wcv)
  1544. osr_wcv->SetPainting(false);
  1545. #endif
  1546. }
  1547. bool WebContents::IsPainting() const {
  1548. if (!IsOffScreen())
  1549. return false;
  1550. #if defined(ENABLE_OSR)
  1551. auto* osr_wcv = GetOffScreenWebContentsView();
  1552. return osr_wcv && osr_wcv->IsPainting();
  1553. #else
  1554. return false;
  1555. #endif
  1556. }
  1557. void WebContents::SetFrameRate(int frame_rate) {
  1558. if (!IsOffScreen())
  1559. return;
  1560. #if defined(ENABLE_OSR)
  1561. auto* osr_wcv = GetOffScreenWebContentsView();
  1562. if (osr_wcv)
  1563. osr_wcv->SetFrameRate(frame_rate);
  1564. #endif
  1565. }
  1566. int WebContents::GetFrameRate() const {
  1567. if (!IsOffScreen())
  1568. return 0;
  1569. #if defined(ENABLE_OSR)
  1570. auto* osr_wcv = GetOffScreenWebContentsView();
  1571. return osr_wcv ? osr_wcv->GetFrameRate() : 0;
  1572. #else
  1573. return 0;
  1574. #endif
  1575. }
  1576. void WebContents::Invalidate() {
  1577. if (IsOffScreen()) {
  1578. #if defined(ENABLE_OSR)
  1579. auto* osr_rwhv = static_cast<OffScreenRenderWidgetHostView*>(
  1580. web_contents()->GetRenderWidgetHostView());
  1581. if (osr_rwhv)
  1582. osr_rwhv->Invalidate();
  1583. #endif
  1584. } else {
  1585. auto* const window = owner_window();
  1586. if (window)
  1587. window->Invalidate();
  1588. }
  1589. }
  1590. gfx::Size WebContents::GetSizeForNewRenderView(content::WebContents* wc) const {
  1591. if (IsOffScreen() && wc == web_contents()) {
  1592. auto* relay = NativeWindowRelay::FromWebContents(web_contents());
  1593. if (relay) {
  1594. return relay->window->GetSize();
  1595. }
  1596. }
  1597. return gfx::Size();
  1598. }
  1599. void WebContents::SetZoomLevel(double level) {
  1600. zoom_controller_->SetZoomLevel(level);
  1601. }
  1602. double WebContents::GetZoomLevel() {
  1603. return zoom_controller_->GetZoomLevel();
  1604. }
  1605. void WebContents::SetZoomFactor(double factor) {
  1606. auto level = content::ZoomFactorToZoomLevel(factor);
  1607. SetZoomLevel(level);
  1608. }
  1609. double WebContents::GetZoomFactor() {
  1610. auto level = GetZoomLevel();
  1611. return content::ZoomLevelToZoomFactor(level);
  1612. }
  1613. void WebContents::OnSetTemporaryZoomLevel(content::RenderFrameHost* rfh,
  1614. double level,
  1615. IPC::Message* reply_msg) {
  1616. zoom_controller_->SetTemporaryZoomLevel(level);
  1617. double new_level = zoom_controller_->GetZoomLevel();
  1618. AtomFrameHostMsg_SetTemporaryZoomLevel::WriteReplyParams(reply_msg,
  1619. new_level);
  1620. rfh->Send(reply_msg);
  1621. }
  1622. void WebContents::OnGetZoomLevel(content::RenderFrameHost* rfh,
  1623. IPC::Message* reply_msg) {
  1624. AtomFrameHostMsg_GetZoomLevel::WriteReplyParams(reply_msg, GetZoomLevel());
  1625. rfh->Send(reply_msg);
  1626. }
  1627. v8::Local<v8::Value> WebContents::GetWebPreferences(v8::Isolate* isolate) {
  1628. auto* web_preferences = WebContentsPreferences::From(web_contents());
  1629. if (!web_preferences)
  1630. return v8::Null(isolate);
  1631. return mate::ConvertToV8(isolate, *web_preferences->dict());
  1632. }
  1633. v8::Local<v8::Value> WebContents::GetLastWebPreferences(v8::Isolate* isolate) {
  1634. WebContentsPreferences* web_preferences =
  1635. WebContentsPreferences::FromWebContents(web_contents());
  1636. if (!web_preferences)
  1637. return v8::Null(isolate);
  1638. return mate::ConvertToV8(isolate, *web_preferences->last_dict());
  1639. }
  1640. v8::Local<v8::Value> WebContents::GetOwnerBrowserWindow() {
  1641. if (owner_window())
  1642. return BrowserWindow::From(isolate(), owner_window());
  1643. else
  1644. return v8::Null(isolate());
  1645. }
  1646. int32_t WebContents::ID() const {
  1647. return weak_map_id();
  1648. }
  1649. v8::Local<v8::Value> WebContents::Session(v8::Isolate* isolate) {
  1650. return v8::Local<v8::Value>::New(isolate, session_);
  1651. }
  1652. content::WebContents* WebContents::HostWebContents() {
  1653. if (!embedder_)
  1654. return nullptr;
  1655. return embedder_->web_contents();
  1656. }
  1657. void WebContents::SetEmbedder(const WebContents* embedder) {
  1658. if (embedder) {
  1659. NativeWindow* owner_window = nullptr;
  1660. auto* relay = NativeWindowRelay::FromWebContents(embedder->web_contents());
  1661. if (relay) {
  1662. owner_window = relay->window.get();
  1663. }
  1664. if (owner_window)
  1665. SetOwnerWindow(owner_window);
  1666. content::RenderWidgetHostView* rwhv =
  1667. web_contents()->GetRenderWidgetHostView();
  1668. if (rwhv) {
  1669. rwhv->Hide();
  1670. rwhv->Show();
  1671. }
  1672. }
  1673. }
  1674. void WebContents::SetDevToolsWebContents(const WebContents* devtools) {
  1675. if (managed_web_contents())
  1676. managed_web_contents()->SetDevToolsWebContents(devtools->web_contents());
  1677. }
  1678. v8::Local<v8::Value> WebContents::GetNativeView() const {
  1679. gfx::NativeView ptr = web_contents()->GetNativeView();
  1680. auto buffer = node::Buffer::Copy(isolate(), reinterpret_cast<char*>(&ptr),
  1681. sizeof(gfx::NativeView));
  1682. if (buffer.IsEmpty())
  1683. return v8::Null(isolate());
  1684. else
  1685. return buffer.ToLocalChecked();
  1686. }
  1687. v8::Local<v8::Value> WebContents::DevToolsWebContents(v8::Isolate* isolate) {
  1688. if (devtools_web_contents_.IsEmpty())
  1689. return v8::Null(isolate);
  1690. else
  1691. return v8::Local<v8::Value>::New(isolate, devtools_web_contents_);
  1692. }
  1693. v8::Local<v8::Value> WebContents::Debugger(v8::Isolate* isolate) {
  1694. if (debugger_.IsEmpty()) {
  1695. auto handle = atom::api::Debugger::Create(isolate, web_contents());
  1696. debugger_.Reset(isolate, handle.ToV8());
  1697. }
  1698. return v8::Local<v8::Value>::New(isolate, debugger_);
  1699. }
  1700. void WebContents::GrantOriginAccess(const GURL& url) {
  1701. content::ChildProcessSecurityPolicy::GetInstance()->GrantOrigin(
  1702. web_contents()->GetMainFrame()->GetProcess()->GetID(), url::Origin(url));
  1703. }
  1704. // static
  1705. void WebContents::BuildPrototype(v8::Isolate* isolate,
  1706. v8::Local<v8::FunctionTemplate> prototype) {
  1707. prototype->SetClassName(mate::StringToV8(isolate, "WebContents"));
  1708. mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
  1709. .MakeDestroyable()
  1710. .SetMethod("getId", &WebContents::GetID)
  1711. .SetMethod("getProcessId", &WebContents::GetProcessID)
  1712. .SetMethod("getOSProcessId", &WebContents::GetOSProcessID)
  1713. .SetMethod("equal", &WebContents::Equal)
  1714. .SetMethod("_loadURL", &WebContents::LoadURL)
  1715. .SetMethod("downloadURL", &WebContents::DownloadURL)
  1716. .SetMethod("_getURL", &WebContents::GetURL)
  1717. .SetMethod("getTitle", &WebContents::GetTitle)
  1718. .SetMethod("isLoading", &WebContents::IsLoading)
  1719. .SetMethod("isLoadingMainFrame", &WebContents::IsLoadingMainFrame)
  1720. .SetMethod("isWaitingForResponse", &WebContents::IsWaitingForResponse)
  1721. .SetMethod("_stop", &WebContents::Stop)
  1722. .SetMethod("_goBack", &WebContents::GoBack)
  1723. .SetMethod("_goForward", &WebContents::GoForward)
  1724. .SetMethod("_goToOffset", &WebContents::GoToOffset)
  1725. .SetMethod("isCrashed", &WebContents::IsCrashed)
  1726. .SetMethod("setUserAgent", &WebContents::SetUserAgent)
  1727. .SetMethod("getUserAgent", &WebContents::GetUserAgent)
  1728. .SetMethod("savePage", &WebContents::SavePage)
  1729. .SetMethod("openDevTools", &WebContents::OpenDevTools)
  1730. .SetMethod("closeDevTools", &WebContents::CloseDevTools)
  1731. .SetMethod("isDevToolsOpened", &WebContents::IsDevToolsOpened)
  1732. .SetMethod("isDevToolsFocused", &WebContents::IsDevToolsFocused)
  1733. .SetMethod("enableDeviceEmulation", &WebContents::EnableDeviceEmulation)
  1734. .SetMethod("disableDeviceEmulation", &WebContents::DisableDeviceEmulation)
  1735. .SetMethod("toggleDevTools", &WebContents::ToggleDevTools)
  1736. .SetMethod("inspectElement", &WebContents::InspectElement)
  1737. .SetMethod("setIgnoreMenuShortcuts", &WebContents::SetIgnoreMenuShortcuts)
  1738. .SetMethod("setAudioMuted", &WebContents::SetAudioMuted)
  1739. .SetMethod("isAudioMuted", &WebContents::IsAudioMuted)
  1740. .SetMethod("undo", &WebContents::Undo)
  1741. .SetMethod("redo", &WebContents::Redo)
  1742. .SetMethod("cut", &WebContents::Cut)
  1743. .SetMethod("copy", &WebContents::Copy)
  1744. .SetMethod("paste", &WebContents::Paste)
  1745. .SetMethod("pasteAndMatchStyle", &WebContents::PasteAndMatchStyle)
  1746. .SetMethod("delete", &WebContents::Delete)
  1747. .SetMethod("selectAll", &WebContents::SelectAll)
  1748. .SetMethod("unselect", &WebContents::Unselect)
  1749. .SetMethod("replace", &WebContents::Replace)
  1750. .SetMethod("replaceMisspelling", &WebContents::ReplaceMisspelling)
  1751. .SetMethod("findInPage", &WebContents::FindInPage)
  1752. .SetMethod("stopFindInPage", &WebContents::StopFindInPage)
  1753. .SetMethod("focus", &WebContents::Focus)
  1754. .SetMethod("isFocused", &WebContents::IsFocused)
  1755. .SetMethod("tabTraverse", &WebContents::TabTraverse)
  1756. .SetMethod("_send", &WebContents::SendIPCMessage)
  1757. .SetMethod("sendInputEvent", &WebContents::SendInputEvent)
  1758. .SetMethod("beginFrameSubscription", &WebContents::BeginFrameSubscription)
  1759. .SetMethod("endFrameSubscription", &WebContents::EndFrameSubscription)
  1760. .SetMethod("startDrag", &WebContents::StartDrag)
  1761. .SetMethod("setSize", &WebContents::SetSize)
  1762. .SetMethod("isGuest", &WebContents::IsGuest)
  1763. .SetMethod("isOffscreen", &WebContents::IsOffScreen)
  1764. .SetMethod("startPainting", &WebContents::StartPainting)
  1765. .SetMethod("stopPainting", &WebContents::StopPainting)
  1766. .SetMethod("isPainting", &WebContents::IsPainting)
  1767. .SetMethod("setFrameRate", &WebContents::SetFrameRate)
  1768. .SetMethod("getFrameRate", &WebContents::GetFrameRate)
  1769. .SetMethod("invalidate", &WebContents::Invalidate)
  1770. .SetMethod("setZoomLevel", &WebContents::SetZoomLevel)
  1771. .SetMethod("_getZoomLevel", &WebContents::GetZoomLevel)
  1772. .SetMethod("setZoomFactor", &WebContents::SetZoomFactor)
  1773. .SetMethod("_getZoomFactor", &WebContents::GetZoomFactor)
  1774. .SetMethod("getType", &WebContents::GetType)
  1775. .SetMethod("getWebPreferences", &WebContents::GetWebPreferences)
  1776. .SetMethod("getLastWebPreferences", &WebContents::GetLastWebPreferences)
  1777. .SetMethod("getOwnerBrowserWindow", &WebContents::GetOwnerBrowserWindow)
  1778. .SetMethod("hasServiceWorker", &WebContents::HasServiceWorker)
  1779. .SetMethod("unregisterServiceWorker",
  1780. &WebContents::UnregisterServiceWorker)
  1781. .SetMethod("inspectServiceWorker", &WebContents::InspectServiceWorker)
  1782. .SetMethod("print", &WebContents::Print)
  1783. .SetMethod("getPrinters", &WebContents::GetPrinterList)
  1784. .SetMethod("_printToPDF", &WebContents::PrintToPDF)
  1785. .SetMethod("addWorkSpace", &WebContents::AddWorkSpace)
  1786. .SetMethod("removeWorkSpace", &WebContents::RemoveWorkSpace)
  1787. .SetMethod("showDefinitionForSelection",
  1788. &WebContents::ShowDefinitionForSelection)
  1789. .SetMethod("copyImageAt", &WebContents::CopyImageAt)
  1790. .SetMethod("capturePage", &WebContents::CapturePage)
  1791. .SetMethod("setEmbedder", &WebContents::SetEmbedder)
  1792. .SetMethod("setDevToolsWebContents", &WebContents::SetDevToolsWebContents)
  1793. .SetMethod("getNativeView", &WebContents::GetNativeView)
  1794. .SetMethod("setWebRTCIPHandlingPolicy",
  1795. &WebContents::SetWebRTCIPHandlingPolicy)
  1796. .SetMethod("getWebRTCIPHandlingPolicy",
  1797. &WebContents::GetWebRTCIPHandlingPolicy)
  1798. .SetMethod("_grantOriginAccess", &WebContents::GrantOriginAccess)
  1799. .SetProperty("id", &WebContents::ID)
  1800. .SetProperty("session", &WebContents::Session)
  1801. .SetProperty("hostWebContents", &WebContents::HostWebContents)
  1802. .SetProperty("devToolsWebContents", &WebContents::DevToolsWebContents)
  1803. .SetProperty("debugger", &WebContents::Debugger);
  1804. }
  1805. AtomBrowserContext* WebContents::GetBrowserContext() const {
  1806. return static_cast<AtomBrowserContext*>(web_contents()->GetBrowserContext());
  1807. }
  1808. void WebContents::OnRendererMessage(content::RenderFrameHost* frame_host,
  1809. const base::string16& channel,
  1810. const base::ListValue& args) {
  1811. // webContents.emit(channel, new Event(), args...);
  1812. Emit(base::UTF16ToUTF8(channel), args);
  1813. }
  1814. void WebContents::OnRendererMessageSync(content::RenderFrameHost* frame_host,
  1815. const base::string16& channel,
  1816. const base::ListValue& args,
  1817. IPC::Message* message) {
  1818. // webContents.emit(channel, new Event(sender, message), args...);
  1819. EmitWithSender(base::UTF16ToUTF8(channel), frame_host, message, args);
  1820. }
  1821. // static
  1822. mate::Handle<WebContents> WebContents::CreateFrom(
  1823. v8::Isolate* isolate,
  1824. content::WebContents* web_contents) {
  1825. // We have an existing WebContents object in JS.
  1826. auto* existing = TrackableObject::FromWrappedClass(isolate, web_contents);
  1827. if (existing)
  1828. return mate::CreateHandle(isolate, static_cast<WebContents*>(existing));
  1829. // Otherwise create a new WebContents wrapper object.
  1830. return mate::CreateHandle(isolate,
  1831. new WebContents(isolate, web_contents, REMOTE));
  1832. }
  1833. mate::Handle<WebContents> WebContents::CreateFrom(
  1834. v8::Isolate* isolate,
  1835. content::WebContents* web_contents,
  1836. Type type) {
  1837. // Otherwise create a new WebContents wrapper object.
  1838. return mate::CreateHandle(isolate,
  1839. new WebContents(isolate, web_contents, type));
  1840. }
  1841. // static
  1842. mate::Handle<WebContents> WebContents::Create(v8::Isolate* isolate,
  1843. const mate::Dictionary& options) {
  1844. return mate::CreateHandle(isolate, new WebContents(isolate, options));
  1845. }
  1846. } // namespace api
  1847. } // namespace atom
  1848. namespace {
  1849. using atom::api::WebContents;
  1850. void Initialize(v8::Local<v8::Object> exports,
  1851. v8::Local<v8::Value> unused,
  1852. v8::Local<v8::Context> context,
  1853. void* priv) {
  1854. v8::Isolate* isolate = context->GetIsolate();
  1855. mate::Dictionary dict(isolate, exports);
  1856. dict.Set("WebContents", WebContents::GetConstructor(isolate)->GetFunction());
  1857. dict.SetMethod("create", &WebContents::Create);
  1858. dict.SetMethod("fromId", &mate::TrackableObject<WebContents>::FromWeakMapID);
  1859. dict.SetMethod("getAllWebContents",
  1860. &mate::TrackableObject<WebContents>::GetAll);
  1861. }
  1862. } // namespace
  1863. NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_web_contents, Initialize)