From 239d535cac0ad766f78d5760c55abdde0504d0b9 Mon Sep 17 00:00:00 2001 From: Robo Date: Thu, 30 Jul 2015 14:42:03 +0530 Subject: [PATCH 1/2] render: executejavascript with option to simulate usergesture --- atom/browser/api/atom_api_web_contents.cc | 5 +++-- atom/browser/api/atom_api_web_contents.h | 3 ++- atom/browser/api/lib/web-contents.coffee | 6 +++--- atom/common/api/api_messages.h | 4 ++++ atom/renderer/atom_render_view_observer.cc | 23 ++++++++++++++++++++++ atom/renderer/atom_render_view_observer.h | 2 ++ docs/api/browser-window.md | 5 +++-- 7 files changed, 40 insertions(+), 8 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 7070b7d6eba..1f68a4d8ad1 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -572,8 +572,9 @@ void WebContents::InsertCSS(const std::string& css) { web_contents()->InsertCSS(css); } -void WebContents::ExecuteJavaScript(const base::string16& code) { - web_contents()->GetMainFrame()->ExecuteJavaScript(code); +void WebContents::ExecuteJavaScript(const base::string16& code, + bool has_user_gesture) { + Send(new AtomViewMsg_ExecuteJavaScript(routing_id(), code, has_user_gesture)); } void WebContents::OpenDevTools(mate::Arguments* args) { diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 68e0ad31052..2fbc1d89977 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -65,7 +65,8 @@ class WebContents : public mate::TrackableObject, void SetUserAgent(const std::string& user_agent); std::string GetUserAgent(); void InsertCSS(const std::string& css); - void ExecuteJavaScript(const base::string16& code); + void ExecuteJavaScript(const base::string16& code, + bool has_user_gesture); void OpenDevTools(mate::Arguments* args); void CloseDevTools(); bool IsDevToolsOpened(); diff --git a/atom/browser/api/lib/web-contents.coffee b/atom/browser/api/lib/web-contents.coffee index cb6cc7c0b3d..06615e31608 100644 --- a/atom/browser/api/lib/web-contents.coffee +++ b/atom/browser/api/lib/web-contents.coffee @@ -46,11 +46,11 @@ wrapWebContents = (webContents) -> # web contents has been loaded. webContents.loaded = false webContents.once 'did-finish-load', -> @loaded = true - webContents.executeJavaScript = (code) -> + webContents.executeJavaScript = (code, hasUserGesture=false) -> if @loaded - @_executeJavaScript code + @_executeJavaScript code, hasUserGesture else - webContents.once 'did-finish-load', @_executeJavaScript.bind(this, code) + webContents.once 'did-finish-load', @_executeJavaScript.bind(this, code, hasUserGesture) # The navigation controller. controller = new NavigationController(webContents) diff --git a/atom/common/api/api_messages.h b/atom/common/api/api_messages.h index eeb26614847..b32df3cef39 100644 --- a/atom/common/api/api_messages.h +++ b/atom/common/api/api_messages.h @@ -34,6 +34,10 @@ IPC_MESSAGE_ROUTED2(AtomViewMsg_Message, base::string16 /* channel */, base::ListValue /* arguments */) +IPC_MESSAGE_ROUTED2(AtomViewMsg_ExecuteJavaScript, + base::string16 /* code */, + bool /* has user gesture */) + // Sent by the renderer when the draggable regions are updated. IPC_MESSAGE_ROUTED1(AtomViewHostMsg_UpdateDraggableRegions, std::vector /* regions */) diff --git a/atom/renderer/atom_render_view_observer.cc b/atom/renderer/atom_render_view_observer.cc index 02250091a4a..eb59fe03d3b 100644 --- a/atom/renderer/atom_render_view_observer.cc +++ b/atom/renderer/atom_render_view_observer.cc @@ -26,6 +26,8 @@ #include "third_party/WebKit/public/web/WebFrame.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" #include "third_party/WebKit/public/web/WebKit.h" +#include "third_party/WebKit/public/web/WebScopedUserGesture.h" +#include "third_party/WebKit/public/web/WebScriptSource.h" #include "third_party/WebKit/public/web/WebView.h" #include "ui/base/resource/resource_bundle.h" @@ -113,6 +115,8 @@ bool AtomRenderViewObserver::OnMessageReceived(const IPC::Message& message) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(AtomRenderViewObserver, message) IPC_MESSAGE_HANDLER(AtomViewMsg_Message, OnBrowserMessage) + IPC_MESSAGE_HANDLER(AtomViewMsg_ExecuteJavaScript, + OnJavaScriptExecuteRequest) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() @@ -143,4 +147,23 @@ void AtomRenderViewObserver::OnBrowserMessage(const base::string16& channel, } } +void AtomRenderViewObserver::OnJavaScriptExecuteRequest( + const base::string16& code, bool has_user_gesture) { + if (!document_created_) + return; + + if (!render_view()->GetWebView()) + return; + + scoped_ptr gesture( + has_user_gesture ? new blink::WebScopedUserGesture : nullptr); + + v8::Isolate* isolate = blink::mainThreadIsolate(); + v8::HandleScope handle_scope(isolate); + + blink::WebFrame* frame = render_view()->GetWebView()->mainFrame(); + frame->executeScriptAndReturnValue( + blink::WebScriptSource(code)); +} + } // namespace atom diff --git a/atom/renderer/atom_render_view_observer.h b/atom/renderer/atom_render_view_observer.h index 4b9d59f3fa0..85a8c159d97 100644 --- a/atom/renderer/atom_render_view_observer.h +++ b/atom/renderer/atom_render_view_observer.h @@ -32,6 +32,8 @@ class AtomRenderViewObserver : public content::RenderViewObserver { void OnBrowserMessage(const base::string16& channel, const base::ListValue& args); + void OnJavaScriptExecuteRequest(const base::string16& code, + bool has_user_gesture); // Weak reference to renderer client. AtomRendererClient* renderer_client_; diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 7257158ec1a..a5f7ab2880f 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -905,11 +905,12 @@ Returns a `String` represents the user agent for this page. Injects CSS into this page. -### WebContents.executeJavaScript(code) +### WebContents.executeJavaScript(code, userGesture) * `code` String +* `userGesture` Boolean - Default false -Evaluates `code` in page. +Evaluates `code` in page. If `userGesture` is set will simulate user gesture. ### WebContents.setAudioMuted(muted) From 9fb03d584c4f2ebcc726c652748eb5661f36f4b3 Mon Sep 17 00:00:00 2001 From: Robo Date: Thu, 30 Jul 2015 21:56:57 +0530 Subject: [PATCH 2/2] add spec and fix docs --- docs/api/browser-window.md | 4 +++- docs/api/web-view-tag.md | 7 +++++-- spec/fixtures/pages/fullscreen.html | 1 + spec/webview-spec.coffee | 14 ++++++++++++++ 4 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 spec/fixtures/pages/fullscreen.html diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index a5f7ab2880f..e4cabd52b3b 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -910,7 +910,9 @@ Injects CSS into this page. * `code` String * `userGesture` Boolean - Default false -Evaluates `code` in page. If `userGesture` is set will simulate user gesture. +Evaluates `code` in page. If `userGesture` is set will create user gesture context, +HTML api like `requestFullScreen` which require user action can take advantage +of this option for automation. ### WebContents.setAudioMuted(muted) diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index 0ff54c16170..a74f5fb50c7 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -225,11 +225,14 @@ Returns a `String` represents the user agent for guest page. Injects CSS into guest page. -### ``.executeJavaScript(code) +### ``.executeJavaScript(code, userGesture) * `code` String +* `userGesture` Boolean - Default false -Evaluates `code` in guest page. +Evaluates `code` in page. If `userGesture` is set will create user gesture context, +HTML api like `requestFullScreen` which require user action can take advantage +of this option for automation. ### ``.openDevTools() diff --git a/spec/fixtures/pages/fullscreen.html b/spec/fixtures/pages/fullscreen.html new file mode 100644 index 00000000000..4e5648e0194 --- /dev/null +++ b/spec/fixtures/pages/fullscreen.html @@ -0,0 +1 @@ + diff --git a/spec/webview-spec.coffee b/spec/webview-spec.coffee index 7ab8969e771..ef0763b0147 100644 --- a/spec/webview-spec.coffee +++ b/spec/webview-spec.coffee @@ -261,3 +261,17 @@ describe ' tag', -> done() webview.src = "file://#{fixtures}/pages/dom-ready.html?port=#{port}" document.body.appendChild webview + + describe 'executeJavaScript', -> + it 'should support user gesture', (done) -> + listener = (e) -> + webview.removeEventListener 'enter-html-full-screen', listener + done() + listener2 = (e) -> + jsScript = 'document.getElementsByTagName("video")[0].webkitRequestFullScreen()' + webview.executeJavaScript jsScript, true + webview.removeEventListener 'did-finish-load', listener2 + webview.addEventListener 'enter-html-full-screen', listener + webview.addEventListener 'did-finish-load', listener2 + webview.src = "file://#{fixtures}/pages/fullscreen.html" + document.body.appendChild webview