mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
61e990e8cd | ||
|
|
fb143a5dab |
@@ -1,2 +0,0 @@
|
||||
* Electron version:
|
||||
* Operating system:
|
||||
@@ -49,15 +49,12 @@ API 레퍼런스가 있습니다. Electron을 빌드 하는 방법과 프로젝
|
||||
|
||||
## 참조 문서 (번역)
|
||||
|
||||
- [브라질 포르투갈어](https://github.com/atom/electron/tree/master/docs-translations/pt-BR)
|
||||
- [브라질 포르투칼어](https://github.com/atom/electron/tree/master/docs-translations/pt-BR)
|
||||
- [한국어](https://github.com/atom/electron/tree/master/docs-translations/ko-KR)
|
||||
- [일본어](https://github.com/atom/electron/tree/master/docs-translations/jp)
|
||||
- [스페인어](https://github.com/atom/electron/tree/master/docs-translations/es)
|
||||
- [중국어 간체](https://github.com/atom/electron/tree/master/docs-translations/zh-CN)
|
||||
- [중국어 번체](https://github.com/atom/electron/tree/master/docs-translations/zh-TW)
|
||||
- [우크라이나어](https://github.com/atom/electron/tree/master/docs-translations/uk-UA)
|
||||
- [러시아어](https://github.com/atom/electron/tree/master/docs-translations/ru-RU)
|
||||
- [프랑스어](https://github.com/atom/electron/tree/master/docs-translations/fr-FR)
|
||||
|
||||
## 시작하기
|
||||
|
||||
@@ -71,8 +68,6 @@ API 레퍼런스가 있습니다. Electron을 빌드 하는 방법과 프로젝
|
||||
- Atom 포럼의 [`electron`](http://discuss.atom.io/c/electron) 카테고리
|
||||
- Freenode 채팅의 `#atom-shell` 채널
|
||||
- Slack의 [`Atom`](http://atom-slack.herokuapp.com/) 채널
|
||||
- [`electron-br`](https://electron-br.slack.com) *(브라질 포르투갈어)* 커뮤니티
|
||||
- [`electron-kr`](http://www.meetup.com/electron-kr/) *(한국어)* 커뮤니티
|
||||
|
||||
[awesome-electron](https://github.com/sindresorhus/awesome-electron) 프로젝트에
|
||||
커뮤니티가 운영중인 유용한 예제 어플리케이션과 도구, 리소스가 있으니 한번 참고해 보시기
|
||||
|
||||
@@ -52,9 +52,7 @@ contains documents describing how to build and contribute to Electron.
|
||||
- [Spanish](https://github.com/atom/electron/tree/master/docs-translations/es)
|
||||
- [Simplified Chinese](https://github.com/atom/electron/tree/master/docs-translations/zh-CN)
|
||||
- [Traditional Chinese](https://github.com/atom/electron/tree/master/docs-translations/zh-TW)
|
||||
- [Ukrainian](https://github.com/atom/electron/tree/master/docs-translations/uk-UA)
|
||||
- [Russian](https://github.com/atom/electron/tree/master/docs-translations/ru-RU)
|
||||
- [French](https://github.com/atom/electron/tree/master/docs-translations/fr-FR)
|
||||
|
||||
## Quick Start
|
||||
|
||||
@@ -70,8 +68,6 @@ forums
|
||||
- `#atom-shell` channel on Freenode
|
||||
- [`Atom`](http://atom-slack.herokuapp.com/) channel on Slack
|
||||
- [`electron-br`](https://electron-br.slack.com) *(Brazilian Portuguese)*
|
||||
- [`electron-kr`](http://www.meetup.com/electron-kr/) *(Korean)*
|
||||
- [`electron-jp`](https://electron-jp-slackin.herokuapp.com/) *(Japanese)*
|
||||
|
||||
Check out [awesome-electron](https://github.com/sindresorhus/awesome-electron)
|
||||
for a community maintained list of useful example apps, tools and resources.
|
||||
|
||||
23
appveyor.yml
23
appveyor.yml
@@ -1,23 +0,0 @@
|
||||
# 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
|
||||
79
atom.gyp
79
atom.gyp
@@ -4,7 +4,7 @@
|
||||
'product_name%': 'Electron',
|
||||
'company_name%': 'GitHub, Inc',
|
||||
'company_abbr%': 'github',
|
||||
'version%': '0.36.8',
|
||||
'version%': '0.35.5',
|
||||
},
|
||||
'includes': [
|
||||
'filenames.gypi',
|
||||
@@ -28,7 +28,7 @@
|
||||
'target_name': '<(project_name)',
|
||||
'type': 'executable',
|
||||
'dependencies': [
|
||||
'js2asar',
|
||||
'compile_coffee',
|
||||
'<(project_name)_lib',
|
||||
],
|
||||
'sources': [
|
||||
@@ -121,6 +121,10 @@
|
||||
],
|
||||
}],
|
||||
],
|
||||
}, { # OS=="mac"
|
||||
'dependencies': [
|
||||
'make_locale_paks',
|
||||
],
|
||||
}], # OS!="mac"
|
||||
['OS=="win"', {
|
||||
'include_dirs': [
|
||||
@@ -144,7 +148,6 @@
|
||||
}, {
|
||||
'copied_libraries': [
|
||||
'<(libchromiumcontent_dir)/pdf.dll',
|
||||
'<(libchromiumcontent_dir)/ffmpeg.dll',
|
||||
],
|
||||
}],
|
||||
],
|
||||
@@ -152,7 +155,6 @@
|
||||
'destination': '<(PRODUCT_DIR)',
|
||||
'files': [
|
||||
'<@(copied_libraries)',
|
||||
'<(libchromiumcontent_dir)/locales',
|
||||
'<(libchromiumcontent_dir)/libEGL.dll',
|
||||
'<(libchromiumcontent_dir)/libGLESv2.dll',
|
||||
'<(libchromiumcontent_dir)/icudtl.dat',
|
||||
@@ -194,7 +196,6 @@
|
||||
}, {
|
||||
'copied_libraries': [
|
||||
'<(PRODUCT_DIR)/lib/libnode.so',
|
||||
'<(libchromiumcontent_dir)/libffmpeg.so',
|
||||
],
|
||||
}],
|
||||
],
|
||||
@@ -202,7 +203,6 @@
|
||||
'destination': '<(PRODUCT_DIR)',
|
||||
'files': [
|
||||
'<@(copied_libraries)',
|
||||
'<(libchromiumcontent_dir)/locales',
|
||||
'<(libchromiumcontent_dir)/icudtl.dat',
|
||||
'<(libchromiumcontent_dir)/content_shell.pak',
|
||||
'<(libchromiumcontent_dir)/natives_blob.bin',
|
||||
@@ -223,7 +223,7 @@
|
||||
'target_name': '<(project_name)_lib',
|
||||
'type': 'static_library',
|
||||
'dependencies': [
|
||||
'atom_js2c',
|
||||
'atom_coffee2c',
|
||||
'vendor/brightray/brightray.gyp:brightray',
|
||||
'vendor/node/node.gyp:node',
|
||||
],
|
||||
@@ -235,8 +235,6 @@
|
||||
# Defined in Chromium but not exposed in its gyp file.
|
||||
'V8_USE_EXTERNAL_STARTUP_DATA',
|
||||
'ENABLE_PLUGINS',
|
||||
'ENABLE_PEPPER_CDMS',
|
||||
'USE_PROPRIETARY_CODECS',
|
||||
],
|
||||
'sources': [
|
||||
'<@(lib_sources)',
|
||||
@@ -258,12 +256,6 @@
|
||||
'vendor/node/deps/cares/include',
|
||||
# The `third_party/WebKit/Source/platform/weborigin/SchemeRegistry.h` is using `platform/PlatformExport.h`.
|
||||
'<(libchromiumcontent_src_dir)/third_party/WebKit/Source',
|
||||
# The 'third_party/libyuv/include/libyuv/scale_argb.h' is using 'libyuv/basic_types.h'.
|
||||
'<(libchromiumcontent_src_dir)/third_party/libyuv/include',
|
||||
# The 'third_party/webrtc/modules/desktop_capture/desktop_frame.h' is using 'webrtc/base/scoped_ptr.h'.
|
||||
'<(libchromiumcontent_src_dir)/third_party/',
|
||||
'<(libchromiumcontent_src_dir)/components/cdm',
|
||||
'<(libchromiumcontent_src_dir)/third_party/widevine',
|
||||
],
|
||||
'direct_dependent_settings': {
|
||||
'include_dirs': [
|
||||
@@ -290,7 +282,6 @@
|
||||
'-lcomctl32.lib',
|
||||
'-lcomdlg32.lib',
|
||||
'-lwininet.lib',
|
||||
'-lwinmm.lib',
|
||||
],
|
||||
},
|
||||
'dependencies': [
|
||||
@@ -353,11 +344,11 @@
|
||||
],
|
||||
}, # target <(product_name)_lib
|
||||
{
|
||||
'target_name': 'js2asar',
|
||||
'target_name': 'compile_coffee',
|
||||
'type': 'none',
|
||||
'actions': [
|
||||
{
|
||||
'action_name': 'js2asar',
|
||||
'action_name': 'compile_coffee',
|
||||
'variables': {
|
||||
'conditions': [
|
||||
['OS=="mac"', {
|
||||
@@ -368,41 +359,41 @@
|
||||
],
|
||||
},
|
||||
'inputs': [
|
||||
'<@(js_sources)',
|
||||
'<@(coffee_sources)',
|
||||
],
|
||||
'outputs': [
|
||||
'<(resources_path)/atom.asar',
|
||||
],
|
||||
'action': [
|
||||
'python',
|
||||
'tools/js2asar.py',
|
||||
'tools/coffee2asar.py',
|
||||
'<@(_outputs)',
|
||||
'<@(_inputs)',
|
||||
],
|
||||
}
|
||||
],
|
||||
}, # target js2asar
|
||||
}, # target compile_coffee
|
||||
{
|
||||
'target_name': 'atom_js2c',
|
||||
'target_name': 'atom_coffee2c',
|
||||
'type': 'none',
|
||||
'actions': [
|
||||
{
|
||||
'action_name': 'atom_js2c',
|
||||
'action_name': 'atom_coffee2c',
|
||||
'inputs': [
|
||||
'<@(js2c_sources)',
|
||||
'<@(coffee2c_sources)',
|
||||
],
|
||||
'outputs': [
|
||||
'<(SHARED_INTERMEDIATE_DIR)/atom_natives.h',
|
||||
],
|
||||
'action': [
|
||||
'python',
|
||||
'tools/js2c.py',
|
||||
'tools/coffee2c.py',
|
||||
'<@(_outputs)',
|
||||
'<@(_inputs)',
|
||||
],
|
||||
}
|
||||
],
|
||||
}, # target atom_js2c
|
||||
}, # target atom_coffee2c
|
||||
],
|
||||
'conditions': [
|
||||
['OS=="mac"', {
|
||||
@@ -463,7 +454,6 @@
|
||||
}, {
|
||||
'copied_libraries': [
|
||||
'<(PRODUCT_DIR)/libnode.dylib',
|
||||
'<(libchromiumcontent_dir)/libffmpeg.dylib',
|
||||
],
|
||||
}],
|
||||
],
|
||||
@@ -503,16 +493,6 @@
|
||||
'Libraries',
|
||||
],
|
||||
},
|
||||
{
|
||||
'postbuild_name': 'Copy locales',
|
||||
'action': [
|
||||
'tools/mac/copy-locales.py',
|
||||
'-d',
|
||||
'<(libchromiumcontent_dir)/locales',
|
||||
'${BUILT_PRODUCTS_DIR}/<(product_name) Framework.framework/Resources',
|
||||
'<@(locales)',
|
||||
],
|
||||
},
|
||||
],
|
||||
'conditions': [
|
||||
['mas_build==0', {
|
||||
@@ -557,6 +537,31 @@
|
||||
},
|
||||
}, # target helper
|
||||
],
|
||||
}, { # OS=="mac"
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'make_locale_paks',
|
||||
'type': 'none',
|
||||
'actions': [
|
||||
{
|
||||
'action_name': 'Make Empty Paks',
|
||||
'inputs': [
|
||||
'tools/make_locale_paks.py',
|
||||
],
|
||||
'outputs': [
|
||||
'<(PRODUCT_DIR)/locales'
|
||||
],
|
||||
'action': [
|
||||
'python',
|
||||
'tools/make_locale_paks.py',
|
||||
'<(PRODUCT_DIR)',
|
||||
'<@(locales)',
|
||||
],
|
||||
'msvs_cygwin_shell': 0,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}], # OS!="mac"
|
||||
],
|
||||
}
|
||||
|
||||
@@ -11,21 +11,12 @@
|
||||
#include "atom/common/chrome_version.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/strings/string_split.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "content/public/common/content_constants.h"
|
||||
#include "content/public/common/pepper_plugin_info.h"
|
||||
#include "content/public/common/user_agent.h"
|
||||
#include "ppapi/shared_impl/ppapi_permissions.h"
|
||||
#include "third_party/widevine/cdm/stub/widevine_cdm_version.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
#include "url/url_constants.h"
|
||||
|
||||
#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
|
||||
#include "chrome/common/widevine_cdm_constants.h"
|
||||
#endif
|
||||
|
||||
namespace atom {
|
||||
|
||||
@@ -40,8 +31,8 @@ content::PepperPluginInfo CreatePepperFlashInfo(const base::FilePath& path,
|
||||
plugin.path = path;
|
||||
plugin.permissions = ppapi::PERMISSION_ALL_BITS;
|
||||
|
||||
std::vector<std::string> flash_version_numbers = base::SplitString(
|
||||
version, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
|
||||
std::vector<std::string> flash_version_numbers;
|
||||
base::SplitString(version, '.', &flash_version_numbers);
|
||||
if (flash_version_numbers.size() < 1)
|
||||
flash_version_numbers.push_back("11");
|
||||
// |SplitString()| puts in an empty string given an empty string. :(
|
||||
@@ -56,7 +47,7 @@ content::PepperPluginInfo CreatePepperFlashInfo(const base::FilePath& path,
|
||||
// E.g., "Shockwave Flash 10.2 r154":
|
||||
plugin.description = plugin.name + " " + flash_version_numbers[0] + "." +
|
||||
flash_version_numbers[1] + " r" + flash_version_numbers[2];
|
||||
plugin.version = base::JoinString(flash_version_numbers, ".");
|
||||
plugin.version = JoinString(flash_version_numbers, '.');
|
||||
content::WebPluginMimeType swf_mime_type(
|
||||
content::kFlashPluginSwfMimeType,
|
||||
content::kFlashPluginSwfExtension,
|
||||
@@ -71,95 +62,8 @@ content::PepperPluginInfo CreatePepperFlashInfo(const base::FilePath& path,
|
||||
return plugin;
|
||||
}
|
||||
|
||||
#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
|
||||
content::PepperPluginInfo CreateWidevineCdmInfo(const base::FilePath& path,
|
||||
const std::string& version) {
|
||||
content::PepperPluginInfo widevine_cdm;
|
||||
widevine_cdm.is_out_of_process = true;
|
||||
widevine_cdm.path = path;
|
||||
widevine_cdm.name = kWidevineCdmDisplayName;
|
||||
widevine_cdm.description = kWidevineCdmDescription +
|
||||
std::string(" (version: ") +
|
||||
version + ")";
|
||||
widevine_cdm.version = version;
|
||||
content::WebPluginMimeType widevine_cdm_mime_type(
|
||||
kWidevineCdmPluginMimeType,
|
||||
kWidevineCdmPluginExtension,
|
||||
kWidevineCdmPluginMimeTypeDescription);
|
||||
|
||||
// Add the supported codecs as if they came from the component manifest.
|
||||
std::vector<std::string> codecs;
|
||||
codecs.push_back(kCdmSupportedCodecVorbis);
|
||||
codecs.push_back(kCdmSupportedCodecVp8);
|
||||
codecs.push_back(kCdmSupportedCodecVp9);
|
||||
#if defined(USE_PROPRIETARY_CODECS)
|
||||
codecs.push_back(kCdmSupportedCodecAac);
|
||||
codecs.push_back(kCdmSupportedCodecAvc1);
|
||||
#endif // defined(USE_PROPRIETARY_CODECS)
|
||||
std::string codec_string = base::JoinString(
|
||||
codecs, std::string(1, kCdmSupportedCodecsValueDelimiter));
|
||||
widevine_cdm_mime_type.additional_param_names.push_back(
|
||||
base::ASCIIToUTF16(kCdmSupportedCodecsParamName));
|
||||
widevine_cdm_mime_type.additional_param_values.push_back(
|
||||
base::ASCIIToUTF16(codec_string));
|
||||
|
||||
widevine_cdm.mime_types.push_back(widevine_cdm_mime_type);
|
||||
widevine_cdm.permissions = kWidevineCdmPluginPermissions;
|
||||
|
||||
return widevine_cdm;
|
||||
}
|
||||
#endif
|
||||
|
||||
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
|
||||
|
||||
void AddPepperFlashFromCommandLine(
|
||||
std::vector<content::PepperPluginInfo>* plugins) {
|
||||
auto command_line = base::CommandLine::ForCurrentProcess();
|
||||
auto flash_path = command_line->GetSwitchValueNative(
|
||||
switches::kPpapiFlashPath);
|
||||
if (flash_path.empty())
|
||||
return;
|
||||
|
||||
auto flash_version = command_line->GetSwitchValueASCII(
|
||||
switches::kPpapiFlashVersion);
|
||||
|
||||
plugins->push_back(
|
||||
CreatePepperFlashInfo(base::FilePath(flash_path), flash_version));
|
||||
}
|
||||
|
||||
#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
|
||||
void AddWidevineCdmFromCommandLine(
|
||||
std::vector<content::PepperPluginInfo>* plugins) {
|
||||
auto command_line = base::CommandLine::ForCurrentProcess();
|
||||
auto widevine_cdm_path = command_line->GetSwitchValueNative(
|
||||
switches::kWidevineCdmPath);
|
||||
if (widevine_cdm_path.empty())
|
||||
return;
|
||||
|
||||
if (!base::PathExists(base::FilePath(widevine_cdm_path)))
|
||||
return;
|
||||
|
||||
auto widevine_cdm_version = command_line->GetSwitchValueASCII(
|
||||
switches::kWidevineCdmVersion);
|
||||
if (widevine_cdm_version.empty())
|
||||
return;
|
||||
|
||||
plugins->push_back(CreateWidevineCdmInfo(base::FilePath(widevine_cdm_path),
|
||||
widevine_cdm_version));
|
||||
}
|
||||
#endif
|
||||
|
||||
AtomContentClient::AtomContentClient() {
|
||||
}
|
||||
|
||||
@@ -176,41 +80,35 @@ std::string AtomContentClient::GetUserAgent() const {
|
||||
ATOM_PRODUCT_NAME "/" ATOM_VERSION_STRING);
|
||||
}
|
||||
|
||||
base::string16 AtomContentClient::GetLocalizedString(int message_id) const {
|
||||
return l10n_util::GetStringUTF16(message_id);
|
||||
}
|
||||
|
||||
void AtomContentClient::AddAdditionalSchemes(
|
||||
std::vector<url::SchemeWithType>* standard_schemes,
|
||||
std::vector<std::string>* standard_schemes,
|
||||
std::vector<std::string>* savable_schemes) {
|
||||
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});
|
||||
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, ',', &schemes);
|
||||
standard_schemes->insert(standard_schemes->end(),
|
||||
schemes.begin(),
|
||||
schemes.end());
|
||||
}
|
||||
standard_schemes->push_back({"chrome-extension", url::SCHEME_WITHOUT_PORT});
|
||||
standard_schemes->push_back("chrome-extension");
|
||||
}
|
||||
|
||||
void AtomContentClient::AddPepperPlugins(
|
||||
std::vector<content::PepperPluginInfo>* plugins) {
|
||||
AddPepperFlashFromCommandLine(plugins);
|
||||
#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
|
||||
AddWidevineCdmFromCommandLine(plugins);
|
||||
#endif
|
||||
}
|
||||
auto command_line = base::CommandLine::ForCurrentProcess();
|
||||
auto flash_path = command_line->GetSwitchValuePath(
|
||||
switches::kPpapiFlashPath);
|
||||
if (flash_path.empty())
|
||||
return;
|
||||
|
||||
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);
|
||||
auto flash_version = command_line->GetSwitchValueASCII(
|
||||
switches::kPpapiFlashVersion);
|
||||
|
||||
plugins->push_back(
|
||||
CreatePepperFlashInfo(flash_path, flash_version));
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#ifndef ATOM_APP_ATOM_CONTENT_CLIENT_H_
|
||||
#define ATOM_APP_ATOM_CONTENT_CLIENT_H_
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -22,14 +21,11 @@ class AtomContentClient : public brightray::ContentClient {
|
||||
// content::ContentClient:
|
||||
std::string GetProduct() const override;
|
||||
std::string GetUserAgent() const override;
|
||||
base::string16 GetLocalizedString(int message_id) const override;
|
||||
void AddAdditionalSchemes(
|
||||
std::vector<url::SchemeWithType>* standard_schemes,
|
||||
std::vector<std::string>* standard_schemes,
|
||||
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,6 +7,10 @@
|
||||
#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>
|
||||
@@ -52,6 +56,12 @@ 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);
|
||||
@@ -99,7 +109,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 (!IsEnvSet("TERM") && !IsEnvSet("ELECTRON_NO_ATTACH_CONSOLE")) {
|
||||
if (!IsCygwin() && !IsEnvSet("ELECTRON_NO_ATTACH_CONSOLE")) {
|
||||
AttachConsole(ATTACH_PARENT_PROCESS);
|
||||
|
||||
FILE* dontcare;
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#include "base/logging.h"
|
||||
#include "chrome/common/chrome_paths.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
#include "ui/base/resource/resource_bundle.h"
|
||||
|
||||
namespace atom {
|
||||
@@ -138,4 +137,16 @@ scoped_ptr<brightray::ContentClient> AtomMainDelegate::CreateContentClient() {
|
||||
return scoped_ptr<brightray::ContentClient>(new AtomContentClient).Pass();
|
||||
}
|
||||
|
||||
void AtomMainDelegate::AddDataPackFromPath(
|
||||
ui::ResourceBundle* bundle, const base::FilePath& pak_dir) {
|
||||
#if defined(OS_WIN)
|
||||
bundle->AddDataPackFromPath(
|
||||
pak_dir.Append(FILE_PATH_LITERAL("ui_resources_200_percent.pak")),
|
||||
ui::SCALE_FACTOR_200P);
|
||||
bundle->AddDataPackFromPath(
|
||||
pak_dir.Append(FILE_PATH_LITERAL("content_resources_200_percent.pak")),
|
||||
ui::SCALE_FACTOR_200P);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -25,6 +25,8 @@ class AtomMainDelegate : public brightray::MainDelegate {
|
||||
|
||||
// brightray::MainDelegate:
|
||||
scoped_ptr<brightray::ContentClient> CreateContentClient() override;
|
||||
void AddDataPackFromPath(
|
||||
ui::ResourceBundle* bundle, const base::FilePath& pak_dir) override;
|
||||
#if defined(OS_MACOSX)
|
||||
void OverrideChildProcessPath() override;
|
||||
void OverrideFrameworkBundlePath() override;
|
||||
|
||||
@@ -37,7 +37,7 @@ bool UvTaskRunner::PostNonNestableDelayedTask(
|
||||
const tracked_objects::Location& from_here,
|
||||
const base::Closure& task,
|
||||
base::TimeDelta delay) {
|
||||
return PostDelayedTask(from_here, task, delay);
|
||||
return PostDelayedTask(from_here, task, delay);;
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#include "atom/common/native_mate_converters/net_converter.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||
#include "atom/common/native_mate_converters/image_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/command_line.h"
|
||||
@@ -35,11 +34,9 @@
|
||||
#include "native_mate/object_template_builder.h"
|
||||
#include "net/ssl/ssl_cert_request_info.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "ui/base/win/shell.h"
|
||||
#endif
|
||||
|
||||
using atom::Browser;
|
||||
@@ -184,8 +181,7 @@ void App::OnWindowAllClosed() {
|
||||
}
|
||||
|
||||
void App::OnQuit() {
|
||||
int exitCode = AtomBrowserMainParts::Get()->GetExitCode();
|
||||
Emit("quit", exitCode);
|
||||
Emit("quit");
|
||||
|
||||
if (process_singleton_.get()) {
|
||||
process_singleton_->Cleanup();
|
||||
@@ -321,12 +317,6 @@ std::string App::GetLocale() {
|
||||
return l10n_util::GetApplicationLocale("");
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
bool App::IsAeroGlassEnabled() {
|
||||
return ui::win::IsAeroGlassEnabled();
|
||||
}
|
||||
#endif
|
||||
|
||||
bool App::MakeSingleInstance(
|
||||
const ProcessSingleton::NotificationCallback& callback) {
|
||||
if (process_singleton_.get())
|
||||
@@ -367,14 +357,9 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder(
|
||||
base::Bind(&Browser::ClearRecentDocuments, browser))
|
||||
.SetMethod("setAppUserModelId",
|
||||
base::Bind(&Browser::SetAppUserModelID, browser))
|
||||
#if defined(OS_MACOSX)
|
||||
.SetMethod("hide", base::Bind(&Browser::Hide, browser))
|
||||
.SetMethod("show", base::Bind(&Browser::Show, browser))
|
||||
#endif
|
||||
#if defined(OS_WIN)
|
||||
.SetMethod("setUserTasks",
|
||||
base::Bind(&Browser::SetUserTasks, browser))
|
||||
.SetMethod("isAeroGlassEnabled", &App::IsAeroGlassEnabled)
|
||||
#endif
|
||||
.SetMethod("setPath", &App::SetPath)
|
||||
.SetMethod("getPath", &App::GetPath)
|
||||
@@ -454,7 +439,6 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||
dict.SetMethod("dockHide", base::Bind(&Browser::DockHide, browser));
|
||||
dict.SetMethod("dockShow", base::Bind(&Browser::DockShow, browser));
|
||||
dict.SetMethod("dockSetMenu", &DockSetMenu);
|
||||
dict.SetMethod("dockSetIcon", base::Bind(&Browser::DockSetIcon, browser));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -88,10 +88,6 @@ class App : public AtomBrowserClient::Delegate,
|
||||
const ProcessSingleton::NotificationCallback& callback);
|
||||
std::string GetLocale();
|
||||
|
||||
#if defined(OS_WIN)
|
||||
bool IsAeroGlassEnabled();
|
||||
#endif
|
||||
|
||||
scoped_ptr<ProcessSingleton> process_singleton_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(App);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "base/bind.h"
|
||||
#include "base/time/time.h"
|
||||
#include "base/values.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
@@ -19,20 +20,138 @@
|
||||
#include "net/url_request/url_request_context.h"
|
||||
#include "net/url_request/url_request_context_getter.h"
|
||||
|
||||
using atom::api::Cookies;
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace mate {
|
||||
namespace {
|
||||
|
||||
template<>
|
||||
struct Converter<atom::api::Cookies::Error> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
atom::api::Cookies::Error val) {
|
||||
if (val == atom::api::Cookies::SUCCESS)
|
||||
return v8::Null(isolate);
|
||||
else
|
||||
return v8::Exception::Error(StringToV8(isolate, "failed"));
|
||||
bool GetCookieListFromStore(
|
||||
net::CookieStore* cookie_store,
|
||||
const std::string& url,
|
||||
const net::CookieMonster::GetCookieListCallback& callback) {
|
||||
DCHECK(cookie_store);
|
||||
GURL gurl(url);
|
||||
net::CookieMonster* monster = cookie_store->GetCookieMonster();
|
||||
// Empty url will match all url cookies.
|
||||
if (url.empty()) {
|
||||
monster->GetAllCookiesAsync(callback);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
if (!gurl.is_valid())
|
||||
return false;
|
||||
|
||||
monster->GetAllCookiesForURLAsync(gurl, callback);
|
||||
return true;
|
||||
}
|
||||
|
||||
void RunGetCookiesCallbackOnUIThread(v8::Isolate* isolate,
|
||||
const std::string& error_message,
|
||||
const net::CookieList& cookie_list,
|
||||
const Cookies::CookiesCallback& callback) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
|
||||
v8::Locker locker(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
|
||||
if (!error_message.empty()) {
|
||||
v8::Local<v8::Value> error = mate::ConvertToV8(isolate, error_message);
|
||||
callback.Run(error, v8::Null(isolate));
|
||||
return;
|
||||
}
|
||||
callback.Run(v8::Null(isolate), mate::ConvertToV8(isolate, cookie_list));
|
||||
}
|
||||
|
||||
void RunRemoveCookiesCallbackOnUIThread(
|
||||
v8::Isolate* isolate,
|
||||
const std::string& error_message,
|
||||
const Cookies::CookiesCallback& callback) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
|
||||
v8::Locker locker(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
|
||||
if (!error_message.empty()) {
|
||||
v8::Local<v8::Value> error = mate::ConvertToV8(isolate, error_message);
|
||||
callback.Run(error, v8::Null(isolate));
|
||||
return;
|
||||
}
|
||||
|
||||
callback.Run(v8::Null(isolate), v8::Null(isolate));
|
||||
}
|
||||
|
||||
void RunSetCookiesCallbackOnUIThread(v8::Isolate* isolate,
|
||||
const std::string& error_message,
|
||||
bool set_success,
|
||||
const Cookies::CookiesCallback& callback) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
|
||||
v8::Locker locker(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
|
||||
if (!error_message.empty()) {
|
||||
v8::Local<v8::Value> error = mate::ConvertToV8(isolate, error_message);
|
||||
callback.Run(error, v8::Null(isolate));
|
||||
return;
|
||||
}
|
||||
if (!set_success) {
|
||||
v8::Local<v8::Value> error = mate::ConvertToV8(
|
||||
isolate, "Failed to set cookies");
|
||||
callback.Run(error, v8::Null(isolate));
|
||||
}
|
||||
|
||||
callback.Run(v8::Null(isolate), v8::Null(isolate));
|
||||
}
|
||||
|
||||
bool MatchesDomain(const base::DictionaryValue* filter,
|
||||
const std::string& cookie_domain) {
|
||||
std::string filter_domain;
|
||||
if (!filter->GetString("domain", &filter_domain))
|
||||
return true;
|
||||
|
||||
// Add a leading '.' character to the filter domain if it doesn't exist.
|
||||
if (net::cookie_util::DomainIsHostOnly(filter_domain))
|
||||
filter_domain.insert(0, ".");
|
||||
|
||||
std::string sub_domain(cookie_domain);
|
||||
// Strip any leading '.' character from the input cookie domain.
|
||||
if (!net::cookie_util::DomainIsHostOnly(sub_domain))
|
||||
sub_domain = sub_domain.substr(1);
|
||||
|
||||
// Now check whether the domain argument is a subdomain of the filter domain.
|
||||
for (sub_domain.insert(0, ".");
|
||||
sub_domain.length() >= filter_domain.length();) {
|
||||
if (sub_domain == filter_domain) {
|
||||
return true;
|
||||
}
|
||||
const size_t next_dot = sub_domain.find('.', 1); // Skip over leading dot.
|
||||
sub_domain.erase(0, next_dot);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MatchesCookie(const base::DictionaryValue* filter,
|
||||
const net::CanonicalCookie& cookie) {
|
||||
std::string name, domain, path;
|
||||
bool is_secure, session;
|
||||
if (filter->GetString("name", &name) && name != cookie.Name())
|
||||
return false;
|
||||
if (filter->GetString("path", &path) && path != cookie.Path())
|
||||
return false;
|
||||
if (!MatchesDomain(filter, cookie.Domain()))
|
||||
return false;
|
||||
if (filter->GetBoolean("secure", &is_secure) &&
|
||||
is_secure != cookie.IsSecure())
|
||||
return false;
|
||||
if (filter->GetBoolean("session", &session) &&
|
||||
session != cookie.IsPersistent())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace mate {
|
||||
|
||||
template<>
|
||||
struct Converter<net::CanonicalCookie> {
|
||||
@@ -42,11 +161,11 @@ struct Converter<net::CanonicalCookie> {
|
||||
dict.Set("name", val.Name());
|
||||
dict.Set("value", val.Value());
|
||||
dict.Set("domain", val.Domain());
|
||||
dict.Set("hostOnly", net::cookie_util::DomainIsHostOnly(val.Domain()));
|
||||
dict.Set("host_only", net::cookie_util::DomainIsHostOnly(val.Domain()));
|
||||
dict.Set("path", val.Path());
|
||||
dict.Set("secure", val.IsSecure());
|
||||
dict.Set("httpOnly", val.IsHttpOnly());
|
||||
dict.Set("session", !val.IsPersistent());
|
||||
dict.Set("http_only", val.IsHttpOnly());
|
||||
dict.Set("session", val.IsPersistent());
|
||||
if (!val.IsPersistent())
|
||||
dict.Set("expirationDate", val.ExpiryDate().ToDoubleT());
|
||||
return dict.GetHandle();
|
||||
@@ -59,117 +178,121 @@ namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
namespace {
|
||||
Cookies::Cookies(content::BrowserContext* browser_context)
|
||||
: request_context_getter_(browser_context->GetRequestContext()) {
|
||||
}
|
||||
|
||||
// Returns whether |domain| matches |filter|.
|
||||
bool MatchesDomain(std::string filter, const std::string& domain) {
|
||||
// Add a leading '.' character to the filter domain if it doesn't exist.
|
||||
if (net::cookie_util::DomainIsHostOnly(filter))
|
||||
filter.insert(0, ".");
|
||||
Cookies::~Cookies() {
|
||||
}
|
||||
|
||||
std::string sub_domain(domain);
|
||||
// Strip any leading '.' character from the input cookie domain.
|
||||
if (!net::cookie_util::DomainIsHostOnly(sub_domain))
|
||||
sub_domain = sub_domain.substr(1);
|
||||
void Cookies::Get(const base::DictionaryValue& options,
|
||||
const CookiesCallback& callback) {
|
||||
scoped_ptr<base::DictionaryValue> filter(
|
||||
options.DeepCopyWithoutEmptyChildren());
|
||||
|
||||
// Now check whether the domain argument is a subdomain of the filter domain.
|
||||
for (sub_domain.insert(0, "."); sub_domain.length() >= filter.length();) {
|
||||
if (sub_domain == filter)
|
||||
return true;
|
||||
const size_t next_dot = sub_domain.find('.', 1); // Skip over leading dot.
|
||||
sub_domain.erase(0, next_dot);
|
||||
content::BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&Cookies::GetCookiesOnIOThread, base::Unretained(this),
|
||||
Passed(&filter), callback));
|
||||
}
|
||||
|
||||
void Cookies::GetCookiesOnIOThread(scoped_ptr<base::DictionaryValue> filter,
|
||||
const CookiesCallback& callback) {
|
||||
std::string url;
|
||||
filter->GetString("url", &url);
|
||||
if (!GetCookieListFromStore(GetCookieStore(), url,
|
||||
base::Bind(&Cookies::OnGetCookies, base::Unretained(this),
|
||||
Passed(&filter), callback))) {
|
||||
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
||||
base::Bind(&RunGetCookiesCallbackOnUIThread, isolate(),
|
||||
"URL is not valid", net::CookieList(), callback));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Returns whether |cookie| matches |filter|.
|
||||
bool MatchesCookie(const base::DictionaryValue* filter,
|
||||
const net::CanonicalCookie& cookie) {
|
||||
std::string str;
|
||||
bool b;
|
||||
if (filter->GetString("name", &str) && str != cookie.Name())
|
||||
return false;
|
||||
if (filter->GetString("path", &str) && str != cookie.Path())
|
||||
return false;
|
||||
if (filter->GetString("domain", &str) && !MatchesDomain(str, cookie.Domain()))
|
||||
return false;
|
||||
if (filter->GetBoolean("secure", &b) && b != cookie.IsSecure())
|
||||
return false;
|
||||
if (filter->GetBoolean("session", &b) && b != !cookie.IsPersistent())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Helper to returns the CookieStore.
|
||||
inline net::CookieStore* GetCookieStore(
|
||||
scoped_refptr<net::URLRequestContextGetter> getter) {
|
||||
return getter->GetURLRequestContext()->cookie_store();
|
||||
}
|
||||
|
||||
// Run |callback| on UI thread.
|
||||
void RunCallbackInUI(const base::Closure& callback) {
|
||||
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback);
|
||||
}
|
||||
|
||||
// Remove cookies from |list| not matching |filter|, and pass it to |callback|.
|
||||
void FilterCookies(scoped_ptr<base::DictionaryValue> filter,
|
||||
const Cookies::GetCallback& callback,
|
||||
const net::CookieList& list) {
|
||||
void Cookies::OnGetCookies(scoped_ptr<base::DictionaryValue> filter,
|
||||
const CookiesCallback& callback,
|
||||
const net::CookieList& cookie_list) {
|
||||
net::CookieList result;
|
||||
for (const auto& cookie : list) {
|
||||
for (const auto& cookie : cookie_list) {
|
||||
if (MatchesCookie(filter.get(), cookie))
|
||||
result.push_back(cookie);
|
||||
}
|
||||
RunCallbackInUI(base::Bind(callback, Cookies::SUCCESS, result));
|
||||
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
|
||||
&RunGetCookiesCallbackOnUIThread, isolate(), "", result, callback));
|
||||
}
|
||||
|
||||
// Receives cookies matching |filter| in IO thread.
|
||||
void GetCookiesOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
scoped_ptr<base::DictionaryValue> filter,
|
||||
const Cookies::GetCallback& callback) {
|
||||
void Cookies::Remove(const mate::Dictionary& details,
|
||||
const CookiesCallback& callback) {
|
||||
GURL url;
|
||||
std::string name;
|
||||
std::string error_message;
|
||||
if (!details.Get("url", &url) || !details.Get("name", &name)) {
|
||||
error_message = "Details(url, name) of removing cookie are required.";
|
||||
}
|
||||
if (error_message.empty() && !url.is_valid()) {
|
||||
error_message = "URL is not valid.";
|
||||
}
|
||||
if (!error_message.empty()) {
|
||||
RunRemoveCookiesCallbackOnUIThread(isolate(), error_message, callback);
|
||||
return;
|
||||
}
|
||||
content::BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&Cookies::RemoveCookiesOnIOThread, base::Unretained(this),
|
||||
url, name, callback));
|
||||
}
|
||||
|
||||
void Cookies::RemoveCookiesOnIOThread(const GURL& url, const std::string& name,
|
||||
const CookiesCallback& callback) {
|
||||
GetCookieStore()->DeleteCookieAsync(url, name,
|
||||
base::Bind(&Cookies::OnRemoveCookies, base::Unretained(this), callback));
|
||||
}
|
||||
|
||||
void Cookies::OnRemoveCookies(const CookiesCallback& callback) {
|
||||
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
||||
base::Bind(&RunRemoveCookiesCallbackOnUIThread, isolate(), "", callback));
|
||||
}
|
||||
|
||||
void Cookies::Set(const base::DictionaryValue& options,
|
||||
const CookiesCallback& callback) {
|
||||
std::string url;
|
||||
filter->GetString("url", &url);
|
||||
std::string error_message;
|
||||
if (!options.GetString("url", &url)) {
|
||||
error_message = "The url field is required.";
|
||||
}
|
||||
|
||||
auto filtered_callback =
|
||||
base::Bind(FilterCookies, base::Passed(&filter), callback);
|
||||
GURL gurl(url);
|
||||
if (error_message.empty() && !gurl.is_valid()) {
|
||||
error_message = "URL is not valid.";
|
||||
}
|
||||
|
||||
net::CookieMonster* monster = GetCookieStore(getter)->GetCookieMonster();
|
||||
// Empty url will match all url cookies.
|
||||
if (url.empty())
|
||||
monster->GetAllCookiesAsync(filtered_callback);
|
||||
else
|
||||
monster->GetAllCookiesForURLAsync(GURL(url), filtered_callback);
|
||||
if (!error_message.empty()) {
|
||||
RunSetCookiesCallbackOnUIThread(isolate(), error_message, false, callback);
|
||||
return;
|
||||
}
|
||||
|
||||
scoped_ptr<base::DictionaryValue> details(
|
||||
options.DeepCopyWithoutEmptyChildren());
|
||||
|
||||
content::BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&Cookies::SetCookiesOnIOThread, base::Unretained(this),
|
||||
Passed(&details), gurl, callback));
|
||||
}
|
||||
|
||||
// Removes cookie with |url| and |name| in IO thread.
|
||||
void RemoveCookieOnIOThread(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
const GURL& url, const std::string& name,
|
||||
const base::Closure& callback) {
|
||||
GetCookieStore(getter)->DeleteCookieAsync(
|
||||
url, name, base::Bind(RunCallbackInUI, callback));
|
||||
}
|
||||
void Cookies::SetCookiesOnIOThread(scoped_ptr<base::DictionaryValue> details,
|
||||
const GURL& url,
|
||||
const CookiesCallback& callback) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
|
||||
// Callback of SetCookie.
|
||||
void OnSetCookie(const Cookies::SetCallback& callback, bool success) {
|
||||
RunCallbackInUI(
|
||||
base::Bind(callback, success ? Cookies::SUCCESS : Cookies::FAILED));
|
||||
}
|
||||
|
||||
// Sets cookie with |details| in IO thread.
|
||||
void SetCookieOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
scoped_ptr<base::DictionaryValue> details,
|
||||
const Cookies::SetCallback& callback) {
|
||||
std::string url, name, value, domain, path;
|
||||
std::string name, value, domain, path;
|
||||
bool secure = false;
|
||||
bool http_only = false;
|
||||
double expiration_date;
|
||||
details->GetString("url", &url);
|
||||
|
||||
details->GetString("name", &name);
|
||||
details->GetString("value", &value);
|
||||
details->GetString("domain", &domain);
|
||||
details->GetString("path", &path);
|
||||
details->GetBoolean("secure", &secure);
|
||||
details->GetBoolean("httpOnly", &http_only);
|
||||
details->GetBoolean("http_only", &http_only);
|
||||
|
||||
base::Time expiration_time;
|
||||
if (details->GetDouble("expirationDate", &expiration_date)) {
|
||||
@@ -178,44 +301,29 @@ void SetCookieOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
base::Time::FromDoubleT(expiration_date);
|
||||
}
|
||||
|
||||
GetCookieStore(getter)->GetCookieMonster()->SetCookieWithDetailsAsync(
|
||||
GURL(url), name, value, domain, path, expiration_time, secure, http_only,
|
||||
false, net::COOKIE_PRIORITY_DEFAULT, base::Bind(OnSetCookie, callback));
|
||||
GetCookieStore()->GetCookieMonster()->SetCookieWithDetailsAsync(
|
||||
url,
|
||||
name,
|
||||
value,
|
||||
domain,
|
||||
path,
|
||||
expiration_time,
|
||||
secure,
|
||||
http_only,
|
||||
false,
|
||||
net::COOKIE_PRIORITY_DEFAULT,
|
||||
base::Bind(&Cookies::OnSetCookies, base::Unretained(this), callback));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Cookies::Cookies(content::BrowserContext* browser_context)
|
||||
: request_context_getter_(browser_context->GetRequestContext()) {
|
||||
void Cookies::OnSetCookies(const CookiesCallback& callback,
|
||||
bool set_success) {
|
||||
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
||||
base::Bind(&RunSetCookiesCallbackOnUIThread, isolate(), "", set_success,
|
||||
callback));
|
||||
}
|
||||
|
||||
Cookies::~Cookies() {
|
||||
}
|
||||
|
||||
void Cookies::Get(const base::DictionaryValue& filter,
|
||||
const GetCallback& callback) {
|
||||
scoped_ptr<base::DictionaryValue> copied(filter.CreateDeepCopy());
|
||||
auto getter = make_scoped_refptr(request_context_getter_);
|
||||
content::BrowserThread::PostTask(
|
||||
BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(GetCookiesOnIO, getter, Passed(&copied), callback));
|
||||
}
|
||||
|
||||
void Cookies::Remove(const GURL& url, const std::string& name,
|
||||
const base::Closure& callback) {
|
||||
auto getter = make_scoped_refptr(request_context_getter_);
|
||||
content::BrowserThread::PostTask(
|
||||
BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(RemoveCookieOnIOThread, getter, url, name, callback));
|
||||
}
|
||||
|
||||
void Cookies::Set(const base::DictionaryValue& details,
|
||||
const SetCallback& callback) {
|
||||
scoped_ptr<base::DictionaryValue> copied(details.CreateDeepCopy());
|
||||
auto getter = make_scoped_refptr(request_context_getter_);
|
||||
content::BrowserThread::PostTask(
|
||||
BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(SetCookieOnIO, getter, Passed(&copied), callback));
|
||||
net::CookieStore* Cookies::GetCookieStore() {
|
||||
return request_context_getter_->GetURLRequestContext()->cookie_store();
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
@@ -20,7 +20,12 @@ namespace content {
|
||||
class BrowserContext;
|
||||
}
|
||||
|
||||
namespace mate {
|
||||
class Dictionary;
|
||||
}
|
||||
|
||||
namespace net {
|
||||
class CookieStore;
|
||||
class URLRequestContextGetter;
|
||||
}
|
||||
|
||||
@@ -30,13 +35,9 @@ namespace api {
|
||||
|
||||
class Cookies : public mate::TrackableObject<Cookies> {
|
||||
public:
|
||||
enum Error {
|
||||
SUCCESS,
|
||||
FAILED,
|
||||
};
|
||||
|
||||
using GetCallback = base::Callback<void(Error, const net::CookieList&)>;
|
||||
using SetCallback = base::Callback<void(Error)>;
|
||||
// node.js style callback function(error, result)
|
||||
typedef base::Callback<void(v8::Local<v8::Value>, v8::Local<v8::Value>)>
|
||||
CookiesCallback;
|
||||
|
||||
static mate::Handle<Cookies> Create(v8::Isolate* isolate,
|
||||
content::BrowserContext* browser_context);
|
||||
@@ -49,12 +50,34 @@ class Cookies : public mate::TrackableObject<Cookies> {
|
||||
explicit Cookies(content::BrowserContext* browser_context);
|
||||
~Cookies();
|
||||
|
||||
void Get(const base::DictionaryValue& filter, const GetCallback& callback);
|
||||
void Remove(const GURL& url, const std::string& name,
|
||||
const base::Closure& callback);
|
||||
void Set(const base::DictionaryValue& details, const SetCallback& callback);
|
||||
void Get(const base::DictionaryValue& options,
|
||||
const CookiesCallback& callback);
|
||||
void Remove(const mate::Dictionary& details,
|
||||
const CookiesCallback& callback);
|
||||
void Set(const base::DictionaryValue& details,
|
||||
const CookiesCallback& callback);
|
||||
|
||||
void GetCookiesOnIOThread(scoped_ptr<base::DictionaryValue> filter,
|
||||
const CookiesCallback& callback);
|
||||
void OnGetCookies(scoped_ptr<base::DictionaryValue> filter,
|
||||
const CookiesCallback& callback,
|
||||
const net::CookieList& cookie_list);
|
||||
|
||||
void RemoveCookiesOnIOThread(const GURL& url,
|
||||
const std::string& name,
|
||||
const CookiesCallback& callback);
|
||||
void OnRemoveCookies(const CookiesCallback& callback);
|
||||
|
||||
void SetCookiesOnIOThread(scoped_ptr<base::DictionaryValue> details,
|
||||
const GURL& url,
|
||||
const CookiesCallback& callback);
|
||||
void OnSetCookies(const CookiesCallback& callback,
|
||||
bool set_success);
|
||||
|
||||
private:
|
||||
// Must be called on IO thread.
|
||||
net::CookieStore* GetCookieStore();
|
||||
|
||||
net::URLRequestContextGetter* request_context_getter_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Cookies);
|
||||
|
||||
@@ -1,195 +0,0 @@
|
||||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/atom_api_debugger.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/json/json_reader.h"
|
||||
#include "base/json/json_writer.h"
|
||||
#include "content/public/browser/devtools_agent_host.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
|
||||
using content::DevToolsAgentHost;
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
namespace {
|
||||
|
||||
// The wrapDebugger funtion which is implemented in JavaScript.
|
||||
using WrapDebuggerCallback = base::Callback<void(v8::Local<v8::Value>)>;
|
||||
WrapDebuggerCallback g_wrap_debugger;
|
||||
|
||||
} // namespace
|
||||
|
||||
Debugger::Debugger(content::WebContents* web_contents)
|
||||
: web_contents_(web_contents),
|
||||
previous_request_id_(0) {
|
||||
}
|
||||
|
||||
Debugger::~Debugger() {
|
||||
}
|
||||
|
||||
void Debugger::AgentHostClosed(DevToolsAgentHost* agent_host,
|
||||
bool replaced_with_another_client) {
|
||||
std::string detach_reason = "target closed";
|
||||
if (replaced_with_another_client)
|
||||
detach_reason = "replaced with devtools";
|
||||
Emit("detach", detach_reason);
|
||||
}
|
||||
|
||||
void Debugger::DispatchProtocolMessage(DevToolsAgentHost* agent_host,
|
||||
const std::string& message) {
|
||||
DCHECK(agent_host == agent_host_.get());
|
||||
|
||||
scoped_ptr<base::Value> parsed_message(base::JSONReader::Read(message));
|
||||
if (!parsed_message->IsType(base::Value::TYPE_DICTIONARY))
|
||||
return;
|
||||
|
||||
base::DictionaryValue* dict =
|
||||
static_cast<base::DictionaryValue*>(parsed_message.get());
|
||||
int id;
|
||||
if (!dict->GetInteger("id", &id)) {
|
||||
std::string method;
|
||||
if (!dict->GetString("method", &method))
|
||||
return;
|
||||
base::DictionaryValue* params_value = nullptr;
|
||||
base::DictionaryValue params;
|
||||
if (dict->GetDictionary("params", ¶ms_value))
|
||||
params.Swap(params_value);
|
||||
Emit("message", method, params);
|
||||
} else {
|
||||
auto send_command_callback = pending_requests_[id];
|
||||
pending_requests_.erase(id);
|
||||
if (send_command_callback.is_null())
|
||||
return;
|
||||
base::DictionaryValue* error_body = nullptr;
|
||||
base::DictionaryValue error;
|
||||
if (dict->GetDictionary("error", &error_body))
|
||||
error.Swap(error_body);
|
||||
|
||||
base::DictionaryValue* result_body = nullptr;
|
||||
base::DictionaryValue result;
|
||||
if (dict->GetDictionary("result", &result_body))
|
||||
result.Swap(result_body);
|
||||
send_command_callback.Run(error, result);
|
||||
}
|
||||
}
|
||||
|
||||
void Debugger::Attach(mate::Arguments* args) {
|
||||
std::string protocol_version;
|
||||
args->GetNext(&protocol_version);
|
||||
|
||||
if (!protocol_version.empty() &&
|
||||
!DevToolsAgentHost::IsSupportedProtocolVersion(protocol_version)) {
|
||||
args->ThrowError("Requested protocol version is not supported");
|
||||
return;
|
||||
}
|
||||
agent_host_ = DevToolsAgentHost::GetOrCreateFor(web_contents_);
|
||||
if (!agent_host_.get()) {
|
||||
args->ThrowError("No target available");
|
||||
return;
|
||||
}
|
||||
if (agent_host_->IsAttached()) {
|
||||
args->ThrowError("Another debugger is already attached to this target");
|
||||
return;
|
||||
}
|
||||
|
||||
agent_host_->AttachClient(this);
|
||||
}
|
||||
|
||||
bool Debugger::IsAttached() {
|
||||
return agent_host_.get() ? agent_host_->IsAttached() : false;
|
||||
}
|
||||
|
||||
void Debugger::Detach() {
|
||||
if (!agent_host_.get())
|
||||
return;
|
||||
agent_host_->DetachClient();
|
||||
AgentHostClosed(agent_host_.get(), false);
|
||||
agent_host_ = nullptr;
|
||||
}
|
||||
|
||||
void Debugger::SendCommand(mate::Arguments* args) {
|
||||
if (!agent_host_.get())
|
||||
return;
|
||||
|
||||
std::string method;
|
||||
if (!args->GetNext(&method)) {
|
||||
args->ThrowError();
|
||||
return;
|
||||
}
|
||||
base::DictionaryValue command_params;
|
||||
args->GetNext(&command_params);
|
||||
SendCommandCallback callback;
|
||||
args->GetNext(&callback);
|
||||
|
||||
base::DictionaryValue request;
|
||||
int request_id = ++previous_request_id_;
|
||||
pending_requests_[request_id] = callback;
|
||||
request.SetInteger("id", request_id);
|
||||
request.SetString("method", method);
|
||||
if (!command_params.empty())
|
||||
request.Set("params", command_params.DeepCopy());
|
||||
|
||||
std::string json_args;
|
||||
base::JSONWriter::Write(request, &json_args);
|
||||
agent_host_->DispatchProtocolMessage(json_args);
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<Debugger> Debugger::Create(
|
||||
v8::Isolate* isolate,
|
||||
content::WebContents* web_contents) {
|
||||
auto handle = mate::CreateHandle(isolate, new Debugger(web_contents));
|
||||
g_wrap_debugger.Run(handle.ToV8());
|
||||
return handle;
|
||||
}
|
||||
|
||||
// static
|
||||
void Debugger::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::ObjectTemplate> prototype) {
|
||||
mate::ObjectTemplateBuilder(isolate, prototype)
|
||||
.SetMethod("attach", &Debugger::Attach)
|
||||
.SetMethod("isAttached", &Debugger::IsAttached)
|
||||
.SetMethod("detach", &Debugger::Detach)
|
||||
.SetMethod("sendCommand", &Debugger::SendCommand);
|
||||
}
|
||||
|
||||
void ClearWrapDebugger() {
|
||||
g_wrap_debugger.Reset();
|
||||
}
|
||||
|
||||
void SetWrapDebugger(const WrapDebuggerCallback& callback) {
|
||||
g_wrap_debugger = callback;
|
||||
|
||||
// Cleanup the wrapper on exit.
|
||||
atom::AtomBrowserMainParts::Get()->RegisterDestructionCallback(
|
||||
base::Bind(ClearWrapDebugger));
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context, void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.SetMethod("_setWrapDebugger", &atom::api::SetWrapDebugger);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_debugger, Initialize);
|
||||
@@ -1,75 +0,0 @@
|
||||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_DEBUGGER_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_DEBUGGER_H_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "base/callback.h"
|
||||
#include "base/values.h"
|
||||
#include "content/public/browser/devtools_agent_host_client.h"
|
||||
#include "native_mate/handle.h"
|
||||
|
||||
namespace content {
|
||||
class DevToolsAgentHost;
|
||||
class WebContents;
|
||||
}
|
||||
|
||||
namespace mate {
|
||||
class Arguments;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class Debugger: public mate::TrackableObject<Debugger>,
|
||||
public content::DevToolsAgentHostClient {
|
||||
public:
|
||||
using SendCommandCallback =
|
||||
base::Callback<void(const base::DictionaryValue&,
|
||||
const base::DictionaryValue&)>;
|
||||
|
||||
static mate::Handle<Debugger> Create(
|
||||
v8::Isolate* isolate, content::WebContents* web_contents);
|
||||
|
||||
// mate::TrackableObject:
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::ObjectTemplate> prototype);
|
||||
|
||||
protected:
|
||||
explicit Debugger(content::WebContents* web_contents);
|
||||
~Debugger();
|
||||
|
||||
// content::DevToolsAgentHostClient:
|
||||
void AgentHostClosed(content::DevToolsAgentHost* agent_host,
|
||||
bool replaced_with_another_client) override;
|
||||
void DispatchProtocolMessage(content::DevToolsAgentHost* agent_host,
|
||||
const std::string& message) override;
|
||||
|
||||
private:
|
||||
using PendingRequestMap = std::map<int, SendCommandCallback>;
|
||||
|
||||
void Attach(mate::Arguments* args);
|
||||
bool IsAttached();
|
||||
void Detach();
|
||||
void SendCommand(mate::Arguments* args);
|
||||
|
||||
content::WebContents* web_contents_; // Weak Reference.
|
||||
scoped_refptr<content::DevToolsAgentHost> agent_host_;
|
||||
|
||||
PendingRequestMap pending_requests_;
|
||||
int previous_request_id_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Debugger);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_DEBUGGER_H_
|
||||
@@ -1,120 +0,0 @@
|
||||
// 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/api/atom_api_desktop_capturer.h"
|
||||
|
||||
#include "atom/common/api/atom_api_native_image.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "chrome/browser/media/desktop_media_list.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h"
|
||||
#include "third_party/webrtc/modules/desktop_capture/screen_capturer.h"
|
||||
#include "third_party/webrtc/modules/desktop_capture/window_capturer.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
template<>
|
||||
struct Converter<DesktopMediaList::Source> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const DesktopMediaList::Source& source) {
|
||||
mate::Dictionary dict(isolate, v8::Object::New(isolate));
|
||||
content::DesktopMediaID id = source.id;
|
||||
dict.Set("name", base::UTF16ToUTF8(source.name));
|
||||
dict.Set("id", id.ToString());
|
||||
dict.Set(
|
||||
"thumbnail",
|
||||
atom::api::NativeImage::Create(isolate, gfx::Image(source.thumbnail)));
|
||||
return ConvertToV8(isolate, dict);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
DesktopCapturer::DesktopCapturer() {
|
||||
}
|
||||
|
||||
DesktopCapturer::~DesktopCapturer() {
|
||||
}
|
||||
|
||||
void DesktopCapturer::StartHandling(bool capture_window,
|
||||
bool capture_screen,
|
||||
const gfx::Size& thumbnail_size) {
|
||||
webrtc::DesktopCaptureOptions options =
|
||||
webrtc::DesktopCaptureOptions::CreateDefault();
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// On windows, desktop effects (e.g. Aero) will be disabled when the Desktop
|
||||
// capture API is active by default.
|
||||
// We keep the desktop effects in most times. Howerver, the screen still
|
||||
// fickers when the API is capturing the window due to limitation of current
|
||||
// implemetation. This is a known and wontFix issue in webrtc (see:
|
||||
// http://code.google.com/p/webrtc/issues/detail?id=3373)
|
||||
options.set_disable_effects(false);
|
||||
#endif
|
||||
|
||||
scoped_ptr<webrtc::ScreenCapturer> screen_capturer(
|
||||
capture_screen ? webrtc::ScreenCapturer::Create(options) : nullptr);
|
||||
scoped_ptr<webrtc::WindowCapturer> window_capturer(
|
||||
capture_window ? webrtc::WindowCapturer::Create(options) : nullptr);
|
||||
media_list_.reset(new NativeDesktopMediaList(screen_capturer.Pass(),
|
||||
window_capturer.Pass()));
|
||||
|
||||
media_list_->SetThumbnailSize(thumbnail_size);
|
||||
media_list_->StartUpdating(this);
|
||||
}
|
||||
|
||||
void DesktopCapturer::OnSourceAdded(int index) {
|
||||
}
|
||||
|
||||
void DesktopCapturer::OnSourceRemoved(int index) {
|
||||
}
|
||||
|
||||
void DesktopCapturer::OnSourceMoved(int old_index, int new_index) {
|
||||
}
|
||||
|
||||
void DesktopCapturer::OnSourceNameChanged(int index) {
|
||||
}
|
||||
|
||||
void DesktopCapturer::OnSourceThumbnailChanged(int index) {
|
||||
}
|
||||
|
||||
bool DesktopCapturer::OnRefreshFinished() {
|
||||
Emit("finished", media_list_->GetSources());
|
||||
media_list_.reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
mate::ObjectTemplateBuilder DesktopCapturer::GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) {
|
||||
return mate::ObjectTemplateBuilder(isolate)
|
||||
.SetMethod("startHandling", &DesktopCapturer::StartHandling);
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<DesktopCapturer> DesktopCapturer::Create(v8::Isolate* isolate) {
|
||||
return mate::CreateHandle(isolate, new DesktopCapturer);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context, void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("desktopCapturer", atom::api::DesktopCapturer::Create(isolate));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_desktop_capturer, Initialize);
|
||||
@@ -1,52 +0,0 @@
|
||||
// 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_API_ATOM_API_DESKTOP_CAPTURER_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_DESKTOP_CAPTURER_H_
|
||||
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "chrome/browser/media/desktop_media_list_observer.h"
|
||||
#include "chrome/browser/media/native_desktop_media_list.h"
|
||||
#include "native_mate/handle.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class DesktopCapturer: public mate::EventEmitter,
|
||||
public DesktopMediaListObserver {
|
||||
public:
|
||||
static mate::Handle<DesktopCapturer> Create(v8::Isolate* isolate);
|
||||
|
||||
void StartHandling(bool capture_window,
|
||||
bool capture_screen,
|
||||
const gfx::Size& thumbnail_size);
|
||||
|
||||
protected:
|
||||
DesktopCapturer();
|
||||
~DesktopCapturer();
|
||||
|
||||
// DesktopMediaListObserver overrides.
|
||||
void OnSourceAdded(int index) override;
|
||||
void OnSourceRemoved(int index) override;
|
||||
void OnSourceMoved(int old_index, int new_index) override;
|
||||
void OnSourceNameChanged(int index) override;
|
||||
void OnSourceThumbnailChanged(int index) override;
|
||||
bool OnRefreshFinished() override;
|
||||
|
||||
private:
|
||||
// mate::Wrappable:
|
||||
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) override;
|
||||
|
||||
scoped_ptr<DesktopMediaList> media_list_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(DesktopCapturer);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_DESKTOP_CAPTURER_H_
|
||||
@@ -41,7 +41,6 @@ namespace {
|
||||
|
||||
void ShowMessageBox(int type,
|
||||
const std::vector<std::string>& buttons,
|
||||
int default_id,
|
||||
int cancel_id,
|
||||
int options,
|
||||
const std::string& title,
|
||||
@@ -55,13 +54,12 @@ void ShowMessageBox(int type,
|
||||
if (mate::Converter<atom::MessageBoxCallback>::FromV8(args->isolate(),
|
||||
peek,
|
||||
&callback)) {
|
||||
atom::ShowMessageBox(window, (atom::MessageBoxType)type, buttons,
|
||||
default_id, cancel_id, options, title,
|
||||
message, detail, icon, callback);
|
||||
atom::ShowMessageBox(window, (atom::MessageBoxType)type, buttons, cancel_id,
|
||||
options, title, message, detail, icon, callback);
|
||||
} else {
|
||||
int chosen = atom::ShowMessageBox(window, (atom::MessageBoxType)type,
|
||||
buttons, default_id, cancel_id,
|
||||
options, title, message, detail, icon);
|
||||
buttons, cancel_id, options, title,
|
||||
message, detail, icon);
|
||||
args->Return(chosen);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/memory/linked_ptr.h"
|
||||
#include "base/message_loop/message_loop.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "net/base/filename_util.h"
|
||||
@@ -48,49 +47,80 @@ namespace atom {
|
||||
namespace api {
|
||||
|
||||
namespace {
|
||||
|
||||
// The wrapDownloadItem funtion which is implemented in JavaScript
|
||||
using WrapDownloadItemCallback = base::Callback<void(v8::Local<v8::Value>)>;
|
||||
WrapDownloadItemCallback g_wrap_download_item;
|
||||
|
||||
std::map<uint32, linked_ptr<v8::Global<v8::Value>>> g_download_item_objects;
|
||||
char kDownloadItemSavePathKey[] = "DownloadItemSavePathKey";
|
||||
|
||||
std::map<uint32, linked_ptr<v8::Global<v8::Value>>> g_download_item_objects;
|
||||
} // namespace
|
||||
|
||||
DownloadItem::DownloadItem(content::DownloadItem* download_item)
|
||||
: download_item_(download_item) {
|
||||
DownloadItem::SavePathData::SavePathData(const base::FilePath& path) :
|
||||
path_(path) {
|
||||
}
|
||||
|
||||
const base::FilePath& DownloadItem::SavePathData::path() {
|
||||
return path_;
|
||||
}
|
||||
|
||||
DownloadItem::DownloadItem(content::DownloadItem* download_item) :
|
||||
download_item_(download_item) {
|
||||
download_item_->AddObserver(this);
|
||||
AttachAsUserData(download_item);
|
||||
}
|
||||
|
||||
DownloadItem::~DownloadItem() {
|
||||
if (download_item_) {
|
||||
// Destroyed by either garbage collection or destroy().
|
||||
download_item_->RemoveObserver(this);
|
||||
download_item_->Remove();
|
||||
}
|
||||
|
||||
// Remove from the global map.
|
||||
auto iter = g_download_item_objects.find(weak_map_id());
|
||||
if (iter != g_download_item_objects.end())
|
||||
g_download_item_objects.erase(iter);
|
||||
if (download_item_)
|
||||
OnDownloadDestroyed(download_item_);
|
||||
}
|
||||
|
||||
void DownloadItem::OnDownloadUpdated(content::DownloadItem* item) {
|
||||
if (download_item_->IsDone()) {
|
||||
Emit("done", item->GetState());
|
||||
|
||||
// Destroy the item once item is downloaded.
|
||||
base::MessageLoop::current()->PostTask(FROM_HERE, GetDestroyClosure());
|
||||
} else {
|
||||
Emit("updated");
|
||||
}
|
||||
download_item_->IsDone() ? Emit("done", item->GetState()) : Emit("updated");
|
||||
}
|
||||
|
||||
void DownloadItem::OnDownloadDestroyed(content::DownloadItem* download_item) {
|
||||
download_item_->RemoveObserver(this);
|
||||
auto iter = g_download_item_objects.find(download_item_->GetId());
|
||||
if (iter != g_download_item_objects.end())
|
||||
g_download_item_objects.erase(iter);
|
||||
download_item_ = nullptr;
|
||||
// Destroy the native class immediately when downloadItem is destroyed.
|
||||
delete this;
|
||||
}
|
||||
|
||||
int64 DownloadItem::GetReceivedBytes() {
|
||||
return download_item_->GetReceivedBytes();
|
||||
}
|
||||
|
||||
int64 DownloadItem::GetTotalBytes() {
|
||||
return download_item_->GetTotalBytes();
|
||||
}
|
||||
|
||||
const GURL& DownloadItem::GetURL() {
|
||||
return download_item_->GetURL();
|
||||
}
|
||||
|
||||
std::string DownloadItem::GetMimeType() {
|
||||
return download_item_->GetMimeType();
|
||||
}
|
||||
|
||||
bool DownloadItem::HasUserGesture() {
|
||||
return download_item_->HasUserGesture();
|
||||
}
|
||||
|
||||
std::string DownloadItem::GetFilename() {
|
||||
return base::UTF16ToUTF8(net::GenerateFileName(GetURL(),
|
||||
GetContentDisposition(),
|
||||
std::string(),
|
||||
download_item_->GetSuggestedFilename(),
|
||||
GetMimeType(),
|
||||
std::string()).LossyDisplayName());
|
||||
}
|
||||
|
||||
std::string DownloadItem::GetContentDisposition() {
|
||||
return download_item_->GetContentDisposition();
|
||||
}
|
||||
|
||||
void DownloadItem::SetSavePath(const base::FilePath& path) {
|
||||
download_item_->SetUserData(UserDataKey(), new SavePathData(path));
|
||||
}
|
||||
|
||||
void DownloadItem::Pause() {
|
||||
@@ -103,48 +133,6 @@ void DownloadItem::Resume() {
|
||||
|
||||
void DownloadItem::Cancel() {
|
||||
download_item_->Cancel(true);
|
||||
download_item_->Remove();
|
||||
}
|
||||
|
||||
int64 DownloadItem::GetReceivedBytes() const {
|
||||
return download_item_->GetReceivedBytes();
|
||||
}
|
||||
|
||||
int64 DownloadItem::GetTotalBytes() const {
|
||||
return download_item_->GetTotalBytes();
|
||||
}
|
||||
|
||||
std::string DownloadItem::GetMimeType() const {
|
||||
return download_item_->GetMimeType();
|
||||
}
|
||||
|
||||
bool DownloadItem::HasUserGesture() const {
|
||||
return download_item_->HasUserGesture();
|
||||
}
|
||||
|
||||
std::string DownloadItem::GetFilename() const {
|
||||
return base::UTF16ToUTF8(net::GenerateFileName(GetURL(),
|
||||
GetContentDisposition(),
|
||||
std::string(),
|
||||
download_item_->GetSuggestedFilename(),
|
||||
GetMimeType(),
|
||||
std::string()).LossyDisplayName());
|
||||
}
|
||||
|
||||
std::string DownloadItem::GetContentDisposition() const {
|
||||
return download_item_->GetContentDisposition();
|
||||
}
|
||||
|
||||
const GURL& DownloadItem::GetURL() const {
|
||||
return download_item_->GetURL();
|
||||
}
|
||||
|
||||
void DownloadItem::SetSavePath(const base::FilePath& path) {
|
||||
save_path_ = path;
|
||||
}
|
||||
|
||||
base::FilePath DownloadItem::GetSavePath() const {
|
||||
return save_path_;
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -157,31 +145,29 @@ void DownloadItem::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("cancel", &DownloadItem::Cancel)
|
||||
.SetMethod("getReceivedBytes", &DownloadItem::GetReceivedBytes)
|
||||
.SetMethod("getTotalBytes", &DownloadItem::GetTotalBytes)
|
||||
.SetMethod("getURL", &DownloadItem::GetURL)
|
||||
.SetMethod("getMimeType", &DownloadItem::GetMimeType)
|
||||
.SetMethod("hasUserGesture", &DownloadItem::HasUserGesture)
|
||||
.SetMethod("getFilename", &DownloadItem::GetFilename)
|
||||
.SetMethod("getContentDisposition", &DownloadItem::GetContentDisposition)
|
||||
.SetMethod("getURL", &DownloadItem::GetURL)
|
||||
.SetMethod("setSavePath", &DownloadItem::SetSavePath)
|
||||
.SetMethod("getSavePath", &DownloadItem::GetSavePath);
|
||||
.SetMethod("setSavePath", &DownloadItem::SetSavePath);
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<DownloadItem> DownloadItem::Create(
|
||||
v8::Isolate* isolate, content::DownloadItem* item) {
|
||||
auto existing = TrackableObject::FromWrappedClass(isolate, item);
|
||||
if (existing)
|
||||
return mate::CreateHandle(isolate, static_cast<DownloadItem*>(existing));
|
||||
|
||||
auto handle = mate::CreateHandle(isolate, new DownloadItem(item));
|
||||
g_wrap_download_item.Run(handle.ToV8());
|
||||
|
||||
// Reference this object in case it got garbage collected.
|
||||
g_download_item_objects[handle->weak_map_id()] = make_linked_ptr(
|
||||
g_download_item_objects[item->GetId()] = make_linked_ptr(
|
||||
new v8::Global<v8::Value>(isolate, handle.ToV8()));
|
||||
return handle;
|
||||
}
|
||||
|
||||
// static
|
||||
void* DownloadItem::UserDataKey() {
|
||||
return &kDownloadItemSavePathKey;
|
||||
}
|
||||
|
||||
void ClearWrapDownloadItem() {
|
||||
g_wrap_download_item.Reset();
|
||||
}
|
||||
|
||||
@@ -20,26 +20,22 @@ namespace api {
|
||||
class DownloadItem : public mate::TrackableObject<DownloadItem>,
|
||||
public content::DownloadItem::Observer {
|
||||
public:
|
||||
class SavePathData : public base::SupportsUserData::Data {
|
||||
public:
|
||||
explicit SavePathData(const base::FilePath& path);
|
||||
const base::FilePath& path();
|
||||
private:
|
||||
base::FilePath path_;
|
||||
};
|
||||
|
||||
static mate::Handle<DownloadItem> Create(v8::Isolate* isolate,
|
||||
content::DownloadItem* item);
|
||||
static void* UserDataKey();
|
||||
|
||||
// mate::TrackableObject:
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::ObjectTemplate> prototype);
|
||||
|
||||
void Pause();
|
||||
void Resume();
|
||||
void Cancel();
|
||||
int64 GetReceivedBytes() const;
|
||||
int64 GetTotalBytes() const;
|
||||
std::string GetMimeType() const;
|
||||
bool HasUserGesture() const;
|
||||
std::string GetFilename() const;
|
||||
std::string GetContentDisposition() const;
|
||||
const GURL& GetURL() const;
|
||||
void SetSavePath(const base::FilePath& path);
|
||||
base::FilePath GetSavePath() const;
|
||||
|
||||
protected:
|
||||
explicit DownloadItem(content::DownloadItem* download_item);
|
||||
~DownloadItem();
|
||||
@@ -48,8 +44,19 @@ class DownloadItem : public mate::TrackableObject<DownloadItem>,
|
||||
void OnDownloadUpdated(content::DownloadItem* download) override;
|
||||
void OnDownloadDestroyed(content::DownloadItem* download) override;
|
||||
|
||||
void Pause();
|
||||
void Resume();
|
||||
void Cancel();
|
||||
int64 GetReceivedBytes();
|
||||
int64 GetTotalBytes();
|
||||
std::string GetMimeType();
|
||||
bool HasUserGesture();
|
||||
std::string GetFilename();
|
||||
std::string GetContentDisposition();
|
||||
const GURL& GetURL();
|
||||
void SetSavePath(const base::FilePath& path);
|
||||
|
||||
private:
|
||||
base::FilePath save_path_;
|
||||
content::DownloadItem* download_item_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(DownloadItem);
|
||||
|
||||
@@ -169,7 +169,8 @@ void Menu::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("isItemCheckedAt", &Menu::IsItemCheckedAt)
|
||||
.SetMethod("isEnabledAt", &Menu::IsEnabledAt)
|
||||
.SetMethod("isVisibleAt", &Menu::IsVisibleAt)
|
||||
.SetMethod("popupAt", &Menu::PopupAt);
|
||||
.SetMethod("_popup", &Menu::Popup)
|
||||
.SetMethod("_popupAt", &Menu::PopupAt);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
@@ -51,9 +51,8 @@ class Menu : public mate::TrackableObject<Menu>,
|
||||
void ExecuteCommand(int command_id, int event_flags) override;
|
||||
void MenuWillShow(ui::SimpleMenuModel* source) override;
|
||||
|
||||
virtual void PopupAt(Window* window,
|
||||
int x = -1, int y = -1,
|
||||
int positioning_item = 0) = 0;
|
||||
virtual void Popup(Window* window) = 0;
|
||||
virtual void PopupAt(Window* window, int x, int y) = 0;
|
||||
|
||||
scoped_ptr<AtomMenuModel> model_;
|
||||
Menu* parent_;
|
||||
|
||||
@@ -19,7 +19,8 @@ class MenuMac : public Menu {
|
||||
protected:
|
||||
MenuMac();
|
||||
|
||||
void PopupAt(Window* window, int x, int y, int positioning_item = 0) override;
|
||||
void Popup(Window* window) override;
|
||||
void PopupAt(Window* window, int x, int y) override;
|
||||
|
||||
base::scoped_nsobject<AtomMenuController> menu_controller_;
|
||||
|
||||
|
||||
@@ -18,7 +18,39 @@ namespace api {
|
||||
MenuMac::MenuMac() {
|
||||
}
|
||||
|
||||
void MenuMac::PopupAt(Window* window, int x, int y, int positioning_item) {
|
||||
void MenuMac::Popup(Window* window) {
|
||||
NativeWindow* native_window = window->window();
|
||||
if (!native_window)
|
||||
return;
|
||||
content::WebContents* web_contents = native_window->web_contents();
|
||||
if (!web_contents)
|
||||
return;
|
||||
|
||||
NSWindow* nswindow = native_window->GetNativeWindow();
|
||||
base::scoped_nsobject<AtomMenuController> menu_controller(
|
||||
[[AtomMenuController alloc] initWithModel:model_.get()]);
|
||||
|
||||
// Fake out a context menu event.
|
||||
NSEvent* currentEvent = [NSApp currentEvent];
|
||||
NSPoint position = [nswindow mouseLocationOutsideOfEventStream];
|
||||
NSTimeInterval eventTime = [currentEvent timestamp];
|
||||
NSEvent* clickEvent = [NSEvent mouseEventWithType:NSRightMouseDown
|
||||
location:position
|
||||
modifierFlags:NSRightMouseDownMask
|
||||
timestamp:eventTime
|
||||
windowNumber:[nswindow windowNumber]
|
||||
context:nil
|
||||
eventNumber:0
|
||||
clickCount:1
|
||||
pressure:1.0];
|
||||
|
||||
// Show the menu.
|
||||
[NSMenu popUpContextMenu:[menu_controller menu]
|
||||
withEvent:clickEvent
|
||||
forView:web_contents->GetContentNativeView()];
|
||||
}
|
||||
|
||||
void MenuMac::PopupAt(Window* window, int x, int y) {
|
||||
NativeWindow* native_window = window->window();
|
||||
if (!native_window)
|
||||
return;
|
||||
@@ -31,23 +63,10 @@ void MenuMac::PopupAt(Window* window, int x, int y, int positioning_item) {
|
||||
NSMenu* menu = [menu_controller menu];
|
||||
NSView* view = web_contents->GetContentNativeView();
|
||||
|
||||
// Which menu item to show.
|
||||
NSMenuItem* item = nil;
|
||||
if (positioning_item < [menu numberOfItems] && positioning_item >= 0)
|
||||
item = [menu itemAtIndex:positioning_item];
|
||||
|
||||
// (-1, -1) means showing on mouse location.
|
||||
NSPoint position;
|
||||
if (x == -1 || y == -1) {
|
||||
NSWindow* nswindow = native_window->GetNativeWindow();
|
||||
position = [view convertPoint:[nswindow mouseLocationOutsideOfEventStream]
|
||||
fromView:nil];
|
||||
} else {
|
||||
position = NSMakePoint(x, [view frame].size.height - y);
|
||||
}
|
||||
|
||||
// Show the menu.
|
||||
[menu popUpMenuPositioningItem:item atLocation:position inView:view];
|
||||
[menu popUpMenuPositioningItem:[menu itemAtIndex:0]
|
||||
atLocation:NSMakePoint(x, [view frame].size.height - y)
|
||||
inView:view];
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
@@ -16,7 +16,11 @@ namespace api {
|
||||
MenuViews::MenuViews() {
|
||||
}
|
||||
|
||||
void MenuViews::PopupAt(Window* window, int x, int y, int positioning_item) {
|
||||
void MenuViews::Popup(Window* window) {
|
||||
PopupAtPoint(window, gfx::Screen::GetNativeScreen()->GetCursorScreenPoint());
|
||||
}
|
||||
|
||||
void MenuViews::PopupAt(Window* window, int x, int y) {
|
||||
NativeWindow* native_window = static_cast<NativeWindow*>(window->window());
|
||||
if (!native_window)
|
||||
return;
|
||||
@@ -27,23 +31,18 @@ void MenuViews::PopupAt(Window* window, int x, int y, int positioning_item) {
|
||||
if (!view)
|
||||
return;
|
||||
|
||||
// (-1, -1) means showing on mouse location.
|
||||
gfx::Point location;
|
||||
if (x == -1 || y == -1) {
|
||||
location = gfx::Screen::GetNativeScreen()->GetCursorScreenPoint();
|
||||
} else {
|
||||
gfx::Point origin = view->GetViewBounds().origin();
|
||||
location = gfx::Point(origin.x() + x, origin.y() + y);
|
||||
}
|
||||
gfx::Point origin = view->GetViewBounds().origin();
|
||||
PopupAtPoint(window, gfx::Point(origin.x() + x, origin.y() + y));
|
||||
}
|
||||
|
||||
// Show the menu.
|
||||
void MenuViews::PopupAtPoint(Window* window, const gfx::Point& point) {
|
||||
views::MenuRunner menu_runner(
|
||||
model(),
|
||||
views::MenuRunner::CONTEXT_MENU | views::MenuRunner::HAS_MNEMONICS);
|
||||
ignore_result(menu_runner.RunMenuAt(
|
||||
static_cast<NativeWindowViews*>(window->window())->widget(),
|
||||
NULL,
|
||||
gfx::Rect(location, gfx::Size()),
|
||||
gfx::Rect(point, gfx::Size()),
|
||||
views::MENU_ANCHOR_TOPLEFT,
|
||||
ui::MENU_SOURCE_MOUSE));
|
||||
}
|
||||
|
||||
@@ -17,9 +17,12 @@ class MenuViews : public Menu {
|
||||
MenuViews();
|
||||
|
||||
protected:
|
||||
void PopupAt(Window* window, int x, int y, int positioning_item = 0) override;
|
||||
void Popup(Window* window) override;
|
||||
void PopupAt(Window* window, int x, int y) override;
|
||||
|
||||
private:
|
||||
void PopupAtPoint(Window* window, const gfx::Point& point);
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(MenuViews);
|
||||
};
|
||||
|
||||
|
||||
@@ -32,8 +32,6 @@ 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",
|
||||
@@ -60,11 +58,6 @@ 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,9 +92,6 @@ 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,
|
||||
|
||||
@@ -10,21 +10,17 @@
|
||||
#include "atom/browser/api/atom_api_cookies.h"
|
||||
#include "atom/browser/api/atom_api_download_item.h"
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
#include "atom/browser/api/atom_api_web_request.h"
|
||||
#include "atom/browser/api/save_page_handler.h"
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/browser/atom_permission_manager.h"
|
||||
#include "atom/browser/net/atom_cert_verifier.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/content_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/net_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/prefs/pref_service.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/thread_task_runner_handle.h"
|
||||
#include "brightray/browser/net/devtools_network_conditions.h"
|
||||
@@ -36,7 +32,6 @@
|
||||
#include "native_mate/object_template_builder.h"
|
||||
#include "net/base/load_flags.h"
|
||||
#include "net/disk_cache/disk_cache.h"
|
||||
#include "net/dns/host_cache.h"
|
||||
#include "net/proxy/proxy_service.h"
|
||||
#include "net/proxy/proxy_config_service_fixed.h"
|
||||
#include "net/url_request/url_request_context.h"
|
||||
@@ -56,7 +51,7 @@ struct ClearStorageDataOptions {
|
||||
uint32 GetStorageMask(const std::vector<std::string>& storage_types) {
|
||||
uint32 storage_mask = 0;
|
||||
for (const auto& it : storage_types) {
|
||||
auto type = base::ToLowerASCII(it);
|
||||
auto type = base::StringToLowerASCII(it);
|
||||
if (type == "appcache")
|
||||
storage_mask |= StoragePartition::REMOVE_DATA_MASK_APPCACHE;
|
||||
else if (type == "cookies")
|
||||
@@ -80,7 +75,7 @@ uint32 GetStorageMask(const std::vector<std::string>& storage_types) {
|
||||
uint32 GetQuotaMask(const std::vector<std::string>& quota_types) {
|
||||
uint32 quota_mask = 0;
|
||||
for (const auto& it : quota_types) {
|
||||
auto type = base::ToLowerASCII(it);
|
||||
auto type = base::StringToLowerASCII(it);
|
||||
if (type == "temporary")
|
||||
quota_mask |= StoragePartition::QUOTA_MANAGED_STORAGE_MASK_TEMPORARY;
|
||||
else if (type == "persistent")
|
||||
@@ -118,25 +113,14 @@ struct Converter<net::ProxyConfig> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
net::ProxyConfig* out) {
|
||||
std::string proxy_rules;
|
||||
GURL pac_url;
|
||||
mate::Dictionary options;
|
||||
// Fallback to previous API when passed String.
|
||||
// https://git.io/vuhjj
|
||||
if (ConvertFromV8(isolate, val, &proxy_rules)) {
|
||||
pac_url = GURL(proxy_rules); // Assume it is PAC script if it is URL.
|
||||
} else if (ConvertFromV8(isolate, val, &options)) {
|
||||
options.Get("pacScript", &pac_url);
|
||||
options.Get("proxyRules", &proxy_rules);
|
||||
} else {
|
||||
std::string proxy;
|
||||
if (!ConvertFromV8(isolate, val, &proxy))
|
||||
return false;
|
||||
}
|
||||
|
||||
// pacScript takes precedence over proxyRules.
|
||||
if (!pac_url.is_empty() && pac_url.is_valid()) {
|
||||
auto pac_url = GURL(proxy);
|
||||
if (pac_url.is_valid()) {
|
||||
out->set_pac_url(pac_url);
|
||||
} else {
|
||||
out->proxy_rules().ParseFromString(proxy_rules);
|
||||
out->proxy_rules().ParseFromString(proxy);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -208,7 +192,7 @@ class ResolveProxyHelper {
|
||||
};
|
||||
|
||||
// Runs the callback in UI thread.
|
||||
template<typename ...T>
|
||||
template <typename ...T>
|
||||
void RunCallbackInUI(const base::Callback<void(T...)>& callback, T... result) {
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::UI, FROM_HERE, base::Bind(callback, result...));
|
||||
@@ -216,35 +200,19 @@ void RunCallbackInUI(const base::Callback<void(T...)>& callback, T... result) {
|
||||
|
||||
// Callback of HttpCache::GetBackend.
|
||||
void OnGetBackend(disk_cache::Backend** backend_ptr,
|
||||
Session::CacheAction action,
|
||||
const net::CompletionCallback& callback,
|
||||
int result) {
|
||||
if (result != net::OK) {
|
||||
RunCallbackInUI(callback, result);
|
||||
} else if (backend_ptr && *backend_ptr) {
|
||||
if (action == Session::CacheAction::CLEAR) {
|
||||
(*backend_ptr)->DoomAllEntries(base::Bind(&RunCallbackInUI<int>,
|
||||
callback));
|
||||
} else if (action == Session::CacheAction::STATS) {
|
||||
base::StringPairs stats;
|
||||
(*backend_ptr)->GetStats(&stats);
|
||||
for (size_t i = 0; i < stats.size(); ++i) {
|
||||
if (stats[i].first == "Current size") {
|
||||
int current_size;
|
||||
base::StringToInt(stats[i].second, ¤t_size);
|
||||
RunCallbackInUI(callback, current_size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
(*backend_ptr)->DoomAllEntries(base::Bind(&RunCallbackInUI<int>, callback));
|
||||
} else {
|
||||
RunCallbackInUI<int>(callback, net::ERR_FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
void DoCacheActionInIO(
|
||||
void ClearHttpCacheInIO(
|
||||
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
|
||||
Session::CacheAction action,
|
||||
const net::CompletionCallback& callback) {
|
||||
auto request_context = context_getter->GetURLRequestContext();
|
||||
auto http_cache = request_context->http_transaction_factory()->GetCache();
|
||||
@@ -255,7 +223,7 @@ void DoCacheActionInIO(
|
||||
using BackendPtr = disk_cache::Backend*;
|
||||
BackendPtr* backend_ptr = new BackendPtr(nullptr);
|
||||
net::CompletionCallback on_get_backend =
|
||||
base::Bind(&OnGetBackend, base::Owned(backend_ptr), action, callback);
|
||||
base::Bind(&OnGetBackend, base::Owned(backend_ptr), callback);
|
||||
int rv = http_cache->GetBackend(backend_ptr, on_get_backend);
|
||||
if (rv != net::ERR_IO_PENDING)
|
||||
on_get_backend.Run(net::OK);
|
||||
@@ -265,26 +233,12 @@ void SetProxyInIO(net::URLRequestContextGetter* getter,
|
||||
const net::ProxyConfig& config,
|
||||
const base::Closure& callback) {
|
||||
auto proxy_service = getter->GetURLRequestContext()->proxy_service();
|
||||
proxy_service->ResetConfigService(make_scoped_ptr(
|
||||
new net::ProxyConfigServiceFixed(config)));
|
||||
proxy_service->ResetConfigService(new net::ProxyConfigServiceFixed(config));
|
||||
// Refetches and applies the new pac script if provided.
|
||||
proxy_service->ForceReloadProxyConfig();
|
||||
RunCallbackInUI(callback);
|
||||
}
|
||||
|
||||
void ClearHostResolverCacheInIO(
|
||||
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
|
||||
const base::Closure& callback) {
|
||||
auto request_context = context_getter->GetURLRequestContext();
|
||||
auto cache = request_context->host_resolver()->GetHostCache();
|
||||
if (cache) {
|
||||
cache->clear();
|
||||
DCHECK_EQ(0u, cache->size());
|
||||
if (!callback.is_null())
|
||||
RunCallbackInUI(callback);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Session::Session(AtomBrowserContext* browser_context)
|
||||
@@ -320,12 +274,10 @@ void Session::ResolveProxy(const GURL& url, ResolveProxyCallback callback) {
|
||||
new ResolveProxyHelper(browser_context(), url, callback);
|
||||
}
|
||||
|
||||
template<Session::CacheAction action>
|
||||
void Session::DoCacheAction(const net::CompletionCallback& callback) {
|
||||
void Session::ClearCache(const net::CompletionCallback& callback) {
|
||||
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&DoCacheActionInIO,
|
||||
base::Bind(&ClearHttpCacheInIO,
|
||||
make_scoped_refptr(browser_context_->GetRequestContext()),
|
||||
action,
|
||||
callback));
|
||||
}
|
||||
|
||||
@@ -347,12 +299,6 @@ void Session::ClearStorageData(mate::Arguments* args) {
|
||||
base::Time(), base::Time::Max(), callback);
|
||||
}
|
||||
|
||||
void Session::FlushStorageData() {
|
||||
auto storage_partition =
|
||||
content::BrowserContext::GetStoragePartition(browser_context(), nullptr);
|
||||
storage_partition->Flush();
|
||||
}
|
||||
|
||||
void Session::SetProxy(const net::ProxyConfig& config,
|
||||
const base::Closure& callback) {
|
||||
auto getter = browser_context_->GetRequestContext();
|
||||
@@ -413,28 +359,6 @@ void Session::SetCertVerifyProc(v8::Local<v8::Value> val,
|
||||
browser_context_->cert_verifier()->SetVerifyProc(proc);
|
||||
}
|
||||
|
||||
void Session::SetPermissionRequestHandler(v8::Local<v8::Value> val,
|
||||
mate::Arguments* args) {
|
||||
AtomPermissionManager::RequestHandler handler;
|
||||
if (!(val->IsNull() || mate::ConvertFromV8(args->isolate(), val, &handler))) {
|
||||
args->ThrowError("Must pass null or function");
|
||||
return;
|
||||
}
|
||||
auto permission_manager = static_cast<AtomPermissionManager*>(
|
||||
browser_context()->GetPermissionManager());
|
||||
permission_manager->SetPermissionRequestHandler(handler);
|
||||
}
|
||||
|
||||
void Session::ClearHostResolverCache(mate::Arguments* args) {
|
||||
base::Closure callback;
|
||||
args->GetNext(&callback);
|
||||
|
||||
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&ClearHostResolverCacheInIO,
|
||||
make_scoped_refptr(browser_context_->GetRequestContext()),
|
||||
callback));
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Session::Cookies(v8::Isolate* isolate) {
|
||||
if (cookies_.IsEmpty()) {
|
||||
auto handle = atom::api::Cookies::Create(isolate, browser_context());
|
||||
@@ -443,14 +367,6 @@ v8::Local<v8::Value> Session::Cookies(v8::Isolate* isolate) {
|
||||
return v8::Local<v8::Value>::New(isolate, cookies_);
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Session::WebRequest(v8::Isolate* isolate) {
|
||||
if (web_request_.IsEmpty()) {
|
||||
auto handle = atom::api::WebRequest::Create(isolate, browser_context());
|
||||
web_request_.Reset(isolate, handle.ToV8());
|
||||
}
|
||||
return v8::Local<v8::Value>::New(isolate, web_request_);
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<Session> Session::CreateFrom(
|
||||
v8::Isolate* isolate, AtomBrowserContext* browser_context) {
|
||||
@@ -477,20 +393,14 @@ void Session::BuildPrototype(v8::Isolate* isolate,
|
||||
mate::ObjectTemplateBuilder(isolate, prototype)
|
||||
.MakeDestroyable()
|
||||
.SetMethod("resolveProxy", &Session::ResolveProxy)
|
||||
.SetMethod("getCacheSize", &Session::DoCacheAction<CacheAction::STATS>)
|
||||
.SetMethod("clearCache", &Session::DoCacheAction<CacheAction::CLEAR>)
|
||||
.SetMethod("clearCache", &Session::ClearCache)
|
||||
.SetMethod("clearStorageData", &Session::ClearStorageData)
|
||||
.SetMethod("flushStorageData", &Session::FlushStorageData)
|
||||
.SetMethod("setProxy", &Session::SetProxy)
|
||||
.SetMethod("setDownloadPath", &Session::SetDownloadPath)
|
||||
.SetMethod("enableNetworkEmulation", &Session::EnableNetworkEmulation)
|
||||
.SetMethod("disableNetworkEmulation", &Session::DisableNetworkEmulation)
|
||||
.SetMethod("setCertificateVerifyProc", &Session::SetCertVerifyProc)
|
||||
.SetMethod("setPermissionRequestHandler",
|
||||
&Session::SetPermissionRequestHandler)
|
||||
.SetMethod("clearHostResolverCache", &Session::ClearHostResolverCache)
|
||||
.SetProperty("cookies", &Session::Cookies)
|
||||
.SetProperty("webRequest", &Session::WebRequest);
|
||||
.SetProperty("cookies", &Session::Cookies);
|
||||
}
|
||||
|
||||
void ClearWrapSession() {
|
||||
|
||||
@@ -38,11 +38,6 @@ class Session: public mate::TrackableObject<Session>,
|
||||
public:
|
||||
using ResolveProxyCallback = base::Callback<void(std::string)>;
|
||||
|
||||
enum class CacheAction {
|
||||
CLEAR,
|
||||
STATS,
|
||||
};
|
||||
|
||||
// Gets or creates Session from the |browser_context|.
|
||||
static mate::Handle<Session> CreateFrom(
|
||||
v8::Isolate* isolate, AtomBrowserContext* browser_context);
|
||||
@@ -67,24 +62,17 @@ class Session: public mate::TrackableObject<Session>,
|
||||
|
||||
private:
|
||||
void ResolveProxy(const GURL& url, ResolveProxyCallback callback);
|
||||
template<CacheAction action>
|
||||
void DoCacheAction(const net::CompletionCallback& callback);
|
||||
void ClearCache(const net::CompletionCallback& callback);
|
||||
void ClearStorageData(mate::Arguments* args);
|
||||
void FlushStorageData();
|
||||
void SetProxy(const net::ProxyConfig& config, const base::Closure& callback);
|
||||
void SetDownloadPath(const base::FilePath& path);
|
||||
void EnableNetworkEmulation(const mate::Dictionary& options);
|
||||
void DisableNetworkEmulation();
|
||||
void SetCertVerifyProc(v8::Local<v8::Value> proc, mate::Arguments* args);
|
||||
void SetPermissionRequestHandler(v8::Local<v8::Value> val,
|
||||
mate::Arguments* args);
|
||||
void ClearHostResolverCache(mate::Arguments* args);
|
||||
v8::Local<v8::Value> Cookies(v8::Isolate* isolate);
|
||||
v8::Local<v8::Value> WebRequest(v8::Isolate* isolate);
|
||||
|
||||
// Cached object.
|
||||
// Cached object for cookies API.
|
||||
v8::Global<v8::Value> cookies_;
|
||||
v8::Global<v8::Value> web_request_;
|
||||
|
||||
scoped_refptr<AtomBrowserContext> browser_context_;
|
||||
|
||||
|
||||
@@ -5,16 +5,13 @@
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/api/atom_api_debugger.h"
|
||||
#include "atom/browser/api/atom_api_session.h"
|
||||
#include "atom/browser/api/atom_api_window.h"
|
||||
#include "atom/browser/atom_browser_client.h"
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/web_contents_permission_helper.h"
|
||||
#include "atom/browser/web_contents_preferences.h"
|
||||
#include "atom/browser/web_view_guest_delegate.h"
|
||||
#include "atom/common/api/api_messages.h"
|
||||
@@ -28,7 +25,6 @@
|
||||
#include "atom/common/native_mate_converters/image_converter.h"
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/mouse_util.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "brightray/browser/inspectable_web_contents.h"
|
||||
@@ -36,6 +32,7 @@
|
||||
#include "chrome/browser/printing/print_view_manager_basic.h"
|
||||
#include "chrome/browser/printing/print_preview_message_handler.h"
|
||||
#include "content/common/view_messages.h"
|
||||
#include "content/public/browser/browser_plugin_guest_manager.h"
|
||||
#include "content/public/browser/favicon_status.h"
|
||||
#include "content/public/browser/native_web_keyboard_event.h"
|
||||
#include "content/public/browser/navigation_details.h"
|
||||
@@ -77,6 +74,15 @@ void SetUserAgentInIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
user_agent));
|
||||
}
|
||||
|
||||
bool NotifyZoomLevelChanged(
|
||||
double level, content::WebContents* guest_web_contents) {
|
||||
guest_web_contents->SendToAllFrames(
|
||||
new AtomViewMsg_SetZoomLevel(MSG_ROUTING_NONE, level));
|
||||
|
||||
// Return false to iterate over all guests.
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace mate {
|
||||
@@ -142,7 +148,7 @@ struct Converter<net::HttpResponseHeaders*> {
|
||||
std::string key;
|
||||
std::string value;
|
||||
while (headers->EnumerateHeaderLines(&iter, &key, &value)) {
|
||||
key = base::ToLowerASCII(key);
|
||||
key = base::StringToLowerASCII(key);
|
||||
if (response_headers.HasKey(key)) {
|
||||
base::ListValue* values = nullptr;
|
||||
if (response_headers.GetList(key, &values))
|
||||
@@ -165,7 +171,7 @@ struct Converter<content::SavePageType> {
|
||||
std::string save_type;
|
||||
if (!ConvertFromV8(isolate, val, &save_type))
|
||||
return false;
|
||||
save_type = base::ToLowerASCII(save_type);
|
||||
save_type = base::StringToLowerASCII(save_type);
|
||||
if (save_type == "htmlonly") {
|
||||
*out = content::SAVE_PAGE_TYPE_AS_ONLY_HTML;
|
||||
} else if (save_type == "htmlcomplete") {
|
||||
@@ -217,8 +223,7 @@ WebContents::WebContents(content::WebContents* web_contents)
|
||||
}
|
||||
|
||||
WebContents::WebContents(v8::Isolate* isolate,
|
||||
const mate::Dictionary& options)
|
||||
: request_id_(0) {
|
||||
const mate::Dictionary& options) {
|
||||
// Whether it is a guest WebContents.
|
||||
bool is_guest = false;
|
||||
options.Get("isGuest", &is_guest);
|
||||
@@ -264,9 +269,6 @@ WebContents::WebContents(v8::Isolate* isolate,
|
||||
// Save the preferences in C++.
|
||||
new WebContentsPreferences(web_contents, options);
|
||||
|
||||
// Intialize permission helper.
|
||||
WebContentsPermissionHelper::CreateForWebContents(web_contents);
|
||||
|
||||
web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent());
|
||||
|
||||
if (is_guest) {
|
||||
@@ -286,17 +288,14 @@ WebContents::WebContents(v8::Isolate* isolate,
|
||||
}
|
||||
|
||||
WebContents::~WebContents() {
|
||||
// The destroy() is called.
|
||||
if (managed_web_contents()) {
|
||||
// For webview we need to tell content module to do some cleanup work before
|
||||
// destroying it.
|
||||
if (type_ == WEB_VIEW)
|
||||
guest_delegate_->Destroy();
|
||||
|
||||
// The WebContentsDestroyed will not be called automatically because we
|
||||
// unsubscribe from webContents before destroying it. So we have to manually
|
||||
// call it here to make sure "destroyed" event is emitted.
|
||||
if (type_ == WEB_VIEW && managed_web_contents()) {
|
||||
// When force destroying the "destroyed" event is not emitted.
|
||||
WebContentsDestroyed();
|
||||
|
||||
guest_delegate_->Destroy();
|
||||
|
||||
Observe(nullptr);
|
||||
DestroyWebContents();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -391,18 +390,6 @@ void WebContents::HandleKeyboardEvent(
|
||||
|
||||
void WebContents::EnterFullscreenModeForTab(content::WebContents* source,
|
||||
const GURL& origin) {
|
||||
auto permission_helper =
|
||||
WebContentsPermissionHelper::FromWebContents(source);
|
||||
auto callback = base::Bind(&WebContents::OnEnterFullscreenModeForTab,
|
||||
base::Unretained(this), source, origin);
|
||||
permission_helper->RequestFullscreenPermission(callback);
|
||||
}
|
||||
|
||||
void WebContents::OnEnterFullscreenModeForTab(content::WebContents* source,
|
||||
const GURL& origin,
|
||||
bool allowed) {
|
||||
if (!allowed)
|
||||
return;
|
||||
CommonWebContentsDelegate::EnterFullscreenModeForTab(source, origin);
|
||||
Emit("enter-html-full-screen");
|
||||
}
|
||||
@@ -433,52 +420,6 @@ bool WebContents::HandleContextMenu(const content::ContextMenuParams& params) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WebContents::OnGoToEntryOffset(int offset) {
|
||||
GoToOffset(offset);
|
||||
return false;
|
||||
}
|
||||
|
||||
void WebContents::FindReply(content::WebContents* web_contents,
|
||||
int request_id,
|
||||
int number_of_matches,
|
||||
const gfx::Rect& selection_rect,
|
||||
int active_match_ordinal,
|
||||
bool final_update) {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
|
||||
mate::Dictionary result = mate::Dictionary::CreateEmpty(isolate());
|
||||
if (number_of_matches == -1) {
|
||||
result.Set("requestId", request_id);
|
||||
result.Set("selectionArea", selection_rect);
|
||||
result.Set("finalUpdate", final_update);
|
||||
Emit("found-in-page", result);
|
||||
} else if (final_update) {
|
||||
result.Set("requestId", request_id);
|
||||
result.Set("matches", number_of_matches);
|
||||
result.Set("finalUpdate", final_update);
|
||||
Emit("found-in-page", result);
|
||||
}
|
||||
}
|
||||
|
||||
void WebContents::RequestMediaAccessPermission(
|
||||
content::WebContents* web_contents,
|
||||
const content::MediaStreamRequest& request,
|
||||
const content::MediaResponseCallback& callback) {
|
||||
auto permission_helper =
|
||||
WebContentsPermissionHelper::FromWebContents(web_contents);
|
||||
permission_helper->RequestMediaAccessPermission(request, callback);
|
||||
}
|
||||
|
||||
void WebContents::RequestToLockMouse(
|
||||
content::WebContents* web_contents,
|
||||
bool user_gesture,
|
||||
bool last_unlocked_by_target) {
|
||||
auto permission_helper =
|
||||
WebContentsPermissionHelper::FromWebContents(web_contents);
|
||||
permission_helper->RequestPointerLockPermission(user_gesture);
|
||||
}
|
||||
|
||||
void WebContents::BeforeUnloadFired(const base::TimeTicks& proceed_time) {
|
||||
// Do nothing, we override this method just to avoid compilation error since
|
||||
// there are two virtual functions named BeforeUnloadFired.
|
||||
@@ -510,22 +451,6 @@ void WebContents::PluginCrashed(const base::FilePath& plugin_path,
|
||||
Emit("plugin-crashed", info.name, info.version);
|
||||
}
|
||||
|
||||
void WebContents::MediaStartedPlaying() {
|
||||
Emit("media-started-playing");
|
||||
}
|
||||
|
||||
void WebContents::MediaPaused() {
|
||||
Emit("media-paused");
|
||||
}
|
||||
|
||||
void WebContents::DidChangeThemeColor(SkColor theme_color) {
|
||||
std::string hex_theme_color = base::StringPrintf("#%02X%02X%02X",
|
||||
SkColorGetR(theme_color),
|
||||
SkColorGetG(theme_color),
|
||||
SkColorGetB(theme_color));
|
||||
Emit("did-change-theme-color", hex_theme_color);
|
||||
}
|
||||
|
||||
void WebContents::DocumentLoadedInFrame(
|
||||
content::RenderFrameHost* render_frame_host) {
|
||||
if (!render_frame_host->GetParent())
|
||||
@@ -595,9 +520,7 @@ void WebContents::DidNavigateMainFrame(
|
||||
const content::LoadCommittedDetails& details,
|
||||
const content::FrameNavigateParams& params) {
|
||||
if (details.is_navigation_to_different_page())
|
||||
Emit("did-navigate", params.url);
|
||||
else if (details.is_in_page)
|
||||
Emit("did-navigate-in-page", params.url);
|
||||
Emit("did-navigate-to-different-page");
|
||||
}
|
||||
|
||||
void WebContents::TitleWasSet(content::NavigationEntry* entry,
|
||||
@@ -654,45 +577,18 @@ bool WebContents::OnMessageReceived(const IPC::Message& message) {
|
||||
IPC_MESSAGE_HANDLER(AtomViewHostMsg_Message, OnRendererMessage)
|
||||
IPC_MESSAGE_HANDLER_DELAY_REPLY(AtomViewHostMsg_Message_Sync,
|
||||
OnRendererMessageSync)
|
||||
IPC_MESSAGE_HANDLER_CODE(ViewHostMsg_SetCursor, OnCursorChange,
|
||||
handled = false)
|
||||
IPC_MESSAGE_HANDLER(AtomViewHostMsg_ZoomLevelChanged, OnZoomLevelChanged)
|
||||
IPC_MESSAGE_UNHANDLED(handled = false)
|
||||
IPC_END_MESSAGE_MAP()
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
// There are three ways of destroying a webContents:
|
||||
// 1. call webContents.destory();
|
||||
// 2. garbage collection;
|
||||
// 3. user closes the window of webContents;
|
||||
// For webview only #1 will happen, for BrowserWindow both #1 and #3 may
|
||||
// happen. The #2 should never happen for webContents, because webview is
|
||||
// managed by GuestViewManager, and BrowserWindow's webContents is managed
|
||||
// by api::Window.
|
||||
// For #1, the destructor will do the cleanup work and we only need to make
|
||||
// sure "destroyed" event is emitted. For #3, the content::WebContents will
|
||||
// be destroyed on close, and WebContentsDestroyed would be called for it, so
|
||||
// we need to make sure the api::WebContents is also deleted.
|
||||
void WebContents::WebContentsDestroyed() {
|
||||
// The RenderViewDeleted was not called when the WebContents is destroyed.
|
||||
RenderViewDeleted(web_contents()->GetRenderViewHost());
|
||||
|
||||
// This event is only for internal use, which is emitted when WebContents is
|
||||
// being destroyed.
|
||||
Emit("will-destroy");
|
||||
|
||||
// Cleanup relationships with other parts.
|
||||
RemoveFromWeakMap();
|
||||
|
||||
// We can not call Destroy here because we need to call Emit first, but we
|
||||
// also do not want any method to be used, so just mark as destroyed here.
|
||||
MarkDestroyed();
|
||||
|
||||
Emit("destroyed");
|
||||
|
||||
// Destroy the native class in next tick.
|
||||
base::MessageLoop::current()->PostTask(FROM_HERE, GetDestroyClosure());
|
||||
RemoveFromWeakMap();
|
||||
}
|
||||
|
||||
void WebContents::NavigationEntryCommitted(
|
||||
@@ -710,14 +606,6 @@ bool WebContents::Equal(const WebContents* web_contents) const {
|
||||
}
|
||||
|
||||
void WebContents::LoadURL(const GURL& url, const mate::Dictionary& options) {
|
||||
if (!url.is_valid()) {
|
||||
Emit("did-fail-load",
|
||||
static_cast<int>(net::ERR_INVALID_URL),
|
||||
net::ErrorToShortString(net::ERR_INVALID_URL),
|
||||
url.possibly_invalid_spec());
|
||||
return;
|
||||
}
|
||||
|
||||
content::NavigationController::LoadURLParams params(url);
|
||||
|
||||
GURL http_referrer;
|
||||
@@ -812,6 +700,11 @@ bool WebContents::SavePage(const base::FilePath& full_file_path,
|
||||
return handler->Handle(full_file_path, save_type);
|
||||
}
|
||||
|
||||
void WebContents::ExecuteJavaScript(const base::string16& code,
|
||||
bool has_user_gesture) {
|
||||
Send(new AtomViewMsg_ExecuteJavaScript(routing_id(), code, has_user_gesture));
|
||||
}
|
||||
|
||||
void WebContents::OpenDevTools(mate::Arguments* args) {
|
||||
if (type_ == REMOTE)
|
||||
return;
|
||||
@@ -841,13 +734,6 @@ bool WebContents::IsDevToolsOpened() {
|
||||
return managed_web_contents()->IsDevToolsViewShowing();
|
||||
}
|
||||
|
||||
bool WebContents::IsDevToolsFocused() {
|
||||
if (type_ == REMOTE)
|
||||
return false;
|
||||
|
||||
return managed_web_contents()->GetView()->IsDevToolsViewFocused();
|
||||
}
|
||||
|
||||
void WebContents::EnableDeviceEmulation(
|
||||
const blink::WebDeviceEmulationParams& params) {
|
||||
if (type_ == REMOTE)
|
||||
@@ -1002,25 +888,6 @@ void WebContents::ReplaceMisspelling(const base::string16& word) {
|
||||
web_contents()->ReplaceMisspelling(word);
|
||||
}
|
||||
|
||||
uint32 WebContents::FindInPage(mate::Arguments* args) {
|
||||
uint32 request_id = GetNextRequestId();
|
||||
base::string16 search_text;
|
||||
blink::WebFindOptions options;
|
||||
if (!args->GetNext(&search_text) || search_text.empty()) {
|
||||
args->ThrowError("Must provide a non-empty search content");
|
||||
return 0;
|
||||
}
|
||||
|
||||
args->GetNext(&options);
|
||||
|
||||
web_contents()->Find(request_id, search_text, options);
|
||||
return request_id;
|
||||
}
|
||||
|
||||
void WebContents::StopFindInPage(content::StopFindAction action) {
|
||||
web_contents()->StopFinding(action);
|
||||
}
|
||||
|
||||
void WebContents::Focus() {
|
||||
web_contents()->Focus();
|
||||
}
|
||||
@@ -1051,7 +918,7 @@ void WebContents::SendInputEvent(v8::Isolate* isolate,
|
||||
return;
|
||||
}
|
||||
} else if (blink::WebInputEvent::isKeyboardEventType(type)) {
|
||||
content::NativeWebKeyboardEvent keyboard_event;
|
||||
content::NativeWebKeyboardEvent keyboard_event;;
|
||||
if (mate::ConvertFromV8(isolate, input_event, &keyboard_event)) {
|
||||
host->ForwardKeyboardEvent(keyboard_event);
|
||||
return;
|
||||
@@ -1084,19 +951,6 @@ void WebContents::EndFrameSubscription() {
|
||||
view->EndFrameSubscription();
|
||||
}
|
||||
|
||||
void WebContents::OnCursorChange(const content::WebCursor& cursor) {
|
||||
content::WebCursor::CursorInfo info;
|
||||
cursor.GetCursorInfo(&info);
|
||||
|
||||
if (cursor.IsCustom()) {
|
||||
Emit("cursor-changed", CursorTypeToString(info),
|
||||
gfx::Image::CreateFrom1xBitmap(info.custom_image),
|
||||
info.image_scale_factor);
|
||||
} else {
|
||||
Emit("cursor-changed", CursorTypeToString(info));
|
||||
}
|
||||
}
|
||||
|
||||
void WebContents::SetSize(const SetSizeParams& params) {
|
||||
if (guest_delegate_)
|
||||
guest_delegate_->SetSize(params);
|
||||
@@ -1135,14 +989,6 @@ v8::Local<v8::Value> WebContents::DevToolsWebContents(v8::Isolate* isolate) {
|
||||
return v8::Local<v8::Value>::New(isolate, devtools_web_contents_);
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> WebContents::Debugger(v8::Isolate* isolate) {
|
||||
if (debugger_.IsEmpty()) {
|
||||
auto handle = atom::api::Debugger::Create(isolate, web_contents());
|
||||
debugger_.Reset(isolate, handle.ToV8());
|
||||
}
|
||||
return v8::Local<v8::Value>::New(isolate, debugger_);
|
||||
}
|
||||
|
||||
// static
|
||||
void WebContents::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::ObjectTemplate> prototype) {
|
||||
@@ -1165,10 +1011,10 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("getUserAgent", &WebContents::GetUserAgent)
|
||||
.SetMethod("insertCSS", &WebContents::InsertCSS)
|
||||
.SetMethod("savePage", &WebContents::SavePage)
|
||||
.SetMethod("_executeJavaScript", &WebContents::ExecuteJavaScript)
|
||||
.SetMethod("openDevTools", &WebContents::OpenDevTools)
|
||||
.SetMethod("closeDevTools", &WebContents::CloseDevTools)
|
||||
.SetMethod("isDevToolsOpened", &WebContents::IsDevToolsOpened)
|
||||
.SetMethod("isDevToolsFocused", &WebContents::IsDevToolsFocused)
|
||||
.SetMethod("enableDeviceEmulation",
|
||||
&WebContents::EnableDeviceEmulation)
|
||||
.SetMethod("disableDeviceEmulation",
|
||||
@@ -1188,8 +1034,6 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("unselect", &WebContents::Unselect)
|
||||
.SetMethod("replace", &WebContents::Replace)
|
||||
.SetMethod("replaceMisspelling", &WebContents::ReplaceMisspelling)
|
||||
.SetMethod("findInPage", &WebContents::FindInPage)
|
||||
.SetMethod("stopFindInPage", &WebContents::StopFindInPage)
|
||||
.SetMethod("focus", &WebContents::Focus)
|
||||
.SetMethod("tabTraverse", &WebContents::TabTraverse)
|
||||
.SetMethod("_send", &WebContents::SendIPCMessage)
|
||||
@@ -1211,8 +1055,7 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("addWorkSpace", &WebContents::AddWorkSpace)
|
||||
.SetMethod("removeWorkSpace", &WebContents::RemoveWorkSpace)
|
||||
.SetProperty("session", &WebContents::Session)
|
||||
.SetProperty("devToolsWebContents", &WebContents::DevToolsWebContents)
|
||||
.SetProperty("debugger", &WebContents::Debugger);
|
||||
.SetProperty("devToolsWebContents", &WebContents::DevToolsWebContents);
|
||||
}
|
||||
|
||||
AtomBrowserContext* WebContents::GetBrowserContext() const {
|
||||
@@ -1232,6 +1075,15 @@ void WebContents::OnRendererMessageSync(const base::string16& channel,
|
||||
EmitWithSender(base::UTF16ToUTF8(channel), web_contents(), message, args);
|
||||
}
|
||||
|
||||
void WebContents::OnZoomLevelChanged(double level) {
|
||||
auto manager = web_contents()->GetBrowserContext()->GetGuestManager();
|
||||
if (!manager)
|
||||
return;
|
||||
manager->ForEachGuest(web_contents(),
|
||||
base::Bind(&NotifyZoomLevelChanged,
|
||||
level));
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<WebContents> WebContents::CreateFrom(
|
||||
v8::Isolate* isolate, content::WebContents* web_contents) {
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include "atom/browser/common_web_contents_delegate.h"
|
||||
#include "content/public/browser/web_contents_observer.h"
|
||||
#include "content/public/common/favicon_url.h"
|
||||
#include "content/common/cursors/webcursor.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
|
||||
@@ -75,10 +74,11 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
bool SavePage(const base::FilePath& full_file_path,
|
||||
const content::SavePageType& save_type,
|
||||
const SavePageHandler::SavePageCallback& callback);
|
||||
void ExecuteJavaScript(const base::string16& code,
|
||||
bool has_user_gesture);
|
||||
void OpenDevTools(mate::Arguments* args);
|
||||
void CloseDevTools();
|
||||
bool IsDevToolsOpened();
|
||||
bool IsDevToolsFocused();
|
||||
void ToggleDevTools();
|
||||
void EnableDeviceEmulation(const blink::WebDeviceEmulationParams& params);
|
||||
void DisableDeviceEmulation();
|
||||
@@ -110,8 +110,6 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
void Unselect();
|
||||
void Replace(const base::string16& word);
|
||||
void ReplaceMisspelling(const base::string16& word);
|
||||
uint32 FindInPage(mate::Arguments* args);
|
||||
void StopFindInPage(content::StopFindAction action);
|
||||
|
||||
// Focus.
|
||||
void Focus();
|
||||
@@ -134,11 +132,6 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
void SetAllowTransparency(bool allow);
|
||||
bool IsGuest() const;
|
||||
|
||||
// Callback triggered on permission response.
|
||||
void OnEnterFullscreenModeForTab(content::WebContents* source,
|
||||
const GURL& origin,
|
||||
bool allowed);
|
||||
|
||||
// Returns the web preferences of current WebContents.
|
||||
v8::Local<v8::Value> GetWebPreferences(v8::Isolate* isolate);
|
||||
|
||||
@@ -148,7 +141,6 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
// Properties.
|
||||
v8::Local<v8::Value> Session(v8::Isolate* isolate);
|
||||
v8::Local<v8::Value> DevToolsWebContents(v8::Isolate* isolate);
|
||||
v8::Local<v8::Value> Debugger(v8::Isolate* isolate);
|
||||
|
||||
// mate::TrackableObject:
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
@@ -194,21 +186,6 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
void RendererUnresponsive(content::WebContents* source) override;
|
||||
void RendererResponsive(content::WebContents* source) override;
|
||||
bool HandleContextMenu(const content::ContextMenuParams& params) override;
|
||||
bool OnGoToEntryOffset(int offset) override;
|
||||
void FindReply(content::WebContents* web_contents,
|
||||
int request_id,
|
||||
int number_of_matches,
|
||||
const gfx::Rect& selection_rect,
|
||||
int active_match_ordinal,
|
||||
bool final_update) override;
|
||||
void RequestMediaAccessPermission(
|
||||
content::WebContents* web_contents,
|
||||
const content::MediaStreamRequest& request,
|
||||
const content::MediaResponseCallback& callback) override;
|
||||
void RequestToLockMouse(
|
||||
content::WebContents* web_contents,
|
||||
bool user_gesture,
|
||||
bool last_unlocked_by_target) override;
|
||||
|
||||
// content::WebContentsObserver:
|
||||
void BeforeUnloadFired(const base::TimeTicks& proceed_time) override;
|
||||
@@ -247,9 +224,6 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
const std::vector<content::FaviconURL>& urls) override;
|
||||
void PluginCrashed(const base::FilePath& plugin_path,
|
||||
base::ProcessId plugin_pid) override;
|
||||
void MediaStartedPlaying() override;
|
||||
void MediaPaused() override;
|
||||
void DidChangeThemeColor(SkColor theme_color) override;
|
||||
|
||||
// brightray::InspectableWebContentsViewDelegate:
|
||||
void DevToolsFocused() override;
|
||||
@@ -265,13 +239,6 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
|
||||
AtomBrowserContext* GetBrowserContext() const;
|
||||
|
||||
uint32 GetNextRequestId() {
|
||||
return ++request_id_;
|
||||
}
|
||||
|
||||
// Called when we receive a CursorChange message from chromium.
|
||||
void OnCursorChange(const content::WebCursor& cursor);
|
||||
|
||||
// Called when received a message from renderer.
|
||||
void OnRendererMessage(const base::string16& channel,
|
||||
const base::ListValue& args);
|
||||
@@ -281,18 +248,18 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
const base::ListValue& args,
|
||||
IPC::Message* message);
|
||||
|
||||
// Called when guests need to be notified of
|
||||
// embedders' zoom level change.
|
||||
void OnZoomLevelChanged(double level);
|
||||
|
||||
v8::Global<v8::Value> session_;
|
||||
v8::Global<v8::Value> devtools_web_contents_;
|
||||
v8::Global<v8::Value> debugger_;
|
||||
|
||||
scoped_ptr<WebViewGuestDelegate> guest_delegate_;
|
||||
|
||||
// The type of current WebContents.
|
||||
Type type_;
|
||||
|
||||
// Request id used for findInPage request.
|
||||
uint32 request_id_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(WebContents);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
// 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/api/atom_api_web_request.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/net/atom_network_delegate.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/net_converter.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace mate {
|
||||
|
||||
template<>
|
||||
struct Converter<extensions::URLPattern> {
|
||||
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
|
||||
extensions::URLPattern* out) {
|
||||
std::string pattern;
|
||||
if (!ConvertFromV8(isolate, val, &pattern))
|
||||
return false;
|
||||
return out->Parse(pattern) == extensions::URLPattern::PARSE_SUCCESS;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
WebRequest::WebRequest(AtomBrowserContext* browser_context)
|
||||
: browser_context_(browser_context) {
|
||||
}
|
||||
|
||||
WebRequest::~WebRequest() {
|
||||
}
|
||||
|
||||
template<AtomNetworkDelegate::SimpleEvent type>
|
||||
void WebRequest::SetSimpleListener(mate::Arguments* args) {
|
||||
SetListener<AtomNetworkDelegate::SimpleListener>(
|
||||
&AtomNetworkDelegate::SetSimpleListenerInIO, type, args);
|
||||
}
|
||||
|
||||
template<AtomNetworkDelegate::ResponseEvent type>
|
||||
void WebRequest::SetResponseListener(mate::Arguments* args) {
|
||||
SetListener<AtomNetworkDelegate::ResponseListener>(
|
||||
&AtomNetworkDelegate::SetResponseListenerInIO, type, args);
|
||||
}
|
||||
|
||||
template<typename Listener, typename Method, typename Event>
|
||||
void WebRequest::SetListener(Method method, Event type, mate::Arguments* args) {
|
||||
// { urls }.
|
||||
URLPatterns patterns;
|
||||
mate::Dictionary dict;
|
||||
args->GetNext(&dict) && dict.Get("urls", &patterns);
|
||||
|
||||
// Function or null.
|
||||
v8::Local<v8::Value> value;
|
||||
Listener listener;
|
||||
if (!args->GetNext(&listener) &&
|
||||
!(args->GetNext(&value) && value->IsNull())) {
|
||||
args->ThrowError("Must pass null or a Function");
|
||||
return;
|
||||
}
|
||||
|
||||
auto delegate = browser_context_->network_delegate();
|
||||
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(method, base::Unretained(delegate), type,
|
||||
patterns, listener));
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<WebRequest> WebRequest::Create(
|
||||
v8::Isolate* isolate,
|
||||
AtomBrowserContext* browser_context) {
|
||||
return mate::CreateHandle(isolate, new WebRequest(browser_context));
|
||||
}
|
||||
|
||||
// static
|
||||
void WebRequest::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::ObjectTemplate> prototype) {
|
||||
mate::ObjectTemplateBuilder(isolate, prototype)
|
||||
.SetMethod("onBeforeRequest",
|
||||
&WebRequest::SetResponseListener<
|
||||
AtomNetworkDelegate::kOnBeforeRequest>)
|
||||
.SetMethod("onBeforeSendHeaders",
|
||||
&WebRequest::SetResponseListener<
|
||||
AtomNetworkDelegate::kOnBeforeSendHeaders>)
|
||||
.SetMethod("onHeadersReceived",
|
||||
&WebRequest::SetResponseListener<
|
||||
AtomNetworkDelegate::kOnHeadersReceived>)
|
||||
.SetMethod("onSendHeaders",
|
||||
&WebRequest::SetSimpleListener<
|
||||
AtomNetworkDelegate::kOnSendHeaders>)
|
||||
.SetMethod("onBeforeRedirect",
|
||||
&WebRequest::SetSimpleListener<
|
||||
AtomNetworkDelegate::kOnBeforeRedirect>)
|
||||
.SetMethod("onResponseStarted",
|
||||
&WebRequest::SetSimpleListener<
|
||||
AtomNetworkDelegate::kOnResponseStarted>)
|
||||
.SetMethod("onCompleted",
|
||||
&WebRequest::SetSimpleListener<
|
||||
AtomNetworkDelegate::kOnCompleted>)
|
||||
.SetMethod("onErrorOccurred",
|
||||
&WebRequest::SetSimpleListener<
|
||||
AtomNetworkDelegate::kOnErrorOccurred>);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
@@ -1,50 +0,0 @@
|
||||
// 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_API_ATOM_API_WEB_REQUEST_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_WEB_REQUEST_H_
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/net/atom_network_delegate.h"
|
||||
#include "native_mate/arguments.h"
|
||||
#include "native_mate/handle.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomBrowserContext;
|
||||
|
||||
namespace api {
|
||||
|
||||
class WebRequest : public mate::TrackableObject<WebRequest> {
|
||||
public:
|
||||
static mate::Handle<WebRequest> Create(v8::Isolate* isolate,
|
||||
AtomBrowserContext* browser_context);
|
||||
|
||||
// mate::TrackableObject:
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::ObjectTemplate> prototype);
|
||||
|
||||
protected:
|
||||
explicit WebRequest(AtomBrowserContext* browser_context);
|
||||
~WebRequest();
|
||||
|
||||
// C++ can not distinguish overloaded member function.
|
||||
template<AtomNetworkDelegate::SimpleEvent type>
|
||||
void SetSimpleListener(mate::Arguments* args);
|
||||
template<AtomNetworkDelegate::ResponseEvent type>
|
||||
void SetResponseListener(mate::Arguments* args);
|
||||
template<typename Listener, typename Method, typename Event>
|
||||
void SetListener(Method method, Event type, mate::Arguments* args);
|
||||
|
||||
private:
|
||||
scoped_refptr<AtomBrowserContext> browser_context_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(WebRequest);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_WEB_REQUEST_H_
|
||||
@@ -107,14 +107,16 @@ void TranslateOldOptions(v8::Isolate* isolate, v8::Local<v8::Object> options) {
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Converts binary data to Buffer.
|
||||
v8::Local<v8::Value> ToBuffer(v8::Isolate* isolate, void* val, int size) {
|
||||
auto buffer = node::Buffer::Copy(isolate, static_cast<char*>(val), size);
|
||||
auto buffer = node::Buffer::New(isolate, static_cast<char*>(val), size);
|
||||
if (buffer.IsEmpty())
|
||||
return v8::Null(isolate);
|
||||
else
|
||||
return buffer.ToLocalChecked();
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -227,14 +229,6 @@ void Window::OnWindowLeaveFullScreen() {
|
||||
Emit("leave-full-screen");
|
||||
}
|
||||
|
||||
void Window::OnWindowScrollTouchBegin() {
|
||||
Emit("scroll-touch-begin");
|
||||
}
|
||||
|
||||
void Window::OnWindowScrollTouchEnd() {
|
||||
Emit("scroll-touch-end");
|
||||
}
|
||||
|
||||
void Window::OnWindowEnterHtmlFullScreen() {
|
||||
Emit("enter-html-full-screen");
|
||||
}
|
||||
@@ -346,20 +340,16 @@ bool Window::IsFullscreen() {
|
||||
return window_->IsFullscreen();
|
||||
}
|
||||
|
||||
void Window::SetBounds(const gfx::Rect& bounds, mate::Arguments* args) {
|
||||
bool animate = false;
|
||||
args->GetNext(&animate);
|
||||
window_->SetBounds(bounds, animate);
|
||||
void Window::SetBounds(const gfx::Rect& bounds) {
|
||||
window_->SetBounds(bounds);
|
||||
}
|
||||
|
||||
gfx::Rect Window::GetBounds() {
|
||||
return window_->GetBounds();
|
||||
}
|
||||
|
||||
void Window::SetSize(int width, int height, mate::Arguments* args) {
|
||||
bool animate = false;
|
||||
args->GetNext(&animate);
|
||||
window_->SetSize(gfx::Size(width, height), animate);
|
||||
void Window::SetSize(int width, int height) {
|
||||
window_->SetSize(gfx::Size(width, height));
|
||||
}
|
||||
|
||||
std::vector<int> Window::GetSize() {
|
||||
@@ -370,10 +360,8 @@ std::vector<int> Window::GetSize() {
|
||||
return result;
|
||||
}
|
||||
|
||||
void Window::SetContentSize(int width, int height, mate::Arguments* args) {
|
||||
bool animate = false;
|
||||
args->GetNext(&animate);
|
||||
window_->SetContentSize(gfx::Size(width, height), animate);
|
||||
void Window::SetContentSize(int width, int height) {
|
||||
window_->SetContentSize(gfx::Size(width, height));
|
||||
}
|
||||
|
||||
std::vector<int> Window::GetContentSize() {
|
||||
@@ -416,46 +404,6 @@ bool Window::IsResizable() {
|
||||
return window_->IsResizable();
|
||||
}
|
||||
|
||||
void Window::SetMovable(bool movable) {
|
||||
window_->SetMovable(movable);
|
||||
}
|
||||
|
||||
bool Window::IsMovable() {
|
||||
return window_->IsMovable();
|
||||
}
|
||||
|
||||
void Window::SetMinimizable(bool minimizable) {
|
||||
window_->SetMinimizable(minimizable);
|
||||
}
|
||||
|
||||
bool Window::IsMinimizable() {
|
||||
return window_->IsMinimizable();
|
||||
}
|
||||
|
||||
void Window::SetMaximizable(bool maximizable) {
|
||||
window_->SetMaximizable(maximizable);
|
||||
}
|
||||
|
||||
bool Window::IsMaximizable() {
|
||||
return window_->IsMaximizable();
|
||||
}
|
||||
|
||||
void Window::SetFullScreenable(bool fullscreenable) {
|
||||
window_->SetFullScreenable(fullscreenable);
|
||||
}
|
||||
|
||||
bool Window::IsFullScreenable() {
|
||||
return window_->IsFullScreenable();
|
||||
}
|
||||
|
||||
void Window::SetClosable(bool closable) {
|
||||
window_->SetClosable(closable);
|
||||
}
|
||||
|
||||
bool Window::IsClosable() {
|
||||
return window_->IsClosable();
|
||||
}
|
||||
|
||||
void Window::SetAlwaysOnTop(bool top) {
|
||||
window_->SetAlwaysOnTop(top);
|
||||
}
|
||||
@@ -468,10 +416,8 @@ void Window::Center() {
|
||||
window_->Center();
|
||||
}
|
||||
|
||||
void Window::SetPosition(int x, int y, mate::Arguments* args) {
|
||||
bool animate = false;
|
||||
args->GetNext(&animate);
|
||||
window_->SetPosition(gfx::Point(x, y), animate);
|
||||
void Window::SetPosition(int x, int y) {
|
||||
window_->SetPosition(gfx::Point(x, y));
|
||||
}
|
||||
|
||||
std::vector<int> Window::GetPosition() {
|
||||
@@ -510,14 +456,6 @@ void Window::SetBackgroundColor(const std::string& color_name) {
|
||||
window_->SetBackgroundColor(color_name);
|
||||
}
|
||||
|
||||
void Window::SetHasShadow(bool has_shadow) {
|
||||
window_->SetHasShadow(has_shadow);
|
||||
}
|
||||
|
||||
bool Window::HasShadow() {
|
||||
return window_->HasShadow();
|
||||
}
|
||||
|
||||
void Window::FocusOnWebView() {
|
||||
window_->FocusOnWebView();
|
||||
}
|
||||
@@ -530,6 +468,10 @@ bool Window::IsWebViewFocused() {
|
||||
return window_->IsWebViewFocused();
|
||||
}
|
||||
|
||||
bool Window::IsDevToolsFocused() {
|
||||
return window_->IsDevToolsFocused();
|
||||
}
|
||||
|
||||
void Window::SetRepresentedFilename(const std::string& filename) {
|
||||
window_->SetRepresentedFilename(filename);
|
||||
}
|
||||
@@ -546,10 +488,6 @@ bool Window::IsDocumentEdited() {
|
||||
return window_->IsDocumentEdited();
|
||||
}
|
||||
|
||||
void Window::SetIgnoreMouseEvents(bool ignore) {
|
||||
return window_->SetIgnoreMouseEvents(ignore);
|
||||
}
|
||||
|
||||
void Window::CapturePage(mate::Arguments* args) {
|
||||
gfx::Rect rect;
|
||||
base::Callback<void(const gfx::Image&)> callback;
|
||||
@@ -656,12 +594,6 @@ void Window::SetAspectRatio(double aspect_ratio, mate::Arguments* args) {
|
||||
window_->SetAspectRatio(aspect_ratio, extra_size);
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Window::GetNativeWindowHandle() {
|
||||
gfx::AcceleratedWidget handle = window_->GetAcceleratedWidget();
|
||||
return ToBuffer(
|
||||
isolate(), static_cast<void*>(&handle), sizeof(gfx::AcceleratedWidget));
|
||||
}
|
||||
|
||||
void Window::SetVisibleOnAllWorkspaces(bool visible) {
|
||||
return window_->SetVisibleOnAllWorkspaces(visible);
|
||||
}
|
||||
@@ -702,7 +634,6 @@ void Window::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("setFullScreen", &Window::SetFullScreen)
|
||||
.SetMethod("isFullScreen", &Window::IsFullscreen)
|
||||
.SetMethod("setAspectRatio", &Window::SetAspectRatio)
|
||||
.SetMethod("getNativeWindowHandle", &Window::GetNativeWindowHandle)
|
||||
.SetMethod("getBounds", &Window::GetBounds)
|
||||
.SetMethod("setBounds", &Window::SetBounds)
|
||||
.SetMethod("getSize", &Window::GetSize)
|
||||
@@ -715,16 +646,6 @@ void Window::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("getMaximumSize", &Window::GetMaximumSize)
|
||||
.SetMethod("setResizable", &Window::SetResizable)
|
||||
.SetMethod("isResizable", &Window::IsResizable)
|
||||
.SetMethod("setMovable", &Window::SetMovable)
|
||||
.SetMethod("isMovable", &Window::IsMovable)
|
||||
.SetMethod("setMinimizable", &Window::SetMinimizable)
|
||||
.SetMethod("isMinimizable", &Window::IsMinimizable)
|
||||
.SetMethod("setMaximizable", &Window::SetMaximizable)
|
||||
.SetMethod("isMaximizable", &Window::IsMaximizable)
|
||||
.SetMethod("setFullScreenable", &Window::SetFullScreenable)
|
||||
.SetMethod("isFullScreenable", &Window::IsFullScreenable)
|
||||
.SetMethod("setClosable", &Window::SetClosable)
|
||||
.SetMethod("isClosable", &Window::IsClosable)
|
||||
.SetMethod("setAlwaysOnTop", &Window::SetAlwaysOnTop)
|
||||
.SetMethod("isAlwaysOnTop", &Window::IsAlwaysOnTop)
|
||||
.SetMethod("center", &Window::Center)
|
||||
@@ -737,16 +658,14 @@ void Window::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("setKiosk", &Window::SetKiosk)
|
||||
.SetMethod("isKiosk", &Window::IsKiosk)
|
||||
.SetMethod("setBackgroundColor", &Window::SetBackgroundColor)
|
||||
.SetMethod("setHasShadow", &Window::SetHasShadow)
|
||||
.SetMethod("hasShadow", &Window::HasShadow)
|
||||
.SetMethod("setRepresentedFilename", &Window::SetRepresentedFilename)
|
||||
.SetMethod("getRepresentedFilename", &Window::GetRepresentedFilename)
|
||||
.SetMethod("setDocumentEdited", &Window::SetDocumentEdited)
|
||||
.SetMethod("isDocumentEdited", &Window::IsDocumentEdited)
|
||||
.SetMethod("setIgnoreMouseEvents", &Window::SetIgnoreMouseEvents)
|
||||
.SetMethod("focusOnWebView", &Window::FocusOnWebView)
|
||||
.SetMethod("blurWebView", &Window::BlurWebView)
|
||||
.SetMethod("isWebViewFocused", &Window::IsWebViewFocused)
|
||||
.SetMethod("isDevToolsFocused", &Window::IsDevToolsFocused)
|
||||
.SetMethod("capturePage", &Window::CapturePage)
|
||||
.SetMethod("setProgressBar", &Window::SetProgressBar)
|
||||
.SetMethod("setOverlayIcon", &Window::SetOverlayIcon)
|
||||
|
||||
@@ -65,8 +65,6 @@ class Window : public mate::TrackableObject<Window>,
|
||||
void OnWindowResize() override;
|
||||
void OnWindowMove() override;
|
||||
void OnWindowMoved() override;
|
||||
void OnWindowScrollTouchBegin() override;
|
||||
void OnWindowScrollTouchEnd() override;
|
||||
void OnWindowEnterFullScreen() override;
|
||||
void OnWindowLeaveFullScreen() override;
|
||||
void OnWindowEnterHtmlFullScreen() override;
|
||||
@@ -96,11 +94,11 @@ class Window : public mate::TrackableObject<Window>,
|
||||
bool IsMinimized();
|
||||
void SetFullScreen(bool fullscreen);
|
||||
bool IsFullscreen();
|
||||
void SetBounds(const gfx::Rect& bounds, mate::Arguments* args);
|
||||
void SetBounds(const gfx::Rect& bounds);
|
||||
gfx::Rect GetBounds();
|
||||
void SetSize(int width, int height, mate::Arguments* args);
|
||||
void SetSize(int width, int height);
|
||||
std::vector<int> GetSize();
|
||||
void SetContentSize(int width, int height, mate::Arguments* args);
|
||||
void SetContentSize(int width, int height);
|
||||
std::vector<int> GetContentSize();
|
||||
void SetMinimumSize(int width, int height);
|
||||
std::vector<int> GetMinimumSize();
|
||||
@@ -108,20 +106,10 @@ class Window : public mate::TrackableObject<Window>,
|
||||
std::vector<int> GetMaximumSize();
|
||||
void SetResizable(bool resizable);
|
||||
bool IsResizable();
|
||||
void SetMovable(bool movable);
|
||||
bool IsMovable();
|
||||
void SetMinimizable(bool minimizable);
|
||||
bool IsMinimizable();
|
||||
void SetMaximizable(bool maximizable);
|
||||
bool IsMaximizable();
|
||||
void SetFullScreenable(bool fullscreenable);
|
||||
bool IsFullScreenable();
|
||||
void SetClosable(bool closable);
|
||||
bool IsClosable();
|
||||
void SetAlwaysOnTop(bool top);
|
||||
bool IsAlwaysOnTop();
|
||||
void Center();
|
||||
void SetPosition(int x, int y, mate::Arguments* args);
|
||||
void SetPosition(int x, int y);
|
||||
std::vector<int> GetPosition();
|
||||
void SetTitle(const std::string& title);
|
||||
std::string GetTitle();
|
||||
@@ -130,16 +118,14 @@ class Window : public mate::TrackableObject<Window>,
|
||||
void SetKiosk(bool kiosk);
|
||||
bool IsKiosk();
|
||||
void SetBackgroundColor(const std::string& color_name);
|
||||
void SetHasShadow(bool has_shadow);
|
||||
bool HasShadow();
|
||||
void FocusOnWebView();
|
||||
void BlurWebView();
|
||||
bool IsWebViewFocused();
|
||||
bool IsDevToolsFocused();
|
||||
void SetRepresentedFilename(const std::string& filename);
|
||||
std::string GetRepresentedFilename();
|
||||
void SetDocumentEdited(bool edited);
|
||||
bool IsDocumentEdited();
|
||||
void SetIgnoreMouseEvents(bool ignore);
|
||||
void CapturePage(mate::Arguments* args);
|
||||
void SetProgressBar(double progress);
|
||||
void SetOverlayIcon(const gfx::Image& overlay,
|
||||
@@ -151,7 +137,6 @@ class Window : public mate::TrackableObject<Window>,
|
||||
void SetMenuBarVisibility(bool visible);
|
||||
bool IsMenuBarVisible();
|
||||
void SetAspectRatio(double aspect_ratio, mate::Arguments* args);
|
||||
v8::Local<v8::Value> GetNativeWindowHandle();
|
||||
|
||||
#if defined(OS_WIN)
|
||||
typedef base::Callback<void(v8::Local<v8::Value>,
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace api {
|
||||
FrameSubscriber::FrameSubscriber(v8::Isolate* isolate,
|
||||
const gfx::Size& size,
|
||||
const FrameCaptureCallback& callback)
|
||||
: isolate_(isolate), size_(size), callback_(callback), weak_factory_(this) {
|
||||
: isolate_(isolate), size_(size), callback_(callback) {
|
||||
}
|
||||
|
||||
bool FrameSubscriber::ShouldCaptureFrame(
|
||||
@@ -24,11 +24,12 @@ bool FrameSubscriber::ShouldCaptureFrame(
|
||||
base::TimeTicks present_time,
|
||||
scoped_refptr<media::VideoFrame>* storage,
|
||||
DeliverFrameCallback* callback) {
|
||||
*storage = media::VideoFrame::CreateFrame(
|
||||
media::PIXEL_FORMAT_YV12,
|
||||
size_, gfx::Rect(size_), size_, base::TimeDelta());
|
||||
*storage = media::VideoFrame::CreateFrame(media::VideoFrame::YV12, size_,
|
||||
gfx::Rect(size_), size_,
|
||||
base::TimeDelta());
|
||||
*callback = base::Bind(&FrameSubscriber::OnFrameDelivered,
|
||||
weak_factory_.GetWeakPtr(), *storage);
|
||||
base::Unretained(this),
|
||||
*storage);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#define ATOM_BROWSER_API_FRAME_SUBSCRIBER_H_
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "content/public/browser/render_widget_host_view_frame_subscriber.h"
|
||||
#include "ui/gfx/geometry/size.h"
|
||||
#include "v8/include/v8.h"
|
||||
@@ -36,8 +35,6 @@ class FrameSubscriber : public content::RenderWidgetHostViewFrameSubscriber {
|
||||
gfx::Size size_;
|
||||
FrameCaptureCallback callback_;
|
||||
|
||||
base::WeakPtrFactory<FrameSubscriber> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(FrameSubscriber);
|
||||
};
|
||||
|
||||
|
||||
72
atom/browser/api/lib/app.coffee
Normal file
72
atom/browser/api/lib/app.coffee
Normal file
@@ -0,0 +1,72 @@
|
||||
{deprecate, session, Menu} = require 'electron'
|
||||
{EventEmitter} = require 'events'
|
||||
|
||||
bindings = process.atomBinding 'app'
|
||||
downloadItemBindings = process.atomBinding 'download_item'
|
||||
|
||||
app = bindings.app
|
||||
app.__proto__ = EventEmitter.prototype
|
||||
|
||||
app.setApplicationMenu = (menu) ->
|
||||
Menu.setApplicationMenu menu
|
||||
|
||||
app.getApplicationMenu = ->
|
||||
Menu.getApplicationMenu()
|
||||
|
||||
app.commandLine =
|
||||
appendSwitch: bindings.appendSwitch,
|
||||
appendArgument: bindings.appendArgument
|
||||
|
||||
if process.platform is 'darwin'
|
||||
app.dock =
|
||||
bounce: (type='informational') -> bindings.dockBounce type
|
||||
cancelBounce: bindings.dockCancelBounce
|
||||
setBadge: bindings.dockSetBadgeText
|
||||
getBadge: bindings.dockGetBadgeText
|
||||
hide: bindings.dockHide
|
||||
show: bindings.dockShow
|
||||
setMenu: bindings.dockSetMenu
|
||||
|
||||
appPath = null
|
||||
app.setAppPath = (path) ->
|
||||
appPath = path
|
||||
|
||||
app.getAppPath = ->
|
||||
appPath
|
||||
|
||||
# Routes the events to webContents.
|
||||
for name in ['login', 'certificate-error', 'select-client-certificate']
|
||||
do (name) ->
|
||||
app.on name, (event, webContents, args...) ->
|
||||
webContents.emit name, event, args...
|
||||
|
||||
# Deprecated.
|
||||
app.getHomeDir = deprecate 'app.getHomeDir', 'app.getPath', ->
|
||||
@getPath 'home'
|
||||
app.getDataPath = deprecate 'app.getDataPath', 'app.getPath', ->
|
||||
@getPath 'userData'
|
||||
app.setDataPath = deprecate 'app.setDataPath', 'app.setPath', (path) ->
|
||||
@setPath 'userData', path
|
||||
app.resolveProxy = deprecate 'app.resolveProxy', 'session.defaultSession.resolveProxy', (url, callback) ->
|
||||
session.defaultSession.resolveProxy url, callback
|
||||
deprecate.rename app, 'terminate', 'quit'
|
||||
deprecate.event app, 'finish-launching', 'ready', ->
|
||||
setImmediate => # give default app a chance to setup default menu.
|
||||
@emit 'finish-launching'
|
||||
deprecate.event app, 'activate-with-no-open-windows', 'activate', (event, hasVisibleWindows) ->
|
||||
@emit 'activate-with-no-open-windows', event if not hasVisibleWindows
|
||||
deprecate.event app, 'select-certificate', 'select-client-certificate'
|
||||
|
||||
# Wrappers for native classes.
|
||||
wrapDownloadItem = (downloadItem) ->
|
||||
# downloadItem is an EventEmitter.
|
||||
downloadItem.__proto__ = EventEmitter.prototype
|
||||
# Deprecated.
|
||||
deprecate.property downloadItem, 'url', 'getURL'
|
||||
deprecate.property downloadItem, 'filename', 'getFilename'
|
||||
deprecate.property downloadItem, 'mimeType', 'getMimeType'
|
||||
deprecate.rename downloadItem, 'getUrl', 'getURL'
|
||||
downloadItemBindings._setWrapDownloadItem wrapDownloadItem
|
||||
|
||||
# Only one App object pemitted.
|
||||
module.exports = app
|
||||
@@ -1,123 +0,0 @@
|
||||
const deprecate = require('electron').deprecate;
|
||||
const session = require('electron').session;
|
||||
const Menu = require('electron').Menu;
|
||||
const EventEmitter = require('events').EventEmitter;
|
||||
|
||||
const bindings = process.atomBinding('app');
|
||||
const downloadItemBindings = process.atomBinding('download_item');
|
||||
const app = bindings.app;
|
||||
|
||||
var slice = [].slice;
|
||||
|
||||
app.__proto__ = EventEmitter.prototype;
|
||||
|
||||
app.setApplicationMenu = function(menu) {
|
||||
return Menu.setApplicationMenu(menu);
|
||||
};
|
||||
|
||||
app.getApplicationMenu = function() {
|
||||
return Menu.getApplicationMenu();
|
||||
};
|
||||
|
||||
app.commandLine = {
|
||||
appendSwitch: bindings.appendSwitch,
|
||||
appendArgument: bindings.appendArgument
|
||||
};
|
||||
|
||||
if (process.platform === 'darwin') {
|
||||
app.dock = {
|
||||
bounce: function(type) {
|
||||
if (type == null) {
|
||||
type = 'informational';
|
||||
}
|
||||
return bindings.dockBounce(type);
|
||||
},
|
||||
cancelBounce: bindings.dockCancelBounce,
|
||||
setBadge: bindings.dockSetBadgeText,
|
||||
getBadge: bindings.dockGetBadgeText,
|
||||
hide: bindings.dockHide,
|
||||
show: bindings.dockShow,
|
||||
setMenu: bindings.dockSetMenu,
|
||||
setIcon: bindings.dockSetIcon
|
||||
};
|
||||
}
|
||||
|
||||
var appPath = null;
|
||||
|
||||
app.setAppPath = function(path) {
|
||||
return appPath = path;
|
||||
};
|
||||
|
||||
app.getAppPath = function() {
|
||||
return appPath;
|
||||
};
|
||||
|
||||
// Routes the events to webContents.
|
||||
var ref1 = ['login', 'certificate-error', 'select-client-certificate'];
|
||||
var fn = function(name) {
|
||||
return app.on(name, function() {
|
||||
var args, event, webContents;
|
||||
event = arguments[0], webContents = arguments[1], args = 3 <= arguments.length ? slice.call(arguments, 2) : [];
|
||||
return webContents.emit.apply(webContents, [name, event].concat(slice.call(args)));
|
||||
});
|
||||
};
|
||||
var i, len;
|
||||
for (i = 0, len = ref1.length; i < len; i++) {
|
||||
fn(ref1[i]);
|
||||
}
|
||||
|
||||
// Deprecated.
|
||||
|
||||
app.getHomeDir = deprecate('app.getHomeDir', 'app.getPath', function() {
|
||||
return this.getPath('home');
|
||||
});
|
||||
|
||||
app.getDataPath = deprecate('app.getDataPath', 'app.getPath', function() {
|
||||
return this.getPath('userData');
|
||||
});
|
||||
|
||||
app.setDataPath = deprecate('app.setDataPath', 'app.setPath', function(path) {
|
||||
return this.setPath('userData', path);
|
||||
});
|
||||
|
||||
app.resolveProxy = deprecate('app.resolveProxy', 'session.defaultSession.resolveProxy', function(url, callback) {
|
||||
return session.defaultSession.resolveProxy(url, callback);
|
||||
});
|
||||
|
||||
deprecate.rename(app, 'terminate', 'quit');
|
||||
|
||||
deprecate.event(app, 'finish-launching', 'ready', function() {
|
||||
|
||||
// give default app a chance to setup default menu.
|
||||
return setImmediate((function(_this) {
|
||||
return function() {
|
||||
return _this.emit('finish-launching');
|
||||
};
|
||||
})(this));
|
||||
});
|
||||
|
||||
deprecate.event(app, 'activate-with-no-open-windows', 'activate', function(event, hasVisibleWindows) {
|
||||
if (!hasVisibleWindows) {
|
||||
return this.emit('activate-with-no-open-windows', event);
|
||||
}
|
||||
});
|
||||
|
||||
deprecate.event(app, 'select-certificate', 'select-client-certificate');
|
||||
|
||||
// Wrappers for native classes.
|
||||
var wrapDownloadItem = function(downloadItem) {
|
||||
|
||||
// downloadItem is an EventEmitter.
|
||||
downloadItem.__proto__ = EventEmitter.prototype;
|
||||
|
||||
// Deprecated.
|
||||
deprecate.property(downloadItem, 'url', 'getURL');
|
||||
deprecate.property(downloadItem, 'filename', 'getFilename');
|
||||
deprecate.property(downloadItem, 'mimeType', 'getMimeType');
|
||||
return deprecate.rename(downloadItem, 'getUrl', 'getURL');
|
||||
};
|
||||
|
||||
downloadItemBindings._setWrapDownloadItem(wrapDownloadItem);
|
||||
|
||||
// Only one App object pemitted.
|
||||
module.exports = app;
|
||||
12
atom/browser/api/lib/auto-updater.coffee
Normal file
12
atom/browser/api/lib/auto-updater.coffee
Normal file
@@ -0,0 +1,12 @@
|
||||
{deprecate} = require 'electron'
|
||||
|
||||
autoUpdater =
|
||||
if process.platform is 'win32'
|
||||
require './auto-updater/auto-updater-win'
|
||||
else
|
||||
require './auto-updater/auto-updater-native'
|
||||
|
||||
# Deprecated.
|
||||
deprecate.rename autoUpdater, 'setFeedUrl', 'setFeedURL'
|
||||
|
||||
module.exports = autoUpdater
|
||||
@@ -1,7 +0,0 @@
|
||||
const deprecate = require('electron').deprecate;
|
||||
const autoUpdater = process.platform === 'win32' ? require('./auto-updater/auto-updater-win') : require('./auto-updater/auto-updater-native');
|
||||
|
||||
// Deprecated.
|
||||
deprecate.rename(autoUpdater, 'setFeedUrl', 'setFeedURL');
|
||||
|
||||
module.exports = autoUpdater;
|
||||
@@ -0,0 +1,6 @@
|
||||
{EventEmitter} = require 'events'
|
||||
{autoUpdater} = process.atomBinding 'auto_updater'
|
||||
|
||||
autoUpdater.__proto__ = EventEmitter.prototype
|
||||
|
||||
module.exports = autoUpdater
|
||||
@@ -1,6 +0,0 @@
|
||||
const EventEmitter = require('events').EventEmitter;
|
||||
const autoUpdater = process.atomBinding('auto_updater').autoUpdater;
|
||||
|
||||
autoUpdater.__proto__ = EventEmitter.prototype;
|
||||
|
||||
module.exports = autoUpdater;
|
||||
42
atom/browser/api/lib/auto-updater/auto-updater-win.coffee
Normal file
42
atom/browser/api/lib/auto-updater/auto-updater-win.coffee
Normal file
@@ -0,0 +1,42 @@
|
||||
{app} = require 'electron'
|
||||
{EventEmitter} = require 'events'
|
||||
url = require 'url'
|
||||
|
||||
squirrelUpdate = require './squirrel-update-win'
|
||||
|
||||
class AutoUpdater extends EventEmitter
|
||||
quitAndInstall: ->
|
||||
squirrelUpdate.processStart()
|
||||
app.quit()
|
||||
|
||||
setFeedURL: (updateURL) ->
|
||||
@updateURL = updateURL
|
||||
|
||||
checkForUpdates: ->
|
||||
return @emitError 'Update URL is not set' unless @updateURL
|
||||
return @emitError 'Can not find Squirrel' unless squirrelUpdate.supported()
|
||||
|
||||
@emit 'checking-for-update'
|
||||
|
||||
squirrelUpdate.download @updateURL, (error, update) =>
|
||||
return @emitError error if error?
|
||||
return @emit 'update-not-available' unless update?
|
||||
|
||||
@emit 'update-available'
|
||||
|
||||
squirrelUpdate.update @updateURL, (error) =>
|
||||
return @emitError error if error?
|
||||
|
||||
{releaseNotes, version} = update
|
||||
# Following information is not available on Windows, so fake them.
|
||||
date = new Date
|
||||
url = @updateURL
|
||||
|
||||
@emit 'update-downloaded', {}, releaseNotes, version, date, url, => @quitAndInstall()
|
||||
|
||||
# Private: Emit both error object and message, this is to keep compatibility
|
||||
# with Old APIs.
|
||||
emitError: (message) ->
|
||||
@emit 'error', new Error(message), message
|
||||
|
||||
module.exports = new AutoUpdater
|
||||
@@ -1,63 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const app = require('electron').app;
|
||||
const EventEmitter = require('events').EventEmitter;
|
||||
const squirrelUpdate = require('./squirrel-update-win');
|
||||
const util = require('util');
|
||||
|
||||
function AutoUpdater() {
|
||||
EventEmitter.call(this);
|
||||
}
|
||||
|
||||
util.inherits(AutoUpdater, EventEmitter);
|
||||
|
||||
AutoUpdater.prototype.quitAndInstall = function() {
|
||||
squirrelUpdate.processStart();
|
||||
return app.quit();
|
||||
};
|
||||
|
||||
AutoUpdater.prototype.setFeedURL = function(updateURL) {
|
||||
return this.updateURL = updateURL;
|
||||
};
|
||||
|
||||
AutoUpdater.prototype.checkForUpdates = function() {
|
||||
if (!this.updateURL) {
|
||||
return this.emitError('Update URL is not set');
|
||||
}
|
||||
if (!squirrelUpdate.supported()) {
|
||||
return this.emitError('Can not find Squirrel');
|
||||
}
|
||||
this.emit('checking-for-update');
|
||||
return squirrelUpdate.download(this.updateURL, (function(_this) {
|
||||
return function(error, update) {
|
||||
if (error != null) {
|
||||
return _this.emitError(error);
|
||||
}
|
||||
if (update == null) {
|
||||
return _this.emit('update-not-available');
|
||||
}
|
||||
_this.emit('update-available');
|
||||
return squirrelUpdate.update(_this.updateURL, function(error) {
|
||||
var date, releaseNotes, version;
|
||||
if (error != null) {
|
||||
return _this.emitError(error);
|
||||
}
|
||||
releaseNotes = update.releaseNotes, version = update.version;
|
||||
|
||||
// Following information is not available on Windows, so fake them.
|
||||
date = new Date;
|
||||
return _this.emit('update-downloaded', {}, releaseNotes, version, date, _this.updateURL, function() {
|
||||
return _this.quitAndInstall();
|
||||
});
|
||||
});
|
||||
};
|
||||
})(this));
|
||||
};
|
||||
|
||||
// Private: Emit both error object and message, this is to keep compatibility
|
||||
// with Old APIs.
|
||||
AutoUpdater.prototype.emitError = function(message) {
|
||||
return this.emit('error', new Error(message), message);
|
||||
};
|
||||
|
||||
module.exports = new AutoUpdater;
|
||||
67
atom/browser/api/lib/auto-updater/squirrel-update-win.coffee
Normal file
67
atom/browser/api/lib/auto-updater/squirrel-update-win.coffee
Normal file
@@ -0,0 +1,67 @@
|
||||
fs = require 'fs'
|
||||
path = require 'path'
|
||||
{spawn} = require 'child_process'
|
||||
|
||||
appFolder = path.dirname process.execPath # i.e. my-app/app-0.1.13/
|
||||
updateExe = path.resolve appFolder, '..', 'Update.exe' # i.e. my-app/Update.exe
|
||||
exeName = path.basename process.execPath
|
||||
|
||||
# Spawn a command and invoke the callback when it completes with an error
|
||||
# and the output from standard out.
|
||||
spawnUpdate = (args, detached, callback) ->
|
||||
try
|
||||
spawnedProcess = spawn updateExe, args, {detached}
|
||||
catch error
|
||||
# Shouldn't happen, but still guard it.
|
||||
process.nextTick -> callback error
|
||||
return
|
||||
|
||||
stdout = ''
|
||||
stderr = ''
|
||||
spawnedProcess.stdout.on 'data', (data) -> stdout += data
|
||||
spawnedProcess.stderr.on 'data', (data) -> stderr += data
|
||||
|
||||
errorEmitted = false
|
||||
spawnedProcess.on 'error', (error) ->
|
||||
errorEmitted = true
|
||||
callback error
|
||||
spawnedProcess.on 'exit', (code, signal) ->
|
||||
# We may have already emitted an error.
|
||||
return if errorEmitted
|
||||
|
||||
# Process terminated with error.
|
||||
if code isnt 0
|
||||
return callback "Command failed: #{signal ? code}\n#{stderr}"
|
||||
|
||||
# Success.
|
||||
callback null, stdout
|
||||
|
||||
# Start an instance of the installed app.
|
||||
exports.processStart = (callback) ->
|
||||
spawnUpdate ['--processStart', exeName], true, ->
|
||||
|
||||
# Download the releases specified by the URL and write new results to stdout.
|
||||
exports.download = (updateURL, callback) ->
|
||||
spawnUpdate ['--download', updateURL], false, (error, stdout) ->
|
||||
return callback(error) if error?
|
||||
|
||||
try
|
||||
# Last line of output is the JSON details about the releases
|
||||
json = stdout.trim().split('\n').pop()
|
||||
update = JSON.parse(json)?.releasesToApply?.pop?()
|
||||
catch
|
||||
return callback "Invalid result:\n#{stdout}"
|
||||
|
||||
callback null, update
|
||||
|
||||
# Update the application to the latest remote version specified by URL.
|
||||
exports.update = (updateURL, callback) ->
|
||||
spawnUpdate ['--update', updateURL], false, callback
|
||||
|
||||
# Is the Update.exe installed with the current application?
|
||||
exports.supported = ->
|
||||
try
|
||||
fs.accessSync updateExe, fs.R_OK
|
||||
return true
|
||||
catch
|
||||
return false
|
||||
@@ -1,98 +0,0 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const spawn = require('child_process').spawn;
|
||||
|
||||
// i.e. my-app/app-0.1.13/
|
||||
const appFolder = path.dirname(process.execPath);
|
||||
|
||||
// i.e. my-app/Update.exe
|
||||
const updateExe = path.resolve(appFolder, '..', 'Update.exe');
|
||||
|
||||
const exeName = path.basename(process.execPath);
|
||||
|
||||
// Spawn a command and invoke the callback when it completes with an error
|
||||
// and the output from standard out.
|
||||
var spawnUpdate = function(args, detached, callback) {
|
||||
var error, errorEmitted, spawnedProcess, stderr, stdout;
|
||||
try {
|
||||
spawnedProcess = spawn(updateExe, args, {
|
||||
detached: detached
|
||||
});
|
||||
} catch (error1) {
|
||||
error = error1;
|
||||
|
||||
// Shouldn't happen, but still guard it.
|
||||
process.nextTick(function() {
|
||||
return callback(error);
|
||||
});
|
||||
return;
|
||||
}
|
||||
stdout = '';
|
||||
stderr = '';
|
||||
spawnedProcess.stdout.on('data', function(data) {
|
||||
return stdout += data;
|
||||
});
|
||||
spawnedProcess.stderr.on('data', function(data) {
|
||||
return stderr += data;
|
||||
});
|
||||
errorEmitted = false;
|
||||
spawnedProcess.on('error', function(error) {
|
||||
errorEmitted = true;
|
||||
return callback(error);
|
||||
});
|
||||
return spawnedProcess.on('exit', function(code, signal) {
|
||||
|
||||
// We may have already emitted an error.
|
||||
if (errorEmitted) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Process terminated with error.
|
||||
if (code !== 0) {
|
||||
return callback("Command failed: " + (signal != null ? signal : code) + "\n" + stderr);
|
||||
}
|
||||
|
||||
// Success.
|
||||
return callback(null, stdout);
|
||||
});
|
||||
};
|
||||
|
||||
// Start an instance of the installed app.
|
||||
exports.processStart = function() {
|
||||
return spawnUpdate(['--processStart', exeName], true, function() {});
|
||||
};
|
||||
|
||||
// Download the releases specified by the URL and write new results to stdout.
|
||||
exports.download = function(updateURL, callback) {
|
||||
return spawnUpdate(['--download', updateURL], false, function(error, stdout) {
|
||||
var json, ref, ref1, update;
|
||||
if (error != null) {
|
||||
return callback(error);
|
||||
}
|
||||
try {
|
||||
// Last line of output is the JSON details about the releases
|
||||
json = stdout.trim().split('\n').pop();
|
||||
update = (ref = JSON.parse(json)) != null ? (ref1 = ref.releasesToApply) != null ? typeof ref1.pop === "function" ? ref1.pop() : void 0 : void 0 : void 0;
|
||||
} catch (jsonError) {
|
||||
return callback("Invalid result:\n" + stdout);
|
||||
}
|
||||
return callback(null, update);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// Update the application to the latest remote version specified by URL.
|
||||
exports.update = function(updateURL, callback) {
|
||||
return spawnUpdate(['--update', updateURL], false, callback);
|
||||
};
|
||||
|
||||
|
||||
// Is the Update.exe installed with the current application?
|
||||
exports.supported = function() {
|
||||
try {
|
||||
fs.accessSync(updateExe, fs.R_OK);
|
||||
return true;
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
112
atom/browser/api/lib/browser-window.coffee
Normal file
112
atom/browser/api/lib/browser-window.coffee
Normal file
@@ -0,0 +1,112 @@
|
||||
{ipcMain, deprecate} = require 'electron'
|
||||
{EventEmitter} = require 'events'
|
||||
|
||||
{BrowserWindow} = process.atomBinding 'window'
|
||||
BrowserWindow::__proto__ = EventEmitter.prototype
|
||||
|
||||
BrowserWindow::_init = ->
|
||||
{app} = require 'electron' # avoid recursive require.
|
||||
|
||||
# Simulate the application menu on platforms other than OS X.
|
||||
if process.platform isnt 'darwin'
|
||||
menu = app.getApplicationMenu()
|
||||
@setMenu menu if menu?
|
||||
|
||||
# Make new windows requested by links behave like "window.open"
|
||||
@webContents.on '-new-window', (event, url, frameName) ->
|
||||
options = show: true, width: 800, height: 600
|
||||
ipcMain.emit 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPEN', event, url, frameName, options
|
||||
|
||||
# window.resizeTo(...)
|
||||
# window.moveTo(...)
|
||||
@webContents.on 'move', (event, size) =>
|
||||
@setBounds size
|
||||
|
||||
# Hide the auto-hide menu when webContents is focused.
|
||||
@webContents.on 'activate', =>
|
||||
if process.platform isnt 'darwin' and @isMenuBarAutoHide() and @isMenuBarVisible()
|
||||
@setMenuBarVisibility false
|
||||
|
||||
# Forward the crashed event.
|
||||
@webContents.on 'crashed', =>
|
||||
@emit 'crashed'
|
||||
|
||||
# Change window title to page title.
|
||||
@webContents.on 'page-title-updated', (event, title, explicitSet) =>
|
||||
@emit 'page-title-updated', event, title
|
||||
@setTitle title unless event.defaultPrevented
|
||||
|
||||
# Sometimes the webContents doesn't get focus when window is shown, so we have
|
||||
# to force focusing on webContents in this case. The safest way is to focus it
|
||||
# when we first start to load URL, if we do it earlier it won't have effect,
|
||||
# if we do it later we might move focus in the page.
|
||||
# Though this hack is only needed on OS X when the app is launched from
|
||||
# Finder, we still do it on all platforms in case of other bugs we don't know.
|
||||
@webContents.once 'load-url', ->
|
||||
@focus()
|
||||
|
||||
# Redirect focus/blur event to app instance too.
|
||||
@on 'blur', (event) =>
|
||||
app.emit 'browser-window-blur', event, this
|
||||
@on 'focus', (event) =>
|
||||
app.emit 'browser-window-focus', event, this
|
||||
|
||||
# Notify the creation of the window.
|
||||
app.emit 'browser-window-created', {}, this
|
||||
|
||||
# Be compatible with old APIs.
|
||||
@webContents.on 'devtools-focused', => @emit 'devtools-focused'
|
||||
@webContents.on 'devtools-opened', => @emit 'devtools-opened'
|
||||
@webContents.on 'devtools-closed', => @emit 'devtools-closed'
|
||||
Object.defineProperty this, 'devToolsWebContents',
|
||||
enumerable: true,
|
||||
configurable: false,
|
||||
get: -> @webContents.devToolsWebContents
|
||||
|
||||
BrowserWindow.getFocusedWindow = ->
|
||||
windows = BrowserWindow.getAllWindows()
|
||||
return window for window in windows when window.isFocused()
|
||||
|
||||
BrowserWindow.fromWebContents = (webContents) ->
|
||||
windows = BrowserWindow.getAllWindows()
|
||||
return window for window in windows when window.webContents?.equal webContents
|
||||
|
||||
BrowserWindow.fromDevToolsWebContents = (webContents) ->
|
||||
windows = BrowserWindow.getAllWindows()
|
||||
return window for window in windows when window.devToolsWebContents?.equal webContents
|
||||
|
||||
# Helpers.
|
||||
BrowserWindow::loadURL = -> @webContents.loadURL.apply @webContents, arguments
|
||||
BrowserWindow::getURL = -> @webContents.getURL()
|
||||
BrowserWindow::reload = -> @webContents.reload.apply @webContents, arguments
|
||||
BrowserWindow::send = -> @webContents.send.apply @webContents, arguments
|
||||
BrowserWindow::openDevTools = -> @webContents.openDevTools.apply @webContents, arguments
|
||||
BrowserWindow::closeDevTools = -> @webContents.closeDevTools()
|
||||
BrowserWindow::isDevToolsOpened = -> @webContents.isDevToolsOpened()
|
||||
BrowserWindow::toggleDevTools = -> @webContents.toggleDevTools()
|
||||
BrowserWindow::inspectElement = -> @webContents.inspectElement.apply @webContents, arguments
|
||||
BrowserWindow::inspectServiceWorker = -> @webContents.inspectServiceWorker()
|
||||
|
||||
# Deprecated.
|
||||
deprecate.member BrowserWindow, 'undo', 'webContents'
|
||||
deprecate.member BrowserWindow, 'redo', 'webContents'
|
||||
deprecate.member BrowserWindow, 'cut', 'webContents'
|
||||
deprecate.member BrowserWindow, 'copy', 'webContents'
|
||||
deprecate.member BrowserWindow, 'paste', 'webContents'
|
||||
deprecate.member BrowserWindow, 'selectAll', 'webContents'
|
||||
deprecate.member BrowserWindow, 'reloadIgnoringCache', 'webContents'
|
||||
deprecate.member BrowserWindow, 'isLoading', 'webContents'
|
||||
deprecate.member BrowserWindow, 'isWaitingForResponse', 'webContents'
|
||||
deprecate.member BrowserWindow, 'stop', 'webContents'
|
||||
deprecate.member BrowserWindow, 'isCrashed', 'webContents'
|
||||
deprecate.member BrowserWindow, 'print', 'webContents'
|
||||
deprecate.member BrowserWindow, 'printToPDF', 'webContents'
|
||||
deprecate.rename BrowserWindow, 'restart', 'reload'
|
||||
deprecate.rename BrowserWindow, 'loadUrl', 'loadURL'
|
||||
deprecate.rename BrowserWindow, 'getUrl', 'getURL'
|
||||
BrowserWindow::executeJavaScriptInDevTools = deprecate 'executeJavaScriptInDevTools', 'devToolsWebContents.executeJavaScript', (code) ->
|
||||
@devToolsWebContents?.executeJavaScript code
|
||||
BrowserWindow::getPageTitle = deprecate 'getPageTitle', 'webContents.getTitle', ->
|
||||
@webContents?.getTitle()
|
||||
|
||||
module.exports = BrowserWindow
|
||||
@@ -1,243 +0,0 @@
|
||||
const ipcMain = require('electron').ipcMain;
|
||||
const deprecate = require('electron').deprecate;
|
||||
const EventEmitter = require('events').EventEmitter;
|
||||
const BrowserWindow = process.atomBinding('window').BrowserWindow;
|
||||
|
||||
BrowserWindow.prototype.__proto__ = EventEmitter.prototype;
|
||||
|
||||
BrowserWindow.prototype._init = function() {
|
||||
|
||||
// avoid recursive require.
|
||||
var app, menu;
|
||||
app = require('electron').app;
|
||||
|
||||
// Simulate the application menu on platforms other than OS X.
|
||||
if (process.platform !== 'darwin') {
|
||||
menu = app.getApplicationMenu();
|
||||
if (menu != null) {
|
||||
this.setMenu(menu);
|
||||
}
|
||||
}
|
||||
|
||||
// Make new windows requested by links behave like "window.open"
|
||||
this.webContents.on('-new-window', function(event, url, frameName) {
|
||||
var options;
|
||||
options = {
|
||||
show: true,
|
||||
width: 800,
|
||||
height: 600
|
||||
};
|
||||
return ipcMain.emit('ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPEN', event, url, frameName, options);
|
||||
});
|
||||
|
||||
// window.resizeTo(...)
|
||||
// window.moveTo(...)
|
||||
this.webContents.on('move', (function(_this) {
|
||||
return function(event, size) {
|
||||
return _this.setBounds(size);
|
||||
};
|
||||
})(this));
|
||||
|
||||
// Hide the auto-hide menu when webContents is focused.
|
||||
this.webContents.on('activate', (function(_this) {
|
||||
return function() {
|
||||
if (process.platform !== 'darwin' && _this.isMenuBarAutoHide() && _this.isMenuBarVisible()) {
|
||||
return _this.setMenuBarVisibility(false);
|
||||
}
|
||||
};
|
||||
})(this));
|
||||
|
||||
// Forward the crashed event.
|
||||
this.webContents.on('crashed', (function(_this) {
|
||||
return function() {
|
||||
return _this.emit('crashed');
|
||||
};
|
||||
})(this));
|
||||
|
||||
// Change window title to page title.
|
||||
this.webContents.on('page-title-updated', (event, title) => {
|
||||
// The page-title-updated event is not emitted immediately (see #3645), so
|
||||
// when the callback is called the BrowserWindow might have been closed.
|
||||
if (this.isDestroyed())
|
||||
return;
|
||||
// Route the event to BrowserWindow.
|
||||
this.emit('page-title-updated', event, title);
|
||||
if (!event.defaultPrevented)
|
||||
this.setTitle(title);
|
||||
});
|
||||
|
||||
// Sometimes the webContents doesn't get focus when window is shown, so we have
|
||||
// to force focusing on webContents in this case. The safest way is to focus it
|
||||
// when we first start to load URL, if we do it earlier it won't have effect,
|
||||
// if we do it later we might move focus in the page.
|
||||
// Though this hack is only needed on OS X when the app is launched from
|
||||
// Finder, we still do it on all platforms in case of other bugs we don't know.
|
||||
this.webContents.once('load-url', function() {
|
||||
return this.focus();
|
||||
});
|
||||
|
||||
// Redirect focus/blur event to app instance too.
|
||||
this.on('blur', (function(_this) {
|
||||
return function(event) {
|
||||
return app.emit('browser-window-blur', event, _this);
|
||||
};
|
||||
})(this));
|
||||
this.on('focus', (function(_this) {
|
||||
return function(event) {
|
||||
return app.emit('browser-window-focus', event, _this);
|
||||
};
|
||||
})(this));
|
||||
|
||||
// Notify the creation of the window.
|
||||
app.emit('browser-window-created', {}, this);
|
||||
|
||||
// Be compatible with old APIs.
|
||||
this.webContents.on('devtools-focused', (function(_this) {
|
||||
return function() {
|
||||
return _this.emit('devtools-focused');
|
||||
};
|
||||
})(this));
|
||||
this.webContents.on('devtools-opened', (function(_this) {
|
||||
return function() {
|
||||
return _this.emit('devtools-opened');
|
||||
};
|
||||
})(this));
|
||||
this.webContents.on('devtools-closed', (function(_this) {
|
||||
return function() {
|
||||
return _this.emit('devtools-closed');
|
||||
};
|
||||
})(this));
|
||||
return Object.defineProperty(this, 'devToolsWebContents', {
|
||||
enumerable: true,
|
||||
configurable: false,
|
||||
get: function() {
|
||||
return this.webContents.devToolsWebContents;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
BrowserWindow.getFocusedWindow = function() {
|
||||
var i, len, window, windows;
|
||||
windows = BrowserWindow.getAllWindows();
|
||||
for (i = 0, len = windows.length; i < len; i++) {
|
||||
window = windows[i];
|
||||
if (window.isFocused()) {
|
||||
return window;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
BrowserWindow.fromWebContents = function(webContents) {
|
||||
var i, len, ref1, window, windows;
|
||||
windows = BrowserWindow.getAllWindows();
|
||||
for (i = 0, len = windows.length; i < len; i++) {
|
||||
window = windows[i];
|
||||
if ((ref1 = window.webContents) != null ? ref1.equal(webContents) : void 0) {
|
||||
return window;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
BrowserWindow.fromDevToolsWebContents = function(webContents) {
|
||||
var i, len, ref1, window, windows;
|
||||
windows = BrowserWindow.getAllWindows();
|
||||
for (i = 0, len = windows.length; i < len; i++) {
|
||||
window = windows[i];
|
||||
if ((ref1 = window.devToolsWebContents) != null ? ref1.equal(webContents) : void 0) {
|
||||
return window;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Helpers.
|
||||
|
||||
BrowserWindow.prototype.loadURL = function() {
|
||||
return this.webContents.loadURL.apply(this.webContents, arguments);
|
||||
};
|
||||
|
||||
BrowserWindow.prototype.getURL = function() {
|
||||
return this.webContents.getURL();
|
||||
};
|
||||
|
||||
BrowserWindow.prototype.reload = function() {
|
||||
return this.webContents.reload.apply(this.webContents, arguments);
|
||||
};
|
||||
|
||||
BrowserWindow.prototype.send = function() {
|
||||
return this.webContents.send.apply(this.webContents, arguments);
|
||||
};
|
||||
|
||||
BrowserWindow.prototype.openDevTools = function() {
|
||||
return this.webContents.openDevTools.apply(this.webContents, arguments);
|
||||
};
|
||||
|
||||
BrowserWindow.prototype.closeDevTools = function() {
|
||||
return this.webContents.closeDevTools();
|
||||
};
|
||||
|
||||
BrowserWindow.prototype.isDevToolsOpened = function() {
|
||||
return this.webContents.isDevToolsOpened();
|
||||
};
|
||||
|
||||
BrowserWindow.prototype.isDevToolsFocused = function() {
|
||||
return this.webContents.isDevToolsFocused();
|
||||
};
|
||||
|
||||
BrowserWindow.prototype.toggleDevTools = function() {
|
||||
return this.webContents.toggleDevTools();
|
||||
};
|
||||
|
||||
BrowserWindow.prototype.inspectElement = function() {
|
||||
return this.webContents.inspectElement.apply(this.webContents, arguments);
|
||||
};
|
||||
|
||||
BrowserWindow.prototype.inspectServiceWorker = function() {
|
||||
return this.webContents.inspectServiceWorker();
|
||||
};
|
||||
|
||||
// Deprecated.
|
||||
|
||||
deprecate.member(BrowserWindow, 'undo', 'webContents');
|
||||
|
||||
deprecate.member(BrowserWindow, 'redo', 'webContents');
|
||||
|
||||
deprecate.member(BrowserWindow, 'cut', 'webContents');
|
||||
|
||||
deprecate.member(BrowserWindow, 'copy', 'webContents');
|
||||
|
||||
deprecate.member(BrowserWindow, 'paste', 'webContents');
|
||||
|
||||
deprecate.member(BrowserWindow, 'selectAll', 'webContents');
|
||||
|
||||
deprecate.member(BrowserWindow, 'reloadIgnoringCache', 'webContents');
|
||||
|
||||
deprecate.member(BrowserWindow, 'isLoading', 'webContents');
|
||||
|
||||
deprecate.member(BrowserWindow, 'isWaitingForResponse', 'webContents');
|
||||
|
||||
deprecate.member(BrowserWindow, 'stop', 'webContents');
|
||||
|
||||
deprecate.member(BrowserWindow, 'isCrashed', 'webContents');
|
||||
|
||||
deprecate.member(BrowserWindow, 'print', 'webContents');
|
||||
|
||||
deprecate.member(BrowserWindow, 'printToPDF', 'webContents');
|
||||
|
||||
deprecate.rename(BrowserWindow, 'restart', 'reload');
|
||||
|
||||
deprecate.rename(BrowserWindow, 'loadUrl', 'loadURL');
|
||||
|
||||
deprecate.rename(BrowserWindow, 'getUrl', 'getURL');
|
||||
|
||||
BrowserWindow.prototype.executeJavaScriptInDevTools = deprecate('executeJavaScriptInDevTools', 'devToolsWebContents.executeJavaScript', function(code) {
|
||||
var ref1;
|
||||
return (ref1 = this.devToolsWebContents) != null ? ref1.executeJavaScript(code) : void 0;
|
||||
});
|
||||
|
||||
BrowserWindow.prototype.getPageTitle = deprecate('getPageTitle', 'webContents.getTitle', function() {
|
||||
var ref1;
|
||||
return (ref1 = this.webContents) != null ? ref1.getTitle() : void 0;
|
||||
});
|
||||
|
||||
module.exports = BrowserWindow;
|
||||
1
atom/browser/api/lib/content-tracing.coffee
Normal file
1
atom/browser/api/lib/content-tracing.coffee
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = process.atomBinding 'content_tracing'
|
||||
@@ -1 +0,0 @@
|
||||
module.exports = process.atomBinding('content_tracing');
|
||||
125
atom/browser/api/lib/dialog.coffee
Normal file
125
atom/browser/api/lib/dialog.coffee
Normal file
@@ -0,0 +1,125 @@
|
||||
{app, BrowserWindow} = require 'electron'
|
||||
|
||||
binding = process.atomBinding 'dialog'
|
||||
v8Util = process.atomBinding 'v8_util'
|
||||
|
||||
fileDialogProperties =
|
||||
openFile: 1 << 0
|
||||
openDirectory: 1 << 1
|
||||
multiSelections: 1 << 2
|
||||
createDirectory: 1 << 3
|
||||
|
||||
messageBoxTypes = ['none', 'info', 'warning', 'error', 'question']
|
||||
|
||||
messageBoxOptions =
|
||||
noLink: 1 << 0
|
||||
|
||||
parseArgs = (window, options, callback) ->
|
||||
unless window is null or window?.constructor is BrowserWindow
|
||||
# Shift.
|
||||
callback = options
|
||||
options = window
|
||||
window = null
|
||||
if not callback? and typeof options is 'function'
|
||||
# Shift.
|
||||
callback = options
|
||||
options = null
|
||||
[window, options, callback]
|
||||
|
||||
checkAppInitialized = ->
|
||||
throw new Error('dialog module can only be used after app is ready') unless app.isReady()
|
||||
|
||||
module.exports =
|
||||
showOpenDialog: (args...) ->
|
||||
checkAppInitialized()
|
||||
[window, options, callback] = parseArgs args...
|
||||
|
||||
options ?= title: 'Open', properties: ['openFile']
|
||||
options.properties ?= ['openFile']
|
||||
throw new TypeError('Properties need to be array') unless Array.isArray options.properties
|
||||
|
||||
properties = 0
|
||||
for prop, value of fileDialogProperties
|
||||
properties |= value if prop in options.properties
|
||||
|
||||
options.title ?= ''
|
||||
options.defaultPath ?= ''
|
||||
options.filters ?= []
|
||||
|
||||
wrappedCallback =
|
||||
if typeof callback is 'function'
|
||||
(success, result) -> callback(if success then result)
|
||||
else
|
||||
null
|
||||
|
||||
binding.showOpenDialog String(options.title),
|
||||
String(options.defaultPath),
|
||||
options.filters
|
||||
properties,
|
||||
window,
|
||||
wrappedCallback
|
||||
|
||||
showSaveDialog: (args...) ->
|
||||
checkAppInitialized()
|
||||
[window, options, callback] = parseArgs args...
|
||||
|
||||
options ?= title: 'Save'
|
||||
options.title ?= ''
|
||||
options.defaultPath ?= ''
|
||||
options.filters ?= []
|
||||
|
||||
wrappedCallback =
|
||||
if typeof callback is 'function'
|
||||
(success, result) -> callback(if success then result)
|
||||
else
|
||||
null
|
||||
|
||||
binding.showSaveDialog String(options.title),
|
||||
String(options.defaultPath),
|
||||
options.filters
|
||||
window,
|
||||
wrappedCallback
|
||||
|
||||
showMessageBox: (args...) ->
|
||||
checkAppInitialized()
|
||||
[window, options, callback] = parseArgs args...
|
||||
|
||||
options ?= type: 'none'
|
||||
options.type ?= 'none'
|
||||
messageBoxType = messageBoxTypes.indexOf options.type
|
||||
throw new TypeError('Invalid message box type') unless messageBoxType > -1
|
||||
|
||||
throw new TypeError('Buttons need to be array') unless Array.isArray options.buttons
|
||||
|
||||
options.title ?= ''
|
||||
options.message ?= ''
|
||||
options.detail ?= ''
|
||||
options.icon ?= null
|
||||
|
||||
# Choose a default button to get selected when dialog is cancelled.
|
||||
unless options.cancelId?
|
||||
options.cancelId = 0
|
||||
for text, i in options.buttons
|
||||
if text.toLowerCase() in ['cancel', 'no']
|
||||
options.cancelId = i
|
||||
break
|
||||
|
||||
flags = if options.noLink then messageBoxOptions.noLink else 0
|
||||
|
||||
binding.showMessageBox messageBoxType,
|
||||
options.buttons,
|
||||
options.cancelId,
|
||||
flags,
|
||||
options.title,
|
||||
options.message,
|
||||
options.detail,
|
||||
options.icon,
|
||||
window,
|
||||
callback
|
||||
|
||||
showErrorBox: (args...) ->
|
||||
binding.showErrorBox args...
|
||||
|
||||
# Mark standard asynchronous functions.
|
||||
for api in ['showMessageBox', 'showOpenDialog', 'showSaveDialog']
|
||||
v8Util.setHiddenValue module.exports[api], 'asynchronous', true
|
||||
@@ -1,170 +0,0 @@
|
||||
const app = require('electron').app;
|
||||
const BrowserWindow = require('electron').BrowserWindow;
|
||||
const binding = process.atomBinding('dialog');
|
||||
const v8Util = process.atomBinding('v8_util');
|
||||
|
||||
var slice = [].slice;
|
||||
var includes = [].includes;
|
||||
|
||||
var fileDialogProperties = {
|
||||
openFile: 1 << 0,
|
||||
openDirectory: 1 << 1,
|
||||
multiSelections: 1 << 2,
|
||||
createDirectory: 1 << 3
|
||||
};
|
||||
|
||||
var messageBoxTypes = ['none', 'info', 'warning', 'error', 'question'];
|
||||
|
||||
var messageBoxOptions = {
|
||||
noLink: 1 << 0
|
||||
};
|
||||
|
||||
var parseArgs = function(window, options, callback) {
|
||||
if (!(window === null || (window != null ? window.constructor : void 0) === BrowserWindow)) {
|
||||
// Shift.
|
||||
callback = options;
|
||||
options = window;
|
||||
window = null;
|
||||
}
|
||||
if ((callback == null) && typeof options === 'function') {
|
||||
// Shift.
|
||||
callback = options;
|
||||
options = null;
|
||||
}
|
||||
return [window, options, callback];
|
||||
};
|
||||
|
||||
var checkAppInitialized = function() {
|
||||
if (!app.isReady()) {
|
||||
throw new Error('dialog module can only be used after app is ready');
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
showOpenDialog: function() {
|
||||
var args, callback, options, prop, properties, ref1, value, window, wrappedCallback;
|
||||
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
|
||||
checkAppInitialized();
|
||||
ref1 = parseArgs.apply(null, args), window = ref1[0], options = ref1[1], callback = ref1[2];
|
||||
if (options == null) {
|
||||
options = {
|
||||
title: 'Open',
|
||||
properties: ['openFile']
|
||||
};
|
||||
}
|
||||
if (options.properties == null) {
|
||||
options.properties = ['openFile'];
|
||||
}
|
||||
if (!Array.isArray(options.properties)) {
|
||||
throw new TypeError('Properties need to be array');
|
||||
}
|
||||
properties = 0;
|
||||
for (prop in fileDialogProperties) {
|
||||
value = fileDialogProperties[prop];
|
||||
if (includes.call(options.properties, prop)) {
|
||||
properties |= value;
|
||||
}
|
||||
}
|
||||
if (options.title == null) {
|
||||
options.title = '';
|
||||
}
|
||||
if (options.defaultPath == null) {
|
||||
options.defaultPath = '';
|
||||
}
|
||||
if (options.filters == null) {
|
||||
options.filters = [];
|
||||
}
|
||||
wrappedCallback = typeof callback === 'function' ? function(success, result) {
|
||||
return callback(success ? result : void 0);
|
||||
} : null;
|
||||
return binding.showOpenDialog(String(options.title), String(options.defaultPath), options.filters, properties, window, wrappedCallback);
|
||||
},
|
||||
showSaveDialog: function() {
|
||||
var args, callback, options, ref1, window, wrappedCallback;
|
||||
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
|
||||
checkAppInitialized();
|
||||
ref1 = parseArgs.apply(null, args), window = ref1[0], options = ref1[1], callback = ref1[2];
|
||||
if (options == null) {
|
||||
options = {
|
||||
title: 'Save'
|
||||
};
|
||||
}
|
||||
if (options.title == null) {
|
||||
options.title = '';
|
||||
}
|
||||
if (options.defaultPath == null) {
|
||||
options.defaultPath = '';
|
||||
}
|
||||
if (options.filters == null) {
|
||||
options.filters = [];
|
||||
}
|
||||
wrappedCallback = typeof callback === 'function' ? function(success, result) {
|
||||
return callback(success ? result : void 0);
|
||||
} : null;
|
||||
return binding.showSaveDialog(String(options.title), String(options.defaultPath), options.filters, window, wrappedCallback);
|
||||
},
|
||||
showMessageBox: function() {
|
||||
var args, callback, flags, i, j, len, messageBoxType, options, ref1, ref2, ref3, text, window;
|
||||
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
|
||||
checkAppInitialized();
|
||||
ref1 = parseArgs.apply(null, args), window = ref1[0], options = ref1[1], callback = ref1[2];
|
||||
if (options == null) {
|
||||
options = {
|
||||
type: 'none'
|
||||
};
|
||||
}
|
||||
if (options.type == null) {
|
||||
options.type = 'none';
|
||||
}
|
||||
messageBoxType = messageBoxTypes.indexOf(options.type);
|
||||
if (!(messageBoxType > -1)) {
|
||||
throw new TypeError('Invalid message box type');
|
||||
}
|
||||
if (!Array.isArray(options.buttons)) {
|
||||
throw new TypeError('Buttons need to be array');
|
||||
}
|
||||
if (options.title == null) {
|
||||
options.title = '';
|
||||
}
|
||||
if (options.message == null) {
|
||||
options.message = '';
|
||||
}
|
||||
if (options.detail == null) {
|
||||
options.detail = '';
|
||||
}
|
||||
if (options.icon == null) {
|
||||
options.icon = null;
|
||||
}
|
||||
if (options.defaultId == null) {
|
||||
options.defaultId = -1;
|
||||
}
|
||||
|
||||
// Choose a default button to get selected when dialog is cancelled.
|
||||
if (options.cancelId == null) {
|
||||
options.cancelId = 0;
|
||||
ref2 = options.buttons;
|
||||
for (i = j = 0, len = ref2.length; j < len; i = ++j) {
|
||||
text = ref2[i];
|
||||
if ((ref3 = text.toLowerCase()) === 'cancel' || ref3 === 'no') {
|
||||
options.cancelId = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
flags = options.noLink ? messageBoxOptions.noLink : 0;
|
||||
return binding.showMessageBox(messageBoxType, options.buttons, options.defaultId, options.cancelId, flags, options.title, options.message, options.detail, options.icon, window, callback);
|
||||
},
|
||||
showErrorBox: function() {
|
||||
var args;
|
||||
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
|
||||
return binding.showErrorBox.apply(binding, args);
|
||||
}
|
||||
};
|
||||
|
||||
// Mark standard asynchronous functions.
|
||||
var ref1 = ['showMessageBox', 'showOpenDialog', 'showSaveDialog'];
|
||||
var j, len, api;
|
||||
for (j = 0, len = ref1.length; j < len; j++) {
|
||||
api = ref1[j];
|
||||
v8Util.setHiddenValue(module.exports[api], 'asynchronous', true);
|
||||
}
|
||||
55
atom/browser/api/lib/exports/electron.coffee
Normal file
55
atom/browser/api/lib/exports/electron.coffee
Normal file
@@ -0,0 +1,55 @@
|
||||
# Import common modules.
|
||||
module.exports = require '../../../../common/api/lib/exports/electron'
|
||||
|
||||
Object.defineProperties module.exports,
|
||||
# Browser side modules, please sort with alphabet order.
|
||||
app:
|
||||
enumerable: true
|
||||
get: -> require '../app'
|
||||
autoUpdater:
|
||||
enumerable: true
|
||||
get: -> require '../auto-updater'
|
||||
BrowserWindow:
|
||||
enumerable: true
|
||||
get: -> require '../browser-window'
|
||||
contentTracing:
|
||||
enumerable: true
|
||||
get: -> require '../content-tracing'
|
||||
dialog:
|
||||
enumerable: true
|
||||
get: -> require '../dialog'
|
||||
ipcMain:
|
||||
enumerable: true
|
||||
get: -> require '../ipc-main'
|
||||
globalShortcut:
|
||||
enumerable: true
|
||||
get: -> require '../global-shortcut'
|
||||
Menu:
|
||||
enumerable: true
|
||||
get: -> require '../menu'
|
||||
MenuItem:
|
||||
enumerable: true
|
||||
get: -> require '../menu-item'
|
||||
powerMonitor:
|
||||
enumerable: true
|
||||
get: -> require '../power-monitor'
|
||||
powerSaveBlocker:
|
||||
enumerable: true
|
||||
get: -> require '../power-save-blocker'
|
||||
protocol:
|
||||
enumerable: true
|
||||
get: -> require '../protocol'
|
||||
screen:
|
||||
enumerable: true
|
||||
get: -> require '../screen'
|
||||
session:
|
||||
enumerable: true
|
||||
get: -> require '../session'
|
||||
Tray:
|
||||
enumerable: true
|
||||
get: -> require '../tray'
|
||||
# The internal modules, invisible unless you know their names.
|
||||
NavigationController:
|
||||
get: -> require '../navigation-controller'
|
||||
webContents:
|
||||
get: -> require '../web-contents'
|
||||
@@ -1,112 +0,0 @@
|
||||
const common = require('../../../../common/api/lib/exports/electron');
|
||||
|
||||
|
||||
// Import common modules.
|
||||
common.defineProperties(exports);
|
||||
|
||||
Object.defineProperties(exports, {
|
||||
|
||||
// Browser side modules, please sort with alphabet order.
|
||||
app: {
|
||||
enumerable: true,
|
||||
get: function() {
|
||||
return require('../app');
|
||||
}
|
||||
},
|
||||
autoUpdater: {
|
||||
enumerable: true,
|
||||
get: function() {
|
||||
return require('../auto-updater');
|
||||
}
|
||||
},
|
||||
BrowserWindow: {
|
||||
enumerable: true,
|
||||
get: function() {
|
||||
return require('../browser-window');
|
||||
}
|
||||
},
|
||||
contentTracing: {
|
||||
enumerable: true,
|
||||
get: function() {
|
||||
return require('../content-tracing');
|
||||
}
|
||||
},
|
||||
dialog: {
|
||||
enumerable: true,
|
||||
get: function() {
|
||||
return require('../dialog');
|
||||
}
|
||||
},
|
||||
ipcMain: {
|
||||
enumerable: true,
|
||||
get: function() {
|
||||
return require('../ipc-main');
|
||||
}
|
||||
},
|
||||
globalShortcut: {
|
||||
enumerable: true,
|
||||
get: function() {
|
||||
return require('../global-shortcut');
|
||||
}
|
||||
},
|
||||
Menu: {
|
||||
enumerable: true,
|
||||
get: function() {
|
||||
return require('../menu');
|
||||
}
|
||||
},
|
||||
MenuItem: {
|
||||
enumerable: true,
|
||||
get: function() {
|
||||
return require('../menu-item');
|
||||
}
|
||||
},
|
||||
powerMonitor: {
|
||||
enumerable: true,
|
||||
get: function() {
|
||||
return require('../power-monitor');
|
||||
}
|
||||
},
|
||||
powerSaveBlocker: {
|
||||
enumerable: true,
|
||||
get: function() {
|
||||
return require('../power-save-blocker');
|
||||
}
|
||||
},
|
||||
protocol: {
|
||||
enumerable: true,
|
||||
get: function() {
|
||||
return require('../protocol');
|
||||
}
|
||||
},
|
||||
screen: {
|
||||
enumerable: true,
|
||||
get: function() {
|
||||
return require('../screen');
|
||||
}
|
||||
},
|
||||
session: {
|
||||
enumerable: true,
|
||||
get: function() {
|
||||
return require('../session');
|
||||
}
|
||||
},
|
||||
Tray: {
|
||||
enumerable: true,
|
||||
get: function() {
|
||||
return require('../tray');
|
||||
}
|
||||
},
|
||||
|
||||
// The internal modules, invisible unless you know their names.
|
||||
NavigationController: {
|
||||
get: function() {
|
||||
return require('../navigation-controller');
|
||||
}
|
||||
},
|
||||
webContents: {
|
||||
get: function() {
|
||||
return require('../web-contents');
|
||||
}
|
||||
}
|
||||
});
|
||||
3
atom/browser/api/lib/global-shortcut.coffee
Normal file
3
atom/browser/api/lib/global-shortcut.coffee
Normal file
@@ -0,0 +1,3 @@
|
||||
{globalShortcut} = process.atomBinding 'global_shortcut'
|
||||
|
||||
module.exports = globalShortcut
|
||||
@@ -1,5 +0,0 @@
|
||||
var globalShortcut;
|
||||
|
||||
globalShortcut = process.atomBinding('global_shortcut').globalShortcut;
|
||||
|
||||
module.exports = globalShortcut;
|
||||
3
atom/browser/api/lib/ipc-main.coffee
Normal file
3
atom/browser/api/lib/ipc-main.coffee
Normal file
@@ -0,0 +1,3 @@
|
||||
{EventEmitter} = require 'events'
|
||||
|
||||
module.exports = new EventEmitter
|
||||
@@ -1,3 +0,0 @@
|
||||
const EventEmitter = require('events').EventEmitter;
|
||||
|
||||
module.exports = new EventEmitter;
|
||||
6
atom/browser/api/lib/ipc.coffee
Normal file
6
atom/browser/api/lib/ipc.coffee
Normal file
@@ -0,0 +1,6 @@
|
||||
{deprecate, ipcMain} = require 'electron'
|
||||
|
||||
# This module is deprecated, we mirror everything from ipcMain.
|
||||
deprecate.warn 'ipc module', 'require("electron").ipcMain'
|
||||
|
||||
module.exports = ipcMain
|
||||
@@ -1,7 +0,0 @@
|
||||
const deprecate = require('electron').deprecate;
|
||||
const ipcMain = require('electron').ipcMain;
|
||||
|
||||
// This module is deprecated, we mirror everything from ipcMain.
|
||||
deprecate.warn('ipc module', 'require("electron").ipcMain');
|
||||
|
||||
module.exports = ipcMain;
|
||||
71
atom/browser/api/lib/menu-item.coffee
Normal file
71
atom/browser/api/lib/menu-item.coffee
Normal file
@@ -0,0 +1,71 @@
|
||||
v8Util = process.atomBinding 'v8_util'
|
||||
|
||||
nextCommandId = 0
|
||||
|
||||
# Maps role to methods of webContents
|
||||
rolesMap =
|
||||
undo: 'undo'
|
||||
redo: 'redo'
|
||||
cut: 'cut'
|
||||
copy: 'copy'
|
||||
paste: 'paste'
|
||||
selectall: 'selectAll'
|
||||
minimize: 'minimize'
|
||||
close: 'close'
|
||||
|
||||
# Maps methods that should be called directly on the BrowserWindow instance
|
||||
methodInBrowserWindow =
|
||||
minimize: true
|
||||
close: true
|
||||
|
||||
class MenuItem
|
||||
@types = ['normal', 'separator', 'submenu', 'checkbox', 'radio']
|
||||
|
||||
constructor: (options) ->
|
||||
{Menu} = require 'electron'
|
||||
|
||||
{click, @selector, @type, @role, @label, @sublabel, @accelerator, @icon, @enabled, @visible, @checked, @submenu} = options
|
||||
|
||||
@type = 'submenu' if not @type? and @submenu?
|
||||
throw new Error('Invalid submenu') if @type is 'submenu' and @submenu?.constructor isnt Menu
|
||||
|
||||
@overrideReadOnlyProperty 'type', 'normal'
|
||||
@overrideReadOnlyProperty 'role'
|
||||
@overrideReadOnlyProperty 'accelerator'
|
||||
@overrideReadOnlyProperty 'icon'
|
||||
@overrideReadOnlyProperty 'submenu'
|
||||
@overrideProperty 'label', ''
|
||||
@overrideProperty 'sublabel', ''
|
||||
@overrideProperty 'enabled', true
|
||||
@overrideProperty 'visible', true
|
||||
@overrideProperty 'checked', false
|
||||
|
||||
throw new Error("Unknown menu type #{@type}") if MenuItem.types.indexOf(@type) is -1
|
||||
|
||||
@commandId = ++nextCommandId
|
||||
@click = (focusedWindow) =>
|
||||
# Manually flip the checked flags when clicked.
|
||||
@checked = !@checked if @type in ['checkbox', 'radio']
|
||||
|
||||
if @role and rolesMap[@role] and process.platform isnt 'darwin' and focusedWindow?
|
||||
methodName = rolesMap[@role]
|
||||
if methodInBrowserWindow[methodName]
|
||||
focusedWindow[methodName]()
|
||||
else
|
||||
focusedWindow.webContents?[methodName]()
|
||||
else if typeof click is 'function'
|
||||
click this, focusedWindow
|
||||
else if typeof @selector is 'string'
|
||||
Menu.sendActionToFirstResponder @selector
|
||||
|
||||
overrideProperty: (name, defaultValue=null) ->
|
||||
this[name] ?= defaultValue
|
||||
|
||||
overrideReadOnlyProperty: (name, defaultValue=null) ->
|
||||
this[name] ?= defaultValue
|
||||
Object.defineProperty this, name,
|
||||
enumerable: true
|
||||
writable: false
|
||||
value: this[name]
|
||||
|
||||
module.exports = MenuItem
|
||||
@@ -1,102 +0,0 @@
|
||||
var MenuItem, methodInBrowserWindow, nextCommandId, rolesMap;
|
||||
|
||||
nextCommandId = 0;
|
||||
|
||||
// Maps role to methods of webContents
|
||||
rolesMap = {
|
||||
undo: 'undo',
|
||||
redo: 'redo',
|
||||
cut: 'cut',
|
||||
copy: 'copy',
|
||||
paste: 'paste',
|
||||
selectall: 'selectAll',
|
||||
minimize: 'minimize',
|
||||
close: 'close'
|
||||
};
|
||||
|
||||
// Maps methods that should be called directly on the BrowserWindow instance
|
||||
methodInBrowserWindow = {
|
||||
minimize: true,
|
||||
close: true
|
||||
};
|
||||
|
||||
MenuItem = (function() {
|
||||
MenuItem.types = ['normal', 'separator', 'submenu', 'checkbox', 'radio'];
|
||||
|
||||
function MenuItem(options) {
|
||||
var click, ref;
|
||||
const Menu = require('electron').Menu;
|
||||
click = options.click, this.selector = options.selector, this.type = options.type, this.role = options.role, this.label = options.label, this.sublabel = options.sublabel, this.accelerator = options.accelerator, this.icon = options.icon, this.enabled = options.enabled, this.visible = options.visible, this.checked = options.checked, this.submenu = options.submenu;
|
||||
if ((this.submenu != null) && this.submenu.constructor !== Menu) {
|
||||
this.submenu = Menu.buildFromTemplate(this.submenu);
|
||||
}
|
||||
if ((this.type == null) && (this.submenu != null)) {
|
||||
this.type = 'submenu';
|
||||
}
|
||||
if (this.type === 'submenu' && ((ref = this.submenu) != null ? ref.constructor : void 0) !== Menu) {
|
||||
throw new Error('Invalid submenu');
|
||||
}
|
||||
this.overrideReadOnlyProperty('type', 'normal');
|
||||
this.overrideReadOnlyProperty('role');
|
||||
this.overrideReadOnlyProperty('accelerator');
|
||||
this.overrideReadOnlyProperty('icon');
|
||||
this.overrideReadOnlyProperty('submenu');
|
||||
this.overrideProperty('label', '');
|
||||
this.overrideProperty('sublabel', '');
|
||||
this.overrideProperty('enabled', true);
|
||||
this.overrideProperty('visible', true);
|
||||
this.overrideProperty('checked', false);
|
||||
if (MenuItem.types.indexOf(this.type) === -1) {
|
||||
throw new Error("Unknown menu type " + this.type);
|
||||
}
|
||||
this.commandId = ++nextCommandId;
|
||||
this.click = (function(_this) {
|
||||
return function(focusedWindow) {
|
||||
|
||||
// Manually flip the checked flags when clicked.
|
||||
var methodName, ref1, ref2;
|
||||
if ((ref1 = _this.type) === 'checkbox' || ref1 === 'radio') {
|
||||
_this.checked = !_this.checked;
|
||||
}
|
||||
if (_this.role && rolesMap[_this.role] && process.platform !== 'darwin' && (focusedWindow != null)) {
|
||||
methodName = rolesMap[_this.role];
|
||||
if (methodInBrowserWindow[methodName]) {
|
||||
return focusedWindow[methodName]();
|
||||
} else {
|
||||
return (ref2 = focusedWindow.webContents) != null ? ref2[methodName]() : void 0;
|
||||
}
|
||||
} else if (typeof click === 'function') {
|
||||
return click(_this, focusedWindow);
|
||||
} else if (typeof _this.selector === 'string') {
|
||||
return Menu.sendActionToFirstResponder(_this.selector);
|
||||
}
|
||||
};
|
||||
})(this);
|
||||
}
|
||||
|
||||
MenuItem.prototype.overrideProperty = function(name, defaultValue) {
|
||||
if (defaultValue == null) {
|
||||
defaultValue = null;
|
||||
}
|
||||
return this[name] != null ? this[name] : this[name] = defaultValue;
|
||||
};
|
||||
|
||||
MenuItem.prototype.overrideReadOnlyProperty = function(name, defaultValue) {
|
||||
if (defaultValue == null) {
|
||||
defaultValue = null;
|
||||
}
|
||||
if (this[name] == null) {
|
||||
this[name] = defaultValue;
|
||||
}
|
||||
return Object.defineProperty(this, name, {
|
||||
enumerable: true,
|
||||
writable: false,
|
||||
value: this[name]
|
||||
});
|
||||
};
|
||||
|
||||
return MenuItem;
|
||||
|
||||
})();
|
||||
|
||||
module.exports = MenuItem;
|
||||
179
atom/browser/api/lib/menu.coffee
Normal file
179
atom/browser/api/lib/menu.coffee
Normal file
@@ -0,0 +1,179 @@
|
||||
{BrowserWindow, MenuItem} = require 'electron'
|
||||
{EventEmitter} = require 'events'
|
||||
|
||||
v8Util = process.atomBinding 'v8_util'
|
||||
bindings = process.atomBinding 'menu'
|
||||
|
||||
# Automatically generated radio menu item's group id.
|
||||
nextGroupId = 0
|
||||
|
||||
# Search between seperators to find a radio menu item and return its group id,
|
||||
# otherwise generate a group id.
|
||||
generateGroupId = (items, pos) ->
|
||||
if pos > 0
|
||||
for i in [pos - 1..0]
|
||||
item = items[i]
|
||||
return item.groupId if item.type is 'radio'
|
||||
break if item.type is 'separator'
|
||||
else if pos < items.length
|
||||
for i in [pos..items.length - 1]
|
||||
item = items[i]
|
||||
return item.groupId if item.type is 'radio'
|
||||
break if item.type is 'separator'
|
||||
++nextGroupId
|
||||
|
||||
# Returns the index of item according to |id|.
|
||||
indexOfItemById = (items, id) ->
|
||||
return i for item, i in items when item.id is id
|
||||
-1
|
||||
|
||||
# Returns the index of where to insert the item according to |position|.
|
||||
indexToInsertByPosition = (items, position) ->
|
||||
return items.length unless position
|
||||
|
||||
[query, id] = position.split '='
|
||||
insertIndex = indexOfItemById items, id
|
||||
if insertIndex is -1 and query isnt 'endof'
|
||||
console.warn "Item with id '#{id}' is not found"
|
||||
return items.length
|
||||
|
||||
switch query
|
||||
when 'after'
|
||||
insertIndex++
|
||||
when 'endof'
|
||||
# If the |id| doesn't exist, then create a new group with the |id|.
|
||||
if insertIndex is -1
|
||||
items.push id: id, type: 'separator'
|
||||
insertIndex = items.length - 1
|
||||
|
||||
# Find the end of the group.
|
||||
insertIndex++
|
||||
while insertIndex < items.length and items[insertIndex].type isnt 'separator'
|
||||
insertIndex++
|
||||
|
||||
insertIndex
|
||||
|
||||
Menu = bindings.Menu
|
||||
Menu::__proto__ = EventEmitter.prototype
|
||||
|
||||
Menu::_init = ->
|
||||
@commandsMap = {}
|
||||
@groupsMap = {}
|
||||
@items = []
|
||||
@delegate =
|
||||
isCommandIdChecked: (commandId) => @commandsMap[commandId]?.checked
|
||||
isCommandIdEnabled: (commandId) => @commandsMap[commandId]?.enabled
|
||||
isCommandIdVisible: (commandId) => @commandsMap[commandId]?.visible
|
||||
getAcceleratorForCommandId: (commandId) => @commandsMap[commandId]?.accelerator
|
||||
getIconForCommandId: (commandId) => @commandsMap[commandId]?.icon
|
||||
executeCommand: (commandId) =>
|
||||
@commandsMap[commandId]?.click BrowserWindow.getFocusedWindow()
|
||||
menuWillShow: =>
|
||||
# Make sure radio groups have at least one menu item seleted.
|
||||
for id, group of @groupsMap
|
||||
checked = false
|
||||
for radioItem in group when radioItem.checked
|
||||
checked = true
|
||||
break
|
||||
v8Util.setHiddenValue group[0], 'checked', true unless checked
|
||||
|
||||
Menu::popup = (window, x, y) ->
|
||||
unless window?.constructor is BrowserWindow
|
||||
# Shift.
|
||||
y = x
|
||||
x = window
|
||||
window = BrowserWindow.getFocusedWindow()
|
||||
if x? and y?
|
||||
@_popupAt(window, x, y)
|
||||
else
|
||||
@_popup window
|
||||
|
||||
Menu::append = (item) ->
|
||||
@insert @getItemCount(), item
|
||||
|
||||
Menu::insert = (pos, item) ->
|
||||
throw new TypeError('Invalid item') unless item?.constructor is MenuItem
|
||||
|
||||
switch item.type
|
||||
when 'normal' then @insertItem pos, item.commandId, item.label
|
||||
when 'checkbox' then @insertCheckItem pos, item.commandId, item.label
|
||||
when 'separator' then @insertSeparator pos
|
||||
when 'submenu' then @insertSubMenu pos, item.commandId, item.label, item.submenu
|
||||
when 'radio'
|
||||
# Grouping radio menu items.
|
||||
item.overrideReadOnlyProperty 'groupId', generateGroupId(@items, pos)
|
||||
@groupsMap[item.groupId] ?= []
|
||||
@groupsMap[item.groupId].push item
|
||||
|
||||
# Setting a radio menu item should flip other items in the group.
|
||||
v8Util.setHiddenValue item, 'checked', item.checked
|
||||
Object.defineProperty item, 'checked',
|
||||
enumerable: true
|
||||
get: -> v8Util.getHiddenValue item, 'checked'
|
||||
set: (val) =>
|
||||
for otherItem in @groupsMap[item.groupId] when otherItem isnt item
|
||||
v8Util.setHiddenValue otherItem, 'checked', false
|
||||
v8Util.setHiddenValue item, 'checked', true
|
||||
|
||||
@insertRadioItem pos, item.commandId, item.label, item.groupId
|
||||
|
||||
@setSublabel pos, item.sublabel if item.sublabel?
|
||||
@setIcon pos, item.icon if item.icon?
|
||||
@setRole pos, item.role if item.role?
|
||||
|
||||
# Make menu accessable to items.
|
||||
item.overrideReadOnlyProperty 'menu', this
|
||||
|
||||
# Remember the items.
|
||||
@items.splice pos, 0, item
|
||||
@commandsMap[item.commandId] = item
|
||||
|
||||
# Force menuWillShow to be called
|
||||
Menu::_callMenuWillShow = ->
|
||||
@delegate?.menuWillShow()
|
||||
item.submenu._callMenuWillShow() for item in @items when item.submenu?
|
||||
|
||||
applicationMenu = null
|
||||
Menu.setApplicationMenu = (menu) ->
|
||||
throw new TypeError('Invalid menu') unless menu is null or menu.constructor is Menu
|
||||
applicationMenu = menu # Keep a reference.
|
||||
|
||||
if process.platform is 'darwin'
|
||||
return if menu is null
|
||||
menu._callMenuWillShow()
|
||||
bindings.setApplicationMenu menu
|
||||
else
|
||||
windows = BrowserWindow.getAllWindows()
|
||||
w.setMenu menu for w in windows
|
||||
|
||||
Menu.getApplicationMenu = -> applicationMenu
|
||||
|
||||
Menu.sendActionToFirstResponder = bindings.sendActionToFirstResponder
|
||||
|
||||
Menu.buildFromTemplate = (template) ->
|
||||
throw new TypeError('Invalid template for Menu') unless Array.isArray template
|
||||
|
||||
positionedTemplate = []
|
||||
insertIndex = 0
|
||||
|
||||
for item in template
|
||||
if item.position
|
||||
insertIndex = indexToInsertByPosition positionedTemplate, item.position
|
||||
else
|
||||
# If no |position| is specified, insert after last item.
|
||||
insertIndex++
|
||||
positionedTemplate.splice insertIndex, 0, item
|
||||
|
||||
menu = new Menu
|
||||
|
||||
for item in positionedTemplate
|
||||
throw new TypeError('Invalid template for MenuItem') unless typeof item is 'object'
|
||||
|
||||
item.submenu = Menu.buildFromTemplate item.submenu if item.submenu?
|
||||
menuItem = new MenuItem(item)
|
||||
menuItem[key] = value for key, value of item when not menuItem[key]?
|
||||
menu.append menuItem
|
||||
|
||||
menu
|
||||
|
||||
module.exports = Menu
|
||||
@@ -1,335 +0,0 @@
|
||||
const BrowserWindow = require('electron').BrowserWindow;
|
||||
const MenuItem = require('electron').MenuItem;
|
||||
const EventEmitter = require('events').EventEmitter;
|
||||
const v8Util = process.atomBinding('v8_util');
|
||||
const bindings = process.atomBinding('menu');
|
||||
|
||||
// Automatically generated radio menu item's group id.
|
||||
var nextGroupId = 0;
|
||||
|
||||
// Search between seperators to find a radio menu item and return its group id,
|
||||
// otherwise generate a group id.
|
||||
var generateGroupId = function(items, pos) {
|
||||
var i, item, j, k, ref1, ref2, ref3;
|
||||
if (pos > 0) {
|
||||
for (i = j = ref1 = pos - 1; ref1 <= 0 ? j <= 0 : j >= 0; i = ref1 <= 0 ? ++j : --j) {
|
||||
item = items[i];
|
||||
if (item.type === 'radio') {
|
||||
return item.groupId;
|
||||
}
|
||||
if (item.type === 'separator') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (pos < items.length) {
|
||||
for (i = k = ref2 = pos, ref3 = items.length - 1; ref2 <= ref3 ? k <= ref3 : k >= ref3; i = ref2 <= ref3 ? ++k : --k) {
|
||||
item = items[i];
|
||||
if (item.type === 'radio') {
|
||||
return item.groupId;
|
||||
}
|
||||
if (item.type === 'separator') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ++nextGroupId;
|
||||
};
|
||||
|
||||
// Returns the index of item according to |id|.
|
||||
var indexOfItemById = function(items, id) {
|
||||
var i, item, j, len;
|
||||
for (i = j = 0, len = items.length; j < len; i = ++j) {
|
||||
item = items[i];
|
||||
if (item.id === id) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
|
||||
// Returns the index of where to insert the item according to |position|.
|
||||
var indexToInsertByPosition = function(items, position) {
|
||||
var id, insertIndex, query, ref1;
|
||||
if (!position) {
|
||||
return items.length;
|
||||
}
|
||||
ref1 = position.split('='), query = ref1[0], id = ref1[1];
|
||||
insertIndex = indexOfItemById(items, id);
|
||||
if (insertIndex === -1 && query !== 'endof') {
|
||||
console.warn("Item with id '" + id + "' is not found");
|
||||
return items.length;
|
||||
}
|
||||
switch (query) {
|
||||
case 'after':
|
||||
insertIndex++;
|
||||
break;
|
||||
case 'endof':
|
||||
|
||||
// If the |id| doesn't exist, then create a new group with the |id|.
|
||||
if (insertIndex === -1) {
|
||||
items.push({
|
||||
id: id,
|
||||
type: 'separator'
|
||||
});
|
||||
insertIndex = items.length - 1;
|
||||
}
|
||||
|
||||
// Find the end of the group.
|
||||
insertIndex++;
|
||||
while (insertIndex < items.length && items[insertIndex].type !== 'separator') {
|
||||
insertIndex++;
|
||||
}
|
||||
}
|
||||
return insertIndex;
|
||||
};
|
||||
|
||||
const Menu = bindings.Menu;
|
||||
|
||||
Menu.prototype.__proto__ = EventEmitter.prototype;
|
||||
|
||||
Menu.prototype._init = function() {
|
||||
this.commandsMap = {};
|
||||
this.groupsMap = {};
|
||||
this.items = [];
|
||||
return this.delegate = {
|
||||
isCommandIdChecked: (function(_this) {
|
||||
return function(commandId) {
|
||||
var ref1;
|
||||
return (ref1 = _this.commandsMap[commandId]) != null ? ref1.checked : void 0;
|
||||
};
|
||||
})(this),
|
||||
isCommandIdEnabled: (function(_this) {
|
||||
return function(commandId) {
|
||||
var ref1;
|
||||
return (ref1 = _this.commandsMap[commandId]) != null ? ref1.enabled : void 0;
|
||||
};
|
||||
})(this),
|
||||
isCommandIdVisible: (function(_this) {
|
||||
return function(commandId) {
|
||||
var ref1;
|
||||
return (ref1 = _this.commandsMap[commandId]) != null ? ref1.visible : void 0;
|
||||
};
|
||||
})(this),
|
||||
getAcceleratorForCommandId: (function(_this) {
|
||||
return function(commandId) {
|
||||
var ref1;
|
||||
return (ref1 = _this.commandsMap[commandId]) != null ? ref1.accelerator : void 0;
|
||||
};
|
||||
})(this),
|
||||
getIconForCommandId: (function(_this) {
|
||||
return function(commandId) {
|
||||
var ref1;
|
||||
return (ref1 = _this.commandsMap[commandId]) != null ? ref1.icon : void 0;
|
||||
};
|
||||
})(this),
|
||||
executeCommand: (function(_this) {
|
||||
return function(commandId) {
|
||||
var ref1;
|
||||
return (ref1 = _this.commandsMap[commandId]) != null ? ref1.click(BrowserWindow.getFocusedWindow()) : void 0;
|
||||
};
|
||||
})(this),
|
||||
menuWillShow: (function(_this) {
|
||||
return function() {
|
||||
|
||||
// Make sure radio groups have at least one menu item seleted.
|
||||
var checked, group, id, j, len, radioItem, ref1, results;
|
||||
ref1 = _this.groupsMap;
|
||||
results = [];
|
||||
for (id in ref1) {
|
||||
group = ref1[id];
|
||||
checked = false;
|
||||
for (j = 0, len = group.length; j < len; j++) {
|
||||
radioItem = group[j];
|
||||
if (!radioItem.checked) {
|
||||
continue;
|
||||
}
|
||||
checked = true;
|
||||
break;
|
||||
}
|
||||
if (!checked) {
|
||||
results.push(v8Util.setHiddenValue(group[0], 'checked', true));
|
||||
} else {
|
||||
results.push(void 0);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
};
|
||||
})(this)
|
||||
};
|
||||
};
|
||||
|
||||
Menu.prototype.popup = function(window, x, y, positioningItem) {
|
||||
if (typeof window != 'object' || window.constructor !== BrowserWindow) {
|
||||
// Shift.
|
||||
positioningItem = y;
|
||||
y = x;
|
||||
x = window;
|
||||
window = BrowserWindow.getFocusedWindow();
|
||||
}
|
||||
|
||||
// Default parameters.
|
||||
if (typeof x !== 'number') x = -1;
|
||||
if (typeof y !== 'number') y = -1;
|
||||
if (typeof positioningItem !== 'number') positioningItem = 0;
|
||||
|
||||
this.popupAt(window, x, y, positioningItem);
|
||||
};
|
||||
|
||||
Menu.prototype.append = function(item) {
|
||||
return this.insert(this.getItemCount(), item);
|
||||
};
|
||||
|
||||
Menu.prototype.insert = function(pos, item) {
|
||||
var base, name;
|
||||
if ((item != null ? item.constructor : void 0) !== MenuItem) {
|
||||
throw new TypeError('Invalid item');
|
||||
}
|
||||
switch (item.type) {
|
||||
case 'normal':
|
||||
this.insertItem(pos, item.commandId, item.label);
|
||||
break;
|
||||
case 'checkbox':
|
||||
this.insertCheckItem(pos, item.commandId, item.label);
|
||||
break;
|
||||
case 'separator':
|
||||
this.insertSeparator(pos);
|
||||
break;
|
||||
case 'submenu':
|
||||
this.insertSubMenu(pos, item.commandId, item.label, item.submenu);
|
||||
break;
|
||||
case 'radio':
|
||||
// Grouping radio menu items.
|
||||
item.overrideReadOnlyProperty('groupId', generateGroupId(this.items, pos));
|
||||
if ((base = this.groupsMap)[name = item.groupId] == null) {
|
||||
base[name] = [];
|
||||
}
|
||||
this.groupsMap[item.groupId].push(item);
|
||||
|
||||
// Setting a radio menu item should flip other items in the group.
|
||||
v8Util.setHiddenValue(item, 'checked', item.checked);
|
||||
Object.defineProperty(item, 'checked', {
|
||||
enumerable: true,
|
||||
get: function() {
|
||||
return v8Util.getHiddenValue(item, 'checked');
|
||||
},
|
||||
set: (function(_this) {
|
||||
return function() {
|
||||
var j, len, otherItem, ref1;
|
||||
ref1 = _this.groupsMap[item.groupId];
|
||||
for (j = 0, len = ref1.length; j < len; j++) {
|
||||
otherItem = ref1[j];
|
||||
if (otherItem !== item) {
|
||||
v8Util.setHiddenValue(otherItem, 'checked', false);
|
||||
}
|
||||
}
|
||||
return v8Util.setHiddenValue(item, 'checked', true);
|
||||
};
|
||||
})(this)
|
||||
});
|
||||
this.insertRadioItem(pos, item.commandId, item.label, item.groupId);
|
||||
}
|
||||
if (item.sublabel != null) {
|
||||
this.setSublabel(pos, item.sublabel);
|
||||
}
|
||||
if (item.icon != null) {
|
||||
this.setIcon(pos, item.icon);
|
||||
}
|
||||
if (item.role != null) {
|
||||
this.setRole(pos, item.role);
|
||||
}
|
||||
|
||||
// Make menu accessable to items.
|
||||
item.overrideReadOnlyProperty('menu', this);
|
||||
|
||||
// Remember the items.
|
||||
this.items.splice(pos, 0, item);
|
||||
return this.commandsMap[item.commandId] = item;
|
||||
};
|
||||
|
||||
|
||||
// Force menuWillShow to be called
|
||||
Menu.prototype._callMenuWillShow = function() {
|
||||
var item, j, len, ref1, ref2, results;
|
||||
if ((ref1 = this.delegate) != null) {
|
||||
ref1.menuWillShow();
|
||||
}
|
||||
ref2 = this.items;
|
||||
results = [];
|
||||
for (j = 0, len = ref2.length; j < len; j++) {
|
||||
item = ref2[j];
|
||||
if (item.submenu != null) {
|
||||
results.push(item.submenu._callMenuWillShow());
|
||||
}
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
var applicationMenu = null;
|
||||
|
||||
Menu.setApplicationMenu = function(menu) {
|
||||
var j, len, results, w, windows;
|
||||
if (!(menu === null || menu.constructor === Menu)) {
|
||||
throw new TypeError('Invalid menu');
|
||||
}
|
||||
|
||||
// Keep a reference.
|
||||
applicationMenu = menu;
|
||||
if (process.platform === 'darwin') {
|
||||
if (menu === null) {
|
||||
return;
|
||||
}
|
||||
menu._callMenuWillShow();
|
||||
return bindings.setApplicationMenu(menu);
|
||||
} else {
|
||||
windows = BrowserWindow.getAllWindows();
|
||||
results = [];
|
||||
for (j = 0, len = windows.length; j < len; j++) {
|
||||
w = windows[j];
|
||||
results.push(w.setMenu(menu));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
};
|
||||
|
||||
Menu.getApplicationMenu = function() {
|
||||
return applicationMenu;
|
||||
};
|
||||
|
||||
Menu.sendActionToFirstResponder = bindings.sendActionToFirstResponder;
|
||||
|
||||
Menu.buildFromTemplate = function(template) {
|
||||
var insertIndex, item, j, k, key, len, len1, menu, menuItem, positionedTemplate, value;
|
||||
if (!Array.isArray(template)) {
|
||||
throw new TypeError('Invalid template for Menu');
|
||||
}
|
||||
positionedTemplate = [];
|
||||
insertIndex = 0;
|
||||
for (j = 0, len = template.length; j < len; j++) {
|
||||
item = template[j];
|
||||
if (item.position) {
|
||||
insertIndex = indexToInsertByPosition(positionedTemplate, item.position);
|
||||
} else {
|
||||
// If no |position| is specified, insert after last item.
|
||||
insertIndex++;
|
||||
}
|
||||
positionedTemplate.splice(insertIndex, 0, item);
|
||||
}
|
||||
menu = new Menu;
|
||||
for (k = 0, len1 = positionedTemplate.length; k < len1; k++) {
|
||||
item = positionedTemplate[k];
|
||||
if (typeof item !== 'object') {
|
||||
throw new TypeError('Invalid template for MenuItem');
|
||||
}
|
||||
menuItem = new MenuItem(item);
|
||||
for (key in item) {
|
||||
value = item[key];
|
||||
if (menuItem[key] == null) {
|
||||
menuItem[key] = value;
|
||||
}
|
||||
}
|
||||
menu.append(menuItem);
|
||||
}
|
||||
return menu;
|
||||
};
|
||||
|
||||
module.exports = Menu;
|
||||
122
atom/browser/api/lib/navigation-controller.coffee
Normal file
122
atom/browser/api/lib/navigation-controller.coffee
Normal file
@@ -0,0 +1,122 @@
|
||||
{ipcMain} = require 'electron'
|
||||
|
||||
# The history operation in renderer is redirected to browser.
|
||||
ipcMain.on 'ATOM_SHELL_NAVIGATION_CONTROLLER', (event, method, args...) ->
|
||||
event.sender[method] args...
|
||||
|
||||
ipcMain.on 'ATOM_SHELL_SYNC_NAVIGATION_CONTROLLER', (event, method, args...) ->
|
||||
event.returnValue = event.sender[method] args...
|
||||
|
||||
# JavaScript implementation of Chromium's NavigationController.
|
||||
# Instead of relying on Chromium for history control, we compeletely do history
|
||||
# control on user land, and only rely on WebContents.loadURL for navigation.
|
||||
# This helps us avoid Chromium's various optimizations so we can ensure renderer
|
||||
# process is restarted everytime.
|
||||
class NavigationController
|
||||
constructor: (@webContents) ->
|
||||
@clearHistory()
|
||||
|
||||
# webContents may have already navigated to a page.
|
||||
if @webContents._getURL()
|
||||
@currentIndex++
|
||||
@history.push @webContents._getURL()
|
||||
|
||||
@webContents.on 'navigation-entry-commited', (event, url, inPage, replaceEntry) =>
|
||||
if @inPageIndex > -1 and not inPage
|
||||
# Navigated to a new page, clear in-page mark.
|
||||
@inPageIndex = -1
|
||||
else if @inPageIndex is -1 and inPage
|
||||
# Started in-page navigations.
|
||||
@inPageIndex = @currentIndex
|
||||
|
||||
if @pendingIndex >= 0 # Go to index.
|
||||
@currentIndex = @pendingIndex
|
||||
@pendingIndex = -1
|
||||
@history[@currentIndex] = url
|
||||
else if replaceEntry # Non-user initialized navigation.
|
||||
@history[@currentIndex] = url
|
||||
else # Normal navigation.
|
||||
@history = @history.slice 0, @currentIndex + 1 # Clear history.
|
||||
currentEntry = @history[@currentIndex]
|
||||
if currentEntry?.url isnt url
|
||||
@currentIndex++
|
||||
@history.push url
|
||||
|
||||
loadURL: (url, options={}) ->
|
||||
@pendingIndex = -1
|
||||
@webContents._loadURL url, options
|
||||
@webContents.emit 'load-url', url, options
|
||||
|
||||
getURL: ->
|
||||
if @currentIndex is -1
|
||||
''
|
||||
else
|
||||
@history[@currentIndex]
|
||||
|
||||
stop: ->
|
||||
@pendingIndex = -1
|
||||
@webContents._stop()
|
||||
|
||||
reload: ->
|
||||
@pendingIndex = @currentIndex
|
||||
@webContents._loadURL @getURL(), {}
|
||||
|
||||
reloadIgnoringCache: ->
|
||||
@pendingIndex = @currentIndex
|
||||
@webContents._loadURL @getURL(), {extraHeaders: "pragma: no-cache\n"}
|
||||
|
||||
canGoBack: ->
|
||||
@getActiveIndex() > 0
|
||||
|
||||
canGoForward: ->
|
||||
@getActiveIndex() < @history.length - 1
|
||||
|
||||
canGoToIndex: (index) ->
|
||||
index >=0 and index < @history.length
|
||||
|
||||
canGoToOffset: (offset) ->
|
||||
@canGoToIndex @currentIndex + offset
|
||||
|
||||
clearHistory: ->
|
||||
@history = []
|
||||
@currentIndex = -1
|
||||
@pendingIndex = -1
|
||||
@inPageIndex = -1
|
||||
|
||||
goBack: ->
|
||||
return unless @canGoBack()
|
||||
@pendingIndex = @getActiveIndex() - 1
|
||||
if @inPageIndex > -1 and @pendingIndex >= @inPageIndex
|
||||
@webContents._goBack()
|
||||
else
|
||||
@webContents._loadURL @history[@pendingIndex], {}
|
||||
|
||||
goForward: ->
|
||||
return unless @canGoForward()
|
||||
@pendingIndex = @getActiveIndex() + 1
|
||||
if @inPageIndex > -1 and @pendingIndex >= @inPageIndex
|
||||
@webContents._goForward()
|
||||
else
|
||||
@webContents._loadURL @history[@pendingIndex], {}
|
||||
|
||||
goToIndex: (index) ->
|
||||
return unless @canGoToIndex index
|
||||
@pendingIndex = index
|
||||
@webContents._loadURL @history[@pendingIndex], {}
|
||||
|
||||
goToOffset: (offset) ->
|
||||
return unless @canGoToOffset offset
|
||||
pendingIndex = @currentIndex + offset
|
||||
if @inPageIndex > -1 and pendingIndex >= @inPageIndex
|
||||
@pendingIndex = pendingIndex
|
||||
@webContents._goToOffset offset
|
||||
else
|
||||
@goToIndex pendingIndex
|
||||
|
||||
getActiveIndex: ->
|
||||
if @pendingIndex is -1 then @currentIndex else @pendingIndex
|
||||
|
||||
length: ->
|
||||
@history.length
|
||||
|
||||
module.exports = NavigationController
|
||||
@@ -1,188 +0,0 @@
|
||||
const ipcMain = require('electron').ipcMain;
|
||||
|
||||
var slice = [].slice;
|
||||
|
||||
// The history operation in renderer is redirected to browser.
|
||||
ipcMain.on('ATOM_SHELL_NAVIGATION_CONTROLLER', function() {
|
||||
var args, event, method, ref;
|
||||
event = arguments[0], method = arguments[1], args = 3 <= arguments.length ? slice.call(arguments, 2) : [];
|
||||
return (ref = event.sender)[method].apply(ref, args);
|
||||
});
|
||||
|
||||
ipcMain.on('ATOM_SHELL_SYNC_NAVIGATION_CONTROLLER', function() {
|
||||
var args, event, method, ref;
|
||||
event = arguments[0], method = arguments[1], args = 3 <= arguments.length ? slice.call(arguments, 2) : [];
|
||||
return event.returnValue = (ref = event.sender)[method].apply(ref, args);
|
||||
});
|
||||
|
||||
// JavaScript implementation of Chromium's NavigationController.
|
||||
// Instead of relying on Chromium for history control, we compeletely do history
|
||||
// control on user land, and only rely on WebContents.loadURL for navigation.
|
||||
// This helps us avoid Chromium's various optimizations so we can ensure renderer
|
||||
// process is restarted everytime.
|
||||
var NavigationController = (function() {
|
||||
function NavigationController(webContents) {
|
||||
this.webContents = webContents;
|
||||
this.clearHistory();
|
||||
|
||||
// webContents may have already navigated to a page.
|
||||
if (this.webContents._getURL()) {
|
||||
this.currentIndex++;
|
||||
this.history.push(this.webContents._getURL());
|
||||
}
|
||||
this.webContents.on('navigation-entry-commited', (function(_this) {
|
||||
return function(event, url, inPage, replaceEntry) {
|
||||
var currentEntry;
|
||||
if (_this.inPageIndex > -1 && !inPage) {
|
||||
|
||||
// Navigated to a new page, clear in-page mark.
|
||||
_this.inPageIndex = -1;
|
||||
} else if (_this.inPageIndex === -1 && inPage) {
|
||||
|
||||
// Started in-page navigations.
|
||||
_this.inPageIndex = _this.currentIndex;
|
||||
}
|
||||
if (_this.pendingIndex >= 0) {
|
||||
|
||||
// Go to index.
|
||||
_this.currentIndex = _this.pendingIndex;
|
||||
_this.pendingIndex = -1;
|
||||
return _this.history[_this.currentIndex] = url;
|
||||
} else if (replaceEntry) {
|
||||
|
||||
// Non-user initialized navigation.
|
||||
return _this.history[_this.currentIndex] = url;
|
||||
} else {
|
||||
|
||||
// Normal navigation. Clear history.
|
||||
_this.history = _this.history.slice(0, _this.currentIndex + 1);
|
||||
currentEntry = _this.history[_this.currentIndex];
|
||||
if ((currentEntry != null ? currentEntry.url : void 0) !== url) {
|
||||
_this.currentIndex++;
|
||||
return _this.history.push(url);
|
||||
}
|
||||
}
|
||||
};
|
||||
})(this));
|
||||
}
|
||||
|
||||
NavigationController.prototype.loadURL = function(url, options) {
|
||||
if (options == null) {
|
||||
options = {};
|
||||
}
|
||||
this.pendingIndex = -1;
|
||||
this.webContents._loadURL(url, options);
|
||||
return this.webContents.emit('load-url', url, options);
|
||||
};
|
||||
|
||||
NavigationController.prototype.getURL = function() {
|
||||
if (this.currentIndex === -1) {
|
||||
return '';
|
||||
} else {
|
||||
return this.history[this.currentIndex];
|
||||
}
|
||||
};
|
||||
|
||||
NavigationController.prototype.stop = function() {
|
||||
this.pendingIndex = -1;
|
||||
return this.webContents._stop();
|
||||
};
|
||||
|
||||
NavigationController.prototype.reload = function() {
|
||||
this.pendingIndex = this.currentIndex;
|
||||
return this.webContents._loadURL(this.getURL(), {});
|
||||
};
|
||||
|
||||
NavigationController.prototype.reloadIgnoringCache = function() {
|
||||
this.pendingIndex = this.currentIndex;
|
||||
return this.webContents._loadURL(this.getURL(), {
|
||||
extraHeaders: "pragma: no-cache\n"
|
||||
});
|
||||
};
|
||||
|
||||
NavigationController.prototype.canGoBack = function() {
|
||||
return this.getActiveIndex() > 0;
|
||||
};
|
||||
|
||||
NavigationController.prototype.canGoForward = function() {
|
||||
return this.getActiveIndex() < this.history.length - 1;
|
||||
};
|
||||
|
||||
NavigationController.prototype.canGoToIndex = function(index) {
|
||||
return index >= 0 && index < this.history.length;
|
||||
};
|
||||
|
||||
NavigationController.prototype.canGoToOffset = function(offset) {
|
||||
return this.canGoToIndex(this.currentIndex + offset);
|
||||
};
|
||||
|
||||
NavigationController.prototype.clearHistory = function() {
|
||||
this.history = [];
|
||||
this.currentIndex = -1;
|
||||
this.pendingIndex = -1;
|
||||
return this.inPageIndex = -1;
|
||||
};
|
||||
|
||||
NavigationController.prototype.goBack = function() {
|
||||
if (!this.canGoBack()) {
|
||||
return;
|
||||
}
|
||||
this.pendingIndex = this.getActiveIndex() - 1;
|
||||
if (this.inPageIndex > -1 && this.pendingIndex >= this.inPageIndex) {
|
||||
return this.webContents._goBack();
|
||||
} else {
|
||||
return this.webContents._loadURL(this.history[this.pendingIndex], {});
|
||||
}
|
||||
};
|
||||
|
||||
NavigationController.prototype.goForward = function() {
|
||||
if (!this.canGoForward()) {
|
||||
return;
|
||||
}
|
||||
this.pendingIndex = this.getActiveIndex() + 1;
|
||||
if (this.inPageIndex > -1 && this.pendingIndex >= this.inPageIndex) {
|
||||
return this.webContents._goForward();
|
||||
} else {
|
||||
return this.webContents._loadURL(this.history[this.pendingIndex], {});
|
||||
}
|
||||
};
|
||||
|
||||
NavigationController.prototype.goToIndex = function(index) {
|
||||
if (!this.canGoToIndex(index)) {
|
||||
return;
|
||||
}
|
||||
this.pendingIndex = index;
|
||||
return this.webContents._loadURL(this.history[this.pendingIndex], {});
|
||||
};
|
||||
|
||||
NavigationController.prototype.goToOffset = function(offset) {
|
||||
var pendingIndex;
|
||||
if (!this.canGoToOffset(offset)) {
|
||||
return;
|
||||
}
|
||||
pendingIndex = this.currentIndex + offset;
|
||||
if (this.inPageIndex > -1 && pendingIndex >= this.inPageIndex) {
|
||||
this.pendingIndex = pendingIndex;
|
||||
return this.webContents._goToOffset(offset);
|
||||
} else {
|
||||
return this.goToIndex(pendingIndex);
|
||||
}
|
||||
};
|
||||
|
||||
NavigationController.prototype.getActiveIndex = function() {
|
||||
if (this.pendingIndex === -1) {
|
||||
return this.currentIndex;
|
||||
} else {
|
||||
return this.pendingIndex;
|
||||
}
|
||||
};
|
||||
|
||||
NavigationController.prototype.length = function() {
|
||||
return this.history.length;
|
||||
};
|
||||
|
||||
return NavigationController;
|
||||
|
||||
})();
|
||||
|
||||
module.exports = NavigationController;
|
||||
7
atom/browser/api/lib/power-monitor.coffee
Normal file
7
atom/browser/api/lib/power-monitor.coffee
Normal file
@@ -0,0 +1,7 @@
|
||||
{EventEmitter} = require 'events'
|
||||
|
||||
{powerMonitor} = process.atomBinding 'power_monitor'
|
||||
|
||||
powerMonitor.__proto__ = EventEmitter.prototype
|
||||
|
||||
module.exports = powerMonitor
|
||||
@@ -1,6 +0,0 @@
|
||||
const EventEmitter = require('events').EventEmitter;
|
||||
const powerMonitor = process.atomBinding('power_monitor').powerMonitor;
|
||||
|
||||
powerMonitor.__proto__ = EventEmitter.prototype;
|
||||
|
||||
module.exports = powerMonitor;
|
||||
3
atom/browser/api/lib/power-save-blocker.coffee
Normal file
3
atom/browser/api/lib/power-save-blocker.coffee
Normal file
@@ -0,0 +1,3 @@
|
||||
{powerSaveBlocker} = process.atomBinding 'power_save_blocker'
|
||||
|
||||
module.exports = powerSaveBlocker
|
||||
@@ -1,5 +0,0 @@
|
||||
var powerSaveBlocker;
|
||||
|
||||
powerSaveBlocker = process.atomBinding('power_save_blocker').powerSaveBlocker;
|
||||
|
||||
module.exports = powerSaveBlocker;
|
||||
25
atom/browser/api/lib/protocol.coffee
Normal file
25
atom/browser/api/lib/protocol.coffee
Normal file
@@ -0,0 +1,25 @@
|
||||
{app} = require 'electron'
|
||||
|
||||
throw new Error('Can not initialize protocol module before app is ready') unless app.isReady()
|
||||
|
||||
{protocol} = process.atomBinding 'protocol'
|
||||
|
||||
# Warn about removed APIs.
|
||||
logAndThrow = (callback, message) ->
|
||||
console.error message
|
||||
if callback then callback(new Error(message)) else throw new Error(message)
|
||||
protocol.registerProtocol = (scheme, handler, callback) ->
|
||||
logAndThrow callback,
|
||||
'registerProtocol API has been replaced by the
|
||||
register[File/Http/Buffer/String]Protocol API family, please
|
||||
switch to the new APIs.'
|
||||
protocol.isHandledProtocol = (scheme, callback) ->
|
||||
logAndThrow callback,
|
||||
'isHandledProtocol API has been replaced by isProtocolHandled.'
|
||||
protocol.interceptProtocol = (scheme, handler, callback) ->
|
||||
logAndThrow callback,
|
||||
'interceptProtocol API has been replaced by the
|
||||
intercept[File/Http/Buffer/String]Protocol API family, please
|
||||
switch to the new APIs.'
|
||||
|
||||
module.exports = protocol
|
||||
@@ -1,31 +0,0 @@
|
||||
const app = require('electron').app;
|
||||
|
||||
if (!app.isReady()) {
|
||||
throw new Error('Can not initialize protocol module before app is ready');
|
||||
}
|
||||
|
||||
const protocol = process.atomBinding('protocol').protocol;
|
||||
|
||||
// Warn about removed APIs.
|
||||
var logAndThrow = function(callback, message) {
|
||||
console.error(message);
|
||||
if (callback) {
|
||||
return callback(new Error(message));
|
||||
} else {
|
||||
throw new Error(message);
|
||||
}
|
||||
};
|
||||
|
||||
protocol.registerProtocol = function(scheme, handler, callback) {
|
||||
return logAndThrow(callback, 'registerProtocol API has been replaced by the register[File/Http/Buffer/String]Protocol API family, please switch to the new APIs.');
|
||||
};
|
||||
|
||||
protocol.isHandledProtocol = function(scheme, callback) {
|
||||
return logAndThrow(callback, 'isHandledProtocol API has been replaced by isProtocolHandled.');
|
||||
};
|
||||
|
||||
protocol.interceptProtocol = function(scheme, handler, callback) {
|
||||
return logAndThrow(callback, 'interceptProtocol API has been replaced by the intercept[File/Http/Buffer/String]Protocol API family, please switch to the new APIs.');
|
||||
};
|
||||
|
||||
module.exports = protocol;
|
||||
6
atom/browser/api/lib/screen.coffee
Normal file
6
atom/browser/api/lib/screen.coffee
Normal file
@@ -0,0 +1,6 @@
|
||||
{EventEmitter} = require 'events'
|
||||
{screen} = process.atomBinding 'screen'
|
||||
|
||||
screen.__proto__ = EventEmitter.prototype
|
||||
|
||||
module.exports = screen
|
||||
@@ -1,6 +0,0 @@
|
||||
const EventEmitter = require('events').EventEmitter;
|
||||
const screen = process.atomBinding('screen').screen;
|
||||
|
||||
screen.__proto__ = EventEmitter.prototype;
|
||||
|
||||
module.exports = screen;
|
||||
23
atom/browser/api/lib/session.coffee
Normal file
23
atom/browser/api/lib/session.coffee
Normal file
@@ -0,0 +1,23 @@
|
||||
{EventEmitter} = require 'events'
|
||||
|
||||
bindings = process.atomBinding 'session'
|
||||
|
||||
PERSIST_PERFIX = 'persist:'
|
||||
|
||||
# Returns the Session from |partition| string.
|
||||
exports.fromPartition = (partition='') ->
|
||||
if partition.startsWith PERSIST_PERFIX
|
||||
bindings.fromPartition partition.substr(PERSIST_PERFIX.length), false
|
||||
else
|
||||
bindings.fromPartition partition, true
|
||||
|
||||
# Returns the default session.
|
||||
Object.defineProperty exports, 'defaultSession',
|
||||
enumerable: true
|
||||
get: -> exports.fromPartition ''
|
||||
|
||||
wrapSession = (session) ->
|
||||
# session is an EventEmitter.
|
||||
session.__proto__ = EventEmitter.prototype
|
||||
|
||||
bindings._setWrapSession wrapSession
|
||||
@@ -1,33 +0,0 @@
|
||||
const EventEmitter = require('events').EventEmitter;
|
||||
const bindings = process.atomBinding('session');
|
||||
const PERSIST_PERFIX = 'persist:';
|
||||
|
||||
// Returns the Session from |partition| string.
|
||||
exports.fromPartition = function(partition) {
|
||||
if (partition == null) {
|
||||
partition = '';
|
||||
}
|
||||
if (partition === '') {
|
||||
return exports.defaultSession;
|
||||
}
|
||||
if (partition.startsWith(PERSIST_PERFIX)) {
|
||||
return bindings.fromPartition(partition.substr(PERSIST_PERFIX.length), false);
|
||||
} else {
|
||||
return bindings.fromPartition(partition, true);
|
||||
}
|
||||
};
|
||||
|
||||
// Returns the default session.
|
||||
Object.defineProperty(exports, 'defaultSession', {
|
||||
enumerable: true,
|
||||
get: function() {
|
||||
return bindings.fromPartition('', false);
|
||||
}
|
||||
});
|
||||
|
||||
var wrapSession = function(session) {
|
||||
// session is an EventEmitter.
|
||||
return session.__proto__ = EventEmitter.prototype;
|
||||
};
|
||||
|
||||
bindings._setWrapSession(wrapSession);
|
||||
19
atom/browser/api/lib/tray.coffee
Normal file
19
atom/browser/api/lib/tray.coffee
Normal file
@@ -0,0 +1,19 @@
|
||||
{deprecate} = require 'electron'
|
||||
{EventEmitter} = require 'events'
|
||||
|
||||
{Tray} = process.atomBinding 'tray'
|
||||
Tray::__proto__ = EventEmitter.prototype
|
||||
|
||||
Tray::_init = ->
|
||||
# Deprecated.
|
||||
deprecate.rename this, 'popContextMenu', 'popUpContextMenu'
|
||||
deprecate.event this, 'clicked', 'click'
|
||||
deprecate.event this, 'double-clicked', 'double-click'
|
||||
deprecate.event this, 'right-clicked', 'right-click'
|
||||
deprecate.event this, 'balloon-clicked', 'balloon-click'
|
||||
|
||||
Tray::setContextMenu = (menu) ->
|
||||
@_setContextMenu menu
|
||||
@menu = menu # Keep a strong reference of menu.
|
||||
|
||||
module.exports = Tray
|
||||
@@ -1,23 +0,0 @@
|
||||
const deprecate = require('electron').deprecate;
|
||||
const EventEmitter = require('events').EventEmitter;
|
||||
const Tray = process.atomBinding('tray').Tray;
|
||||
|
||||
Tray.prototype.__proto__ = EventEmitter.prototype;
|
||||
|
||||
Tray.prototype._init = function() {
|
||||
// Deprecated.
|
||||
deprecate.rename(this, 'popContextMenu', 'popUpContextMenu');
|
||||
deprecate.event(this, 'clicked', 'click');
|
||||
deprecate.event(this, 'double-clicked', 'double-click');
|
||||
deprecate.event(this, 'right-clicked', 'right-click');
|
||||
return deprecate.event(this, 'balloon-clicked', 'balloon-click');
|
||||
};
|
||||
|
||||
Tray.prototype.setContextMenu = function(menu) {
|
||||
this._setContextMenu(menu);
|
||||
|
||||
// Keep a strong reference of menu.
|
||||
return this.menu = menu;
|
||||
};
|
||||
|
||||
module.exports = Tray;
|
||||
132
atom/browser/api/lib/web-contents.coffee
Normal file
132
atom/browser/api/lib/web-contents.coffee
Normal file
@@ -0,0 +1,132 @@
|
||||
{EventEmitter} = require 'events'
|
||||
{deprecate, ipcMain, session, NavigationController, Menu} = require 'electron'
|
||||
|
||||
binding = process.atomBinding 'web_contents'
|
||||
|
||||
nextId = 0
|
||||
getNextId = -> ++nextId
|
||||
|
||||
PDFPageSize =
|
||||
A4:
|
||||
custom_display_name: "A4"
|
||||
height_microns: 297000
|
||||
name: "ISO_A4"
|
||||
is_default: "true"
|
||||
width_microns: 210000
|
||||
A3:
|
||||
custom_display_name: "A3"
|
||||
height_microns: 420000
|
||||
name: "ISO_A3"
|
||||
width_microns: 297000
|
||||
Legal:
|
||||
custom_display_name: "Legal"
|
||||
height_microns: 355600
|
||||
name: "NA_LEGAL"
|
||||
width_microns: 215900
|
||||
Letter:
|
||||
custom_display_name: "Letter"
|
||||
height_microns: 279400
|
||||
name: "NA_LETTER"
|
||||
width_microns: 215900
|
||||
Tabloid:
|
||||
height_microns: 431800
|
||||
name: "NA_LEDGER"
|
||||
width_microns: 279400
|
||||
custom_display_name: "Tabloid"
|
||||
|
||||
wrapWebContents = (webContents) ->
|
||||
# webContents is an EventEmitter.
|
||||
webContents.__proto__ = EventEmitter.prototype
|
||||
|
||||
# WebContents::send(channel, args..)
|
||||
webContents.send = (channel, args...) ->
|
||||
@_send channel, [args...]
|
||||
|
||||
# Make sure webContents.executeJavaScript would run the code only when the
|
||||
# web contents has been loaded.
|
||||
webContents.executeJavaScript = (code, hasUserGesture=false) ->
|
||||
if @getURL() and not @isLoading()
|
||||
@_executeJavaScript code, hasUserGesture
|
||||
else
|
||||
webContents.once 'did-finish-load', @_executeJavaScript.bind(this, code, hasUserGesture)
|
||||
|
||||
# The navigation controller.
|
||||
controller = new NavigationController(webContents)
|
||||
for name, method of NavigationController.prototype when method instanceof Function
|
||||
do (name, method) ->
|
||||
webContents[name] = -> method.apply controller, arguments
|
||||
|
||||
# Dispatch IPC messages to the ipc module.
|
||||
webContents.on 'ipc-message', (event, packed) ->
|
||||
[channel, args...] = packed
|
||||
ipcMain.emit channel, event, args...
|
||||
webContents.on 'ipc-message-sync', (event, packed) ->
|
||||
[channel, args...] = packed
|
||||
Object.defineProperty event, 'returnValue', set: (value) -> event.sendReply JSON.stringify(value)
|
||||
ipcMain.emit channel, event, args...
|
||||
|
||||
# Handle context menu action request from pepper plugin.
|
||||
webContents.on 'pepper-context-menu', (event, params) ->
|
||||
menu = Menu.buildFromTemplate params.menu
|
||||
menu.popup params.x, params.y
|
||||
|
||||
# This error occurs when host could not be found.
|
||||
webContents.on 'did-fail-provisional-load', (args...) ->
|
||||
# Calling loadURL during this event might cause crash, so delay the event
|
||||
# until next tick.
|
||||
setImmediate => @emit 'did-fail-load', args...
|
||||
|
||||
# Delays the page-title-updated event to next tick.
|
||||
webContents.on '-page-title-updated', (args...) ->
|
||||
setImmediate => @emit 'page-title-updated', args...
|
||||
|
||||
# Deprecated.
|
||||
deprecate.rename webContents, 'loadUrl', 'loadURL'
|
||||
deprecate.rename webContents, 'getUrl', 'getURL'
|
||||
deprecate.event webContents, 'page-title-set', 'page-title-updated', (args...) ->
|
||||
@emit 'page-title-set', args...
|
||||
|
||||
webContents.printToPDF = (options, callback) ->
|
||||
printingSetting =
|
||||
pageRage: []
|
||||
mediaSize: {}
|
||||
landscape: false
|
||||
color: 2
|
||||
headerFooterEnabled: false
|
||||
marginsType: 0
|
||||
isFirstRequest: false
|
||||
requestID: getNextId()
|
||||
previewModifiable: true
|
||||
printToPDF: true
|
||||
printWithCloudPrint: false
|
||||
printWithPrivet: false
|
||||
printWithExtension: false
|
||||
deviceName: "Save as PDF"
|
||||
generateDraftData: true
|
||||
fitToPageEnabled: false
|
||||
duplex: 0
|
||||
copies: 1
|
||||
collate: true
|
||||
shouldPrintBackgrounds: false
|
||||
shouldPrintSelectionOnly: false
|
||||
|
||||
if options.landscape
|
||||
printingSetting.landscape = options.landscape
|
||||
if options.marginsType
|
||||
printingSetting.marginsType = options.marginsType
|
||||
if options.printSelectionOnly
|
||||
printingSetting.shouldPrintSelectionOnly = options.printSelectionOnly
|
||||
if options.printBackground
|
||||
printingSetting.shouldPrintBackgrounds = options.printBackground
|
||||
|
||||
if options.pageSize and PDFPageSize[options.pageSize]
|
||||
printingSetting.mediaSize = PDFPageSize[options.pageSize]
|
||||
else
|
||||
printingSetting.mediaSize = PDFPageSize['A4']
|
||||
|
||||
@_printToPDF printingSetting, callback
|
||||
|
||||
binding._setWrapWebContents wrapWebContents
|
||||
|
||||
module.exports.create = (options={}) ->
|
||||
binding.create(options)
|
||||
@@ -1,236 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const EventEmitter = require('events').EventEmitter;
|
||||
const deprecate = require('electron').deprecate;
|
||||
const ipcMain = require('electron').ipcMain;
|
||||
const NavigationController = require('electron').NavigationController;
|
||||
const Menu = require('electron').Menu;
|
||||
|
||||
const binding = process.atomBinding('web_contents');
|
||||
const debuggerBinding = process.atomBinding('debugger');
|
||||
|
||||
let slice = [].slice;
|
||||
let nextId = 0;
|
||||
|
||||
let getNextId = function() {
|
||||
return ++nextId;
|
||||
};
|
||||
|
||||
let PDFPageSize = {
|
||||
A5: {
|
||||
custom_display_name: "A5",
|
||||
height_microns: 210000,
|
||||
name: "ISO_A5",
|
||||
width_microns: 148000
|
||||
},
|
||||
A4: {
|
||||
custom_display_name: "A4",
|
||||
height_microns: 297000,
|
||||
name: "ISO_A4",
|
||||
is_default: "true",
|
||||
width_microns: 210000
|
||||
},
|
||||
A3: {
|
||||
custom_display_name: "A3",
|
||||
height_microns: 420000,
|
||||
name: "ISO_A3",
|
||||
width_microns: 297000
|
||||
},
|
||||
Legal: {
|
||||
custom_display_name: "Legal",
|
||||
height_microns: 355600,
|
||||
name: "NA_LEGAL",
|
||||
width_microns: 215900
|
||||
},
|
||||
Letter: {
|
||||
custom_display_name: "Letter",
|
||||
height_microns: 279400,
|
||||
name: "NA_LETTER",
|
||||
width_microns: 215900
|
||||
},
|
||||
Tabloid: {
|
||||
height_microns: 431800,
|
||||
name: "NA_LEDGER",
|
||||
width_microns: 279400,
|
||||
custom_display_name: "Tabloid"
|
||||
}
|
||||
};
|
||||
|
||||
// Following methods are mapped to webFrame.
|
||||
const webFrameMethods = [
|
||||
'executeJavaScript',
|
||||
'insertText',
|
||||
'setZoomFactor',
|
||||
'setZoomLevel',
|
||||
'setZoomLevelLimits'
|
||||
];
|
||||
|
||||
let wrapWebContents = function(webContents) {
|
||||
// webContents is an EventEmitter.
|
||||
var controller, method, name, ref1;
|
||||
webContents.__proto__ = EventEmitter.prototype;
|
||||
|
||||
// Every remote callback from renderer process would add a listenter to the
|
||||
// render-view-deleted event, so ignore the listenters warning.
|
||||
webContents.setMaxListeners(0);
|
||||
|
||||
// WebContents::send(channel, args..)
|
||||
webContents.send = function() {
|
||||
var args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
|
||||
var channel = arguments[0];
|
||||
if (channel == null) {
|
||||
throw new Error('Missing required channel argument');
|
||||
}
|
||||
return this._send(channel, slice.call(args));
|
||||
};
|
||||
|
||||
// The navigation controller.
|
||||
controller = new NavigationController(webContents);
|
||||
ref1 = NavigationController.prototype;
|
||||
for (name in ref1) {
|
||||
method = ref1[name];
|
||||
if (method instanceof Function) {
|
||||
(function(name, method) {
|
||||
return webContents[name] = function() {
|
||||
return method.apply(controller, arguments);
|
||||
};
|
||||
})(name, method);
|
||||
}
|
||||
}
|
||||
|
||||
// Mapping webFrame methods.
|
||||
for (let method of webFrameMethods) {
|
||||
webContents[method] = function() {
|
||||
let args = Array.prototype.slice.call(arguments);
|
||||
this.send('ELECTRON_INTERNAL_RENDERER_WEB_FRAME_METHOD', method, args);
|
||||
};
|
||||
}
|
||||
|
||||
// Make sure webContents.executeJavaScript would run the code only when the
|
||||
// webContents has been loaded.
|
||||
const executeJavaScript = webContents.executeJavaScript;
|
||||
webContents.executeJavaScript = function(code, hasUserGesture) {
|
||||
if (this.getURL() && !this.isLoading())
|
||||
return executeJavaScript.call(this, code, hasUserGesture);
|
||||
else
|
||||
return this.once('did-finish-load', executeJavaScript.bind(this, code, hasUserGesture));
|
||||
};
|
||||
|
||||
// Dispatch IPC messages to the ipc module.
|
||||
webContents.on('ipc-message', function(event, packed) {
|
||||
var args, channel;
|
||||
channel = packed[0], args = 2 <= packed.length ? slice.call(packed, 1) : [];
|
||||
return ipcMain.emit.apply(ipcMain, [channel, event].concat(slice.call(args)));
|
||||
});
|
||||
webContents.on('ipc-message-sync', function(event, packed) {
|
||||
var args, channel;
|
||||
channel = packed[0], args = 2 <= packed.length ? slice.call(packed, 1) : [];
|
||||
Object.defineProperty(event, 'returnValue', {
|
||||
set: function(value) {
|
||||
return event.sendReply(JSON.stringify(value));
|
||||
}
|
||||
});
|
||||
return ipcMain.emit.apply(ipcMain, [channel, event].concat(slice.call(args)));
|
||||
});
|
||||
|
||||
// Handle context menu action request from pepper plugin.
|
||||
webContents.on('pepper-context-menu', function(event, params) {
|
||||
var menu;
|
||||
menu = Menu.buildFromTemplate(params.menu);
|
||||
return menu.popup(params.x, params.y);
|
||||
});
|
||||
|
||||
// This error occurs when host could not be found.
|
||||
webContents.on('did-fail-provisional-load', function() {
|
||||
var args;
|
||||
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
|
||||
|
||||
// Calling loadURL during this event might cause crash, so delay the event
|
||||
// until next tick.
|
||||
return setImmediate((function(_this) {
|
||||
return function() {
|
||||
return _this.emit.apply(_this, ['did-fail-load'].concat(slice.call(args)));
|
||||
};
|
||||
})(this));
|
||||
});
|
||||
|
||||
// Delays the page-title-updated event to next tick.
|
||||
webContents.on('-page-title-updated', function() {
|
||||
var args;
|
||||
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
|
||||
return setImmediate((function(_this) {
|
||||
return function() {
|
||||
return _this.emit.apply(_this, ['page-title-updated'].concat(slice.call(args)));
|
||||
};
|
||||
})(this));
|
||||
});
|
||||
|
||||
// Deprecated.
|
||||
deprecate.rename(webContents, 'loadUrl', 'loadURL');
|
||||
deprecate.rename(webContents, 'getUrl', 'getURL');
|
||||
deprecate.event(webContents, 'page-title-set', 'page-title-updated', function() {
|
||||
var args;
|
||||
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
|
||||
return this.emit.apply(this, ['page-title-set'].concat(slice.call(args)));
|
||||
});
|
||||
return webContents.printToPDF = function(options, callback) {
|
||||
var printingSetting;
|
||||
printingSetting = {
|
||||
pageRage: [],
|
||||
mediaSize: {},
|
||||
landscape: false,
|
||||
color: 2,
|
||||
headerFooterEnabled: false,
|
||||
marginsType: 0,
|
||||
isFirstRequest: false,
|
||||
requestID: getNextId(),
|
||||
previewModifiable: true,
|
||||
printToPDF: true,
|
||||
printWithCloudPrint: false,
|
||||
printWithPrivet: false,
|
||||
printWithExtension: false,
|
||||
deviceName: "Save as PDF",
|
||||
generateDraftData: true,
|
||||
fitToPageEnabled: false,
|
||||
duplex: 0,
|
||||
copies: 1,
|
||||
collate: true,
|
||||
shouldPrintBackgrounds: false,
|
||||
shouldPrintSelectionOnly: false
|
||||
};
|
||||
if (options.landscape) {
|
||||
printingSetting.landscape = options.landscape;
|
||||
}
|
||||
if (options.marginsType) {
|
||||
printingSetting.marginsType = options.marginsType;
|
||||
}
|
||||
if (options.printSelectionOnly) {
|
||||
printingSetting.shouldPrintSelectionOnly = options.printSelectionOnly;
|
||||
}
|
||||
if (options.printBackground) {
|
||||
printingSetting.shouldPrintBackgrounds = options.printBackground;
|
||||
}
|
||||
if (options.pageSize && PDFPageSize[options.pageSize]) {
|
||||
printingSetting.mediaSize = PDFPageSize[options.pageSize];
|
||||
} else {
|
||||
printingSetting.mediaSize = PDFPageSize['A4'];
|
||||
}
|
||||
return this._printToPDF(printingSetting, callback);
|
||||
};
|
||||
};
|
||||
|
||||
// Wrapper for native class.
|
||||
let wrapDebugger = function(webContentsDebugger) {
|
||||
// debugger is an EventEmitter.
|
||||
webContentsDebugger.__proto__ = EventEmitter.prototype;
|
||||
};
|
||||
|
||||
binding._setWrapWebContents(wrapWebContents);
|
||||
debuggerBinding._setWrapDebugger(wrapDebugger);
|
||||
|
||||
module.exports.create = function(options) {
|
||||
if (options == null) {
|
||||
options = {};
|
||||
}
|
||||
return binding.create(options);
|
||||
};
|
||||
@@ -15,7 +15,6 @@
|
||||
#include "atom/browser/atom_resource_dispatcher_host_delegate.h"
|
||||
#include "atom/browser/atom_speech_recognition_manager_delegate.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/web_contents_permission_helper.h"
|
||||
#include "atom/browser/web_contents_preferences.h"
|
||||
#include "atom/browser/window_list.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
@@ -26,7 +25,6 @@
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "chrome/browser/printing/printing_message_filter.h"
|
||||
#include "chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h"
|
||||
#include "chrome/browser/renderer_host/pepper/widevine_cdm_message_filter.h"
|
||||
#include "chrome/browser/speech/tts_message_filter.h"
|
||||
#include "content/public/browser/browser_ppapi_host.h"
|
||||
#include "content/public/browser/client_certificate_delegate.h"
|
||||
@@ -56,8 +54,6 @@ 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) {
|
||||
@@ -88,12 +84,7 @@ void AtomBrowserClient::SuppressRendererProcessRestartForOnce() {
|
||||
|
||||
void AtomBrowserClient::SetCustomSchemes(
|
||||
const std::vector<std::string>& schemes) {
|
||||
g_custom_schemes = base::JoinString(schemes, ",");
|
||||
}
|
||||
|
||||
void AtomBrowserClient::SetCustomServiceWorkerSchemes(
|
||||
const std::vector<std::string>& schemes) {
|
||||
g_custom_service_worker_schemes = base::JoinString(schemes, ",");
|
||||
g_custom_schemes = JoinString(schemes, ',');
|
||||
}
|
||||
|
||||
AtomBrowserClient::AtomBrowserClient() : delegate_(nullptr) {
|
||||
@@ -107,8 +98,6 @@ void AtomBrowserClient::RenderProcessWillLaunch(
|
||||
int process_id = host->GetID();
|
||||
host->AddFilter(new printing::PrintingMessageFilter(process_id));
|
||||
host->AddFilter(new TtsMessageFilter(process_id, host->GetBrowserContext()));
|
||||
host->AddFilter(
|
||||
new WidevineCdmMessageFilter(process_id, host->GetBrowserContext()));
|
||||
}
|
||||
|
||||
content::SpeechRecognitionManagerDelegate*
|
||||
@@ -127,6 +116,7 @@ void AtomBrowserClient::OverrideWebkitPrefs(
|
||||
prefs->javascript_can_open_windows_automatically = true;
|
||||
prefs->plugins_enabled = true;
|
||||
prefs->dom_paste_enabled = true;
|
||||
prefs->java_enabled = false;
|
||||
prefs->allow_scripts_to_close_windows = true;
|
||||
prefs->javascript_can_access_clipboard = true;
|
||||
prefs->local_storage_enabled = true;
|
||||
@@ -183,11 +173,6 @@ 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;
|
||||
@@ -201,16 +186,9 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches(
|
||||
if (ContainsKey(pending_processes_, process_id))
|
||||
process_id = pending_processes_[process_id];
|
||||
|
||||
|
||||
// Certain render process will be created with no associated render view,
|
||||
// for example: ServiceWorker.
|
||||
auto rvh = content::RenderViewHost::FromID(process_id, kDefaultRoutingID);
|
||||
if (!rvh)
|
||||
return;
|
||||
|
||||
// Get the WebContents of the render process.
|
||||
content::WebContents* web_contents =
|
||||
content::WebContents::FromRenderViewHost(rvh);
|
||||
content::WebContents* web_contents = content::WebContents::FromRenderViewHost(
|
||||
content::RenderViewHost::FromID(process_id, kDefaultRoutingID));
|
||||
if (!web_contents)
|
||||
return;
|
||||
|
||||
@@ -282,24 +260,6 @@ brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts(
|
||||
return new AtomBrowserMainParts;
|
||||
}
|
||||
|
||||
void AtomBrowserClient::WebNotificationAllowed(
|
||||
int render_process_id,
|
||||
const base::Callback<void(bool)>& callback) {
|
||||
content::WebContents* web_contents = content::WebContents::FromRenderViewHost(
|
||||
content::RenderViewHost::FromID(render_process_id, kDefaultRoutingID));
|
||||
if (!web_contents) {
|
||||
callback.Run(false);
|
||||
return;
|
||||
}
|
||||
auto permission_helper =
|
||||
WebContentsPermissionHelper::FromWebContents(web_contents);
|
||||
if (!permission_helper) {
|
||||
callback.Run(false);
|
||||
return;
|
||||
}
|
||||
permission_helper->RequestWebNotificationPermission(callback);
|
||||
}
|
||||
|
||||
void AtomBrowserClient::RenderProcessHostDestroyed(
|
||||
content::RenderProcessHost* host) {
|
||||
int process_id = host->GetID();
|
||||
|
||||
@@ -38,9 +38,6 @@ 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:
|
||||
@@ -81,9 +78,6 @@ class AtomBrowserClient : public brightray::BrowserClient,
|
||||
// brightray::BrowserClient:
|
||||
brightray::BrowserMainParts* OverrideCreateBrowserMainParts(
|
||||
const content::MainFunctionParams&) override;
|
||||
void WebNotificationAllowed(
|
||||
int render_process_id,
|
||||
const base::Callback<void(bool)>& callback) override;
|
||||
|
||||
// content::RenderProcessHostObserver:
|
||||
void RenderProcessHostDestroyed(content::RenderProcessHost* host) override;
|
||||
|
||||
@@ -8,25 +8,21 @@
|
||||
#include "atom/browser/atom_download_manager_delegate.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/net/atom_cert_verifier.h"
|
||||
#include "atom/browser/net/atom_network_delegate.h"
|
||||
#include "atom/browser/net/atom_ssl_config_service.h"
|
||||
#include "atom/browser/net/atom_url_request_job_factory.h"
|
||||
#include "atom/browser/net/asar/asar_protocol_handler.h"
|
||||
#include "atom/browser/net/http_protocol_handler.h"
|
||||
#include "atom/browser/atom_permission_manager.h"
|
||||
#include "atom/browser/web_view_manager.h"
|
||||
#include "atom/common/atom_version.h"
|
||||
#include "atom/common/chrome_version.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/prefs/pref_registry_simple.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "base/threading/sequenced_worker_pool.h"
|
||||
#include "base/threading/worker_pool.h"
|
||||
#include "chrome/common/chrome_paths.h"
|
||||
#include "chrome/common/pref_names.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/common/url_constants.h"
|
||||
@@ -65,19 +61,14 @@ std::string RemoveWhitespace(const std::string& str) {
|
||||
AtomBrowserContext::AtomBrowserContext(const std::string& partition,
|
||||
bool in_memory)
|
||||
: brightray::BrowserContext(partition, in_memory),
|
||||
cert_verifier_(nullptr),
|
||||
cert_verifier_(new AtomCertVerifier),
|
||||
job_factory_(new AtomURLRequestJobFactory),
|
||||
network_delegate_(new AtomNetworkDelegate),
|
||||
allow_ntlm_everywhere_(false) {
|
||||
}
|
||||
|
||||
AtomBrowserContext::~AtomBrowserContext() {
|
||||
}
|
||||
|
||||
net::NetworkDelegate* AtomBrowserContext::CreateNetworkDelegate() {
|
||||
return network_delegate_;
|
||||
}
|
||||
|
||||
std::string AtomBrowserContext::GetUserAgent() {
|
||||
Browser* browser = Browser::Get();
|
||||
std::string name = RemoveWhitespace(browser->GetName());
|
||||
@@ -95,8 +86,7 @@ std::string AtomBrowserContext::GetUserAgent() {
|
||||
return content::BuildUserAgentFromProduct(user_agent);
|
||||
}
|
||||
|
||||
scoped_ptr<net::URLRequestJobFactory>
|
||||
AtomBrowserContext::CreateURLRequestJobFactory(
|
||||
net::URLRequestJobFactory* AtomBrowserContext::CreateURLRequestJobFactory(
|
||||
content::ProtocolHandlerMap* handlers,
|
||||
content::URLRequestInterceptorScopedVector* interceptors) {
|
||||
scoped_ptr<AtomURLRequestJobFactory> job_factory(job_factory_);
|
||||
@@ -141,7 +131,7 @@ AtomBrowserContext::CreateURLRequestJobFactory(
|
||||
top_job_factory.Pass(), make_scoped_ptr(*it)));
|
||||
interceptors->weak_clear();
|
||||
|
||||
return top_job_factory.Pass();
|
||||
return top_job_factory.release();
|
||||
}
|
||||
|
||||
net::HttpCache::BackendFactory*
|
||||
@@ -170,16 +160,8 @@ content::BrowserPluginGuestManager* AtomBrowserContext::GetGuestManager() {
|
||||
return guest_manager_.get();
|
||||
}
|
||||
|
||||
content::PermissionManager* AtomBrowserContext::GetPermissionManager() {
|
||||
if (!permission_manager_.get())
|
||||
permission_manager_.reset(new AtomPermissionManager);
|
||||
return permission_manager_.get();
|
||||
}
|
||||
|
||||
scoped_ptr<net::CertVerifier> AtomBrowserContext::CreateCertVerifier() {
|
||||
DCHECK(!cert_verifier_);
|
||||
cert_verifier_ = new AtomCertVerifier;
|
||||
return make_scoped_ptr(cert_verifier_);
|
||||
net::CertVerifier* AtomBrowserContext::CreateCertVerifier() {
|
||||
return cert_verifier_;
|
||||
}
|
||||
|
||||
net::SSLConfigService* AtomBrowserContext::CreateSSLConfigService() {
|
||||
@@ -189,10 +171,8 @@ net::SSLConfigService* AtomBrowserContext::CreateSSLConfigService() {
|
||||
void AtomBrowserContext::RegisterPrefs(PrefRegistrySimple* pref_registry) {
|
||||
pref_registry->RegisterFilePathPref(prefs::kSelectFileLastDirectory,
|
||||
base::FilePath());
|
||||
base::FilePath download_dir;
|
||||
PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS, &download_dir);
|
||||
pref_registry->RegisterFilePathPref(prefs::kDownloadDefaultDirectory,
|
||||
download_dir);
|
||||
base::FilePath());
|
||||
}
|
||||
|
||||
bool AtomBrowserContext::AllowNTLMCredentialsForDomain(const GURL& origin) {
|
||||
|
||||
@@ -13,8 +13,6 @@ namespace atom {
|
||||
|
||||
class AtomDownloadManagerDelegate;
|
||||
class AtomCertVerifier;
|
||||
class AtomNetworkDelegate;
|
||||
class AtomPermissionManager;
|
||||
class AtomURLRequestJobFactory;
|
||||
class WebViewManager;
|
||||
|
||||
@@ -24,21 +22,19 @@ class AtomBrowserContext : public brightray::BrowserContext {
|
||||
~AtomBrowserContext() override;
|
||||
|
||||
// brightray::URLRequestContextGetter::Delegate:
|
||||
net::NetworkDelegate* CreateNetworkDelegate() override;
|
||||
std::string GetUserAgent() override;
|
||||
scoped_ptr<net::URLRequestJobFactory> CreateURLRequestJobFactory(
|
||||
net::URLRequestJobFactory* CreateURLRequestJobFactory(
|
||||
content::ProtocolHandlerMap* handlers,
|
||||
content::URLRequestInterceptorScopedVector* interceptors) override;
|
||||
net::HttpCache::BackendFactory* CreateHttpCacheBackendFactory(
|
||||
const base::FilePath& base_path) override;
|
||||
scoped_ptr<net::CertVerifier> CreateCertVerifier() override;
|
||||
net::CertVerifier* CreateCertVerifier() override;
|
||||
net::SSLConfigService* CreateSSLConfigService() override;
|
||||
bool AllowNTLMCredentialsForDomain(const GURL& auth_origin) override;
|
||||
|
||||
// content::BrowserContext:
|
||||
content::DownloadManagerDelegate* GetDownloadManagerDelegate() override;
|
||||
content::BrowserPluginGuestManager* GetGuestManager() override;
|
||||
content::PermissionManager* GetPermissionManager() override;
|
||||
|
||||
// brightray::BrowserContext:
|
||||
void RegisterPrefs(PrefRegistrySimple* pref_registry) override;
|
||||
@@ -49,17 +45,13 @@ class AtomBrowserContext : public brightray::BrowserContext {
|
||||
|
||||
AtomURLRequestJobFactory* job_factory() const { return job_factory_; }
|
||||
|
||||
AtomNetworkDelegate* network_delegate() const { return network_delegate_; }
|
||||
|
||||
private:
|
||||
scoped_ptr<AtomDownloadManagerDelegate> download_manager_delegate_;
|
||||
scoped_ptr<WebViewManager> guest_manager_;
|
||||
scoped_ptr<AtomPermissionManager> permission_manager_;
|
||||
|
||||
// Managed by brightray::BrowserContext.
|
||||
AtomCertVerifier* cert_verifier_;
|
||||
AtomURLRequestJobFactory* job_factory_;
|
||||
AtomNetworkDelegate* network_delegate_;
|
||||
|
||||
bool allow_ntlm_everywhere_;
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
|
||||
#if defined(USE_X11)
|
||||
#include "chrome/browser/ui/libgtk2ui/gtk2_util.h"
|
||||
#include "ui/events/devices/x11/touch_factory_x11.h"
|
||||
#endif
|
||||
|
||||
namespace atom {
|
||||
@@ -62,10 +61,6 @@ 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);
|
||||
@@ -117,10 +112,6 @@ void AtomBrowserMainParts::PreMainMessageLoopRun() {
|
||||
node_bindings_->PrepareMessageLoop();
|
||||
node_bindings_->RunMessageLoop();
|
||||
|
||||
#if defined(USE_X11)
|
||||
ui::TouchFactory::SetTouchDeviceListFromCommandLine();
|
||||
#endif
|
||||
|
||||
// Start idle gc.
|
||||
gc_timer_.Start(
|
||||
FROM_HERE, base::TimeDelta::FromMinutes(1),
|
||||
|
||||
@@ -34,9 +34,6 @@ 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.
|
||||
|
||||
@@ -13,14 +13,20 @@
|
||||
namespace atom {
|
||||
|
||||
void AtomBrowserMainParts::PreMainMessageLoopStart() {
|
||||
// Force the NSApplication subclass to be used.
|
||||
[AtomApplication sharedApplication];
|
||||
// Initialize locale setting.
|
||||
l10n_util::OverrideLocaleWithCocoaLocale();
|
||||
|
||||
// Force the NSApplication subclass to be used.
|
||||
NSApplication* application = [AtomApplication sharedApplication];
|
||||
|
||||
// Set our own application delegate.
|
||||
AtomApplicationDelegate* delegate = [[AtomApplicationDelegate alloc] init];
|
||||
[NSApp setDelegate:(id<NSFileManagerDelegate>)delegate];
|
||||
|
||||
brightray::BrowserMainParts::PreMainMessageLoopStart();
|
||||
NSBundle* frameworkBundle = base::mac::FrameworkBundle();
|
||||
NSNib* mainNib = [[NSNib alloc] initWithNibNamed:@"MainMenu"
|
||||
bundle:frameworkBundle];
|
||||
[mainNib instantiateWithOwner:application topLevelObjects:nil];
|
||||
[mainNib release];
|
||||
|
||||
// Prevent Cocoa from turning command-line arguments into
|
||||
// |-application:openFiles:|, since we already handle them directly.
|
||||
|
||||
@@ -109,30 +109,27 @@ bool AtomDownloadManagerDelegate::DetermineDownloadTarget(
|
||||
download->GetForcedFilePath());
|
||||
return true;
|
||||
}
|
||||
|
||||
// Try to get the save path from JS wrapper.
|
||||
{
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
v8::Locker locker(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
api::DownloadItem* download_item = api::DownloadItem::FromWrappedClass(
|
||||
isolate, download);
|
||||
if (download_item) {
|
||||
base::FilePath save_path = download_item->GetSavePath();
|
||||
if (!save_path.empty()) {
|
||||
callback.Run(save_path,
|
||||
content::DownloadItem::TARGET_DISPOSITION_OVERWRITE,
|
||||
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
|
||||
save_path);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
base::SupportsUserData::Data* save_path = download->GetUserData(
|
||||
atom::api::DownloadItem::UserDataKey());
|
||||
if (save_path) {
|
||||
const base::FilePath& default_download_path =
|
||||
static_cast<api::DownloadItem::SavePathData*>(save_path)->path();
|
||||
callback.Run(default_download_path,
|
||||
content::DownloadItem::TARGET_DISPOSITION_OVERWRITE,
|
||||
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
|
||||
default_download_path);
|
||||
return true;
|
||||
}
|
||||
|
||||
AtomBrowserContext* browser_context = static_cast<AtomBrowserContext*>(
|
||||
download_manager_->GetBrowserContext());
|
||||
base::FilePath default_download_path = browser_context->prefs()->GetFilePath(
|
||||
prefs::kDownloadDefaultDirectory);
|
||||
// If users didn't set download path, use 'Downloads' directory by default.
|
||||
if (default_download_path.empty()) {
|
||||
auto path = download_manager_->GetBrowserContext()->GetPath();
|
||||
default_download_path = path.Append(FILE_PATH_LITERAL("Downloads"));
|
||||
}
|
||||
|
||||
CreateDownloadPathCallback download_path_callback =
|
||||
base::Bind(&AtomDownloadManagerDelegate::OnDownloadPathGenerated,
|
||||
|
||||
@@ -1,136 +0,0 @@
|
||||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/atom_permission_manager.h"
|
||||
|
||||
#include "content/public/browser/child_process_security_policy.h"
|
||||
#include "content/public/browser/permission_type.h"
|
||||
#include "content/public/browser/render_frame_host.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "content/public/browser/render_view_host.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
// Must be kept in sync with atom_browser_client.cc
|
||||
int kDefaultRoutingID = 2;
|
||||
|
||||
bool WebContentsDestroyed(int process_id) {
|
||||
auto rvh = content::RenderViewHost::FromID(process_id, kDefaultRoutingID);
|
||||
if (rvh) {
|
||||
auto contents = content::WebContents::FromRenderViewHost(rvh);
|
||||
return contents->IsBeingDestroyed();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
AtomPermissionManager::AtomPermissionManager()
|
||||
: request_id_(0) {
|
||||
}
|
||||
|
||||
AtomPermissionManager::~AtomPermissionManager() {
|
||||
}
|
||||
|
||||
void AtomPermissionManager::SetPermissionRequestHandler(
|
||||
const RequestHandler& handler) {
|
||||
if (handler.is_null() && !pending_requests_.empty()) {
|
||||
for (const auto& request : pending_requests_) {
|
||||
if (!WebContentsDestroyed(request.second.render_process_id))
|
||||
request.second.callback.Run(content::PERMISSION_STATUS_DENIED);
|
||||
}
|
||||
pending_requests_.clear();
|
||||
}
|
||||
request_handler_ = handler;
|
||||
}
|
||||
|
||||
int AtomPermissionManager::RequestPermission(
|
||||
content::PermissionType permission,
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& requesting_origin,
|
||||
bool user_gesture,
|
||||
const ResponseCallback& response_callback) {
|
||||
int process_id = render_frame_host->GetProcess()->GetID();
|
||||
|
||||
if (permission == content::PermissionType::MIDI_SYSEX) {
|
||||
content::ChildProcessSecurityPolicy::GetInstance()->
|
||||
GrantSendMidiSysExMessage(process_id);
|
||||
}
|
||||
|
||||
if (!request_handler_.is_null()) {
|
||||
auto web_contents =
|
||||
content::WebContents::FromRenderFrameHost(render_frame_host);
|
||||
++request_id_;
|
||||
auto callback = base::Bind(&AtomPermissionManager::OnPermissionResponse,
|
||||
base::Unretained(this),
|
||||
request_id_,
|
||||
requesting_origin,
|
||||
response_callback);
|
||||
pending_requests_[request_id_] = { process_id, callback };
|
||||
request_handler_.Run(web_contents, permission, callback);
|
||||
return request_id_;
|
||||
}
|
||||
|
||||
response_callback.Run(content::PERMISSION_STATUS_GRANTED);
|
||||
return kNoPendingOperation;
|
||||
}
|
||||
|
||||
void AtomPermissionManager::OnPermissionResponse(
|
||||
int request_id,
|
||||
const GURL& origin,
|
||||
const ResponseCallback& callback,
|
||||
content::PermissionStatus status) {
|
||||
auto request = pending_requests_.find(request_id);
|
||||
if (request != pending_requests_.end()) {
|
||||
if (!WebContentsDestroyed(request->second.render_process_id))
|
||||
callback.Run(status);
|
||||
pending_requests_.erase(request);
|
||||
}
|
||||
}
|
||||
|
||||
void AtomPermissionManager::CancelPermissionRequest(int request_id) {
|
||||
auto request = pending_requests_.find(request_id);
|
||||
if (request != pending_requests_.end()) {
|
||||
if (!WebContentsDestroyed(request->second.render_process_id))
|
||||
request->second.callback.Run(content::PERMISSION_STATUS_DENIED);
|
||||
pending_requests_.erase(request);
|
||||
}
|
||||
}
|
||||
|
||||
void AtomPermissionManager::ResetPermission(
|
||||
content::PermissionType permission,
|
||||
const GURL& requesting_origin,
|
||||
const GURL& embedding_origin) {
|
||||
}
|
||||
|
||||
content::PermissionStatus AtomPermissionManager::GetPermissionStatus(
|
||||
content::PermissionType permission,
|
||||
const GURL& requesting_origin,
|
||||
const GURL& embedding_origin) {
|
||||
return content::PERMISSION_STATUS_GRANTED;
|
||||
}
|
||||
|
||||
void AtomPermissionManager::RegisterPermissionUsage(
|
||||
content::PermissionType permission,
|
||||
const GURL& requesting_origin,
|
||||
const GURL& embedding_origin) {
|
||||
}
|
||||
|
||||
int AtomPermissionManager::SubscribePermissionStatusChange(
|
||||
content::PermissionType permission,
|
||||
const GURL& requesting_origin,
|
||||
const GURL& embedding_origin,
|
||||
const ResponseCallback& callback) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
void AtomPermissionManager::UnsubscribePermissionStatusChange(
|
||||
int subscription_id) {
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
@@ -1,84 +0,0 @@
|
||||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_ATOM_PERMISSION_MANAGER_H_
|
||||
#define ATOM_BROWSER_ATOM_PERMISSION_MANAGER_H_
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "content/public/browser/permission_manager.h"
|
||||
|
||||
namespace content {
|
||||
class WebContents;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomPermissionManager : public content::PermissionManager {
|
||||
public:
|
||||
AtomPermissionManager();
|
||||
~AtomPermissionManager() override;
|
||||
|
||||
using ResponseCallback =
|
||||
base::Callback<void(content::PermissionStatus)>;
|
||||
using RequestHandler =
|
||||
base::Callback<void(content::WebContents*,
|
||||
content::PermissionType,
|
||||
const ResponseCallback&)>;
|
||||
|
||||
// Handler to dispatch permission requests in JS.
|
||||
void SetPermissionRequestHandler(const RequestHandler& handler);
|
||||
|
||||
// content::PermissionManager:
|
||||
int RequestPermission(
|
||||
content::PermissionType permission,
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& requesting_origin,
|
||||
bool user_gesture,
|
||||
const ResponseCallback& callback) override;
|
||||
|
||||
protected:
|
||||
void OnPermissionResponse(int request_id,
|
||||
const GURL& url,
|
||||
const ResponseCallback& callback,
|
||||
content::PermissionStatus status);
|
||||
|
||||
// content::PermissionManager:
|
||||
void CancelPermissionRequest(int request_id) override;
|
||||
void ResetPermission(content::PermissionType permission,
|
||||
const GURL& requesting_origin,
|
||||
const GURL& embedding_origin) override;
|
||||
content::PermissionStatus GetPermissionStatus(
|
||||
content::PermissionType permission,
|
||||
const GURL& requesting_origin,
|
||||
const GURL& embedding_origin) override;
|
||||
void RegisterPermissionUsage(content::PermissionType permission,
|
||||
const GURL& requesting_origin,
|
||||
const GURL& embedding_origin) override;
|
||||
int SubscribePermissionStatusChange(
|
||||
content::PermissionType permission,
|
||||
const GURL& requesting_origin,
|
||||
const GURL& embedding_origin,
|
||||
const base::Callback<void(content::PermissionStatus)>& callback) override;
|
||||
void UnsubscribePermissionStatusChange(int subscription_id) override;
|
||||
|
||||
private:
|
||||
struct RequestInfo {
|
||||
int render_process_id;
|
||||
ResponseCallback callback;
|
||||
};
|
||||
|
||||
RequestHandler request_handler_;
|
||||
|
||||
std::map<int, RequestInfo> pending_requests_;
|
||||
|
||||
int request_id_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomPermissionManager);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_ATOM_PERMISSION_MANAGER_H_
|
||||
@@ -26,8 +26,7 @@ bool AtomResourceDispatcherHostDelegate::HandleExternalProtocol(
|
||||
bool has_user_gesture) {
|
||||
GURL escaped_url(net::EscapeExternalHandlerValue(url.spec()));
|
||||
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
||||
base::Bind(
|
||||
base::IgnoreResult(platform_util::OpenExternal), escaped_url, true));
|
||||
base::Bind(base::IgnoreResult(platform_util::OpenExternal), escaped_url));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
Shutdown();
|
||||
NotifyAndShutdown();
|
||||
} else {
|
||||
// Unlike Quit(), we do not ask to close window, but destroy the window
|
||||
// without asking.
|
||||
|
||||
@@ -27,10 +27,6 @@ namespace ui {
|
||||
class MenuModel;
|
||||
}
|
||||
|
||||
namespace gfx {
|
||||
class Image;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
class LoginHandler;
|
||||
@@ -77,12 +73,6 @@ class Browser : public WindowListObserver {
|
||||
void SetAppUserModelID(const base::string16& name);
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
// Hide the application.
|
||||
void Hide();
|
||||
|
||||
// Show the application.
|
||||
void Show();
|
||||
|
||||
// Bounce the dock icon.
|
||||
enum BounceType {
|
||||
BOUNCE_CRITICAL = 0,
|
||||
@@ -101,9 +91,6 @@ class Browser : public WindowListObserver {
|
||||
|
||||
// Set docks' menu.
|
||||
void DockSetMenu(ui::MenuModel* model);
|
||||
|
||||
// Set docks' icon.
|
||||
void DockSetIcon(const gfx::Image& image);
|
||||
#endif // defined(OS_MACOSX)
|
||||
|
||||
#if defined(OS_WIN)
|
||||
|
||||
@@ -18,26 +18,12 @@ void Browser::Focus() {
|
||||
[[AtomApplication sharedApplication] activateIgnoringOtherApps:YES];
|
||||
}
|
||||
|
||||
void Browser::Hide() {
|
||||
[[AtomApplication sharedApplication] hide:nil];
|
||||
}
|
||||
|
||||
void Browser::Show() {
|
||||
[[AtomApplication sharedApplication] unhide:nil];
|
||||
}
|
||||
|
||||
void Browser::AddRecentDocument(const base::FilePath& path) {
|
||||
NSString* path_string = base::mac::FilePathToNSString(path);
|
||||
if (!path_string)
|
||||
return;
|
||||
NSURL* u = [NSURL fileURLWithPath:path_string];
|
||||
if (!u)
|
||||
return;
|
||||
NSURL* u = [NSURL fileURLWithPath:base::mac::FilePathToNSString(path)];
|
||||
[[NSDocumentController sharedDocumentController] noteNewRecentDocumentURL:u];
|
||||
}
|
||||
|
||||
void Browser::ClearRecentDocuments() {
|
||||
[[NSDocumentController sharedDocumentController] clearRecentDocuments:nil];
|
||||
}
|
||||
|
||||
void Browser::SetAppUserModelID(const base::string16& name) {
|
||||
@@ -52,12 +38,11 @@ std::string Browser::GetExecutableFileProductName() const {
|
||||
}
|
||||
|
||||
int Browser::DockBounce(BounceType type) {
|
||||
return [[AtomApplication sharedApplication]
|
||||
requestUserAttention:(NSRequestUserAttentionType)type];
|
||||
return [[AtomApplication sharedApplication] requestUserAttention:(NSRequestUserAttentionType)type];
|
||||
}
|
||||
|
||||
void Browser::DockCancelBounce(int request_id) {
|
||||
[[AtomApplication sharedApplication] cancelUserAttentionRequest:request_id];
|
||||
void Browser::DockCancelBounce(int rid) {
|
||||
[[AtomApplication sharedApplication] cancelUserAttentionRequest:rid];
|
||||
}
|
||||
|
||||
void Browser::DockSetBadgeText(const std::string& label) {
|
||||
@@ -80,29 +65,8 @@ void Browser::DockHide() {
|
||||
}
|
||||
|
||||
void Browser::DockShow() {
|
||||
BOOL active = [[NSRunningApplication currentApplication] isActive];
|
||||
ProcessSerialNumber psn = { 0, kCurrentProcess };
|
||||
if (active) {
|
||||
// Workaround buggy behavior of TransformProcessType.
|
||||
// http://stackoverflow.com/questions/7596643/
|
||||
NSArray* runningApps = [NSRunningApplication
|
||||
runningApplicationsWithBundleIdentifier:@"com.apple.dock"];
|
||||
for (NSRunningApplication* app in runningApps) {
|
||||
[app activateWithOptions:NSApplicationActivateIgnoringOtherApps];
|
||||
break;
|
||||
}
|
||||
dispatch_time_t one_ms = dispatch_time(DISPATCH_TIME_NOW, USEC_PER_SEC);
|
||||
dispatch_after(one_ms, dispatch_get_main_queue(), ^{
|
||||
TransformProcessType(&psn, kProcessTransformToForegroundApplication);
|
||||
dispatch_time_t one_ms = dispatch_time(DISPATCH_TIME_NOW, USEC_PER_SEC);
|
||||
dispatch_after(one_ms, dispatch_get_main_queue(), ^{
|
||||
[[NSRunningApplication currentApplication]
|
||||
activateWithOptions:NSApplicationActivateIgnoringOtherApps];
|
||||
});
|
||||
});
|
||||
} else {
|
||||
TransformProcessType(&psn, kProcessTransformToForegroundApplication);
|
||||
}
|
||||
TransformProcessType(&psn, kProcessTransformToForegroundApplication);
|
||||
}
|
||||
|
||||
void Browser::DockSetMenu(ui::MenuModel* model) {
|
||||
@@ -110,9 +74,4 @@ void Browser::DockSetMenu(ui::MenuModel* model) {
|
||||
[delegate setApplicationDockMenu:model];
|
||||
}
|
||||
|
||||
void Browser::DockSetIcon(const gfx::Image& image) {
|
||||
[[AtomApplication sharedApplication]
|
||||
setApplicationIconImage:image.AsNSImage()];
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -127,7 +127,7 @@ void Browser::SetUserTasks(const std::vector<UserTask>& tasks) {
|
||||
|
||||
PCWSTR Browser::GetAppUserModelID() {
|
||||
if (app_user_model_id_.empty()) {
|
||||
SetAppUserModelID(base::ReplaceStringPlaceholders(
|
||||
SetAppUserModelID(ReplaceStringPlaceholders(
|
||||
kAppUserModelIDFormat, base::UTF8ToUTF16(GetName()), nullptr));
|
||||
}
|
||||
|
||||
|
||||
@@ -181,6 +181,13 @@ content::WebContents* CommonWebContentsDelegate::OpenURLFromTab(
|
||||
return source;
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::RequestToLockMouse(
|
||||
content::WebContents* web_contents,
|
||||
bool user_gesture,
|
||||
bool last_unlocked_by_target) {
|
||||
GetWebContents()->GotResponseToLockMouseRequest(true);
|
||||
}
|
||||
|
||||
bool CommonWebContentsDelegate::CanOverscrollContent() const {
|
||||
return false;
|
||||
}
|
||||
@@ -373,7 +380,7 @@ gfx::ImageSkia CommonWebContentsDelegate::GetDevToolsWindowIcon() {
|
||||
void CommonWebContentsDelegate::GetDevToolsWindowWMClass(
|
||||
std::string* name, std::string* class_name) {
|
||||
*class_name = Browser::Get()->GetName();
|
||||
*name = base::ToLowerASCII(*class_name);
|
||||
*name = base::StringToLowerASCII(*class_name);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user