Merge remote-tracking branch 'atom/master'

This commit is contained in:
Plusb Preco 2015-09-04 18:18:07 +09:00
commit 44528ce60e
18 changed files with 379 additions and 73 deletions

View file

@ -159,11 +159,19 @@ WebContents::WebContents(const mate::Dictionary& options) {
type_ = is_guest ? WEB_VIEW : BROWSER_WINDOW;
auto browser_context = AtomBrowserMainParts::Get()->browser_context();
content::BrowserContext* browser_context =
AtomBrowserMainParts::Get()->browser_context();
content::WebContents* web_contents;
if (is_guest) {
content::SiteInstance* site_instance = content::SiteInstance::CreateForURL(
browser_context, GURL("chrome-guest://fake-host"));
GURL guest_site;
options.Get("partition", &guest_site);
// use hosts' browser_context when no partition is specified.
if (!guest_site.query().empty()) {
browser_context = AtomBrowserMainParts::Get()
->GetBrowserContextForPartition(guest_site);
}
auto site_instance =
content::SiteInstance::CreateForURL(browser_context, guest_site);
content::WebContents::CreateParams params(browser_context, site_instance);
guest_delegate_.reset(new WebViewGuestDelegate);
params.guest_delegate = guest_delegate_.get();

View file

@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "atom/browser/api/atom_api_web_contents.h"
#include "atom/browser/web_view_constants.h"
#include "atom/browser/web_view_manager.h"
#include "atom/common/native_mate_converters/gurl_converter.h"
#include "content/public/browser/browser_context.h"
@ -34,16 +35,19 @@ struct Converter<atom::WebViewManager::WebViewInfo> {
return false;
GURL preload_url;
if (!options.Get("preloadUrl", &preload_url))
if (!options.Get(atom::web_view::kPreloadUrl, &preload_url))
return false;
if (!preload_url.is_empty() &&
!net::FileURLToFilePath(preload_url, &(out->preload_script)))
return false;
return options.Get("nodeIntegration", &(out->node_integration)) &&
options.Get("plugins", &(out->plugins)) &&
options.Get("disableWebSecurity", &(out->disable_web_security));
return options.Get(atom::web_view::kNodeIntegration,
&(out->node_integration)) &&
options.Get(atom::web_view::kPlugins, &(out->plugins)) &&
options.Get(atom::web_view::kPartitionId, &(out->partition_id)) &&
options.Get(atom::web_view::kDisableWebSecurity,
&(out->disable_web_security));
}
};
@ -67,12 +71,15 @@ void AddGuest(int guest_instance_id,
content::WebContents* guest_web_contents,
atom::WebViewManager::WebViewInfo info) {
auto manager = GetWebViewManager(embedder);
if (manager) {
info.guest_instance_id = guest_instance_id;
info.embedder = embedder;
if (manager)
manager->AddGuest(guest_instance_id, element_instance_id, embedder,
guest_web_contents, info);
}
guest_web_contents);
info.guest_instance_id = guest_instance_id;
info.embedder = embedder;
auto data = new atom::WebViewManager::WebViewInfoUserData(info);
guest_web_contents->SetUserData(
atom::web_view::kWebViewInfoKeyName, data);
}
void RemoveGuest(content::WebContents* embedder, int guest_instance_id) {

View file

@ -16,6 +16,7 @@
#include "atom/browser/browser.h"
#include "atom/browser/native_window.h"
#include "atom/browser/web_view_manager.h"
#include "atom/browser/web_view_constants.h"
#include "atom/browser/window_list.h"
#include "atom/common/options_switches.h"
#include "base/command_line.h"
@ -74,8 +75,12 @@ ProcessOwner GetProcessOwner(int process_id,
return OWNER_NATIVE_WINDOW;
// Then search for guest WebContents.
if (WebViewManager::GetInfoForWebContents(web_contents, info))
auto data = static_cast<WebViewManager::WebViewInfoUserData*>(
web_contents->GetUserData(web_view::kWebViewInfoKeyName));
if (data) {
*info = data->web_view_info();
return OWNER_GUEST_WEB_CONTENTS;
}
return OWNER_NONE;
}
@ -155,9 +160,10 @@ void AtomBrowserClient::OverrideWebkitPrefs(
// Custom preferences of guest page.
auto web_contents = content::WebContents::FromRenderViewHost(host);
WebViewManager::WebViewInfo info;
if (WebViewManager::GetInfoForWebContents(web_contents, &info)) {
prefs->web_security_enabled = !info.disable_web_security;
auto info = static_cast<WebViewManager::WebViewInfoUserData*>(
web_contents->GetUserData(web_view::kWebViewInfoKeyName));
if (info) {
prefs->web_security_enabled = !info->web_view_info().disable_web_security;
return;
}

View file

@ -26,6 +26,23 @@
namespace atom {
namespace {
const base::FilePath::CharType kStoragePartitionDirname[] = "Partitions";
void GetStoragePartitionConfig(const GURL& partition,
base::FilePath* partition_path,
bool* in_memory,
std::string* id) {
*in_memory = (partition.path() != "/persist");
net::UnescapeRule::Type flags =
net::UnescapeRule::SPACES | net::UnescapeRule::URL_SPECIAL_CHARS;
*id = net::UnescapeURLComponent(partition.query(), flags);
*partition_path = base::FilePath(kStoragePartitionDirname).AppendASCII(*id);
}
} // namespace
// static
AtomBrowserMainParts* AtomBrowserMainParts::self_ = NULL;
@ -50,6 +67,21 @@ AtomBrowserMainParts* AtomBrowserMainParts::Get() {
return self_;
}
content::BrowserContext* AtomBrowserMainParts::GetBrowserContextForPartition(
const GURL& partition) {
std::string id;
bool in_memory;
base::FilePath partition_path;
GetStoragePartitionConfig(partition, &partition_path, &in_memory, &id);
if (browser_context_map_.contains(id))
return browser_context_map_.get(id);
scoped_ptr<brightray::BrowserContext> browser_context(CreateBrowserContext());
browser_context->Initialize(partition_path.value(), in_memory);
browser_context_map_.set(id, browser_context.Pass());
return browser_context_map_.get(id);
}
void AtomBrowserMainParts::RegisterDestructionCallback(
const base::Closure& callback) {
destruction_callbacks_.push_back(callback);

View file

@ -6,10 +6,14 @@
#define ATOM_BROWSER_ATOM_BROWSER_MAIN_PARTS_H_
#include <list>
#include <map>
#include <string>
#include "base/callback.h"
#include "base/containers/scoped_ptr_hash_map.h"
#include "base/timer/timer.h"
#include "brightray/browser/browser_main_parts.h"
#include "content/public/browser/browser_context.h"
class BrowserProcess;
@ -29,6 +33,10 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
static AtomBrowserMainParts* Get();
// Returns the BrowserContext associated with the partition.
content::BrowserContext* GetBrowserContextForPartition(
const GURL& partition);
// Register a callback that should be destroyed before JavaScript environment
// gets destroyed.
void RegisterDestructionCallback(const base::Closure& callback);
@ -70,6 +78,10 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
// List of callbacks should be executed before destroying JS env.
std::list<base::Closure> destruction_callbacks_;
// partition_id => browser_context
base::ScopedPtrHashMap<std::string, scoped_ptr<brightray::BrowserContext>>
browser_context_map_;
static AtomBrowserMainParts* self_;
DISALLOW_COPY_AND_ASSIGN(AtomBrowserMainParts);

View file

@ -38,12 +38,29 @@ moveLastToFirst = (list) ->
getNextInstanceId = (webContents) ->
++nextInstanceId
# Generate URL encoded partition id.
getPartitionId = (partition) ->
# Guest site url will be chrome-guest://fake-host/{persist}?{partitionId}
partitionId = "chrome-guest://fake-host/"
if partition
persist = partition.startsWith('persist:')
if persist
partition = partition.substring('persist:'.length)
partitionId += 'persist?'
else
# Just to differentiate from same persistant ID
partition += "_temp"
partitionId += '?'
partitionId += encodeURIComponent(partition)
return partitionId
# Create a new guest instance.
createGuest = (embedder, params) ->
webViewManager ?= process.atomBinding 'web_view_manager'
id = getNextInstanceId embedder
guest = webContents.create {isGuest: true, embedder}
partitionId = getPartitionId params.partition
guest = webContents.create {isGuest: true, partition: partitionId, embedder}
guestInstances[id] = {guest, embedder}
# Destroy guest when the embedder is gone or navigated.
@ -120,6 +137,7 @@ attachGuest = (embedder, elementInstanceId, guestInstanceId, params) ->
plugins: params.plugins
disableWebSecurity: params.disablewebsecurity
preloadUrl: params.preload ? ''
partitionId: getPartitionId(params.partition)
guest.attachParams = params
embedderElementsMap[key] = guestInstanceId

View file

@ -0,0 +1,24 @@
// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/web_view_constants.h"
namespace atom {
namespace web_view {
const char kPreloadUrl[] = "preloadUrl";
const char kNodeIntegration[] = "nodeIntegration";
const char kPlugins[] = "plugins";
const char kDisableWebSecurity[] = "disableWebSecurity";
const char kPartitionId[] = "partitionId";
const int kDefaultWidth = 300;
const int kDefaultHeight = 300;
const char kWebViewInfoKeyName[] = "web_view_info";
} // namespace web_view
} // namespace atom

View file

@ -0,0 +1,27 @@
// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_WEB_VIEW_CONSTANTS_H_
#define ATOM_BROWSER_WEB_VIEW_CONSTANTS_H_
namespace atom {
namespace web_view {
extern const char kPreloadUrl[];
extern const char kNodeIntegration[];
extern const char kPlugins[];
extern const char kDisableWebSecurity[];
extern const char kPartitionId[];
extern const int kDefaultWidth;
extern const int kDefaultHeight;
extern const char kWebViewInfoKeyName[];
} // namespace web_view
} // namespace atom
#endif // ATOM_BROWSER_WEB_VIEW_CONSTANTS_H_

View file

@ -5,6 +5,7 @@
#include "atom/browser/web_view_guest_delegate.h"
#include "atom/browser/api/atom_api_web_contents.h"
#include "atom/browser/web_view_constants.h"
#include "atom/common/native_mate_converters/gurl_converter.h"
#include "content/public/browser/guest_host.h"
#include "content/public/browser/render_frame_host.h"
@ -13,13 +14,6 @@
namespace atom {
namespace {
const int kDefaultWidth = 300;
const int kDefaultHeight = 300;
} // namespace
WebViewGuestDelegate::WebViewGuestDelegate()
: guest_opaque_(true),
guest_host_(nullptr),
@ -178,7 +172,7 @@ gfx::Size WebViewGuestDelegate::GetDefaultSize() const {
return embedder_web_contents_->GetRenderWidgetHostView()
->GetVisibleViewportSize();
} else {
return gfx::Size(kDefaultWidth, kDefaultHeight);
return gfx::Size(web_view::kDefaultWidth, web_view::kDefaultHeight);
}
}

View file

@ -5,37 +5,12 @@
#include "atom/browser/web_view_manager.h"
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/atom_browser_main_parts.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
namespace atom {
namespace {
WebViewManager* GetManagerFromWebContents(
const content::WebContents* web_contents) {
auto context = web_contents->GetBrowserContext();
if (!context)
return nullptr;
return static_cast<WebViewManager*>(context->GetGuestManager());
}
} // namespace
// static
bool WebViewManager::GetInfoForWebContents(
const content::WebContents* web_contents, WebViewInfo* info) {
auto manager = GetManagerFromWebContents(web_contents);
if (!manager)
return false;
base::AutoLock auto_lock(manager->lock_);
auto iter = manager->webview_info_map_.find(web_contents);
if (iter == manager->webview_info_map_.end())
return false;
*info = iter->second;
return true;
}
WebViewManager::WebViewManager(content::BrowserContext* context) {
}
@ -45,11 +20,9 @@ WebViewManager::~WebViewManager() {
void WebViewManager::AddGuest(int guest_instance_id,
int element_instance_id,
content::WebContents* embedder,
content::WebContents* web_contents,
const WebViewInfo& info) {
content::WebContents* web_contents) {
base::AutoLock auto_lock(lock_);
web_contents_embdder_map_[guest_instance_id] = { web_contents, embedder };
webview_info_map_[web_contents] = info;
web_contents_embedder_map_[guest_instance_id] = { web_contents, embedder };
// Map the element in embedder to guest.
int owner_process_id = embedder->GetRenderProcessHost()->GetID();
@ -59,12 +32,10 @@ void WebViewManager::AddGuest(int guest_instance_id,
void WebViewManager::RemoveGuest(int guest_instance_id) {
base::AutoLock auto_lock(lock_);
if (!ContainsKey(web_contents_embdder_map_, guest_instance_id))
if (!ContainsKey(web_contents_embedder_map_, guest_instance_id))
return;
auto web_contents = web_contents_embdder_map_[guest_instance_id].web_contents;
web_contents_embdder_map_.erase(guest_instance_id);
webview_info_map_.erase(web_contents);
web_contents_embedder_map_.erase(guest_instance_id);
// Remove the record of element in embedder too.
for (const auto& element : element_instance_id_to_guest_map_)
@ -82,15 +53,15 @@ content::WebContents* WebViewManager::GetGuestByInstanceID(
return nullptr;
int guest_instance_id = element_instance_id_to_guest_map_[key];
if (ContainsKey(web_contents_embdder_map_, guest_instance_id))
return web_contents_embdder_map_[guest_instance_id].web_contents;
if (ContainsKey(web_contents_embedder_map_, guest_instance_id))
return web_contents_embedder_map_[guest_instance_id].web_contents;
else
return nullptr;
}
bool WebViewManager::ForEachGuest(content::WebContents* embedder_web_contents,
const GuestCallback& callback) {
for (auto& item : web_contents_embdder_map_)
for (auto& item : web_contents_embedder_map_)
if (item.second.embedder == embedder_web_contents &&
callback.Run(item.second.web_contents))
return true;

View file

@ -8,8 +8,10 @@
#include <map>
#include "base/files/file_path.h"
#include "base/supports_user_data.h"
#include "base/synchronization/lock.h"
#include "content/public/browser/browser_plugin_guest_manager.h"
#include "content/public/browser/site_instance.h"
namespace content {
class BrowserContext;
@ -27,12 +29,20 @@ class WebViewManager : public content::BrowserPluginGuestManager {
bool plugins;
bool disable_web_security;
base::FilePath preload_script;
GURL partition_id;
};
// Finds the WebViewManager attached with |web_contents| and returns the
// WebViewInfo of it.
static bool GetInfoForWebContents(const content::WebContents* web_contents,
WebViewInfo* info);
class WebViewInfoUserData : public base::SupportsUserData::Data {
public:
explicit WebViewInfoUserData(WebViewInfo info)
: web_view_info_(info) {}
~WebViewInfoUserData() override {}
WebViewInfo& web_view_info() { return web_view_info_; }
private:
WebViewInfo web_view_info_;
};
explicit WebViewManager(content::BrowserContext* context);
virtual ~WebViewManager();
@ -40,8 +50,7 @@ class WebViewManager : public content::BrowserPluginGuestManager {
void AddGuest(int guest_instance_id,
int element_instance_id,
content::WebContents* embedder,
content::WebContents* web_contents,
const WebViewInfo& info);
content::WebContents* web_contents);
void RemoveGuest(int guest_instance_id);
protected:
@ -57,7 +66,7 @@ class WebViewManager : public content::BrowserPluginGuestManager {
content::WebContents* embedder;
};
// guest_instance_id => (web_contents, embedder)
std::map<int, WebContentsWithEmbedder> web_contents_embdder_map_;
std::map<int, WebContentsWithEmbedder> web_contents_embedder_map_;
struct ElementInstanceKey {
int embedder_process_id;
@ -81,10 +90,6 @@ class WebViewManager : public content::BrowserPluginGuestManager {
// (embedder_process_id, element_instance_id) => guest_instance_id
std::map<ElementInstanceKey, int> element_instance_id_to_guest_map_;
typedef std::map<const content::WebContents*, WebViewInfo> WebViewInfoMap;
// web_contents => (guest_instance_id, embedder, ...)
WebViewInfoMap webview_info_map_;
base::Lock lock_;
DISALLOW_COPY_AND_ASSIGN(WebViewManager);

View file

@ -0,0 +1,29 @@
# Electron 和 NW.js (原名 node-webkit) 在技术上的差异
__备注Electron 的原名是 Atom Shell。__
与 NW.js 相似Electron 提供了一个能通过 JavaScript 和 HTML 创建桌面应用的平台,同时集成 Node 来授予网页访问底层系统的权限。
但是这两个项目也有本质上的区别,使得 Electron 和 NW.js 成为两个相互独立的产品。
__1. 应用的入口__
在 NW.js 中,一个应用的主入口是一个页面。你在 `package.json` 中指定一个主页面,它会作为应用的主窗口被打开。
在 Electron 中,入口是一个 JavaScript 脚本。不同于直接提供一个URL你需要手动创建一个浏览器窗口然后通过 API 加载 HTML 文件。你还可以监听窗口事件,决定何时让应用退出。
Electron 的工作方式更像 Node.js 运行时。 Electron 的 APIs 更加底层,因此你可以它替代 [PhantomJS](http://phantomjs.org/) 做浏览器测试。
__2. 构建系统__
为了避免构建整个 Chromium 带来的复杂度Electron 通过 [`libchromiumcontent`](https://github.com/brightray/libchromiumcontent) 来访问 Chromium 的 Content API。`libchromiumcontent` 是一个独立的、引入了 Chromium Content 模块及其所有依赖的共享库。用户不需要一个强劲的机器来构建 Electron。
__3. Node 集成__
在 NW.js网页中的 Node 集成需要通过给 Chromium 打补丁来实现。但在 Electron 中,我们选择了另一种方式:通过各个平台的消息循环与 libuv 的循环集成,避免了直接在 Chromium 上做改动。你可以看 [`node_bindings`](../../atom/common/) 来了解这是如何完成的。
__4. 多上下文__
如果你是有经验的 NW.js 用户,你应该会熟悉 Node 上下文和 web 上下文的概念。这些概念的产生源于 NW.js 的实现方式。
通过使用 Node 的[多上下文](http://strongloop.com/strongblog/whats-new-node-js-v0-12-multiple-context-execution/)特性Electron不需要在网页中引入新的 JavaScript 上下文。

View file

@ -0,0 +1,30 @@
# 编码规范
以下是 Electron 项目中代码书写规范的指导方针。
## C++ 和 Python
对于 C++ 和 Python我们追随 Chromium 的[Coding
Style](http://www.chromium.org/developers/coding-style)。你可以通过 `script/cpplint.py` 来检验所有文件是否符合要求。
我们使用的 Pyhton 版本是 Python 2.7。
其中 C++ 代码中用到了许多 Chromium 的抽象和类型,我们希望你对其有所熟悉。一个好的去处是
Chromium 的[重要的抽象和数据结构](https://www.chromium.org/developers/coding-style/important-abstractions-and-data-structures)。这个文档提到了一些特殊的类型、域内类型(当超出作用域时会自动释放内存)、日志机制等等。
## CoffeeScript
对于 CoffeeScript我们追随 GitHub 的[Style
Guide](https://github.com/styleguide/javascript) 及如下规则:
* 文件不应该以换行结尾,因为我们要匹配 Google 的规范。
* 文件名应该以 `-` 作连接而不是 `_`,等等。
`file-name.coffee` 而不是 `file_name.coffee`,因为在
[github/atom](https://github.com/github/atom) 模块名通常都是 `module-name` 的形式。这条规则仅应用于 `.coffee` 文件。
## API 名称
当新建一个API时我们应该倾向于 getters 和 setters 的方式,而不是
jQuery 的单函数形式。例如,`.getText()` 和 `.setText(text)`
优于 `.text([text])`。这里是相关的
[讨论记录](https://github.com/atom/electron/issues/46)。

View file

@ -0,0 +1,80 @@
# 在線/離線事件偵測
我們可以在渲染引擎 (renderer) 的行程裡用標準的 HTML5 API 來實作在線與離線事件的偵測。
請參考以下範例:
_main.js_
```javascript
var app = require('app');
var BrowserWindow = require('browser-window');
var onlineStatusWindow;
app.on('ready', function() {
onlineStatusWindow = new BrowserWindow({ width: 0, height: 0, show: false });
onlineStatusWindow.loadUrl('file://' + __dirname + '/online-status.html');
});
```
_online-status.html_
```html
<!DOCTYPE html>
<html>
<body>
<script>
var alertOnlineStatus = function() {
window.alert(navigator.onLine ? 'online' : 'offline');
};
window.addEventListener('online', alertOnlineStatus);
window.addEventListener('offline', alertOnlineStatus);
alertOnlineStatus();
</script>
</body>
</html>
```
您也許有時候也會有想要在主行程裡回應這些事件的情況。然而,在主行程裡並沒有 `navigator` 這個物件,因此不能直接地偵測這些事件。
但我們可以使用 Electron 所提供的跨行程 (inter-process) 溝通的工具,事件就可以被傳送到主程序內並做您所需的處理。
請參考以下範例:
_main.js_
```javascript
var app = require('app');
var ipc = require('ipc');
var BrowserWindow = require('browser-window');
var onlineStatusWindow;
app.on('ready', function() {
onlineStatusWindow = new BrowserWindow({ width: 0, height: 0, show: false });
onlineStatusWindow.loadUrl('file://' + __dirname + '/online-status.html');
});
ipc.on('online-status-changed', function(event, status) {
console.log(status);
});
```
_online-status.html_
```html
<!DOCTYPE html>
<html>
<body>
<script>
var ipc = require('ipc');
var updateOnlineStatus = function() {
ipc.send('online-status-changed', navigator.onLine ? 'online' : 'offline');
};
window.addEventListener('online', updateOnlineStatus);
window.addEventListener('offline', updateOnlineStatus);
updateOnlineStatus();
</script>
</body>
</html>
```

View file

@ -131,6 +131,24 @@ page is loaded, use the `setUserAgent` method to change the user agent.
If "on", the guest page will have web security disabled.
### partition
```html
<webview src="https://github.com" partition="persist:github"></webview>
<webview src="http://electron.atom.io" partition="electron"></webview>
```
Sets the storage partition used by the `webview`. If the storage partition ID starts with `persist:`,
the `webview` will use a persistent storage partition available to all `webview` in the app with
the same storage partition ID. if there is no `persist:` prefix, the `webview` will
use an in-memory storage partition. By assigning the same partition ID, multiple `webview`
can share the same storage partition. If the storage partition ID is unset then default storage
of the app will be used.
This value can only be modified before the first navigation, since the storage partition of an active
renderer process cannot change. Subsequent attempts to modify the value will fail with a
DOM exception.
## Methods
The `webview` tag has the following methods:

View file

@ -226,6 +226,8 @@
'atom/browser/ui/x/window_state_watcher.h',
'atom/browser/ui/x/x_window_utils.cc',
'atom/browser/ui/x/x_window_utils.h',
'atom/browser/web_view_constants.cc',
'atom/browser/web_view_constants.h',
'atom/browser/web_view_guest_delegate.cc',
'atom/browser/web_view_guest_delegate.h',
'atom/browser/web_view_manager.cc',

View file

@ -0,0 +1,4 @@
<script>
const item = window.localStorage.getItem('test');
console.log([item, window.localStorage.length].join(' '));
</script>

View file

@ -154,6 +154,45 @@ describe '<webview> tag', ->
webview.src = "data:text/html;base64,#{encoded}"
document.body.appendChild webview
describe 'partition attribute', ->
it 'inserts no node symbols when not set', (done) ->
webview.addEventListener 'console-message', (e) ->
assert.equal e.message, 'undefined undefined undefined undefined'
done()
webview.src = "file://#{fixtures}/pages/c.html"
webview.partition = "test"
document.body.appendChild webview
it 'inserts node symbols when set', (done) ->
webview.addEventListener 'console-message', (e) ->
assert.equal e.message, 'function object object'
done()
webview.setAttribute 'nodeintegration', 'on'
webview.src = "file://#{fixtures}/pages/d.html"
webview.partition = "test"
document.body.appendChild webview
it 'isolates storage for different id', (done) ->
listener = (e) ->
assert.equal e.message, " 0"
webview.removeEventListener 'console-message', listener
done()
window.localStorage.setItem 'test', 'one'
webview.addEventListener 'console-message', listener
webview.src = "file://#{fixtures}/pages/partition/one.html"
webview.partition = "test"
document.body.appendChild webview
it 'uses current session storage when no id is provided', (done) ->
listener = (e) ->
assert.equal e.message, "one 1"
webview.removeEventListener 'console-message', listener
done()
window.localStorage.setItem 'test', 'one'
webview.addEventListener 'console-message', listener
webview.src = "file://#{fixtures}/pages/partition/one.html"
document.body.appendChild webview
describe 'new-window event', ->
it 'emits when window.open is called', (done) ->
webview.addEventListener 'new-window', (e) ->