Make remote.getCurrentWindow() work in <webview>

This commit is contained in:
Cheng Zhao 2014-10-26 19:30:53 +08:00
parent 10a8f3c884
commit 404e08c0e7
11 changed files with 66 additions and 48 deletions

View file

@ -13,6 +13,7 @@
#include "atom/browser/window_list.h" #include "atom/browser/window_list.h"
#include "atom/common/options_switches.h" #include "atom/common/options_switches.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "base/strings/string_number_conversions.h"
#include "chrome/browser/printing/printing_message_filter.h" #include "chrome/browser/printing/printing_message_filter.h"
#include "chrome/browser/speech/tts_message_filter.h" #include "chrome/browser/speech/tts_message_filter.h"
#include "content/public/browser/render_process_host.h" #include "content/public/browser/render_process_host.h"
@ -147,9 +148,12 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches(
// Append commnad line arguments for guest web view. // Append commnad line arguments for guest web view.
WebViewRendererState::WebViewInfo info; WebViewRendererState::WebViewInfo info;
if (WebViewRendererState::GetInstance()->GetInfo(child_process_id, &info)) { if (WebViewRendererState::GetInstance()->GetInfo(child_process_id, &info)) {
command_line->AppendSwitch("guest"); command_line->AppendSwitchASCII(
command_line->AppendSwitchASCII(switches::kNodeIntegration, switches::kGuestInstanceID,
info.node_integration ? "true" : "false"); base::IntToString(info.guest_instance_id));
command_line->AppendSwitchASCII(
switches::kNodeIntegration,
info.node_integration ? "true" : "false");
} }
} }

View file

@ -32,7 +32,7 @@ createGuest = (embedder, params) ->
isGuest: true isGuest: true
guestInstanceId: id guestInstanceId: id
storagePartitionId: params.storagePartitionId storagePartitionId: params.storagePartitionId
guestInstances[id] = guest guestInstances[id] = {guest, embedder}
webViewManager.addGuest id, embedder, guest, params.nodeIntegration webViewManager.addGuest id, embedder, guest, params.nodeIntegration
# Destroy guest when the embedder is gone. # Destroy guest when the embedder is gone.
@ -65,7 +65,7 @@ createGuest = (embedder, params) ->
# Destroy an existing guest instance. # Destroy an existing guest instance.
destroyGuest = (id) -> destroyGuest = (id) ->
webViewManager.removeGuest id webViewManager.removeGuest id
guestInstances[id].destroy() guestInstances[id].guest.destroy()
delete guestInstances[id] delete guestInstances[id]
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_CREATE_GUEST', (event, type, params, requestId) -> ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_CREATE_GUEST', (event, type, params, requestId) ->
@ -75,11 +75,15 @@ ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_DESTROY_GUEST', (event, id) ->
destroyGuest id destroyGuest id
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_SET_AUTO_SIZE', (event, id, params) -> ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_SET_AUTO_SIZE', (event, id, params) ->
guestInstances[id]?.setAutoSize params.enableAutoSize, params.min, params.max guestInstances[id]?.guest.setAutoSize params.enableAutoSize, params.min, params.max
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_SET_ALLOW_TRANSPARENCY', (event, id, allowtransparency) -> ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_SET_ALLOW_TRANSPARENCY', (event, id, allowtransparency) ->
guestInstances[id]?.setAllowTransparency allowtransparency guestInstances[id]?.guest.setAllowTransparency allowtransparency
# Returns WebContents from its guest id. # Returns WebContents from its guest id.
exports.getGuest = (id) -> exports.getGuest = (id) ->
guestInstances[id] guestInstances[id]?.guest
# Returns the embedder of the guest.
exports.getEmbedder = (id) ->
guestInstances[id]?.embedder

View file

@ -94,11 +94,15 @@ ipc.on 'ATOM_BROWSER_GLOBAL', (event, name) ->
catch e catch e
event.returnValue = errorToMeta e event.returnValue = errorToMeta e
ipc.on 'ATOM_BROWSER_CURRENT_WINDOW', (event) -> ipc.on 'ATOM_BROWSER_CURRENT_WINDOW', (event, guestInstanceId) ->
try try
BrowserWindow = require 'browser-window' BrowserWindow = require 'browser-window'
window = BrowserWindow.fromWebContents event.sender if guestInstanceId?
window = BrowserWindow.fromDevToolsWebContents event.sender unless window? guestViewManager = require './guest-view-manager'
window = BrowserWindow.fromWebContents guestViewManager.getEmbedder(guestInstanceId)
else
window = BrowserWindow.fromWebContents event.sender
window = BrowserWindow.fromDevToolsWebContents event.sender unless window?
event.returnValue = valueToMeta event.sender, window event.returnValue = valueToMeta event.sender, window
catch e catch e
event.returnValue = errorToMeta e event.returnValue = errorToMeta e

View file

@ -46,7 +46,9 @@ void WebViewManager::AddGuest(int guest_instance_id,
bool node_integration) { bool node_integration) {
web_contents_map_[guest_instance_id] = { web_contents, embedder }; web_contents_map_[guest_instance_id] = { web_contents, embedder };
WebViewRendererState::WebViewInfo web_view_info = { node_integration }; WebViewRendererState::WebViewInfo web_view_info = {
guest_instance_id, node_integration
};
content::BrowserThread::PostTask( content::BrowserThread::PostTask(
content::BrowserThread::IO, content::BrowserThread::IO,
FROM_HERE, FROM_HERE,

View file

@ -20,6 +20,7 @@ class WebViewManager;
class WebViewRendererState { class WebViewRendererState {
public: public:
struct WebViewInfo { struct WebViewInfo {
int guest_instance_id;
bool node_integration; bool node_integration;
}; };

View file

@ -63,6 +63,9 @@ const char kDirectWrite[] = "direct-write";
// Enable plugins. // Enable plugins.
const char kEnablePlugins[] = "enable-plugins"; const char kEnablePlugins[] = "enable-plugins";
// Instancd ID of guest WebContents.
const char kGuestInstanceID[] = "guest-instance-id";
// Web runtime features. // Web runtime features.
const char kExperimentalFeatures[] = "experimental-features"; const char kExperimentalFeatures[] = "experimental-features";
const char kExperimentalCanvasFeatures[] = "experimental-canvas-features"; const char kExperimentalCanvasFeatures[] = "experimental-canvas-features";

View file

@ -37,6 +37,7 @@ extern const char kEnableLargerThanScreen[];
extern const char kDarkTheme[]; extern const char kDarkTheme[];
extern const char kDirectWrite[]; extern const char kDirectWrite[];
extern const char kEnablePlugins[]; extern const char kEnablePlugins[];
extern const char kGuestInstanceID[];
extern const char kExperimentalFeatures[]; extern const char kExperimentalFeatures[];
extern const char kExperimentalCanvasFeatures[]; extern const char kExperimentalCanvasFeatures[];

View file

@ -1,4 +1,5 @@
EventEmitter = require('events').EventEmitter EventEmitter = require('events').EventEmitter
process = global.process
ipc = process.atomBinding('ipc') ipc = process.atomBinding('ipc')
class Ipc extends EventEmitter class Ipc extends EventEmitter

View file

@ -1,6 +1,7 @@
process = global.process
ipc = require 'ipc' ipc = require 'ipc'
CallbacksRegistry = require 'callbacks-registry'
v8Util = process.atomBinding 'v8_util' v8Util = process.atomBinding 'v8_util'
CallbacksRegistry = require 'callbacks-registry'
callbacksRegistry = new CallbacksRegistry callbacksRegistry = new CallbacksRegistry
@ -110,7 +111,7 @@ exports.require = (module) ->
windowCache = null windowCache = null
exports.getCurrentWindow = -> exports.getCurrentWindow = ->
return windowCache if windowCache? return windowCache if windowCache?
meta = ipc.sendChannelSync 'ATOM_BROWSER_CURRENT_WINDOW' meta = ipc.sendChannelSync 'ATOM_BROWSER_CURRENT_WINDOW', process.guestInstanceId
windowCache = metaToValue meta windowCache = metaToValue meta
# Get a global object in browser. # Get a global object in browser.

View file

@ -21,17 +21,14 @@ globalPaths.push path.join(process.resourcesPath, 'app')
require path.resolve(__dirname, '..', '..', 'common', 'lib', 'init.js') require path.resolve(__dirname, '..', '..', 'common', 'lib', 'init.js')
# Process command line arguments. # Process command line arguments.
isGuest = false
nodeIntegration = 'false' nodeIntegration = 'false'
for arg in process.argv for arg in process.argv
if arg is '--guest' if arg.indexOf('--guest-instance-id=') == 0
# This is a guest web view. # This is a guest web view.
isGuest = true process.guestInstanceId = parseInt arg.substr(arg.indexOf('=') + 1)
# Set the frame name to make AtomRendererClient recognize this guest. # Set the frame name to make AtomRendererClient recognize this guest.
require('web-frame').setName 'ATOM_SHELL_GUEST_WEB_VIEW' require('web-frame').setName 'ATOM_SHELL_GUEST_WEB_VIEW'
else else if arg.indexOf('--node-integration=') == 0
index = arg.indexOf '--node-integration='
continue unless index == 0
nodeIntegration = arg.substr arg.indexOf('=') + 1 nodeIntegration = arg.substr arg.indexOf('=') + 1
if location.protocol is 'chrome-devtools:' if location.protocol is 'chrome-devtools:'
@ -44,7 +41,7 @@ else
# Override default web functions. # Override default web functions.
require path.join(__dirname, 'override') require path.join(__dirname, 'override')
# Load webview tag implementation. # Load webview tag implementation.
require path.join(__dirname, 'web-view') unless isGuest require path.join(__dirname, 'web-view') unless process.guestInstanceId?
if nodeIntegration in ['true', 'all', 'except-iframe', 'manual-enable-iframe'] if nodeIntegration in ['true', 'all', 'except-iframe', 'manual-enable-iframe']
# Export node bindings to global. # Export node bindings to global.

View file

@ -1,43 +1,43 @@
process = global.process
remote = require 'remote'
# Override default window.close, see: unless process.guestInstanceId?
# https://github.com/atom/atom-shell/issues/70 # Override default window.close, see:
window.close = -> window.close = ->
require('remote').getCurrentWindow().close() remote.getCurrentWindow().close()
# Override default window.open. # Override default window.open.
window.open = (url, name, features) -> window.open = (url, name, features) ->
options = {} options = {}
for feature in features.split ',' for feature in features.split ','
[name, value] = feature.split '=' [name, value] = feature.split '='
options[name] = options[name] =
if value is 'yes' if value is 'yes'
true true
else if value is 'no' else if value is 'no'
false false
else else
value value
options.x ?= options.left options.x ?= options.left
options.y ?= options.top options.y ?= options.top
options.title ?= name options.title ?= name
options.width ?= 800 options.width ?= 800
options.height ?= 600 options.height ?= 600
BrowserWindow = require('remote').require 'browser-window' BrowserWindow = require('remote').require 'browser-window'
browser = new BrowserWindow options browser = new BrowserWindow options
browser.loadUrl url browser.loadUrl url
browser browser
# Use the dialog API to implement alert(). # Use the dialog API to implement alert().
window.alert = (message, title='') -> window.alert = (message, title='') ->
remote = require 'remote'
dialog = remote.require 'dialog' dialog = remote.require 'dialog'
buttons = ['OK'] buttons = ['OK']
dialog.showMessageBox remote.getCurrentWindow(), {message, title, buttons} dialog.showMessageBox remote.getCurrentWindow(), {message, title, buttons}
# And the confirm(). # And the confirm().
window.confirm = (message, title='') -> window.confirm = (message, title='') ->
remote = require 'remote'
dialog = remote.require 'dialog' dialog = remote.require 'dialog'
buttons = ['OK', 'Cancel'] buttons = ['OK', 'Cancel']
not dialog.showMessageBox remote.getCurrentWindow(), {message, title, buttons} not dialog.showMessageBox remote.getCurrentWindow(), {message, title, buttons}