Merge pull request #5684 from electron/webview-visibilitychange
Support document visibility and events in webviews
This commit is contained in:
commit
4ea7602871
8 changed files with 80 additions and 13 deletions
|
@ -14,22 +14,12 @@ using atom::WebContentsPreferences;
|
|||
|
||||
namespace {
|
||||
|
||||
atom::WebViewManager* GetWebViewManager(content::WebContents* web_contents) {
|
||||
auto context = web_contents->GetBrowserContext();
|
||||
if (context) {
|
||||
auto manager = context->GetGuestManager();
|
||||
return static_cast<atom::WebViewManager*>(manager);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void AddGuest(int guest_instance_id,
|
||||
int element_instance_id,
|
||||
content::WebContents* embedder,
|
||||
content::WebContents* guest_web_contents,
|
||||
const base::DictionaryValue& options) {
|
||||
auto manager = GetWebViewManager(embedder);
|
||||
auto manager = atom::WebViewManager::GetWebViewManager(embedder);
|
||||
if (manager)
|
||||
manager->AddGuest(guest_instance_id, element_instance_id, embedder,
|
||||
guest_web_contents);
|
||||
|
@ -38,7 +28,7 @@ void AddGuest(int guest_instance_id,
|
|||
}
|
||||
|
||||
void RemoveGuest(content::WebContents* embedder, int guest_instance_id) {
|
||||
auto manager = GetWebViewManager(embedder);
|
||||
auto manager = atom::WebViewManager::GetWebViewManager(embedder);
|
||||
if (manager)
|
||||
manager->RemoveGuest(guest_instance_id);
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/web_view_manager.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/command_line.h"
|
||||
|
@ -130,7 +131,7 @@ void WebContentsPreferences::AppendExtraCommandLineSwitches(
|
|||
base::DoubleToString(zoom_factor));
|
||||
|
||||
// --guest-instance-id, which is used to identify guest WebContents.
|
||||
int guest_instance_id;
|
||||
int guest_instance_id = 0;
|
||||
if (web_preferences.GetInteger(options::kGuestInstanceID, &guest_instance_id))
|
||||
command_line->AppendSwitchASCII(switches::kGuestInstanceID,
|
||||
base::IntToString(guest_instance_id));
|
||||
|
@ -157,6 +158,17 @@ void WebContentsPreferences::AppendExtraCommandLineSwitches(
|
|||
|
||||
// The initial visibility state.
|
||||
NativeWindow* window = NativeWindow::FromWebContents(web_contents);
|
||||
|
||||
// Use embedder window for webviews
|
||||
if (guest_instance_id && !window) {
|
||||
auto manager = WebViewManager::GetWebViewManager(web_contents);
|
||||
if (manager) {
|
||||
auto embedder = manager->GetEmbedder(guest_instance_id);
|
||||
if (embedder)
|
||||
window = NativeWindow::FromWebContents(embedder);
|
||||
}
|
||||
}
|
||||
|
||||
if (window) {
|
||||
bool visible = window->IsVisible() && !window->IsMinimized();
|
||||
if (!visible) // Default state is visible.
|
||||
|
|
|
@ -42,6 +42,13 @@ void WebViewManager::RemoveGuest(int guest_instance_id) {
|
|||
}
|
||||
}
|
||||
|
||||
content::WebContents* WebViewManager::GetEmbedder(int guest_instance_id) {
|
||||
if (ContainsKey(web_contents_embedder_map_, guest_instance_id))
|
||||
return web_contents_embedder_map_[guest_instance_id].embedder;
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
content::WebContents* WebViewManager::GetGuestByInstanceID(
|
||||
int owner_process_id,
|
||||
int element_instance_id) {
|
||||
|
@ -65,4 +72,16 @@ bool WebViewManager::ForEachGuest(content::WebContents* embedder_web_contents,
|
|||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
WebViewManager* WebViewManager::GetWebViewManager(
|
||||
content::WebContents* web_contents) {
|
||||
auto context = web_contents->GetBrowserContext();
|
||||
if (context) {
|
||||
auto manager = context->GetGuestManager();
|
||||
return static_cast<WebViewManager*>(manager);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
|
|
@ -21,6 +21,9 @@ class WebViewManager : public content::BrowserPluginGuestManager {
|
|||
content::WebContents* embedder,
|
||||
content::WebContents* web_contents);
|
||||
void RemoveGuest(int guest_instance_id);
|
||||
content::WebContents* GetEmbedder(int guest_instance_id);
|
||||
|
||||
static WebViewManager* GetWebViewManager(content::WebContents* web_contents);
|
||||
|
||||
protected:
|
||||
// content::BrowserPluginGuestManager:
|
||||
|
|
|
@ -42,6 +42,11 @@ var WebViewImpl = (function () {
|
|||
this.webviewNode.setZoomLevel(zoomLevel)
|
||||
}
|
||||
webFrame.on('zoom-level-changed', this.onZoomLevelChanged)
|
||||
|
||||
this.onVisibilityChanged = (event, visibilityState) => {
|
||||
this.webviewNode.send('ELECTRON_RENDERER_WINDOW_VISIBILITY_CHANGE', visibilityState)
|
||||
}
|
||||
ipcRenderer.on('ELECTRON_RENDERER_WINDOW_VISIBILITY_CHANGE', this.onVisibilityChanged)
|
||||
}
|
||||
|
||||
WebViewImpl.prototype.createBrowserPluginNode = function () {
|
||||
|
@ -56,6 +61,7 @@ var WebViewImpl = (function () {
|
|||
WebViewImpl.prototype.reset = function () {
|
||||
// Unlisten the zoom-level-changed event.
|
||||
webFrame.removeListener('zoom-level-changed', this.onZoomLevelChanged)
|
||||
ipcRenderer.removeListener('ELECTRON_RENDERER_WINDOW_VISIBILITY_CHANGE', this.onVisibilityChanged)
|
||||
|
||||
// If guestInstanceId is defined then the <webview> has navigated and has
|
||||
// already picked up a partition ID. Thus, we need to reset the initialization
|
||||
|
|
11
spec/fixtures/pages/visibilitychange.html
vendored
Normal file
11
spec/fixtures/pages/visibilitychange.html
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
<html>
|
||||
<body>
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
const {ipcRenderer} = require('electron')
|
||||
ipcRenderer.send('pong', document.visibilityState, document.hidden)
|
||||
document.addEventListener('visibilitychange', function () {
|
||||
ipcRenderer.send('pong', document.visibilityState, document.hidden)
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
5
spec/fixtures/pages/webview-visibilitychange.html
vendored
Normal file
5
spec/fixtures/pages/webview-visibilitychange.html
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
<html>
|
||||
<body>
|
||||
<webview nodeintegration src="visibilitychange.html"/>
|
||||
</body>
|
||||
</html>
|
|
@ -867,4 +867,25 @@ describe('<webview> tag', function () {
|
|||
})
|
||||
w.loadURL('file://' + fixtures + '/pages/webview-zoom-factor.html')
|
||||
})
|
||||
|
||||
it('inherits the parent window visibility state and receives visibilitychange events', function (done) {
|
||||
w = new BrowserWindow({
|
||||
show: false
|
||||
})
|
||||
|
||||
ipcMain.once('pong', function (event, visibilityState, hidden) {
|
||||
assert.equal(visibilityState, 'hidden')
|
||||
assert.equal(hidden, true)
|
||||
|
||||
w.webContents.send('ELECTRON_RENDERER_WINDOW_VISIBILITY_CHANGE', 'visible')
|
||||
|
||||
ipcMain.once('pong', function (event, visibilityState, hidden) {
|
||||
assert.equal(visibilityState, 'visible')
|
||||
assert.equal(hidden, false)
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
w.loadURL('file://' + fixtures + '/pages/webview-visibilitychange.html')
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue