Merge pull request #6470 from electron/session-options
Ad options for creating Session
This commit is contained in:
commit
183b599b9c
14 changed files with 189 additions and 133 deletions
|
@ -497,7 +497,7 @@ bool App::IsAccessibilitySupportEnabled() {
|
||||||
void App::ImportCertificate(
|
void App::ImportCertificate(
|
||||||
const base::DictionaryValue& options,
|
const base::DictionaryValue& options,
|
||||||
const net::CompletionCallback& callback) {
|
const net::CompletionCallback& callback) {
|
||||||
auto browser_context = brightray::BrowserContext::From("", false);
|
auto browser_context = AtomBrowserContext::From("", false);
|
||||||
if (!certificate_manager_model_) {
|
if (!certificate_manager_model_) {
|
||||||
std::unique_ptr<base::DictionaryValue> copy = options.CreateDeepCopy();
|
std::unique_ptr<base::DictionaryValue> copy = options.CreateDeepCopy();
|
||||||
CertificateManagerModel::Create(
|
CertificateManagerModel::Create(
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include "atom/browser/atom_browser_client.h"
|
#include "atom/browser/atom_browser_client.h"
|
||||||
#include "atom/browser/atom_browser_main_parts.h"
|
#include "atom/browser/atom_browser_main_parts.h"
|
||||||
|
#include "atom/browser/browser.h"
|
||||||
#include "atom/browser/net/url_request_async_asar_job.h"
|
#include "atom/browser/net/url_request_async_asar_job.h"
|
||||||
#include "atom/browser/net/url_request_buffer_job.h"
|
#include "atom/browser/net/url_request_buffer_job.h"
|
||||||
#include "atom/browser/net/url_request_fetch_job.h"
|
#include "atom/browser/net/url_request_fetch_job.h"
|
||||||
|
@ -192,7 +193,13 @@ void Protocol::BuildPrototype(
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
void RegisterStandardSchemes(
|
void RegisterStandardSchemes(
|
||||||
const std::vector<std::string>& schemes) {
|
const std::vector<std::string>& schemes, mate::Arguments* args) {
|
||||||
|
if (atom::Browser::Get()->is_ready()) {
|
||||||
|
args->ThrowError("protocol.registerStandardSchemes should be called before "
|
||||||
|
"app is ready");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto policy = content::ChildProcessSecurityPolicy::GetInstance();
|
auto policy = content::ChildProcessSecurityPolicy::GetInstance();
|
||||||
for (const auto& scheme : schemes) {
|
for (const auto& scheme : schemes) {
|
||||||
url::AddStandardScheme(scheme.c_str(), url::SCHEME_WITHOUT_PORT);
|
url::AddStandardScheme(scheme.c_str(), url::SCHEME_WITHOUT_PORT);
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "atom/browser/api/atom_api_download_item.h"
|
#include "atom/browser/api/atom_api_download_item.h"
|
||||||
#include "atom/browser/api/atom_api_protocol.h"
|
#include "atom/browser/api/atom_api_protocol.h"
|
||||||
#include "atom/browser/api/atom_api_web_request.h"
|
#include "atom/browser/api/atom_api_web_request.h"
|
||||||
|
#include "atom/browser/browser.h"
|
||||||
#include "atom/browser/atom_browser_context.h"
|
#include "atom/browser/atom_browser_context.h"
|
||||||
#include "atom/browser/atom_browser_main_parts.h"
|
#include "atom/browser/atom_browser_main_parts.h"
|
||||||
#include "atom/browser/atom_permission_manager.h"
|
#include "atom/browser/atom_permission_manager.h"
|
||||||
|
@ -20,6 +21,7 @@
|
||||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||||
#include "atom/common/native_mate_converters/net_converter.h"
|
#include "atom/common/native_mate_converters/net_converter.h"
|
||||||
|
#include "atom/common/native_mate_converters/value_converter.h"
|
||||||
#include "atom/common/node_includes.h"
|
#include "atom/common/node_includes.h"
|
||||||
#include "base/files/file_path.h"
|
#include "base/files/file_path.h"
|
||||||
#include "base/guid.h"
|
#include "base/guid.h"
|
||||||
|
@ -163,6 +165,8 @@ namespace api {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
const char kPersistPrefix[] = "persist:";
|
||||||
|
|
||||||
// The wrapSession funtion which is implemented in JavaScript
|
// The wrapSession funtion which is implemented in JavaScript
|
||||||
using WrapSessionCallback = base::Callback<void(v8::Local<v8::Value>)>;
|
using WrapSessionCallback = base::Callback<void(v8::Local<v8::Value>)>;
|
||||||
WrapSessionCallback g_wrap_session;
|
WrapSessionCallback g_wrap_session;
|
||||||
|
@ -533,10 +537,19 @@ mate::Handle<Session> Session::CreateFrom(
|
||||||
|
|
||||||
// static
|
// static
|
||||||
mate::Handle<Session> Session::FromPartition(
|
mate::Handle<Session> Session::FromPartition(
|
||||||
v8::Isolate* isolate, const std::string& partition, bool in_memory) {
|
v8::Isolate* isolate, const std::string& partition,
|
||||||
auto browser_context = brightray::BrowserContext::From(partition, in_memory);
|
const base::DictionaryValue& options) {
|
||||||
return CreateFrom(isolate,
|
scoped_refptr<AtomBrowserContext> browser_context;
|
||||||
static_cast<AtomBrowserContext*>(browser_context.get()));
|
if (partition.empty()) {
|
||||||
|
browser_context = AtomBrowserContext::From("", false, options);
|
||||||
|
} else if (base::StartsWith(partition, kPersistPrefix,
|
||||||
|
base::CompareCase::SENSITIVE)) {
|
||||||
|
std::string name = partition.substr(8);
|
||||||
|
browser_context = AtomBrowserContext::From(name, false, options);
|
||||||
|
} else {
|
||||||
|
browser_context = AtomBrowserContext::From(partition, true, options);
|
||||||
|
}
|
||||||
|
return CreateFrom(isolate, browser_context.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
@ -576,11 +589,23 @@ void SetWrapSession(const WrapSessionCallback& callback) {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
v8::Local<v8::Value> FromPartition(
|
||||||
|
const std::string& partition, mate::Arguments* args) {
|
||||||
|
if (!atom::Browser::Get()->is_ready()) {
|
||||||
|
args->ThrowError("Session can only be received when app is ready");
|
||||||
|
return v8::Null(args->isolate());
|
||||||
|
}
|
||||||
|
base::DictionaryValue options;
|
||||||
|
args->GetNext(&options);
|
||||||
|
return atom::api::Session::FromPartition(
|
||||||
|
args->isolate(), partition, options).ToV8();
|
||||||
|
}
|
||||||
|
|
||||||
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||||
v8::Local<v8::Context> context, void* priv) {
|
v8::Local<v8::Context> context, void* priv) {
|
||||||
v8::Isolate* isolate = context->GetIsolate();
|
v8::Isolate* isolate = context->GetIsolate();
|
||||||
mate::Dictionary dict(isolate, exports);
|
mate::Dictionary dict(isolate, exports);
|
||||||
dict.SetMethod("fromPartition", &atom::api::Session::FromPartition);
|
dict.SetMethod("fromPartition", &FromPartition);
|
||||||
dict.SetMethod("_setWrapSession", &atom::api::SetWrapSession);
|
dict.SetMethod("_setWrapSession", &atom::api::SetWrapSession);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "atom/browser/api/trackable_object.h"
|
#include "atom/browser/api/trackable_object.h"
|
||||||
|
#include "base/values.h"
|
||||||
#include "content/public/browser/download_manager.h"
|
#include "content/public/browser/download_manager.h"
|
||||||
#include "native_mate/handle.h"
|
#include "native_mate/handle.h"
|
||||||
#include "net/base/completion_callback.h"
|
#include "net/base/completion_callback.h"
|
||||||
|
@ -47,9 +48,10 @@ class Session: public mate::TrackableObject<Session>,
|
||||||
static mate::Handle<Session> CreateFrom(
|
static mate::Handle<Session> CreateFrom(
|
||||||
v8::Isolate* isolate, AtomBrowserContext* browser_context);
|
v8::Isolate* isolate, AtomBrowserContext* browser_context);
|
||||||
|
|
||||||
// Gets the Session of |partition| and |in_memory|.
|
// Gets the Session of |partition|.
|
||||||
static mate::Handle<Session> FromPartition(
|
static mate::Handle<Session> FromPartition(
|
||||||
v8::Isolate* isolate, const std::string& partition, bool in_memory);
|
v8::Isolate* isolate, const std::string& partition,
|
||||||
|
const base::DictionaryValue& options = base::DictionaryValue());
|
||||||
|
|
||||||
AtomBrowserContext* browser_context() const { return browser_context_.get(); }
|
AtomBrowserContext* browser_context() const { return browser_context_.get(); }
|
||||||
|
|
||||||
|
|
|
@ -285,16 +285,11 @@ WebContents::WebContents(v8::Isolate* isolate,
|
||||||
std::string partition;
|
std::string partition;
|
||||||
mate::Handle<api::Session> session;
|
mate::Handle<api::Session> session;
|
||||||
if (options.Get("session", &session)) {
|
if (options.Get("session", &session)) {
|
||||||
} else if (options.Get("partition", &partition) && !partition.empty()) {
|
} else if (options.Get("partition", &partition)) {
|
||||||
bool in_memory = true;
|
session = Session::FromPartition(isolate, partition);
|
||||||
if (base::StartsWith(partition, "persist:", base::CompareCase::SENSITIVE)) {
|
|
||||||
in_memory = false;
|
|
||||||
partition = partition.substr(8);
|
|
||||||
}
|
|
||||||
session = Session::FromPartition(isolate, partition, in_memory);
|
|
||||||
} else {
|
} else {
|
||||||
// Use the default session if not specified.
|
// Use the default session if not specified.
|
||||||
session = Session::FromPartition(isolate, "", false);
|
session = Session::FromPartition(isolate, "");
|
||||||
}
|
}
|
||||||
session_.Reset(isolate, session.ToV8());
|
session_.Reset(isolate, session.ToV8());
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ void AtomAccessTokenStore::SaveAccessToken(const GURL& server_url,
|
||||||
}
|
}
|
||||||
|
|
||||||
void AtomAccessTokenStore::GetRequestContextOnUIThread() {
|
void AtomAccessTokenStore::GetRequestContextOnUIThread() {
|
||||||
auto browser_context = brightray::BrowserContext::From("", false);
|
auto browser_context = AtomBrowserContext::From("", false);
|
||||||
request_context_getter_ = browser_context->GetRequestContext();
|
request_context_getter_ = browser_context->GetRequestContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,8 +63,9 @@ std::string RemoveWhitespace(const std::string& str) {
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
AtomBrowserContext::AtomBrowserContext(const std::string& partition,
|
AtomBrowserContext::AtomBrowserContext(
|
||||||
bool in_memory)
|
const std::string& partition, bool in_memory,
|
||||||
|
const base::DictionaryValue& options)
|
||||||
: brightray::BrowserContext(partition, in_memory),
|
: brightray::BrowserContext(partition, in_memory),
|
||||||
network_delegate_(new AtomNetworkDelegate) {
|
network_delegate_(new AtomNetworkDelegate) {
|
||||||
// Construct user agent string.
|
// Construct user agent string.
|
||||||
|
@ -82,6 +83,10 @@ AtomBrowserContext::AtomBrowserContext(const std::string& partition,
|
||||||
CHROME_VERSION_STRING);
|
CHROME_VERSION_STRING);
|
||||||
}
|
}
|
||||||
user_agent_ = content::BuildUserAgentFromProduct(user_agent);
|
user_agent_ = content::BuildUserAgentFromProduct(user_agent);
|
||||||
|
|
||||||
|
// Read options.
|
||||||
|
use_cache_ = true;
|
||||||
|
options.GetBoolean("cache", &use_cache_);
|
||||||
}
|
}
|
||||||
|
|
||||||
AtomBrowserContext::~AtomBrowserContext() {
|
AtomBrowserContext::~AtomBrowserContext() {
|
||||||
|
@ -144,7 +149,7 @@ net::HttpCache::BackendFactory*
|
||||||
AtomBrowserContext::CreateHttpCacheBackendFactory(
|
AtomBrowserContext::CreateHttpCacheBackendFactory(
|
||||||
const base::FilePath& base_path) {
|
const base::FilePath& base_path) {
|
||||||
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
|
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
|
||||||
if (command_line->HasSwitch(switches::kDisableHttpCache))
|
if (!use_cache_ || command_line->HasSwitch(switches::kDisableHttpCache))
|
||||||
return new NoCacheBackend;
|
return new NoCacheBackend;
|
||||||
else
|
else
|
||||||
return brightray::BrowserContext::CreateHttpCacheBackendFactory(base_path);
|
return brightray::BrowserContext::CreateHttpCacheBackendFactory(base_path);
|
||||||
|
@ -190,14 +195,15 @@ void AtomBrowserContext::RegisterPrefs(PrefRegistrySimple* pref_registry) {
|
||||||
pref_registry->RegisterDictionaryPref(prefs::kDevToolsFileSystemPaths);
|
pref_registry->RegisterDictionaryPref(prefs::kDevToolsFileSystemPaths);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace atom
|
|
||||||
|
|
||||||
namespace brightray {
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
scoped_refptr<BrowserContext> BrowserContext::Create(
|
scoped_refptr<AtomBrowserContext> AtomBrowserContext::From(
|
||||||
const std::string& partition, bool in_memory) {
|
const std::string& partition, bool in_memory,
|
||||||
return make_scoped_refptr(new atom::AtomBrowserContext(partition, in_memory));
|
const base::DictionaryValue& options) {
|
||||||
|
auto browser_context = brightray::BrowserContext::Get(partition, in_memory);
|
||||||
|
if (browser_context)
|
||||||
|
return static_cast<AtomBrowserContext*>(browser_context.get());
|
||||||
|
|
||||||
|
return new AtomBrowserContext(partition, in_memory, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace brightray
|
} // namespace atom
|
||||||
|
|
|
@ -18,8 +18,12 @@ class WebViewManager;
|
||||||
|
|
||||||
class AtomBrowserContext : public brightray::BrowserContext {
|
class AtomBrowserContext : public brightray::BrowserContext {
|
||||||
public:
|
public:
|
||||||
AtomBrowserContext(const std::string& partition, bool in_memory);
|
// Get or create the BrowserContext according to its |partition| and
|
||||||
~AtomBrowserContext() override;
|
// |in_memory|. The |options| will be passed to constructor when there is no
|
||||||
|
// existing BrowserContext.
|
||||||
|
static scoped_refptr<AtomBrowserContext> From(
|
||||||
|
const std::string& partition, bool in_memory,
|
||||||
|
const base::DictionaryValue& options = base::DictionaryValue());
|
||||||
|
|
||||||
void SetUserAgent(const std::string& user_agent);
|
void SetUserAgent(const std::string& user_agent);
|
||||||
|
|
||||||
|
@ -43,11 +47,17 @@ class AtomBrowserContext : public brightray::BrowserContext {
|
||||||
|
|
||||||
AtomNetworkDelegate* network_delegate() const { return network_delegate_; }
|
AtomNetworkDelegate* network_delegate() const { return network_delegate_; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
AtomBrowserContext(const std::string& partition, bool in_memory,
|
||||||
|
const base::DictionaryValue& options);
|
||||||
|
~AtomBrowserContext() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<AtomDownloadManagerDelegate> download_manager_delegate_;
|
std::unique_ptr<AtomDownloadManagerDelegate> download_manager_delegate_;
|
||||||
std::unique_ptr<WebViewManager> guest_manager_;
|
std::unique_ptr<WebViewManager> guest_manager_;
|
||||||
std::unique_ptr<AtomPermissionManager> permission_manager_;
|
std::unique_ptr<AtomPermissionManager> permission_manager_;
|
||||||
std::string user_agent_;
|
std::string user_agent_;
|
||||||
|
bool use_cache_;
|
||||||
|
|
||||||
// Managed by brightray::BrowserContext.
|
// Managed by brightray::BrowserContext.
|
||||||
AtomNetworkDelegate* network_delegate_;
|
AtomNetworkDelegate* network_delegate_;
|
||||||
|
|
|
@ -20,17 +20,25 @@ const ses = win.webContents.session
|
||||||
|
|
||||||
The `session` module has the following methods:
|
The `session` module has the following methods:
|
||||||
|
|
||||||
### session.fromPartition(partition)
|
### session.fromPartition(partition[, options])
|
||||||
|
|
||||||
* `partition` String
|
* `partition` String
|
||||||
|
* `options` Object
|
||||||
|
* `cache` Boolean - Whether to enable cache.
|
||||||
|
|
||||||
Returns a new `Session` instance from `partition` string.
|
Returns a `Session` instance from `partition` string. When there is an existing
|
||||||
|
`Session` with the same `partition`, it will be returned; othewise a new
|
||||||
|
`Session` instance will be created with `options`.
|
||||||
|
|
||||||
If `partition` starts with `persist:`, the page will use a persistent session
|
If `partition` starts with `persist:`, the page will use a persistent session
|
||||||
available to all pages in the app with the same `partition`. if there is no
|
available to all pages in the app with the same `partition`. if there is no
|
||||||
`persist:` prefix, the page will use an in-memory session. If the `partition` is
|
`persist:` prefix, the page will use an in-memory session. If the `partition` is
|
||||||
empty then default session of the app will be returned.
|
empty then default session of the app will be returned.
|
||||||
|
|
||||||
|
To create a `Session` with `options`, you have to ensure the `Session` with the
|
||||||
|
`partition` has never been used before. There is no way to change the `options`
|
||||||
|
of an existing `Session` object.
|
||||||
|
|
||||||
## Properties
|
## Properties
|
||||||
|
|
||||||
The `session` module has the following properties:
|
The `session` module has the following properties:
|
||||||
|
|
|
@ -1,23 +1,27 @@
|
||||||
const {app, session} = require('electron')
|
const {app, session} = require('electron')
|
||||||
const {registerStandardSchemes} = process.atomBinding('protocol')
|
|
||||||
|
|
||||||
exports.registerStandardSchemes = function (schemes) {
|
// Global protocol APIs.
|
||||||
if (app.isReady()) {
|
module.exports = process.atomBinding('protocol')
|
||||||
console.warn('protocol.registerStandardSchemes should be called before app is ready')
|
|
||||||
return
|
// Fallback protocol APIs of default session.
|
||||||
|
Object.setPrototypeOf(module.exports, new Proxy({}, {
|
||||||
|
get (target, property) {
|
||||||
|
if (!app.isReady()) return
|
||||||
|
|
||||||
|
const protocol = session.defaultSession.protocol
|
||||||
|
if (!protocol.hasOwnProperty(property)) return
|
||||||
|
|
||||||
|
// Returning a native function directly would throw error.
|
||||||
|
return (...args) => protocol[property](...args)
|
||||||
|
},
|
||||||
|
|
||||||
|
ownKeys () {
|
||||||
|
if (!app.isReady()) return []
|
||||||
|
|
||||||
|
return Object.getOwnPropertyNames(session.defaultSession.protocol)
|
||||||
|
},
|
||||||
|
|
||||||
|
getOwnPropertyDescriptor (target) {
|
||||||
|
return { configurable: true, enumerable: true }
|
||||||
}
|
}
|
||||||
registerStandardSchemes(schemes)
|
}))
|
||||||
}
|
|
||||||
|
|
||||||
const setupProtocol = function () {
|
|
||||||
let protocol = session.defaultSession.protocol
|
|
||||||
for (let method in protocol) {
|
|
||||||
exports[method] = protocol[method].bind(protocol)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (app.isReady()) {
|
|
||||||
setupProtocol()
|
|
||||||
} else {
|
|
||||||
app.once('ready', setupProtocol)
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,44 +1,22 @@
|
||||||
const {EventEmitter} = require('events')
|
const {EventEmitter} = require('events')
|
||||||
const electron = require('electron')
|
const {app} = require('electron')
|
||||||
const bindings = process.atomBinding('session')
|
const {fromPartition, _setWrapSession} = process.atomBinding('session')
|
||||||
|
|
||||||
const PERSIST_PREFIX = 'persist:'
|
|
||||||
const Session = new EventEmitter()
|
|
||||||
|
|
||||||
// Wrapper of binding.fromPartition that checks for ready event.
|
|
||||||
const fromPartition = function (partition, persist) {
|
|
||||||
if (!electron.app.isReady()) {
|
|
||||||
throw new Error('session module can only be used when app is ready')
|
|
||||||
}
|
|
||||||
|
|
||||||
return bindings.fromPartition(partition, persist)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the Session from |partition| string.
|
|
||||||
Session.fromPartition = function (partition = '') {
|
|
||||||
if (partition === '') return exports.defaultSession
|
|
||||||
|
|
||||||
if (partition.startsWith(PERSIST_PREFIX)) {
|
|
||||||
return fromPartition(partition.substr(PERSIST_PREFIX.length), false)
|
|
||||||
} else {
|
|
||||||
return fromPartition(partition, true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the default session.
|
// Returns the default session.
|
||||||
Object.defineProperty(Session, 'defaultSession', {
|
Object.defineProperties(exports, {
|
||||||
enumerable: true,
|
defaultSession: {
|
||||||
get: function () {
|
enumerable: true,
|
||||||
return fromPartition('', false)
|
get () { return fromPartition('') }
|
||||||
|
},
|
||||||
|
fromPartition: {
|
||||||
|
enumerable: true,
|
||||||
|
value: fromPartition
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const wrapSession = function (session) {
|
// Wraps native Session class.
|
||||||
|
_setWrapSession(function (session) {
|
||||||
// Session is an EventEmitter.
|
// Session is an EventEmitter.
|
||||||
Object.setPrototypeOf(session, EventEmitter.prototype)
|
Object.setPrototypeOf(session, EventEmitter.prototype)
|
||||||
Session.emit('session-created', session)
|
app.emit('session-created', session)
|
||||||
}
|
})
|
||||||
|
|
||||||
bindings._setWrapSession(wrapSession)
|
|
||||||
|
|
||||||
module.exports = Session
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
const {app, ipcMain, session, webContents, BrowserWindow} = require('electron')
|
const {app, ipcMain, webContents, BrowserWindow} = require('electron')
|
||||||
const {getAllWebContents} = process.atomBinding('web_contents')
|
const {getAllWebContents} = process.atomBinding('web_contents')
|
||||||
const renderProcessPreferences = process.atomBinding('render_process_preferences').forAllWebContents()
|
const renderProcessPreferences = process.atomBinding('render_process_preferences').forAllWebContents()
|
||||||
|
|
||||||
|
@ -86,6 +86,7 @@ const startBackgroundPages = function (manifest) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const contents = webContents.create({
|
const contents = webContents.create({
|
||||||
|
partition: 'persist:__chrome_extension',
|
||||||
isBackgroundPage: true,
|
isBackgroundPage: true,
|
||||||
commandLineSwitches: ['--background-page']
|
commandLineSwitches: ['--background-page']
|
||||||
})
|
})
|
||||||
|
@ -284,6 +285,39 @@ app.on('web-contents-created', function (event, webContents) {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// The chrome-extension: can map a extension URL request to real file path.
|
||||||
|
const chromeExtensionHandler = function (request, callback) {
|
||||||
|
const parsed = url.parse(request.url)
|
||||||
|
if (!parsed.hostname || !parsed.path) return callback()
|
||||||
|
|
||||||
|
const manifest = manifestMap[parsed.hostname]
|
||||||
|
if (!manifest) return callback()
|
||||||
|
|
||||||
|
const page = backgroundPages[parsed.hostname]
|
||||||
|
if (page && parsed.path === `/${page.name}`) {
|
||||||
|
return callback({
|
||||||
|
mimeType: 'text/html',
|
||||||
|
data: page.html
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.readFile(path.join(manifest.srcDirectory, parsed.path), function (err, content) {
|
||||||
|
if (err) {
|
||||||
|
return callback(-6) // FILE_NOT_FOUND
|
||||||
|
} else {
|
||||||
|
return callback(content)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
app.on('session-created', function (ses) {
|
||||||
|
ses.protocol.registerBufferProtocol('chrome-extension', chromeExtensionHandler, function (error) {
|
||||||
|
if (error) {
|
||||||
|
console.error(`Unable to register chrome-extension protocol: ${error}`)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
// The persistent path of "DevTools Extensions" preference file.
|
// The persistent path of "DevTools Extensions" preference file.
|
||||||
let loadedExtensionsPath = null
|
let loadedExtensionsPath = null
|
||||||
|
|
||||||
|
@ -309,38 +343,6 @@ app.on('will-quit', function () {
|
||||||
|
|
||||||
// We can not use protocol or BrowserWindow until app is ready.
|
// We can not use protocol or BrowserWindow until app is ready.
|
||||||
app.once('ready', function () {
|
app.once('ready', function () {
|
||||||
// The chrome-extension: can map a extension URL request to real file path.
|
|
||||||
const chromeExtensionHandler = function (request, callback) {
|
|
||||||
const parsed = url.parse(request.url)
|
|
||||||
if (!parsed.hostname || !parsed.path) return callback()
|
|
||||||
|
|
||||||
const manifest = manifestMap[parsed.hostname]
|
|
||||||
if (!manifest) return callback()
|
|
||||||
|
|
||||||
const page = backgroundPages[parsed.hostname]
|
|
||||||
if (page && parsed.path === `/${page.name}`) {
|
|
||||||
return callback({
|
|
||||||
mimeType: 'text/html',
|
|
||||||
data: page.html
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fs.readFile(path.join(manifest.srcDirectory, parsed.path), function (err, content) {
|
|
||||||
if (err) {
|
|
||||||
return callback(-6) // FILE_NOT_FOUND
|
|
||||||
} else {
|
|
||||||
return callback(content)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
session.on('session-created', function (ses) {
|
|
||||||
ses.protocol.registerBufferProtocol('chrome-extension', chromeExtensionHandler, function (error) {
|
|
||||||
if (error) {
|
|
||||||
console.error(`Unable to register chrome-extension protocol: ${error}`)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
// Load persisted extensions.
|
// Load persisted extensions.
|
||||||
loadedExtensionsPath = path.join(app.getPath('userData'), 'DevTools Extensions')
|
loadedExtensionsPath = path.join(app.getPath('userData'), 'DevTools Extensions')
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -3,12 +3,8 @@ const http = require('http')
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
const fs = require('fs')
|
const fs = require('fs')
|
||||||
|
|
||||||
const ipcRenderer = require('electron').ipcRenderer
|
const {ipcRenderer, remote} = require('electron')
|
||||||
const remote = require('electron').remote
|
const {ipcMain, session, BrowserWindow} = remote
|
||||||
|
|
||||||
const ipcMain = remote.ipcMain
|
|
||||||
const session = remote.session
|
|
||||||
const BrowserWindow = remote.BrowserWindow
|
|
||||||
|
|
||||||
describe('session module', function () {
|
describe('session module', function () {
|
||||||
this.timeout(10000)
|
this.timeout(10000)
|
||||||
|
@ -35,7 +31,30 @@ describe('session module', function () {
|
||||||
w = null
|
w = null
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('session.cookies', function () {
|
describe('session.defaultSession', function () {
|
||||||
|
it('returns the default session', function () {
|
||||||
|
assert.equal(session.defaultSession, session.fromPartition(''))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('session.fromPartition(partition, options)', function () {
|
||||||
|
it('returns existing session with same partition', function () {
|
||||||
|
assert.equal(session.fromPartition('test'), session.fromPartition('test'))
|
||||||
|
})
|
||||||
|
|
||||||
|
it('created session is ref-counted', function () {
|
||||||
|
const partition = 'test2'
|
||||||
|
const userAgent = 'test-agent'
|
||||||
|
const ses1 = session.fromPartition(partition)
|
||||||
|
ses1.setUserAgent(userAgent)
|
||||||
|
assert.equal(ses1.getUserAgent(), userAgent)
|
||||||
|
ses1.destroy()
|
||||||
|
const ses2 = session.fromPartition(partition)
|
||||||
|
assert.notEqual(ses2.getUserAgent(), userAgent)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('ses.cookies', function () {
|
||||||
it('should get cookies', function (done) {
|
it('should get cookies', function (done) {
|
||||||
var server = http.createServer(function (req, res) {
|
var server = http.createServer(function (req, res) {
|
||||||
res.setHeader('Set-Cookie', ['0=0'])
|
res.setHeader('Set-Cookie', ['0=0'])
|
||||||
|
@ -141,7 +160,7 @@ describe('session module', function () {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('session.clearStorageData(options)', function () {
|
describe('ses.clearStorageData(options)', function () {
|
||||||
fixtures = path.resolve(__dirname, 'fixtures')
|
fixtures = path.resolve(__dirname, 'fixtures')
|
||||||
it('clears localstorage data', function (done) {
|
it('clears localstorage data', function (done) {
|
||||||
ipcMain.on('count', function (event, count) {
|
ipcMain.on('count', function (event, count) {
|
||||||
|
@ -163,7 +182,7 @@ describe('session module', function () {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('session will-download event', function () {
|
describe('will-download event', function () {
|
||||||
var w = null
|
var w = null
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
|
@ -280,7 +299,7 @@ describe('session module', function () {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('session.protocol', function () {
|
describe('ses.protocol', function () {
|
||||||
const partitionName = 'temp'
|
const partitionName = 'temp'
|
||||||
const protocolName = 'sp'
|
const protocolName = 'sp'
|
||||||
const partitionProtocol = session.fromPartition(partitionName).protocol
|
const partitionProtocol = session.fromPartition(partitionName).protocol
|
||||||
|
|
2
vendor/brightray
vendored
2
vendor/brightray
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 3b993f9fd7ffdd0e92bb77521a8b7f32af5eba5b
|
Subproject commit 91abdb01a1825c12522fd5fc2349a7ba9a091a48
|
Loading…
Reference in a new issue