Merge remote-tracking branch 'refs/remotes/atom/master'
This commit is contained in:
commit
ec16c6a146
28 changed files with 280 additions and 25 deletions
23
appveyor.yml
Normal file
23
appveyor.yml
Normal file
|
@ -0,0 +1,23 @@
|
|||
# appveyor file
|
||||
# http://www.appveyor.com/docs/appveyor-yml
|
||||
version: "{build}"
|
||||
|
||||
init:
|
||||
- git config --global core.autocrlf input
|
||||
|
||||
platform:
|
||||
- x86
|
||||
- x64
|
||||
|
||||
install:
|
||||
- cmd: SET PATH=C:\Program Files (x86)\MSBuild\12.0\bin\;%PATH%
|
||||
- cmd: SET PATH=C:\python27;%PATH%
|
||||
- cmd: python script/cibuild
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
|
||||
# disable build and test pahses
|
||||
build: off
|
||||
test: off
|
|
@ -17,6 +17,7 @@
|
|||
#include "content/public/common/pepper_plugin_info.h"
|
||||
#include "content/public/common/user_agent.h"
|
||||
#include "ppapi/shared_impl/ppapi_permissions.h"
|
||||
#include "url/url_constants.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
|
@ -62,6 +63,17 @@ content::PepperPluginInfo CreatePepperFlashInfo(const base::FilePath& path,
|
|||
return plugin;
|
||||
}
|
||||
|
||||
void ConvertStringWithSeparatorToVector(std::vector<std::string>* vec,
|
||||
const char* separator,
|
||||
const char* cmd_switch) {
|
||||
auto command_line = base::CommandLine::ForCurrentProcess();
|
||||
auto string_with_separator = command_line->GetSwitchValueASCII(cmd_switch);
|
||||
if (!string_with_separator.empty())
|
||||
*vec = base::SplitString(string_with_separator, separator,
|
||||
base::TRIM_WHITESPACE,
|
||||
base::SPLIT_WANT_NONEMPTY);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
AtomContentClient::AtomContentClient() {
|
||||
|
@ -83,12 +95,10 @@ std::string AtomContentClient::GetUserAgent() const {
|
|||
void AtomContentClient::AddAdditionalSchemes(
|
||||
std::vector<url::SchemeWithType>* standard_schemes,
|
||||
std::vector<std::string>* savable_schemes) {
|
||||
auto command_line = base::CommandLine::ForCurrentProcess();
|
||||
auto custom_schemes = command_line->GetSwitchValueASCII(
|
||||
switches::kRegisterStandardSchemes);
|
||||
if (!custom_schemes.empty()) {
|
||||
std::vector<std::string> schemes = base::SplitString(
|
||||
custom_schemes, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
|
||||
std::vector<std::string> schemes;
|
||||
ConvertStringWithSeparatorToVector(&schemes, ",",
|
||||
switches::kRegisterStandardSchemes);
|
||||
if (!schemes.empty()) {
|
||||
for (const std::string& scheme : schemes)
|
||||
standard_schemes->push_back({scheme.c_str(), url::SCHEME_WITHOUT_PORT});
|
||||
}
|
||||
|
@ -110,4 +120,16 @@ void AtomContentClient::AddPepperPlugins(
|
|||
CreatePepperFlashInfo(flash_path, flash_version));
|
||||
}
|
||||
|
||||
void AtomContentClient::AddServiceWorkerSchemes(
|
||||
std::set<std::string>* service_worker_schemes) {
|
||||
std::vector<std::string> schemes;
|
||||
ConvertStringWithSeparatorToVector(&schemes, ",",
|
||||
switches::kRegisterServiceWorkerSchemes);
|
||||
if (!schemes.empty()) {
|
||||
for (const std::string& scheme : schemes)
|
||||
service_worker_schemes->insert(scheme);
|
||||
}
|
||||
service_worker_schemes->insert(url::kFileScheme);
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#ifndef ATOM_APP_ATOM_CONTENT_CLIENT_H_
|
||||
#define ATOM_APP_ATOM_CONTENT_CLIENT_H_
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
@ -26,6 +27,8 @@ class AtomContentClient : public brightray::ContentClient {
|
|||
std::vector<std::string>* savable_schemes) override;
|
||||
void AddPepperPlugins(
|
||||
std::vector<content::PepperPluginInfo>* plugins) override;
|
||||
void AddServiceWorkerSchemes(
|
||||
std::set<std::string>* service_worker_schemes) override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomContentClient);
|
||||
|
|
|
@ -7,10 +7,6 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include <stdio.h>
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <windows.h>
|
||||
#include <shellscalingapi.h>
|
||||
#include <tchar.h>
|
||||
|
@ -56,12 +52,6 @@ bool IsRunAsNode() {
|
|||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
bool IsCygwin() {
|
||||
std::string os;
|
||||
scoped_ptr<base::Environment> env(base::Environment::Create());
|
||||
return env->GetVar("OS", &os) && os == "cygwin";
|
||||
}
|
||||
|
||||
// Win8.1 supports monitor-specific DPI scaling.
|
||||
bool SetProcessDpiAwarenessWrapper(PROCESS_DPI_AWARENESS value) {
|
||||
typedef HRESULT(WINAPI *SetProcessDpiAwarenessPtr)(PROCESS_DPI_AWARENESS);
|
||||
|
@ -109,7 +99,7 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
|||
wchar_t** wargv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
|
||||
|
||||
// Make output work in console if we are not in cygiwn.
|
||||
if (!IsCygwin() && !IsEnvSet("ELECTRON_NO_ATTACH_CONSOLE")) {
|
||||
if (!IsEnvSet("TERM") && !IsEnvSet("ELECTRON_NO_ATTACH_CONSOLE")) {
|
||||
AttachConsole(ATTACH_PARENT_PROCESS);
|
||||
|
||||
FILE* dontcare;
|
||||
|
|
|
@ -181,7 +181,8 @@ void App::OnWindowAllClosed() {
|
|||
}
|
||||
|
||||
void App::OnQuit() {
|
||||
Emit("quit");
|
||||
int exitCode = AtomBrowserMainParts::Get()->GetExitCode();
|
||||
Emit("quit", exitCode);
|
||||
|
||||
if (process_singleton_.get()) {
|
||||
process_singleton_->Cleanup();
|
||||
|
|
|
@ -32,6 +32,8 @@ mate::ObjectTemplateBuilder Protocol::GetObjectTemplateBuilder(
|
|||
v8::Isolate* isolate) {
|
||||
return mate::ObjectTemplateBuilder(isolate)
|
||||
.SetMethod("registerStandardSchemes", &Protocol::RegisterStandardSchemes)
|
||||
.SetMethod("registerServiceWorkerSchemes",
|
||||
&Protocol::RegisterServiceWorkerSchemes)
|
||||
.SetMethod("registerStringProtocol",
|
||||
&Protocol::RegisterProtocol<URLRequestStringJob>)
|
||||
.SetMethod("registerBufferProtocol",
|
||||
|
@ -58,6 +60,11 @@ void Protocol::RegisterStandardSchemes(
|
|||
atom::AtomBrowserClient::SetCustomSchemes(schemes);
|
||||
}
|
||||
|
||||
void Protocol::RegisterServiceWorkerSchemes(
|
||||
const std::vector<std::string>& schemes) {
|
||||
atom::AtomBrowserClient::SetCustomServiceWorkerSchemes(schemes);
|
||||
}
|
||||
|
||||
void Protocol::UnregisterProtocol(
|
||||
const std::string& scheme, mate::Arguments* args) {
|
||||
CompletionCallback callback;
|
||||
|
|
|
@ -92,6 +92,9 @@ class Protocol : public mate::Wrappable {
|
|||
// Register schemes to standard scheme list.
|
||||
void RegisterStandardSchemes(const std::vector<std::string>& schemes);
|
||||
|
||||
// Register schemes that can handle service worker.
|
||||
void RegisterServiceWorkerSchemes(const std::vector<std::string>& schemes);
|
||||
|
||||
// Register the protocol with certain request job.
|
||||
template<typename RequestJob>
|
||||
void RegisterProtocol(const std::string& scheme,
|
||||
|
|
|
@ -54,6 +54,8 @@ bool g_suppress_renderer_process_restart = false;
|
|||
|
||||
// Custom schemes to be registered to standard.
|
||||
std::string g_custom_schemes = "";
|
||||
// Custom schemes to be registered to handle service worker.
|
||||
std::string g_custom_service_worker_schemes = "";
|
||||
|
||||
scoped_refptr<net::X509Certificate> ImportCertFromFile(
|
||||
const base::FilePath& path) {
|
||||
|
@ -87,6 +89,11 @@ void AtomBrowserClient::SetCustomSchemes(
|
|||
g_custom_schemes = base::JoinString(schemes, ",");
|
||||
}
|
||||
|
||||
void AtomBrowserClient::SetCustomServiceWorkerSchemes(
|
||||
const std::vector<std::string>& schemes) {
|
||||
g_custom_service_worker_schemes = base::JoinString(schemes, ",");
|
||||
}
|
||||
|
||||
AtomBrowserClient::AtomBrowserClient() : delegate_(nullptr) {
|
||||
}
|
||||
|
||||
|
@ -172,6 +179,11 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches(
|
|||
command_line->AppendSwitchASCII(switches::kRegisterStandardSchemes,
|
||||
g_custom_schemes);
|
||||
|
||||
// The registered service worker schemes.
|
||||
if (!g_custom_service_worker_schemes.empty())
|
||||
command_line->AppendSwitchASCII(switches::kRegisterServiceWorkerSchemes,
|
||||
g_custom_service_worker_schemes);
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Append --app-user-model-id.
|
||||
PWSTR current_app_id;
|
||||
|
|
|
@ -38,6 +38,9 @@ class AtomBrowserClient : public brightray::BrowserClient,
|
|||
static void SuppressRendererProcessRestartForOnce();
|
||||
// Custom schemes to be registered to standard.
|
||||
static void SetCustomSchemes(const std::vector<std::string>& schemes);
|
||||
// Custom schemes to be registered to handle service worker.
|
||||
static void SetCustomServiceWorkerSchemes(
|
||||
const std::vector<std::string>& schemes);
|
||||
|
||||
protected:
|
||||
// content::ContentBrowserClient:
|
||||
|
|
|
@ -61,6 +61,10 @@ bool AtomBrowserMainParts::SetExitCode(int code) {
|
|||
return true;
|
||||
}
|
||||
|
||||
int AtomBrowserMainParts::GetExitCode() {
|
||||
return exit_code_ != nullptr ? *exit_code_ : 0;
|
||||
}
|
||||
|
||||
base::Closure AtomBrowserMainParts::RegisterDestructionCallback(
|
||||
const base::Closure& callback) {
|
||||
auto iter = destructors_.insert(destructors_.end(), callback);
|
||||
|
|
|
@ -34,6 +34,9 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
|
|||
// Sets the exit code, will fail if the the message loop is not ready.
|
||||
bool SetExitCode(int code);
|
||||
|
||||
// Gets the exit code
|
||||
int GetExitCode();
|
||||
|
||||
// Register a callback that should be destroyed before JavaScript environment
|
||||
// gets destroyed.
|
||||
// Returns a closure that can be used to remove |callback| from the list.
|
||||
|
|
|
@ -55,7 +55,7 @@ void Browser::Exit(int code) {
|
|||
// Must destroy windows before quitting, otherwise bad things can happen.
|
||||
atom::WindowList* window_list = atom::WindowList::GetInstance();
|
||||
if (window_list->size() == 0) {
|
||||
NotifyAndShutdown();
|
||||
Shutdown();
|
||||
} else {
|
||||
// Unlike Quit(), we do not ask to close window, but destroy the window
|
||||
// without asking.
|
||||
|
|
|
@ -53,8 +53,8 @@ process.on 'uncaughtException', (error) ->
|
|||
|
||||
# Emit 'exit' event on quit.
|
||||
{app} = require 'electron'
|
||||
app.on 'quit', ->
|
||||
process.emit 'exit'
|
||||
app.on 'quit', (event, exitCode) ->
|
||||
process.emit 'exit', exitCode
|
||||
|
||||
# Map process.exit to app.exit, which quits gracefully.
|
||||
process.exit = app.exit
|
||||
|
|
|
@ -21,6 +21,9 @@
|
|||
}
|
||||
|
||||
- (void)applicationWillFinishLaunching:(NSNotification*)notify {
|
||||
// Don't add the "Enter Full Screen" menu item automatically.
|
||||
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"NSFullScreenMenuItemEverywhere"];
|
||||
|
||||
atom::Browser::Get()->WillFinishLaunching();
|
||||
}
|
||||
|
||||
|
|
|
@ -7,13 +7,14 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/common/asar/archive.h"
|
||||
#include "atom/common/asar/asar_util.h"
|
||||
#include "atom/common/atom_constants.h"
|
||||
#include "base/bind.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/synchronization/lock.h"
|
||||
#include "base/task_runner.h"
|
||||
#include "atom/common/asar/archive.h"
|
||||
#include "atom/common/asar/asar_util.h"
|
||||
#include "net/base/file_stream.h"
|
||||
#include "net/base/filename_util.h"
|
||||
#include "net/base/io_buffer.h"
|
||||
|
@ -227,6 +228,19 @@ void URLRequestAsarJob::SetExtraRequestHeaders(
|
|||
}
|
||||
}
|
||||
|
||||
int URLRequestAsarJob::GetResponseCode() const {
|
||||
// Request Job gets created only if path exists.
|
||||
return 200;
|
||||
}
|
||||
|
||||
void URLRequestAsarJob::GetResponseInfo(net::HttpResponseInfo* info) {
|
||||
std::string status("HTTP/1.1 200 OK");
|
||||
net::HttpResponseHeaders* headers = new net::HttpResponseHeaders(status);
|
||||
|
||||
headers->AddHeader(atom::kCORSHeader);
|
||||
info->headers = headers;
|
||||
}
|
||||
|
||||
void URLRequestAsarJob::FetchMetaInfo(const base::FilePath& file_path,
|
||||
FileMetaInfo* meta_info) {
|
||||
base::File::Info file_info;
|
||||
|
|
|
@ -61,6 +61,8 @@ class URLRequestAsarJob : public net::URLRequestJob {
|
|||
net::Filter* SetupFilter() const override;
|
||||
bool GetMimeType(std::string* mime_type) const override;
|
||||
void SetExtraRequestHeaders(const net::HttpRequestHeaders& headers) override;
|
||||
int GetResponseCode() const override;
|
||||
void GetResponseInfo(net::HttpResponseInfo* info) override;
|
||||
|
||||
private:
|
||||
// Meta information about the file. It's used as a member in the
|
||||
|
|
|
@ -90,12 +90,14 @@ void URLRequestFetchJob::StartAsync(scoped_ptr<base::Value> options) {
|
|||
|
||||
std::string url, method, referrer;
|
||||
base::Value* session = nullptr;
|
||||
base::DictionaryValue* upload_data = nullptr;
|
||||
base::DictionaryValue* dict =
|
||||
static_cast<base::DictionaryValue*>(options.get());
|
||||
dict->GetString("url", &url);
|
||||
dict->GetString("method", &method);
|
||||
dict->GetString("referrer", &referrer);
|
||||
dict->Get("session", &session);
|
||||
dict->GetDictionary("uploadData", &upload_data);
|
||||
|
||||
// Check if URL is valid.
|
||||
GURL formated_url(url);
|
||||
|
@ -127,6 +129,14 @@ void URLRequestFetchJob::StartAsync(scoped_ptr<base::Value> options) {
|
|||
else
|
||||
fetcher_->SetReferrer(referrer);
|
||||
|
||||
// Set the data needed for POSTs.
|
||||
if (upload_data && request_type == net::URLFetcher::POST) {
|
||||
std::string content_type, data;
|
||||
upload_data->GetString("contentType", &content_type);
|
||||
upload_data->GetString("data", &data);
|
||||
fetcher_->SetUploadData(content_type, data);
|
||||
}
|
||||
|
||||
// Use |request|'s headers.
|
||||
fetcher_->SetExtraRequestHeaders(
|
||||
request()->extra_request_headers().ToString());
|
||||
|
|
|
@ -5,9 +5,14 @@
|
|||
#include "atom/common/native_mate_converters/net_converter.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "net/base/upload_bytes_element_reader.h"
|
||||
#include "net/base/upload_data_stream.h"
|
||||
#include "net/base/upload_element_reader.h"
|
||||
#include "net/base/upload_file_element_reader.h"
|
||||
#include "net/cert/x509_certificate.h"
|
||||
#include "net/url_request/url_request.h"
|
||||
|
||||
|
@ -20,6 +25,30 @@ v8::Local<v8::Value> Converter<const net::URLRequest*>::ToV8(
|
|||
dict.Set("method", val->method());
|
||||
dict.Set("url", val->url().spec());
|
||||
dict.Set("referrer", val->referrer());
|
||||
const net::UploadDataStream* upload_data = val->get_upload();
|
||||
if (upload_data) {
|
||||
const ScopedVector<net::UploadElementReader>* readers =
|
||||
upload_data->GetElementReaders();
|
||||
std::vector<mate::Dictionary> upload_data_list;
|
||||
upload_data_list.reserve(readers->size());
|
||||
for (const auto& reader : *readers) {
|
||||
auto upload_data_dict = mate::Dictionary::CreateEmpty(isolate);
|
||||
if (reader->AsBytesReader()) {
|
||||
const net::UploadBytesElementReader* bytes_reader =
|
||||
reader->AsBytesReader();
|
||||
auto bytes =
|
||||
node::Buffer::Copy(isolate, bytes_reader->bytes(),
|
||||
bytes_reader->length()).ToLocalChecked();
|
||||
upload_data_dict.Set("bytes", bytes);
|
||||
} else if (reader->AsFileReader()) {
|
||||
const net::UploadFileElementReader* file_reader =
|
||||
reader->AsFileReader();
|
||||
upload_data_dict.Set("file", file_reader->path().AsUTF8Unsafe());
|
||||
}
|
||||
upload_data_list.push_back(upload_data_dict);
|
||||
}
|
||||
dict.Set("uploadData", upload_data_list);
|
||||
}
|
||||
return mate::ConvertToV8(isolate, dict);
|
||||
}
|
||||
|
||||
|
|
|
@ -119,6 +119,9 @@ const char kDisableHttpCache[] = "disable-http-cache";
|
|||
// Register schemes to standard.
|
||||
const char kRegisterStandardSchemes[] = "register-standard-schemes";
|
||||
|
||||
// Register schemes to handle service worker.
|
||||
const char kRegisterServiceWorkerSchemes[] = "register-service-worker-schemes";
|
||||
|
||||
// The minimum SSL/TLS version ("tls1", "tls1.1", or "tls1.2") that
|
||||
// TLS fallback will accept.
|
||||
const char kSSLVersionFallbackMin[] = "ssl-version-fallback-min";
|
||||
|
|
|
@ -66,6 +66,7 @@ extern const char kPpapiFlashVersion[];
|
|||
extern const char kClientCertificate[];
|
||||
extern const char kDisableHttpCache[];
|
||||
extern const char kRegisterStandardSchemes[];
|
||||
extern const char kRegisterServiceWorkerSchemes[];
|
||||
extern const char kSSLVersionFallbackMin[];
|
||||
extern const char kCipherSuiteBlacklist[];
|
||||
extern const char kAppUserModelId[];
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "third_party/WebKit/public/web/WebLocalFrame.h"
|
||||
#include "third_party/WebKit/public/web/WebPluginParams.h"
|
||||
#include "third_party/WebKit/public/web/WebKit.h"
|
||||
#include "third_party/WebKit/public/web/WebSecurityPolicy.h"
|
||||
#include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
|
||||
#include "third_party/WebKit/public/web/WebView.h"
|
||||
|
||||
|
@ -129,6 +130,9 @@ void AtomRendererClient::RenderFrameCreated(
|
|||
content::RenderFrame* render_frame) {
|
||||
new PepperHelper(render_frame);
|
||||
new AtomRenderFrameObserver(render_frame, this);
|
||||
|
||||
// Allow file scheme to handle service worker by default.
|
||||
blink::WebSecurityPolicy::registerURLSchemeAsAllowingServiceWorkers("file");
|
||||
}
|
||||
|
||||
void AtomRendererClient::RenderViewCreated(content::RenderView* render_view) {
|
||||
|
|
|
@ -64,6 +64,11 @@ the `will-quit` and `window-all-closed` events.
|
|||
|
||||
### Event: 'quit'
|
||||
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `exitCode` Integer
|
||||
|
||||
Emitted when the application is quitting.
|
||||
|
||||
### Event: 'open-file' _OS X_
|
||||
|
|
|
@ -38,6 +38,10 @@ A standard `scheme` adheres to what RFC 3986 calls
|
|||
[generic URI syntax](https://tools.ietf.org/html/rfc3986#section-3). This
|
||||
includes `file:` and `filesystem:`.
|
||||
|
||||
### `protocol.registerServiceWorkerSchemes(schemes)`
|
||||
|
||||
* `schemes` Array - Custom schemes to be registered to handle service workers.
|
||||
|
||||
### `protocol.registerFileProtocol(scheme, handler[, completion])`
|
||||
|
||||
* `scheme` String
|
||||
|
@ -103,11 +107,16 @@ Registers a protocol of `scheme` that will send a `String` as a response. The
|
|||
|
||||
Registers a protocol of `scheme` that will send an HTTP request as a response.
|
||||
The `callback` should be called with an object that has the `url`, `method`,
|
||||
`referrer`, and `session` properties.
|
||||
`referrer`, `uploadData` and `session` properties.
|
||||
|
||||
By default the HTTP request will reuse the current session. If you want the
|
||||
request to have a different session you should set `session` to `null`.
|
||||
|
||||
POST request should provide an `uploadData` object.
|
||||
* `uploadData` object
|
||||
* `contentType` String - MIME type of the content.
|
||||
* `data` String - Content to be sent.
|
||||
|
||||
### `protocol.unregisterProtocol(scheme[, completion])`
|
||||
|
||||
* `scheme` String
|
||||
|
|
|
@ -7,7 +7,7 @@ import sys
|
|||
|
||||
|
||||
BASE_URL = os.getenv('LIBCHROMIUMCONTENT_MIRROR') or \
|
||||
'http://github-janky-artifacts.s3.amazonaws.com/libchromiumcontent'
|
||||
'https://s3.amazonaws.com/github-janky-artifacts/libchromiumcontent'
|
||||
LIBCHROMIUMCONTENT_COMMIT = 'cfbe8ec7e14af4cabd1474386f54e197db1f7ac1'
|
||||
|
||||
PLATFORM = {
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
assert = require 'assert'
|
||||
ChildProcess = require 'child_process'
|
||||
path = require 'path'
|
||||
{remote} = require 'electron'
|
||||
{app, BrowserWindow} = remote.require 'electron'
|
||||
|
||||
|
@ -29,6 +31,23 @@ describe 'app module', ->
|
|||
it 'should not be empty', ->
|
||||
assert.notEqual app.getLocale(), ''
|
||||
|
||||
describe 'app.exit(exitCode)', ->
|
||||
appProcess = null
|
||||
afterEach ->
|
||||
appProcess?.kill()
|
||||
|
||||
it 'emits a process exit event with the code', (done) ->
|
||||
appPath = path.join(__dirname, 'fixtures', 'api', 'quit-app')
|
||||
electronPath = remote.getGlobal('process').execPath
|
||||
appProcess = ChildProcess.spawn(electronPath, [appPath])
|
||||
|
||||
output = ''
|
||||
appProcess.stdout.on 'data', (data) -> output += data
|
||||
appProcess.on 'close', (code) ->
|
||||
assert.notEqual output.indexOf('Exit event with code: 123'), -1
|
||||
assert.equal code, 123
|
||||
done()
|
||||
|
||||
describe 'BrowserWindow events', ->
|
||||
w = null
|
||||
afterEach ->
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
assert = require 'assert'
|
||||
http = require 'http'
|
||||
path = require 'path'
|
||||
qs = require 'querystring'
|
||||
|
||||
{remote} = require 'electron'
|
||||
{protocol} = remote.require 'electron'
|
||||
|
@ -8,6 +9,9 @@ path = require 'path'
|
|||
describe 'protocol module', ->
|
||||
protocolName = 'sp'
|
||||
text = 'valar morghulis'
|
||||
postData =
|
||||
name: 'post test'
|
||||
type: 'string'
|
||||
|
||||
afterEach (done) ->
|
||||
protocol.unregisterProtocol protocolName, ->
|
||||
|
@ -405,6 +409,22 @@ describe 'protocol module', ->
|
|||
error: (xhr, errorType, error) ->
|
||||
done(error)
|
||||
|
||||
it 'can receive post data', (done) ->
|
||||
handler = (request, callback) ->
|
||||
uploadData = request.uploadData[0].bytes.toString()
|
||||
callback({data: uploadData})
|
||||
protocol.interceptStringProtocol 'http', handler, (error) ->
|
||||
return done(error) if error
|
||||
$.ajax
|
||||
url: "http://fake-host"
|
||||
type: "POST"
|
||||
data: postData
|
||||
success: (data) ->
|
||||
assert.deepEqual qs.parse(data), postData
|
||||
done()
|
||||
error: (xhr, errorType, error) ->
|
||||
done(error)
|
||||
|
||||
describe 'protocol.interceptBufferProtocol', ->
|
||||
it 'can intercept http protocol', (done) ->
|
||||
handler = (request, callback) -> callback(new Buffer(text))
|
||||
|
@ -418,6 +438,55 @@ describe 'protocol module', ->
|
|||
error: (xhr, errorType, error) ->
|
||||
done(error)
|
||||
|
||||
it 'can receive post data', (done) ->
|
||||
handler = (request, callback) ->
|
||||
uploadData = request.uploadData[0].bytes
|
||||
callback(uploadData)
|
||||
protocol.interceptBufferProtocol 'http', handler, (error) ->
|
||||
return done(error) if error
|
||||
$.ajax
|
||||
url: "http://fake-host"
|
||||
type: "POST"
|
||||
data: postData
|
||||
success: (data) ->
|
||||
assert.equal data, $.param postData
|
||||
done()
|
||||
error: (xhr, errorType, error) ->
|
||||
done(error)
|
||||
|
||||
describe 'protocol.interceptHttpProtocol', ->
|
||||
it 'can send POST request', (done) ->
|
||||
server = http.createServer (req, res) ->
|
||||
body = ''
|
||||
req.on 'data', (chunk) ->
|
||||
body += chunk
|
||||
req.on 'end', ->
|
||||
res.end body
|
||||
server.close()
|
||||
server.listen 0, '127.0.0.1', ->
|
||||
{port} = server.address()
|
||||
url = "http://127.0.0.1:#{port}"
|
||||
handler = (request, callback) ->
|
||||
data =
|
||||
url: url
|
||||
method: 'POST'
|
||||
uploadData:
|
||||
contentType: 'application/x-www-form-urlencoded'
|
||||
data: request.uploadData[0].bytes.toString()
|
||||
session: null
|
||||
callback(data)
|
||||
protocol.interceptHttpProtocol 'http', handler, (error) ->
|
||||
return done(error) if error
|
||||
$.ajax
|
||||
url: "http://fake-host"
|
||||
type: "POST"
|
||||
data: postData
|
||||
success: (data) ->
|
||||
assert.deepEqual qs.parse(data), postData
|
||||
done()
|
||||
error: (xhr, errorType, error) ->
|
||||
done(error)
|
||||
|
||||
describe 'protocol.uninterceptProtocol', ->
|
||||
it 'returns error when scheme does not exist', (done) ->
|
||||
protocol.uninterceptProtocol 'not-exist', (error) ->
|
||||
|
|
12
spec/fixtures/api/quit-app/main.js
vendored
Normal file
12
spec/fixtures/api/quit-app/main.js
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
var app = require('electron').app
|
||||
|
||||
app.on('ready', function () {
|
||||
// This setImmediate call gets the spec passing on Linux
|
||||
setImmediate(function () {
|
||||
app.exit(123)
|
||||
})
|
||||
})
|
||||
|
||||
process.on('exit', function (code) {
|
||||
console.log('Exit event with code: ' + code)
|
||||
})
|
4
spec/fixtures/api/quit-app/package.json
vendored
Normal file
4
spec/fixtures/api/quit-app/package.json
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "quit-app",
|
||||
"main": "main.js"
|
||||
}
|
Loading…
Reference in a new issue