Compare commits

...

799 Commits

Author SHA1 Message Date
Cheng Zhao
2bcf8c7bc2 Bump v0.29.1 2015-07-03 23:33:49 +08:00
Cheng Zhao
bea45867d2 Remove ~/.node-gyp in clean script 2015-07-03 23:33:49 +08:00
Cheng Zhao
70987a9029 Checkout boto in our repo 2015-07-03 23:33:49 +08:00
Cheng Zhao
5c85c2e5d5 Update node 2015-07-03 22:12:19 +08:00
Cheng Zhao
6f137d62c7 Revert "Set openssl_fips in config.gypi"
This reverts commit 26525d6b0f.
2015-07-03 22:08:53 +08:00
Cheng Zhao
3533be2f9f Fist line of config.gypi should be empty 2015-07-03 21:41:27 +08:00
Cheng Zhao
a1b28c362d Revert "Get the pending version from the commit message"
This reverts commit 16acd669a7.
2015-07-03 21:21:19 +08:00
Cheng Zhao
26525d6b0f Set openssl_fips in config.gypi 2015-07-03 20:56:49 +08:00
Cheng Zhao
16acd669a7 Get the pending version from the commit message 2015-07-03 20:38:34 +08:00
Cheng Zhao
a3463119e8 Don't warn arch on Windows 2015-07-03 18:03:52 +08:00
Cheng Zhao
9159b06835 Fix uploading headers when release draft exists 2015-07-03 17:44:36 +08:00
Cheng Zhao
4c76112698 Don't check valid upload when -p is specified 2015-07-03 17:28:36 +08:00
Cheng Zhao
d158dbdb68 Don't check build version for arm target 2015-07-03 09:01:16 +00:00
Cheng Zhao
dadd34249a Bump v0.29.0 2015-07-03 16:45:56 +08:00
Cheng Zhao
173babc18b Merge pull request #2111 from atom/upload-in-ci
Create Release distributions in CI machine
2015-07-03 16:42:05 +08:00
Cheng Zhao
64c0e0dfdc Only creates Release build when ELECTRON_RELEASE is set 2015-07-03 16:31:33 +08:00
Cheng Zhao
bdbb994c72 Fix pylint warning 2015-07-03 15:31:55 +08:00
Cheng Zhao
ffb1732607 Delete the original file before uploading in CI 2015-07-03 15:26:54 +08:00
Cheng Zhao
02f3d7a25e Just ignore all OSError for rm_rf 2015-07-03 15:07:11 +08:00
Cheng Zhao
518ec36511 WindowsError is undefined on POSIX 2015-07-03 14:54:32 +08:00
Cheng Zhao
12233d704b Use better tag and title 2015-07-03 14:49:29 +08:00
Cheng Zhao
2717556a92 WindowsError is a subclass of OSError 2015-07-03 14:46:26 +08:00
Cheng Zhao
7288581393 Fix path to requests library 2015-07-03 14:43:58 +08:00
Cheng Zhao
f87a4b9a04 One failing rm should not block others 2015-07-03 14:40:32 +08:00
Cheng Zhao
b30709f133 No need to clean after cibuild 2015-07-03 14:36:45 +08:00
Cheng Zhao
20e9abe26a Don't check build version in CI 2015-07-03 14:30:59 +08:00
Cheng Zhao
89b22db618 Build the python requests library 2015-07-03 14:23:42 +08:00
Cheng Zhao
e95ee4775e Ignore Windows errors in clean.py 2015-07-03 13:59:02 +08:00
Cheng Zhao
f5ae3111ba Fix calling clean.py 2015-07-03 13:54:29 +08:00
Cheng Zhao
6b7d3a070a Clean before and after cibuild
Our CI machine is out of disk space
2015-07-03 13:52:13 +08:00
Cheng Zhao
e4530e6e32 Don't force redownloading some assets 2015-07-03 13:46:26 +08:00
Cheng Zhao
1212e45a6e Fix pylint warning 2015-07-03 13:45:29 +08:00
Cheng Zhao
82153eb75f Upload dist to Releases 2015-07-03 13:43:20 +08:00
Cheng Zhao
f99cd4d05a Try doing release in CI 2015-07-03 12:08:14 +08:00
Cheng Zhao
a720e52568 Set DISPLAY in CI machine 2015-07-03 12:04:27 +08:00
Cheng Zhao
83ee7a464d Avoid using the old gyp lib in system 2015-07-03 11:59:34 +08:00
Cheng Zhao
8e5a434560 Suppress window operations in CI 2015-07-03 11:40:20 +08:00
Cheng Zhao
8f06bd6f3e Merge pull request #2107 from atom/win-ci
Build in Windows CI
2015-07-03 11:28:16 +08:00
Cheng Zhao
fe877da61f Do debug build on Windows CI for non-release 2015-07-03 11:17:58 +08:00
Cheng Zhao
a1bb0d4d66 Don't call register_required_dll for now 2015-07-03 11:10:23 +08:00
Cheng Zhao
a6073113a1 No need to remove node_modules 2015-07-03 11:04:57 +08:00
Cheng Zhao
7d2866f3a7 Do not run tests in Windows CI 2015-07-03 10:35:40 +08:00
Cheng Zhao
52ba6a25df Create release dist when ELECTRON_RELEASE is set 2015-07-03 10:17:20 +08:00
Cheng Zhao
25e15869ec Force using VS2013 for building 2015-07-03 10:01:44 +08:00
Cheng Zhao
b3c76f3904 Only define mac_framework_dirs on Mac 2015-07-03 09:49:55 +08:00
Cheng Zhao
8de9c75caf Don't define source_root on Windows 2015-07-03 09:46:35 +08:00
Cheng Zhao
33109a2718 Ignore npm install errors when running in CI 2015-07-03 09:43:09 +08:00
Cheng Zhao
cab1b75c41 Use npm@2.12.1
See https://github.com/npm/npm/issues/8702.
2015-07-03 09:35:16 +08:00
Cheng Zhao
1e9af82bf6 Install npm before cleaning node_modules 2015-07-02 22:45:26 +08:00
Cheng Zhao
ddaf005c2b Fix calling npm on win32 2015-07-02 22:35:41 +08:00
Cheng Zhao
558a612d37 Install latest npm in CI 2015-07-02 22:34:05 +08:00
Cheng Zhao
5ccc909f2f Merge pull request #2094 from atom/arm
Add arm build
2015-07-02 16:04:37 +08:00
Cheng Zhao
a367934b95 docs: Cross compilation 2015-07-02 15:55:21 +08:00
Cheng Zhao
2078e5736e Don't upload arm version of mksnapshot too 2015-07-02 07:26:53 +00:00
Cheng Zhao
f0eac9d828 Don't upload arm version of chromedriver 2015-07-02 07:25:17 +00:00
Cheng Zhao
8110f2f221 Call correct strip for arm target 2015-07-02 07:19:39 +00:00
Cheng Zhao
c76d87719d Build dump_syms for host arch 2015-07-02 07:10:05 +00:00
Cheng Zhao
9bdefa6f1f Use clang's integrated as
The system as is throwing error when compiling atom_api_web_contents.cc:
/tmp/xxx.s: Assembler messages:
/tmp/xxx.s:23559: Internal error!
Assertion failure in get_line_subseg at ../../gas/dwarf2dbg.c line 262.
2015-07-02 06:31:10 +00:00
Cheng Zhao
b261c5f87c Libraries on host side is needed to make pkg-config work 2015-07-02 05:27:12 +00:00
Cheng Zhao
f569617d24 Clean up the libraries to install 2015-07-02 05:19:53 +00:00
Cheng Zhao
88b71b9633 Only run tests for x64 target 2015-07-02 05:18:05 +00:00
Cheng Zhao
f2daeb9d70 Build ia32 target with sysroot 2015-07-02 05:07:56 +00:00
Cheng Zhao
6088af623e Install ia32 build dependencies 2015-07-02 04:47:43 +00:00
Cheng Zhao
57262dd5ef Install arm build dependencies 2015-07-02 04:42:36 +00:00
Cheng Zhao
2de5ae9991 Add build matrix for arm and ia32 2015-07-02 03:13:18 +00:00
Cheng Zhao
3a094e9802 Use prebuild clang to build node modules 2015-07-02 02:56:56 +00:00
Cheng Zhao
62a5159e72 Don't install ubuntu test toolchain 2015-07-02 01:27:33 +00:00
Cheng Zhao
7b955fe829 Update libchromiumcontent to get arm build 2015-07-02 01:09:53 +00:00
Cheng Zhao
14bc544d89 Use our custom debian sysroot image 2015-07-02 00:47:14 +00:00
Cheng Zhao
a04bfbbc4b Never send email notifications
It is anonnying.
2015-07-02 00:46:10 +00:00
Kevin Sawicki
69ef175ac5 Merge pull request #2083 from johnhaley81/patch-1
Fix `window.open` with wrong name
2015-07-01 09:12:02 -07:00
Kevin Sawicki
cbac7179fd Merge pull request #2087 from shainnif/patch-1
Update build-instructions-windows.md
2015-07-01 09:07:55 -07:00
Kevin Sawicki
d6e25af59a Merge pull request #2095 from atom/fix-page-key-error
Fix the wrong reverse `pageup` and `pagedown` keys.
2015-07-01 09:07:33 -07:00
Haojian Wu
c01a79de6b Fix the wrong reverse pageup and pagedown keys. 2015-07-01 21:24:51 +08:00
Cheng Zhao
4214b62551 Set sysroot for arm build 2015-07-01 09:54:27 +00:00
Cheng Zhao
88eb5283a0 Download debian arm sysroot image 2015-07-01 09:22:40 +00:00
Cheng Zhao
af05f5b329 Add function to get host_arch 2015-07-01 09:17:44 +00:00
Cheng Zhao
1b3a8435e5 Define chromeos 2015-07-01 08:59:17 +00:00
Cheng Zhao
432bab3107 Only allow building on 64bit machine 2015-07-01 16:51:06 +08:00
Cheng Zhao
e15b05603d Merge pull request #2092 from atom/download-clang
Use downloaded clang binaries for building
2015-07-01 16:43:13 +08:00
Cheng Zhao
b1db947def Fix compilation errors due to compiler change 2015-07-01 07:56:29 +00:00
Cheng Zhao
3d88d56965 Support cross-compiling 2015-07-01 07:47:21 +00:00
Cheng Zhao
fdf7452ba9 Use downloaded clang for building 2015-07-01 14:44:45 +08:00
Cheng Zhao
bceac2ab7f Download prebuilt clang 2015-07-01 14:27:15 +08:00
Shaine Ismail
11cfe20395 Update build-instructions-windows.md
Very very very minor typo
2015-06-30 13:00:20 +01:00
Kevin Sawicki
dbb6723dfa Remove extra newline 2015-06-29 16:47:36 -07:00
Kevin Sawicki
ee3ac608cf Add slack back to README 2015-06-29 16:46:22 -07:00
John Haley
565a500320 Fix window.open with wrong name
When calling `window.open` the newly created window would have the name of the last option in the `features` argument as the title. I think it's supposed to be pointed to `frameName`.
2015-06-29 10:32:27 -07:00
Cheng Zhao
ebfbbc0801 Don't override user's menu in default_app
Close #2068.
2015-06-29 13:11:53 +08:00
Cheng Zhao
b508346ed8 Merge pull request #2077 from atom/iojs-latest
Update to io.js v2.3.1
2015-06-29 12:41:38 +08:00
Cheng Zhao
04de1aa51d Update to io.js v2.3.1 2015-06-29 12:18:50 +08:00
Cheng Zhao
1e514620b5 Remove window from window list before notifying closed event 2015-06-27 17:11:36 +08:00
Kevin Sawicki
4b4654ec71 Merge pull request #2066 from atom/doc-type-error
📝 Fix a type error.
2015-06-26 08:24:33 -06:00
Cheng Zhao
a79fcac047 Merge pull request #2063 from darwin/missing-overrides
Missing overrides
2015-06-26 21:49:57 +08:00
Cheng Zhao
572d4c5687 Merge pull request #2060 from geelen/patch-1
electron-installer not atom-shell-installer
2015-06-26 21:26:15 +08:00
Antonin Hildebrand
a8d58ea448 Missing overrides
ninja compilation failed for me under OS X 10.11
2015-06-26 11:43:39 +02:00
Glen Maddern
19daed9479 electron-installer not atom-shell-installer
<3
2015-06-26 14:17:52 +10:00
Cheng Zhao
637b642837 Fix building on Windows 2015-06-26 12:04:15 +08:00
Cheng Zhao
e6f3c4c22b Merge pull request #2002 from atom/app-commands-win32
Windows App Commands
2015-06-26 11:43:08 +08:00
Cheng Zhao
b5ff77ef0d Small cleanups 2015-06-26 11:20:12 +08:00
Cheng Zhao
bff66caaa6 Only convert command ID on Windows 2015-06-26 11:16:50 +08:00
Cheng Zhao
aa20f75335 Clean up ResolveProxyHelper
Since the ResolveProxyHelper is deleted after the callback is called,
there is no need to use weak reference.
2015-06-26 11:04:12 +08:00
Cheng Zhao
143a5e1178 Merge pull request #2054 from deepak1556/proxy_patch
session: using storageparttion to retrieve requestcontext
2015-06-26 10:54:47 +08:00
Cheng Zhao
a96ff85005 Clean up code in AtomBrowserClient 2015-06-26 10:53:37 +08:00
Haojian Wu
80e02d945c 📝 Fix a type error. 2015-06-26 10:47:50 +08:00
Cheng Zhao
edf60b8529 spec: Remove grabage console.log 2015-06-26 10:47:36 +08:00
Cheng Zhao
7fd60294f9 Merge pull request #2057 from atom/app-gpu-crash
Move gpu-crashed event to app
2015-06-26 10:47:04 +08:00
Cheng Zhao
a3ec50437d Rename event name to gpu-process-crashed 2015-06-26 10:34:38 +08:00
Cheng Zhao
5b5393e82b docs: gpu-crashed is moved to app 2015-06-26 10:34:13 +08:00
Cheng Zhao
ffd9c743de Move gpu-crashed event to app 2015-06-26 10:33:52 +08:00
Cheng Zhao
09c2317ae6 Merge pull request #1941 from deepak1556/certificate_api_patch
app: event to pass client certificate data
2015-06-26 10:31:18 +08:00
Paul Betts
58efb3c018 I forget cpplint every time 2015-06-25 15:09:25 -06:00
Paul Betts
528e0f3efb Revert submodule change 2015-06-25 11:31:32 -06:00
Paul Betts
2a2158e0e3 📝 consistency 2015-06-25 11:29:58 -06:00
Paul Betts
cde7c6a4ef Move app commands to strings 2015-06-25 11:29:57 -06:00
Paul Betts
210417b428 cpplint see me rollin', he hatin' 2015-06-25 11:29:28 -06:00
Paul Betts
1509aca788 Invisible character tyranny 2015-06-25 11:29:27 -06:00
Paul Betts
b98154431c 📝 app commands 2015-06-25 11:29:25 -06:00
Paul Betts
55a8862374 Add appcommand to files 2015-06-25 11:29:24 -06:00
Paul Betts
c2290ad058 Add enum for media keys on Win32 2015-06-25 11:29:23 -06:00
Paul Betts
cec6895e67 Emit the message as an event 2015-06-25 11:29:22 -06:00
Paul Betts
794f89abf5 In our widget delegate, signal our Observer 2015-06-25 11:29:21 -06:00
Paul Betts
37d18d512b Create a method to signal our Observer method 2015-06-25 11:29:21 -06:00
Paul Betts
d98cece115 Create a new method for NativeWindowObserver for AppCommands 2015-06-25 11:29:20 -06:00
deepak1556
0fbd908fb6 app: event to pass client certificate data 2015-06-25 21:29:21 +05:30
deepak1556
c15a9e7d5c session: using storageparttion to retrieve requestcontext 2015-06-25 19:55:57 +05:30
Cheng Zhao
1418fdbc02 Merge pull request #2051 from atom/detach-web-contents
Decouple WebContents from NativeWindow
2015-06-25 15:11:40 +08:00
Cheng Zhao
9f52b11761 Remove NativeWindow::GetWebContents 2015-06-25 14:54:00 +08:00
Cheng Zhao
01dc0f973c Remove inspectable_web_contents_ 2015-06-25 14:32:38 +08:00
Cheng Zhao
b2a8678c47 Move BrowserPluginGuestDelegate to a separate class 2015-06-25 14:28:13 +08:00
Cheng Zhao
9974a238c2 Fix the order of function definitions 2015-06-25 13:29:30 +08:00
Cheng Zhao
62c44ee47b Rename CloseWebContents to RequestToClosePage 2015-06-25 13:27:51 +08:00
Cheng Zhao
e41b0d4d2c Remove NativeWindow::ActivateContents 2015-06-25 13:18:36 +08:00
Cheng Zhao
eb370ba22a Allowing destroying a closed window 2015-06-25 13:08:11 +08:00
Cheng Zhao
afa9f30aac Add InspectableWebContentsViewDelegate 2015-06-25 12:30:04 +08:00
Cheng Zhao
2ea2413752 Set sender in EventEmitter.emit 2015-06-25 11:16:42 +08:00
Cheng Zhao
fb5fe7a714 Decouple WebContentsDelegate from NativeWindow 2015-06-25 11:07:23 +08:00
Cheng Zhao
5236b0c067 Don't create WebContents in NativeWindow 2015-06-25 09:47:57 +08:00
Cheng Zhao
081a4597e9 Pass isGuest when creating WebContents 2015-06-24 23:29:32 +08:00
Cheng Zhao
4b61683cdf Store NativeWindow in weak ptr 2015-06-24 22:29:44 +08:00
Cheng Zhao
19ca011735 Discard is_guest_, use type_ instead 2015-06-24 22:23:38 +08:00
Cheng Zhao
2bfa9da82e Store NativeWindow's weak ptr in WebContents 2015-06-24 22:14:46 +08:00
Cheng Zhao
2532318bee Add type for WebContents 2015-06-24 21:44:27 +08:00
Cheng Zhao
87f44c42df Handle close cancel in BeforeUnloadDialogCancelled 2015-06-24 21:28:36 +08:00
Cheng Zhao
b822a83bc2 Remove usages of NotificationObserver 2015-06-24 20:16:51 +08:00
Cheng Zhao
7d05a12ee9 Remove ActivateContents and DeactivateContents 2015-06-24 20:10:07 +08:00
Cheng Zhao
bd4d6dcda2 Merge pull request #2046 from atom/id-weak-map
Track native JS objects in C++
2015-06-24 20:01:42 +08:00
Cheng Zhao
9b9108f789 Remove JS override of setMenu 2015-06-24 19:51:11 +08:00
Cheng Zhao
f198148c79 Always initailize webContents in BrowserWindow 2015-06-24 19:04:08 +08:00
Cheng Zhao
8c83dfe918 Remove usages of JS IDWeakMap in browser-window 2015-06-24 19:01:44 +08:00
Cheng Zhao
f93d50c380 Merge pull request #2025 from atom/power-save-blocker-api
Power save blocker API
2015-06-24 18:53:10 +08:00
Cheng Zhao
cc8b22b5ff Make each class only have one weak map 2015-06-24 17:58:12 +08:00
Cheng Zhao
28d1fb8cad Add Values() method for IDWeakMap 2015-06-24 16:54:20 +08:00
Cheng Zhao
5e62b5975b Move "id" and "fromId" to C++ 2015-06-24 16:37:48 +08:00
Cheng Zhao
c2f14e6053 Initialize defaultSession after app is ready 2015-06-24 16:14:49 +08:00
Cheng Zhao
0ebd4d04ad Make Session trackable 2015-06-24 15:39:05 +08:00
Cheng Zhao
1023b67d59 Make sure each C++ WebContents has only one JS WebContents 2015-06-24 15:22:11 +08:00
Cheng Zhao
552a12d2ee Enable storing TrackableObject in other C++ class 2015-06-24 14:49:08 +08:00
Cheng Zhao
7f0658efa7 Add mate::TrackableObject 2015-06-24 14:36:05 +08:00
Cheng Zhao
15f350edcb Don't make IDWeakMap public API 2015-06-24 13:38:55 +08:00
Cheng Zhao
d02413de00 Make the JS IDWeakMap a thin wrapper of C++ IDWeakMap 2015-06-24 13:35:39 +08:00
Cheng Zhao
cd93b9412c Add C++ version of IDWeakMap 2015-06-24 13:22:09 +08:00
Haojian Wu
13784e6551 More updates: use string instead of integer to identify blocker type. 2015-06-24 13:06:39 +08:00
Cheng Zhao
b8cf9a2788 Merge pull request #2043 from atom/default-session
Add app.defaultSession
2015-06-24 12:25:06 +08:00
Cheng Zhao
09a6e37a09 Keep compatibility with app.resolveProxy 2015-06-24 12:01:19 +08:00
Cheng Zhao
ea69e91e49 Move resolveProxy From app to session 2015-06-24 11:59:11 +08:00
Cheng Zhao
ab6ed823d1 Merge pull request #2027 from deepak1556/devtools_file_save_patch
devtools: writing to filesystem in FILE thread
2015-06-24 10:45:22 +08:00
Cheng Zhao
33c2768a77 Add app.defaultSession 2015-06-23 23:40:41 +08:00
deepak1556
1f3a73e802 devtools: write to file in FILE thread 2015-06-23 20:58:56 +05:30
Cheng Zhao
4359eb4472 mac: Set NSHighResolutionCapable in Info.plist, close #2020 2015-06-23 23:02:49 +08:00
Cheng Zhao
3b762fddfb Merge pull request #2039 from atom/cleanup-web-contents-js
Some cleanup of WebContents and BrowserWindow code
2015-06-23 22:57:08 +08:00
Cheng Zhao
93fb70b62f Merge pull request #2030 from deepak1556/file_download_patch
browser: creating download manager delegate to handle downloads
2015-06-23 22:39:12 +08:00
Cheng Zhao
6d9ca4f52b Clean up coffee files 2015-06-23 22:11:59 +08:00
Cheng Zhao
77dbec305f Emit ATOM_BROWSER_RELEASE_RENDER_VIEW in C++ 2015-06-23 21:27:50 +08:00
deepak1556
8f429bc25a browser: creating download manager delegate to handle downloads 2015-06-23 17:54:07 +05:30
Cheng Zhao
42e21d15bf Remove all calls to node::MakeCallback
node::MakeCallback is doing too much for us, avoid calling it.
2015-06-23 20:14:03 +08:00
Cheng Zhao
78459b913b Add EmitEvent function to replace node::MakeCallback 2015-06-23 19:46:37 +08:00
Cheng Zhao
197a9b4165 Remove calls to v8::Isolate::GetCurrent
It is generally a bad thing to do since we might have multiple Isolates.
2015-06-23 17:22:14 +08:00
Cheng Zhao
1f97cee7c9 Fix release render view with wrong ID 2015-06-23 16:43:55 +08:00
Cheng Zhao
015ef3e014 Omit extra transfer of new-window event 2015-06-23 16:34:22 +08:00
Cheng Zhao
2d65c3bcd0 Clean up SetAllowTransparency 2015-06-23 16:19:12 +08:00
Cheng Zhao
52789ab96f Implement getId in C++ 2015-06-23 16:16:10 +08:00
Cheng Zhao
89c7028ed1 Don't include routing ID in WebContents's ID 2015-06-23 16:09:34 +08:00
Cheng Zhao
b3905e867e Bump v0.28.3 2015-06-23 14:22:17 +08:00
Cheng Zhao
aba517d4fd Merge pull request #2014 from atom/enable-zygote
Use zygote process on Linux
2015-06-23 13:34:40 +08:00
Cheng Zhao
4f6e70a75c Merge pull request #2034 from hongrich/internalModuleReadFile-asar-unpack
Update internalModuleReadFile to support unpacked asar files
2015-06-23 12:38:02 +08:00
Cheng Zhao
7b542b88f0 Merge pull request #2028 from preco21/master
Translate docs to korean (Re PR)
2015-06-23 11:12:23 +08:00
Cheng Zhao
3519dd96ee Merge pull request #2019 from atom/pdf-api-doc
Add usage sample code of printToPDF API.
2015-06-23 10:20:46 +08:00
Cheng Zhao
1ce86b6dfc win: Fix building, close #2018 2015-06-23 10:18:43 +08:00
Cheng Zhao
19963bfcd1 Merge pull request #1981 from atom/cookies-api
Implement Cookies api
2015-06-23 10:04:42 +08:00
Cheng Zhao
2fca10ac98 Merge pull request #2009 from deepak1556/webview_patch
override: set window.opener to null for webview
2015-06-23 10:03:40 +08:00
Rich Hong
f51103f44a Update internalModuleReadFile to support unpacked asar files
Add tests for reading unpacked files using both fs.readFileSync and
internalModuleReadFile
2015-06-22 19:38:47 -04:00
Kevin Sawicki
339496a361 Merge pull request #2024 from atom/dev-tools-doc
📝 Add missing BrowserWindow.isDevToolsOpened method.
2015-06-22 08:49:40 -07:00
Plusb Preco
30dfd54575 First translation
Translate docs to korean
2015-06-22 14:06:06 +09:00
Haojian Wu
532f75fcab Update PowerSaveBlocker APIs design. 2015-06-22 12:08:09 +08:00
Haojian Wu
7ee2a703d9 📝 Add powerSaveBlocker APIs doc. 2015-06-21 21:14:49 +08:00
Haojian Wu
7c5afdd388 Add PowerSaveBlocker APIs. 2015-06-21 21:14:14 +08:00
Haojian Wu
f73e1f9188 📝 Add missing BrowserWindow.isDevToolsOpened method. 2015-06-21 10:56:40 +08:00
Haojian Wu
d50db378d7 Add usage sample code of printToPDF API. 2015-06-20 15:18:21 +08:00
Haojian Wu
db23d1165c Update cookies spec. 2015-06-20 10:42:18 +08:00
Haojian Wu
bafbee805c Fix more code styles. 2015-06-20 10:41:40 +08:00
Cheng Zhao
ef59f4f243 Move headers to atom/common 2015-06-19 23:11:53 +08:00
Cheng Zhao
83fe340b98 Make process.argv work with zygote 2015-06-19 22:56:10 +08:00
Cheng Zhao
b4f90c8c81 Update libchromiumcontent to enable zygote process 2015-06-19 22:01:32 +08:00
Cheng Zhao
a1cbd11b5b Only append --register-standard-schemes when needed 2015-06-19 21:53:29 +08:00
Cheng Zhao
befdfceada Merge pull request #1998 from deepak1556/process_patch
process: add hang method
2015-06-19 16:21:29 +08:00
Cheng Zhao
49e1316f7f Merge pull request #1970 from deepak1556/scheme_patch
protocol: api to register custom schemes to standard schemes
2015-06-19 16:16:46 +08:00
Haojian Wu
c164da5a38 Make cookie aligns to Chrome's. 2015-06-19 14:18:22 +08:00
Haojian Wu
969916442f Use webContents BrowserContext.
Also fix some code styles.
2015-06-19 13:57:54 +08:00
Haojian Wu
99bfc9b7f5 Move cookies APIs to webContents.session.cookies namespace. 2015-06-19 10:30:08 +08:00
Haojian Wu
245dc01e33 Add cookies spec. 2015-06-19 10:29:18 +08:00
Haojian Wu
4818e76ad9 📝 add cookies doc. 2015-06-19 10:29:18 +08:00
Haojian Wu
98adcac5df Move set status code into error. 2015-06-19 10:29:17 +08:00
Haojian Wu
19e96cc212 Fix cpplint. 2015-06-19 10:29:17 +08:00
Haojian Wu
cfffe39151 Add cookies.set API. 2015-06-19 10:29:17 +08:00
Haojian Wu
0dfd00f664 Add cookies.remove API. 2015-06-19 10:29:17 +08:00
Haojian Wu
dbbc2f19f4 Implement cookies.get API. 2015-06-19 10:29:17 +08:00
deepak1556
cb1d9f60ec override: set window.opener to null for webview 2015-06-18 21:14:45 +05:30
Cheng Zhao
db2042f561 Merge pull request #2004 from atom/remove-global-browser-context
Remove global browser context
2015-06-18 18:25:42 +08:00
Cheng Zhao
91f3b3955a Remove AtomBrowserContext::Get 2015-06-18 17:19:29 +08:00
Cheng Zhao
923296b4ee Use the BrowserContext from protocol 2015-06-18 17:18:11 +08:00
Cheng Zhao
e209312459 Replace a few calls to AtomBrowserMainParts::Get.
These calls replies on global BrowserContext, we can just make them use
the future default BrowserContext.
2015-06-18 17:01:23 +08:00
Cheng Zhao
b47fae7393 Make api::Protocol per-context 2015-06-18 16:59:03 +08:00
deepak1556
8e05fe3350 process: add hang method 2015-06-18 14:14:29 +05:30
Cheng Zhao
e6341ceaaa Move BrowserProcess to BrowserMainParts 2015-06-18 16:34:02 +08:00
Cheng Zhao
0120be5b8c Don't rely on real focus/blur events in tests
It is super unreliable.
2015-06-18 16:31:55 +08:00
Cheng Zhao
19436358fb win: Fix setContentSize changing window position
Close #1934.
2015-06-18 16:17:13 +08:00
Cheng Zhao
2cb1aa6639 Merge pull request #1997 from deepak1556/api_app_patch
app: adding focus/blur events
2015-06-18 15:55:59 +08:00
deepak1556
2f36f5ca78 app: adding browser-window-focus/blur events 2015-06-18 11:29:08 +05:30
Cheng Zhao
25a7bcef82 Bump v0.28.2 2015-06-18 13:15:13 +08:00
Cheng Zhao
c8eaaaea83 mac: Use NSFileManager::resultingItemURL for moving file to trash
This allows the deleted file to be restored, fixes #2001.
2015-06-18 13:09:02 +08:00
Cheng Zhao
beb2853bbf Update how to rebrand from source, close #1999 2015-06-18 12:59:13 +08:00
Cheng Zhao
f76b60f295 Update brightray 2015-06-18 12:42:02 +08:00
deepak1556
663a48ee38 protocol: api to register custom schemes to standard schemes 2015-06-17 14:43:04 +05:30
Cheng Zhao
db8ffe1dc7 Handle ".." in asar path, fix #1982 2015-06-17 15:52:49 +08:00
Cheng Zhao
ad59393641 Update brightray, close #1025 2015-06-17 12:38:36 +08:00
Cheng Zhao
a751f4c689 Merge pull request #1835 from hokein/pdf-api
Add `BrowserWindow.printToPDF` API Implementation
2015-06-17 12:22:56 +08:00
Cheng Zhao
b3e9d35667 Merge pull request #1995 from atom/request-http-job
Implement protocol.RequestHttpJob
2015-06-17 12:00:26 +08:00
Cheng Zhao
c2aa7d538f Fix cpplint warnings 2015-06-17 11:34:47 +08:00
Cheng Zhao
1d41903779 docs: protocol.RequestHttpJob 2015-06-17 11:32:39 +08:00
Cheng Zhao
92f3371118 Use |request|'s headers if possible 2015-06-17 11:30:31 +08:00
Cheng Zhao
543c4d5597 Allow setting referrer 2015-06-17 11:22:02 +08:00
Cheng Zhao
e07f5cd53f Use |request|'s method if |method| is not specified 2015-06-17 11:11:13 +08:00
Cheng Zhao
66c4c7e77b Clear pending_buffer_ at correct time 2015-06-17 11:04:15 +08:00
Cheng Zhao
274854876c Allow setting method for RequestHttpJob 2015-06-17 10:57:26 +08:00
Cheng Zhao
81db8e098e Don't need buffer for piping data 2015-06-17 10:19:58 +08:00
Cheng Zhao
af05f26a5f Make URLRequestFetchJob actually work 2015-06-17 09:31:33 +08:00
Paul Betts
0b35d97821 Merge pull request #1994 from atom/paulcbetts-patch-1
Note that setPressedImage only has an effect on OS X
2015-06-16 18:18:14 -07:00
Paul Betts
8a56ab3947 Note that setPressedImage only has an effect on OS X 2015-06-16 18:17:51 -07:00
Haojian Wu
82b1607c1e 📝 Add missing printToPDF API in webview. 2015-06-16 20:17:58 +08:00
Haojian Wu
16348fc895 Copy pdf data on IO thread to avoid causing main process hangs. 2015-06-16 20:08:30 +08:00
Haojian Wu
1eba552a8d Also Expose printToPDF to BrowserWindow. 2015-06-16 20:08:30 +08:00
Haojian Wu
47eac062f6 Expose Print API to webContents and webView.
Also move the print implementation from window to webContents.
2015-06-16 20:08:30 +08:00
Haojian Wu
57580e00f9 Fix code style. 2015-06-16 20:07:45 +08:00
Haojian Wu
93bbc6c810 Simplify the pdf-data handled code. 2015-06-16 20:07:45 +08:00
Haojian Wu
894f9c0cb0 Don't use duprecated node buffer api, fix build error on OS X. 2015-06-16 20:07:44 +08:00
Haojian Wu
f22662ffb2 📝 Update docs. 2015-06-16 20:07:44 +08:00
Haojian Wu
559eb20e7f Fixing type: printBackgrounds => printBackground 2015-06-16 20:07:44 +08:00
Haojian Wu
ccbe554ec0 Make callback aligns node.js style. 2015-06-16 20:07:44 +08:00
Haojian Wu
93243ef223 Remove some unused IPC messages. 2015-06-16 20:07:44 +08:00
Haojian Wu
47439cd77c Fix a type error. 2015-06-16 20:07:44 +08:00
Haojian Wu
ac62871645 Return node::Buffer as a printToPDF callback result. 2015-06-16 20:07:44 +08:00
Haojian Wu
ab40da3f31 Add silent and savePath options. 2015-06-16 20:07:43 +08:00
Haojian Wu
6e099af5fe Move PDF printing setting in JS part. 2015-06-16 20:07:43 +08:00
Haojian Wu
c0a6cb69bf Move printToPDF API to WebContents.
Also expose in webview.
2015-06-16 20:06:52 +08:00
Haojian Wu
2597ded985 Cleanup. 2015-06-16 20:02:25 +08:00
Haojian Wu
10da361db1 Fix a type error in checking function options. 2015-06-16 20:02:25 +08:00
Haojian Wu
36fa4da252 Fix Linux compilation error. 2015-06-16 20:02:25 +08:00
Haojian Wu
68005f9ad4 Fix OS X compilation error. 2015-06-16 20:02:25 +08:00
Haojian Wu
bf5d448e37 📝 Add BrowserWindow.printToPDF API docs. 2015-06-16 20:02:24 +08:00
Haojian Wu
600077996c Fix a landscape option error. 2015-06-16 20:02:24 +08:00
Haojian Wu
cef177abc4 Add preview failed error. 2015-06-16 20:02:24 +08:00
Haojian Wu
8572ccb807 Add callback function in printToPDF API. 2015-06-16 20:02:24 +08:00
Haojian Wu
ce8bbb689c Add options to custom print settings in printToPDF API. 2015-06-16 20:02:24 +08:00
Haojian Wu
9cf9229308 Write PDF file in FILE thread. 2015-06-16 20:02:23 +08:00
Haojian Wu
7ffa7042b1 Add printToPDF Implementation. 2015-06-16 20:02:23 +08:00
Haojian Wu
b360f7d86a Add printToPDF API skeleton. 2015-06-16 20:02:23 +08:00
Cheng Zhao
44f8bfc550 Don't leak URLFetcher 2015-06-16 17:09:25 +08:00
Cheng Zhao
bd704dd8aa Merge pull request #1979 from deepak1556/remote_args_patch
remote: handle circular reference in wrapArgs
2015-06-16 16:40:06 +08:00
Cheng Zhao
7b3fc14023 docs: --ignore-connections-limit 2015-06-16 16:13:46 +08:00
deepak1556
193f95a888 remote: handle circular reference in wrapArgs 2015-06-16 13:43:30 +05:30
Cheng Zhao
b03f44df10 Update brightray for #1960 2015-06-16 16:04:03 +08:00
Cheng Zhao
bf9af4d45b Merge pull request #1980 from magicae/set-audio-mute
webContents: add setAudioMuted to webContents
2015-06-16 14:46:31 +08:00
Cheng Zhao
8181e9a0ef Update brightray for #1941 2015-06-16 13:38:21 +08:00
Cheng Zhao
d9db657b43 Merge pull request #1967 from j13z/patch-1
Add minor grammar fixes
2015-06-16 10:30:06 +08:00
Cheng Zhao
e96119fc32 s/liste/listen 2015-06-16 10:08:32 +08:00
Magica
8aa559fe51 Add setAudioMuted to webContents 2015-06-15 21:40:49 +08:00
deepak1556
a5e2f8e79e protocol: adding requestHttpJob method 2015-06-15 03:20:45 +05:30
Johannes Schmitz
2b3a80ecda Add minor grammar fixes 2015-06-13 16:58:18 +02:00
Benjamin Pasero
7da3e84369 Update app.md to document how open-file is emitted
On Mac, open-file is also emitted when the application is not yet running.
2015-06-12 12:37:53 +02:00
Cheng Zhao
8b8a6aea74 Bump v0.28.1 2015-06-12 16:26:51 +08:00
Cheng Zhao
16e224bb86 Don't set browser_handles_all_top_level_requests
POST requests currently can not be handled on browser side.

Fix #1945.
2015-06-12 16:26:04 +08:00
Cheng Zhao
459d389e03 Merge pull request #1951 from sotayamashita/translate/quick-start-jp.md
Translate quick-start.md into Japanese.
2015-06-12 15:49:21 +08:00
Cheng Zhao
8e4581a3c0 Merge pull request #1932 from samueleaton/master
adds example for "before using methods"
2015-06-12 15:07:17 +08:00
Cheng Zhao
c97c3fb9a1 Use LSGetApplicationForURL to search for app
It costs less.
2015-06-12 13:54:42 +08:00
Cheng Zhao
7ce8156691 Merge branch 'master' of https://github.com/mattotodd/electron into mattotodd-master 2015-06-12 13:49:51 +08:00
Sota Yamashita
0e6a70c556 Tranlsate quick-start-jp.md: status first
Translate: quick-start-jp.md

Fix bug

Tranlsate the world web

Change the method

Translate tutorial/quick-start-jp.md

Translate docs

Translate

Translate quick-start
2015-06-12 14:44:47 +09:00
Sam Eaton
b68d559329 Merge branch 'master' of https://github.com/atom/electron 2015-06-11 07:13:45 -06:00
Cheng Zhao
18fcd6990b win: Fix running spec 2015-06-11 14:14:22 +08:00
Cheng Zhao
5fe130a684 Bump v0.28.0 2015-06-11 12:13:18 +08:00
eaton11
d367af3fa4 Merge branch 'master' of https://github.com/atom/electron 2015-06-10 19:28:14 -06:00
Sam Eaton
549ec51bce adds 'before using methods' example
The document does not inform that the webview element has to be loaded
before using the element's methods. It is not clear.
2015-06-10 19:24:36 -06:00
msullivan
b4674923c9 return bool on shell.openExternal 2015-06-10 11:06:22 -04:00
Cheng Zhao
71598e15bf Update node to fix crash caused by malloc 2015-06-10 21:08:54 +08:00
Cheng Zhao
cd3c061448 win: Fix compilation error 2015-06-10 19:34:30 +08:00
Cheng Zhao
163790d107 docs: Update formats 2015-06-10 19:18:33 +08:00
Cheng Zhao
2fdc5780ff Merge pull request #1859 from deepak1556/client_certificate_patch
browser: support client certificate
2015-06-10 19:17:41 +08:00
Cheng Zhao
b76642bd10 Update brightray 2015-06-10 19:16:45 +08:00
Cheng Zhao
209e24bf0f Merge pull request #1925 from atom/update-iojs
Update to io.js v2.2.1
2015-06-10 19:11:57 +08:00
Cheng Zhao
731773765e Update iojs to fix linking on Linux 2015-06-10 16:40:35 +08:00
Cheng Zhao
333fe87490 Define V8_BASE 2015-06-10 16:30:47 +08:00
Cheng Zhao
36f0ef703a Update io.js to v2.2.1 2015-06-10 16:19:19 +08:00
Cheng Zhao
605722c397 Make asar work with internalModuleReadFile and internalModuleStat 2015-06-10 16:18:55 +08:00
Cheng Zhao
132c13a11b Fix calls to deprecated node::ThrowError API 2015-06-10 14:21:09 +08:00
Cheng Zhao
04d24f61fe Update to node.gyp's changes 2015-06-10 14:11:34 +08:00
Cheng Zhao
8eb5e651a2 Suppress some tests on CI
The Mac runner of Travis CI is too flacky.
2015-06-10 12:52:52 +08:00
Cheng Zhao
5cd0fc4d52 Merge pull request #1921 from samueleaton/patch-1
adds display:inline-block to style tag
2015-06-10 12:48:57 +08:00
Cheng Zhao
d12697c657 Merge pull request #1918 from kirkouimet/master
Fixing an issue compiling on Windows and improving webview interopability with other JavaScript libraries
2015-06-10 12:48:45 +08:00
Cheng Zhao
0819176cb1 Merge branch 'master' of https://github.com/alexwarren/electron into alexwarren-master 2015-06-10 12:39:59 +08:00
Cheng Zhao
7d1f6dae6f Merge pull request #1911 from thomastuts/doc-fixes
Documentation fixes: grammar, spelling and code
2015-06-10 12:35:55 +08:00
Cheng Zhao
5c2bb42d49 Merge pull request #1922 from atom/remote-clipboard
Don't use clipboard module in renderer process on Linux
2015-06-10 12:34:32 +08:00
Cheng Zhao
db9615f5cd Don't rely on JS for setting optional argument
It makes the code much shorter and cleaner.
2015-06-10 12:12:37 +08:00
Kirk Ouimet
09c5da7147 Fixing cpplint line width 2015-06-09 21:06:40 -07:00
Cheng Zhao
4b12a95d37 Transfer Buffer through "remote" 2015-06-10 11:58:15 +08:00
Cheng Zhao
200a19dad9 linux: Don't use clipboard module in renderer process 2015-06-10 11:57:28 +08:00
Sam Eaton
2ee6e43fb3 adds display:inline-block to style tag
The example attempts to change the height of an inline element (webview), which has no effect. 
The height will now take effect.
2015-06-09 21:51:10 -06:00
Kirk Ouimet
0fef09281b Guarding webview attributes against polluted Object.prototypes
Ran into an error with the buildParams function breaking when using a JavaScript library that modified the Object.prototype, this small fix resolves the issue.
2015-06-09 16:17:00 -07:00
kirkouimet
f91a81fe77 Convert std::string path to a FilePath to get compiling working on Windows 2015-06-09 15:56:54 -07:00
Alex Warren
78eff673ec Make consistent with other example 2015-06-09 22:09:23 +01:00
Alex Warren
51dc8ad70a Corrections to menu.md 2015-06-09 22:08:34 +01:00
Thomas Tuts
d8cd9b71b0 Clean up Selenium webdriver code example 2015-06-09 18:18:47 +02:00
Thomas Tuts
c78a3ff714 Replace shorthand if-statement notation in Pepper Flash docs 2015-06-09 18:17:38 +02:00
Thomas Tuts
4642630674 Replace shorthand if-statement notation in quick start docs 2015-06-09 18:17:12 +02:00
Thomas Tuts
a6a5d50c3f Add missing semicolons in devtools extension docs 2015-06-09 18:15:54 +02:00
Thomas Tuts
b4790a7531 Remove trailing commas in desktop environment docs 2015-06-09 18:15:30 +02:00
Thomas Tuts
9199d0df0a Add missing semicolon in webview tag documentation 2015-06-09 18:14:06 +02:00
Thomas Tuts
a84e6227ef Remove obsolete space in console log when using multiple arguments 2015-06-09 18:12:34 +02:00
Thomas Tuts
35dcdfc492 Remove trailing comma in tray code example 2015-06-09 18:11:40 +02:00
Thomas Tuts
2f4333b852 Declare one variable per statement in protocol code example 2015-06-09 18:10:02 +02:00
Thomas Tuts
bd1fd9680f Add missing commas in menu docs 2015-06-09 18:08:27 +02:00
Thomas Tuts
cf79f439ce Remove trailing commas in menu docs 2015-06-09 18:08:02 +02:00
Thomas Tuts
e829a28947 Clean up code in global shortcut code example 2015-06-09 18:01:09 +02:00
Thomas Tuts
6d756d9d13 Remove trailing commas from dialog filters code example 2015-06-09 17:59:53 +02:00
Thomas Tuts
29abfa68e9 Fix grammar and JS example for Chrome command line switches docs 2015-06-09 16:59:14 +02:00
Thomas Tuts
ab98dcd7cf Try to clarify docs for window.onbeforeunload() 2015-06-09 16:56:45 +02:00
Thomas Tuts
6494ed6b13 Make platform compatibility notes consistent 2015-06-09 16:51:54 +02:00
Thomas Tuts
8893c9502a Use consistent naming convention for 'task bar' concept 2015-06-09 16:49:44 +02:00
Thomas Tuts
13b6ed6dc5 Fix several typos and grammar errors 2015-06-09 16:49:21 +02:00
Cheng Zhao
8aa815e6d1 Merge pull request #1907 from timruffles/patch-1
doc on how to test with your application
2015-06-09 18:48:52 +08:00
Tim Ruffles
719f68a44b doc on how to test with your application 2015-06-09 10:29:47 +01:00
Cheng Zhao
4c48f0cd36 Merge pull request #1882 from atom/get_uploaded_report_api
Implement crash-reporter.getUploadedReports API
2015-06-09 16:35:08 +08:00
Cheng Zhao
8ef3351846 Merge pull request #1906 from atom/guest-owner-window
Fix getting owner window in guest WebContents
2015-06-09 16:23:28 +08:00
Cheng Zhao
9f0ac13edc Pass embedder when creating WebContents 2015-06-09 15:50:20 +08:00
Cheng Zhao
5459137d3d Remove unused options for WebContents.create 2015-06-09 15:40:04 +08:00
deepak1556
52b2c0d27f default to first certificate from cert store 2015-06-09 13:00:20 +05:30
Cheng Zhao
89087d402d Merge pull request #1873 from atom/multiline-headers
Support multiple-line headers in `did-get-response-details'
2015-06-09 12:03:45 +08:00
Haojian Wu
64e84b8f6a Support multiple-line headers in web-contents `did-get-response-details' event. 2015-06-09 11:18:46 +08:00
Cheng Zhao
24586c1330 Merge pull request #1883 from atom/http-referer-doc
📝 Add missing `httpreferer` option doc.
2015-06-09 11:15:44 +08:00
Cheng Zhao
f8c6056eec Upgrade brightray, fix #1901 2015-06-09 11:10:15 +08:00
Cheng Zhao
03ab9b2686 Merge pull request #1848 from Bitbored/master
Added `bounds` payload to tray `clicked` event on Windows
2015-06-09 10:49:01 +08:00
Haojian Wu
f1a8c5a1ca Use httpReferrer and userAgent new names in webview. 2015-06-09 10:44:54 +08:00
Haojian Wu
488801e244 Rename httpreferrer to httpReferrer, useragent to userAgent. 2015-06-09 10:10:29 +08:00
Haojian Wu
bf1765f941 📝 Add missing useragent doc. 2015-06-09 10:10:28 +08:00
Haojian Wu
994be9cdab 📝 Add missing httpreferer option doc. 2015-06-09 10:10:28 +08:00
Cheng Zhao
d4e4c6ca15 docs: Update formats of command line switches 2015-06-09 09:56:19 +08:00
Cheng Zhao
47cb06e201 Update brightray for --log-net-log 2015-06-09 09:52:11 +08:00
Seppe Stas
cac97cca0d Initialized rect with zeros
As per @zcbenz 's remark: The rect should be initialized with zeros to prevent random values being passed to the click event handler when `Shell_NotifyIconGetRect` fails.
2015-06-08 19:07:46 +02:00
Seppe Stas
16c08e7e37 Switched to gfx::Rect constructor that takes a RECT
As per @zcbenz's suggestion the rect passed to the click event handler now passes a rect constructed using `gfx::Rect(const RECT& r)`.
2015-06-08 19:04:56 +02:00
deepak1556
2de5f9de6c browser: support client certificate 2015-06-08 21:00:32 +05:30
Cheng Zhao
06a3875726 Merge pull request #1880 from deepak1556/net_log_patch
doc: adding info about log-net-log flag
2015-06-08 23:13:27 +08:00
Cheng Zhao
1ae8bed96a Merge pull request #1899 from kirkouimet/guard-for-in-loop
Guarding against polluted Object.prototypes
2015-06-08 22:45:43 +08:00
Cheng Zhao
2ec74b5958 Merge pull request #1886 from BobCochran/linux-build-instructions-issue-1809
Linux build instructions issue 1809
2015-06-08 22:42:04 +08:00
Cheng Zhao
72ebb2c9fe Merge pull request #1885 from lucidogen/patch-1
Added note and link for poorly documented operation.
2015-06-08 22:33:08 +08:00
Cheng Zhao
52166d2999 Merge pull request #1884 from lucidogen/master
Fixed example with correct capturePage api.
2015-06-08 22:32:06 +08:00
Cheng Zhao
676cfa03a1 Merge pull request #1894 from samccone/patch-5
📝 Fix english errors and language
2015-06-08 22:31:17 +08:00
Cheng Zhao
64a89fe755 Merge pull request #1889 from samccone/patch-2
📝 Fix english errors
2015-06-08 22:30:35 +08:00
Cheng Zhao
2bd03f6eda Merge pull request #1890 from samccone/patch-3
📝 Fix english errors and clarify docs
2015-06-08 22:30:25 +08:00
Cheng Zhao
eeaee1a0b7 Merge pull request #1891 from samccone/patch-4
📝 Improve devtools documentation
2015-06-08 22:29:06 +08:00
Cheng Zhao
fed9ef0687 Merge pull request #1860 from atom/dialog-show-file-name
Fix dialog.showSaveDialog doesn't show the non-exist file name on Linux.
2015-06-08 19:41:33 +08:00
Kirk Ouimet
75448ad7ed Guarding against polluted Object.prototypes 2015-06-07 23:59:49 -07:00
Cheng Zhao
25db6e0bd8 Merge pull request #1897 from atom/dumpsyms
mac: Build dump_syms
2015-06-08 13:54:24 +08:00
Cheng Zhao
cefe540ec0 mac: Build dump_syms
Crashpad doesn't ship dump_syms, we have to build to from breakpad.

Related: #1822
2015-06-08 13:47:08 +08:00
Cheng Zhao
8363a39a56 Bump v0.27.3 2015-06-08 13:24:47 +08:00
Cheng Zhao
57ef6adbbd win: Fix runing clipboard spec 2015-06-08 13:24:14 +08:00
Cheng Zhao
5ae9c633ca Fix building on Windows, close #1896 2015-06-08 13:19:56 +08:00
Sam Saccone
b6a5e927e0 📝 Fix english errors and language 2015-06-07 15:32:54 -04:00
BobCochran
625c17fa24 Merge branch 'linux-build-instructions-issue-vm' into linux-build-instructions-issue-1809
Edit the virtual machine section of the instructions.
2015-06-07 08:22:53 -04:00
BobCochran
f776932718 Edited virtual machines sections. 2015-06-07 08:11:44 -04:00
Sam Saccone
55c07cec68 📝 Improve devtools documentation 2015-06-06 21:56:13 -04:00
Sam Saccone
161dc45ec8 📝 Fix english errors and clarify docs 2015-06-06 21:46:51 -04:00
Sam Saccone
29827fa66b 📝 Fix english errors 2015-06-06 21:42:21 -04:00
BobCochran
40b6a1a37c Add instructions to clean build products 2015-06-06 18:04:11 -04:00
Lucidogen Media
e4ae579b16 Added note and link for poorly documented operation.
Accessing renderer process from main process is not documented and as "remote" does the opposite, it seems fair to add a pointer here.
2015-06-06 13:38:00 +02:00
Lucidogen Media
582a42f97c Added ending semicolon for consistency. 2015-06-06 13:31:22 +02:00
Lucidogen Media
9a0a10e766 Fixed example with correct capturePage api. 2015-06-06 13:20:47 +02:00
Haojian Wu
cd1c331112 Fix coffeelint error. 2015-06-06 17:59:20 +08:00
BobCochran
8a2b665097 Edit linux build instructions based on feedback 2015-06-05 19:38:30 -04:00
deepak1556
690513db7f doc: adding info about log-net-log flag 2015-06-06 00:59:28 +05:30
Cheng Zhao
13c1b078f9 Fix refreshing test window 2015-06-05 19:48:58 +08:00
Haojian Wu
4da7578dab 📝 Add getUploadedReports API doc. 2015-06-05 19:05:55 +08:00
Haojian Wu
c821a06e2f Implement crash-reporter.getUploadedReports API.
Also redefine the getLastCrashReport API implementation using
getUploadedReports API.
2015-06-05 18:59:03 +08:00
Cheng Zhao
cd7b3dd291 Merge pull request #1874 from atom/fewer-code
Remove duplicate code between api::WebContents and NativeWindow
2015-06-05 18:40:38 +08:00
Cheng Zhao
bb42c2c7b6 Avoid destorying api::WebContents for twice 2015-06-05 18:13:30 +08:00
Cheng Zhao
af62b7b5c9 Put common code of OpenURLFromTab to CommonWebContentsDelegate 2015-06-05 17:45:17 +08:00
Cheng Zhao
8f9a109fa6 Implement HTML5 fullscreen in CommonWebContentsDelegate 2015-06-05 17:27:24 +08:00
Cheng Zhao
05468cc3fa Remove devtools APIs from NativeWindow 2015-06-05 17:01:17 +08:00
Cheng Zhao
94d69777fa Enable calling WebContents::openDevTools for BrowserWindow's WebContents 2015-06-05 15:41:03 +08:00
Cheng Zhao
67144aaf2a Remove duplicate def of is_guest 2015-06-05 15:18:15 +08:00
Cheng Zhao
d9efc3b4bf Move more methods to CommonWebContentsDelegate 2015-06-05 15:12:38 +08:00
Cheng Zhao
c32aac0a56 Manage webview with CommonWebContentsDelegate 2015-06-05 15:01:51 +08:00
Cheng Zhao
92b15c81e9 Manage InspectableWebContents in CommonWebContentsDelegate 2015-06-05 14:55:07 +08:00
Cheng Zhao
19d742de37 Add CommonWebContentsDelegate 2015-06-05 13:49:24 +08:00
Cheng Zhao
e8f33f51fb Use DefaultWebContentsDelegate in api::WebContents 2015-06-05 13:41:45 +08:00
Cheng Zhao
7f7cdbf775 Remove NativeWindow::CallDevToolsFunction 2015-06-05 13:32:01 +08:00
Cheng Zhao
7f42c0fa21 Update brightray 2015-06-05 13:27:13 +08:00
Cheng Zhao
8306dc427a Merge pull request #1867 from deepak1556/devtools_workspace_patch
devtools: supporting workspace usage
2015-06-05 13:26:37 +08:00
Cheng Zhao
66b3972fbc Fix typo 2015-06-05 10:03:01 +08:00
BobCochran
ed244648d0 Update build instructions for Linux 2015-06-04 21:03:45 -04:00
deepak1556
790fba598e devtools: supporting workspace usage 2015-06-05 01:06:53 +05:30
Cheng Zhao
129159c895 docs: Say more about page-visibility option 2015-06-04 22:42:36 +08:00
Cheng Zhao
f4c696b922 Merge pull request #1863 from atom/default-menu
Create a default menu for apps ran by default_app
2015-06-04 22:36:33 +08:00
Cheng Zhao
f54506acc0 Merge pull request #1822 from hokein/crashpad-mac
Crashpad!
2015-06-04 22:11:14 +08:00
Cheng Zhao
4466082592 Revert "Update libchromiumcontent, fix #1786"
This reverts commit 1314b7c7e5.
2015-06-04 21:15:29 +08:00
Cheng Zhao
a8256a62e0 Merge pull request #1837 from deepak1556/render_client_patch
renderer: option to override page visiblity state
2015-06-04 21:13:55 +08:00
deepak1556
683917ae67 renderer: option to override page visiblity state 2015-06-04 14:40:13 +05:30
Cheng Zhao
a22b9be681 mac: Do nothing if calling Menu.setApplicationMenu(null) 2015-06-04 16:14:19 +08:00
Cheng Zhao
3b20f2aced docs: Mention how to remove menu bar 2015-06-04 16:12:29 +08:00
Cheng Zhao
5d23b7468e Allow removing menu bar 2015-06-04 16:10:19 +08:00
Haojian Wu
d5b47d1059 Simplify and polish the code. 2015-06-04 15:53:37 +08:00
Cheng Zhao
47e9deeb9a Remove Menu::AttachToWindow
It makes the logic more complex without any benefit
2015-06-04 15:32:33 +08:00
Cheng Zhao
6d6e75795f Allow settting menu to null 2015-06-04 15:14:43 +08:00
Cheng Zhao
cc3066e746 Create a default menu for apps ran by default_app 2015-06-04 14:54:53 +08:00
Cheng Zhao
0fcc0f3e0a Update brightray for #1809 2015-06-04 14:41:44 +08:00
Haojian Wu
da83ba6c06 Fix dialog.showSaveDialog doesn't show the non-exist file name on Linux. 2015-06-04 14:16:53 +08:00
Cheng Zhao
3c186946eb docs: python 2.7 is required, close #1830 2015-06-03 19:27:04 +08:00
Cheng Zhao
31beee9599 Check for nullness when comparing webContents, close #1838 2015-06-03 18:48:10 +08:00
Cheng Zhao
912ed2ca10 Merge pull request #1839 from deepak1556/devtools_api_patch
devtools: initialise devtoolsWebContents when opened with inspect* apis
2015-06-03 18:31:25 +08:00
Cheng Zhao
c2352d3499 Merge pull request #1850 from atom/webview-update-process-id
Don't search NativeWindow or guest view by child process ID
2015-06-03 15:02:39 +08:00
Cheng Zhao
3a3b05b2f0 Clean up code 2015-06-03 14:53:19 +08:00
Cheng Zhao
95a8f3fc70 Fix changing src would calling loadUrl for twice 2015-06-03 14:33:22 +08:00
Cheng Zhao
34cd1435b4 Clean up code 2015-06-03 14:17:28 +08:00
Cheng Zhao
d4be2da70e Don't rely on process_id to search for NativeWindow 2015-06-03 14:08:56 +08:00
Seppe Stas
e5c4e34ac4 Ow 💩, where did that extra space come from? 2015-06-03 07:54:38 +02:00
Cheng Zhao
6dfa7b5383 Don't rely on guest_process_id for searching guest 2015-06-03 13:45:06 +08:00
Haojian Wu
94382cbaa2 Fix cpplint error. 2015-06-03 11:31:34 +08:00
Haojian Wu
981908c336 Add missing crashpad submodule. 2015-06-03 11:13:20 +08:00
Cheng Zhao
3ee054e316 Merge pull request #1849 from atom/remove-devtools-hack
Remove AtomResourceDispatcherHostDelegate
2015-06-03 10:48:31 +08:00
Cheng Zhao
f22d4bf0c0 Merge pull request #1814 from fraserxu/master
convert message to string for window.alert method
2015-06-03 10:20:59 +08:00
Cheng Zhao
d46e986e80 Remove AtomResourceDispatcherHostDelegate 2015-06-03 10:08:05 +08:00
Cheng Zhao
bd6d41bd87 Update brightray for updates on devtools_ui 2015-06-03 10:00:29 +08:00
Haojian Wu
4457edb1d3 Implement crash-reporter.getLastLastCrashReport API on OS X. 2015-06-03 09:47:42 +08:00
Seppe Stas
e920ce3e24 Updated tray api docs to reflect changes in ce8aa07 2015-06-02 23:19:49 +02:00
Seppe Stas
ce8aa073ee Added bounds payload to tray clicked event
Used [Shell_NotifyIconGetRect function](https://msdn.microsoft.com/en-us/library/windows/desktop/dd378426) to get the bounds of the application's tray icon.
Note: only works with Windows 7 and later.

Related to #1159, #1500.
2015-06-02 21:43:37 +02:00
Haojian Wu
2396b51cb6 Switch to use crashpad repo under atom org. 2015-06-02 11:46:20 +08:00
Haojian Wu
317406f26d Update crashpad implementation after code review. 2015-06-02 11:41:47 +08:00
deepak1556
67a9931b55 devtools: initialise devtoolsWebContents when opened with inspect* apis 2015-06-01 17:23:44 +05:30
Cheng Zhao
ad851547e0 Merge pull request #1834 from hokein/master
Ship pdf.dll in release, fix #1826
2015-06-01 13:25:31 +08:00
Haojian Wu
c4cbb5ecdb Ship pdf.dll in release. 2015-06-01 13:03:56 +08:00
Cheng Zhao
b97c22d4d7 win: Load pdf.dll with abosolute path, fix #1826 2015-06-01 12:53:43 +08:00
Cheng Zhao
fe631e6eeb Bump v0.27.2 2015-06-01 12:22:36 +08:00
Cheng Zhao
1314b7c7e5 Update libchromiumcontent, fix #1786 2015-06-01 12:19:56 +08:00
Yeechan Lu
c026863d48 Print real error messages even if it looks like an invalid app 2015-06-01 10:13:33 +08:00
Haojian Wu
51d5ef9d86 📝 crash-reporter note on OS X. 2015-05-30 10:06:29 +08:00
Haojian Wu
16fb847009 Add script to setup crashpad repository.
Crashpad use `gclient` to maintain its third_party libraries.
This patch switches `gclient` instead of `git submodule` to align crashpad way.
2015-05-30 09:42:40 +08:00
Haojian Wu
cd8ceec62e Send all crash reports to collection server.
Crashpad client only send reports once per hour. It's different with breakpad.
With this behavior, the other reports generated within an hour will be totally
skipped, which causes the crash api test only run once with an hour.

This patch unrestricts this time limit.
2015-05-30 08:47:52 +08:00
Haojian Wu
98a9d8a9e3 Enable crashpad test on OS X. 2015-05-30 07:34:56 +08:00
Haojian Wu
4e2f242ad0 Use Crashpad instead of Breakpad on OS X. 2015-05-29 23:25:11 +08:00
Cheng Zhao
02bdace366 Delete Node's symbols after Environment has been loaded
Fix #1803.
2015-05-29 22:20:20 +08:00
Cheng Zhao
6ed538b952 docs: Remove obsolete build instructions, close #1809 2015-05-29 18:21:25 +08:00
Cheng Zhao
dfbe158ca9 mac: Remove dead "Frameworks" link, close #1801 2015-05-29 18:14:59 +08:00
Cheng Zhao
fb37b5720d Update brightray to use correct Chrome version string
Close #1808
2015-05-29 17:52:46 +08:00
fraserxu
57ab704300 convert message to string for window.alert method 2015-05-29 15:55:11 +08:00
Cheng Zhao
4a310ad630 Merge pull request #1811 from atom/new-webview
Change how webview is resized
2015-05-29 14:14:23 +08:00
Cheng Zhao
a9ad783bca The ElementSizeChanged has been removed 2015-05-29 13:52:14 +08:00
Cheng Zhao
b5c9fe78f1 Listen to ElementSizeChanged event 2015-05-29 13:47:09 +08:00
Cheng Zhao
e4bb456964 Pass element size when attaching 2015-05-29 11:47:54 +08:00
Cheng Zhao
b45ed8d9a2 pendingGuestCreation is removed 2015-05-29 11:20:28 +08:00
Cheng Zhao
bdf73fcd4c Update to the new algorithm of setting webview size 2015-05-29 11:12:55 +08:00
Cheng Zhao
3e720bd611 Bump v0.27.1 2015-05-28 16:23:29 +08:00
Cheng Zhao
ad89a923e9 Merge pull request #1785 from deepak1556/browser_client_patch
browserClient: dont restart render process for javascript scheme
2015-05-28 16:22:45 +08:00
Cheng Zhao
725115e0b5 Merge pull request #1799 from atom/linux-travis-ci
Use gcc-4.8 on CI machine
2015-05-28 16:22:36 +08:00
Cheng Zhao
419a14a63f Use gcc-4.8 on CI machine 2015-05-28 16:03:06 +08:00
Cheng Zhao
d9102efff7 Merge pull request #1752 from deepak1556/clipboard_patch
clipboard: api to list supported types, reading and writing markup
2015-05-28 15:29:36 +08:00
Cheng Zhao
895ab49857 Merge pull request #1797 from deepak1556/response_headers_patch
fix accessing headers from resourcerequestdetails
2015-05-28 14:44:46 +08:00
Cheng Zhao
ebbb974aca Fix running spec on Windows 2015-05-28 14:43:16 +08:00
Cheng Zhao
8a6ba7c49f Update libchromiumcontent for race condition fix 2015-05-28 14:43:15 +08:00
deepak1556
f98da217e1 fix accessing headers from resourcerequestdetails 2015-05-28 11:20:07 +05:30
Jessica Lord
2060acd914 Merge pull request #1792 from atom/jl-cmd
Replace cmd with bash
2015-05-27 14:37:17 -07:00
Jessica Lord
014d80c359 Replace cmd with bash
Markdown parser doesn’t recognize cmd.
2015-05-27 12:51:19 -07:00
deepak1556
9b7ad675c6 browserClient: dont restart render process for javascript: scheme 2015-05-27 16:39:02 +05:30
Cheng Zhao
6ee8f6e4f2 Bump v0.27.0 2015-05-27 16:57:41 +08:00
deepak1556
4d56281972 restore clipboard.has api and fix docs 2015-05-27 13:35:51 +05:30
deepak1556
5584e3fd49 clipboard: api to list supported types, reading and writing markup 2015-05-27 13:21:56 +05:30
Cheng Zhao
4a376694b4 Merge pull request #1719 from deepak1556/service_worker_patch
devtools: api to inspect service worker
2015-05-27 15:47:41 +08:00
Cheng Zhao
fbdea15649 Update node, fix #634 2015-05-27 15:26:48 +08:00
Cheng Zhao
f961f0617f test: Add case for #634 2015-05-27 15:26:32 +08:00
Cheng Zhao
1c60575dc0 Merge pull request #1738 from deepak1556/http_ptach
webContents: providing header details with response event
2015-05-27 15:05:55 +08:00
Cheng Zhao
abf8ffd3a2 Merge pull request #1689 from deepak1556/ftp_patch
protocol: adding ftp scheme support
2015-05-27 15:04:21 +08:00
Cheng Zhao
935cd92ef3 Update brightray 2015-05-27 15:03:12 +08:00
Cheng Zhao
172a5a71fc docs: "move" and "moved" are platform-dependent 2015-05-27 14:57:14 +08:00
Cheng Zhao
c244e83e10 Merge pull request #1633 from deepak1556/window_event_patch
window: adding resize and move events
2015-05-27 14:54:36 +08:00
Cheng Zhao
291604515f Update libchromiumcontent for optional pdf.dll 2015-05-26 12:44:24 +08:00
Cheng Zhao
904b75ab4a Merge pull request #1669 from hokein/pdf-dll
Load pdf library dynamically
2015-05-26 12:41:51 +08:00
deepak1556
2de0b025f1 retrieve headers from response info 2015-05-24 10:56:25 +05:30
Cheng Zhao
5f52ca918f Merge pull request #1763 from samccone/patch-4
Fix grammatical issues take 3
2015-05-24 10:43:37 +08:00
Cheng Zhao
16a95a42ff Merge pull request #1761 from samccone/patch-3
docs: Fix grammatical issues
2015-05-24 10:42:53 +08:00
Cheng Zhao
4282ed6a3c Merge pull request #1760 from samccone/patch-2
Docs: Fix grammatical issue
2015-05-24 10:42:47 +08:00
Sam Saccone
a642782a00 💄 Fix grammatical issues 2015-05-23 18:44:58 -04:00
Sam Saccone
0bb4e0e44a 💄 Fix grammatical issues 2015-05-23 16:00:09 -04:00
Sam Saccone
d91ddc6177 💄 Fix grammatical issue 2015-05-23 15:41:36 -04:00
deepak1556
2b9826404a using mate::Dictionary instead of base::DictionaryValue 2015-05-23 19:26:47 +05:30
deepak1556
4d5790dc09 return headers as object 2015-05-23 19:26:47 +05:30
deepak1556
c22b138b67 webContents: providing header details with response event 2015-05-23 19:26:47 +05:30
Haojian Wu
fdad5892d9 📝 Add pdf.dll note doc. 2015-05-23 21:39:59 +08:00
Haojian Wu
c3791bba78 Remove duplicated macro. 2015-05-23 19:24:37 +08:00
Haojian Wu
bf5f85645e Remove the multiple rules generate pdf.dll warning in GYP during debug
build.
2015-05-23 19:24:35 +08:00
Haojian Wu
f1f801b7a2 Copy pdf.dll to build directory. 2015-05-23 19:24:30 +08:00
Haojian Wu
5ede62459c Rename PrintHandler to PrintHandlerWin since only used on Windows. 2015-05-23 19:24:29 +08:00
Haojian Wu
abd97a7513 Load pdf component dynamically.
Ship pdf as dll library, electron only loads pdf.dll when calling print
API. In this way, the developer who don't need print feature can safe
remove the pdf.dll in saving their binary size.
2015-05-23 19:24:27 +08:00
Cheng Zhao
30d815e28f Merge pull request #1755 from atom/chrome43
Upgrade to Chrome 43
2015-05-23 12:24:36 +08:00
Cheng Zhao
e233eab4f2 HandleMouseDown is deprecated 2015-05-23 11:58:20 +08:00
Cheng Zhao
b202bba2e6 Don't read Buffer in IO thread 2015-05-22 22:15:13 +08:00
Cheng Zhao
d78efe7c22 Use Local instead of Handle 2015-05-22 19:11:22 +08:00
Cheng Zhao
b169ac016e Start AtomRenderFrameObserver 2015-05-22 15:59:29 +08:00
Cheng Zhao
d1685f79a2 Initialize V8 in browser process
Previously it was initialized by ProxyResolverV8, but after Chrome 43 V8
started to initialize V8 lazily.
2015-05-22 15:30:02 +08:00
Cheng Zhao
01e891652f Fix compilation errors 2015-05-22 15:24:34 +08:00
Cheng Zhao
c82d21b39f Add AtomRenderFrameObserver 2015-05-22 15:01:13 +08:00
Cheng Zhao
63c2a7f1a9 Upgrade to Chrome 43 2015-05-22 14:57:00 +08:00
deepak1556
9a60fde59b alias move and moved event on OS X 2015-05-22 12:24:12 +05:30
Robo
f46fcd158a chnage move hook and add details to doc 2015-05-22 12:13:01 +05:30
Robo
1b1735bca9 avoid unnecessary api calls 2015-05-22 12:13:00 +05:30
deepak1556
3a5977e09f window: adding resize and move events 2015-05-22 12:13:00 +05:30
Cheng Zhao
d34800bb0a Merge pull request #1708 from kevva/patch-1
Add link to `awesome-electron`
2015-05-22 14:24:59 +08:00
Cheng Zhao
662261f84f Merge pull request #1724 from atom/jl-contrib
Add a CONTRIBUTING.md document
2015-05-22 10:33:39 +08:00
Cheng Zhao
33a926c5d3 Fix typo 2015-05-22 10:32:59 +08:00
Cheng Zhao
c372dcb462 Merge pull request #1706 from hammerandchisel/crash-reporter-reinit
Explicitly null the crash reporter before assigning it
2015-05-22 10:17:00 +08:00
Andy Dill
9a768dd4f0 Remove explicit nullptr and add clarifying comment. 2015-05-21 09:02:17 -07:00
Cheng Zhao
82377cbfd5 Bump v0.26.1 2015-05-21 15:52:42 +08:00
Cheng Zhao
83ba21f622 Merge pull request #1741 from atom/gtk-tray-click
Notify the click event in Linux tray icon
2015-05-21 15:46:15 +08:00
Cheng Zhao
f31bfab127 gtk: Notify the click event 2015-05-21 15:22:52 +08:00
Cheng Zhao
466fc9a2fa Remove trailing white space 2015-05-21 15:16:06 +08:00
Cheng Zhao
fd41f1e8bc Merge pull request #1616 from deepak1556/webview_fullscreen_patch
webContents: override fullscreen notification apis for webview
2015-05-21 15:03:48 +08:00
Cheng Zhao
32b2ef3539 Merge pull request #1710 from deepak1556/screen_patch
screen: initialise displays_ vector with primary display
2015-05-21 14:58:27 +08:00
Cheng Zhao
cde6b41a05 Merge pull request #1730 from deepak1556/webview_navigation_patch
navigation: adding clearHistory method
2015-05-21 14:56:30 +08:00
deepak1556
3ecfadf367 screen: initialise displays_ vector with available displays 2015-05-21 11:28:48 +05:30
deepak1556
27c3727ddb use generated constants 2015-05-21 11:07:25 +05:30
deepak1556
ea147c588f protocol: adding ftp scheme support 2015-05-21 10:59:56 +05:30
deepak1556
e8a02316ce also emit html fullscreen notification on windows when its webview contents trigger it 2015-05-21 10:41:53 +05:30
deepak1556
0dcf061dc1 check if window is html or forced fullscreen 2015-05-21 10:16:11 +05:30
deepak1556
f2d91bc53c adding events to notify fullscreen state 2015-05-21 10:16:11 +05:30
deepak1556
ddda8e4197 track html api triggered fullscreen separaely 2015-05-21 10:16:11 +05:30
deepak1556
4fe294ed04 check for renderviewhost availability before using 2015-05-21 10:16:10 +05:30
deepak1556
be57151037 webContents: override fullscreen notification apis for webview 2015-05-21 10:16:10 +05:30
Cheng Zhao
71ee864d1d docs: Open devtools in the quick start example 2015-05-21 11:16:39 +08:00
Cheng Zhao
427b9567ca Merge pull request #1713 from deepak1556/navigation_patch
navigation: fix accessing url from history array for goToIndex
2015-05-21 10:43:34 +08:00
Cheng Zhao
5e7d6f89e8 Merge pull request #1705 from hammerandchisel/node-not-in-path
compile-coffee.py searches for node even on non-windows systems
2015-05-21 10:38:09 +08:00
Andy Dill
7644799790 Check PATH first 2015-05-20 14:37:26 -07:00
Cheng Zhao
dbecc8d5f5 Merge pull request #1701 from CharlieHess/paste-and-match-style
Paste and Match Style
2015-05-20 23:12:46 +08:00
Cheng Zhao
4ae1998d09 Revert #1604 2015-05-20 20:35:54 +08:00
Cheng Zhao
bbd8f091e0 Merge pull request #1737 from magicae/patch-1
doc: fix typo in pepper flash document
2015-05-20 19:24:09 +08:00
Cheng Zhao
6f806190b6 Merge pull request #1604 from deepak1556/contents_event_patch
webContents: providing response headers in did-get-response-details event
2015-05-20 19:08:54 +08:00
deepak1556
e80e4ae02c remove usage global browser context 2015-05-20 16:14:57 +05:30
deepak1556
04b797ff0c webContents: providing response headers in did-get-response-details event 2015-05-20 15:54:30 +05:30
Magica
f960c2dc63 doc: fix typo in pepper flash document
Add brackets around `plugins: true`
2015-05-20 18:04:51 +08:00
Cheng Zhao
9b445c27a2 Merge pull request #1668 from deepak1556/carsh_events_patch
webContents: adding events to detect gpu and plugin process crashes
2015-05-20 17:51:06 +08:00
Cheng Zhao
97a2889fd9 Merge pull request #1663 from khornberg/patch-1
Correct link of debugging UI
2015-05-20 17:44:29 +08:00
deepak1556
c548b9c87e webContents: adding events to detect gpu and plugin process crashes 2015-05-20 15:05:48 +05:30
Cheng Zhao
097d4d9870 Merge pull request #1734 from atom/forked-original-fs
Make "original-fs" available in forked scripts
2015-05-20 16:57:35 +08:00
Cheng Zhao
b238ac5981 Merge pull request #1660 from deepak1556/filesysem_patch
browser: create quota permission context to allow quota request
2015-05-20 14:05:53 +08:00
Cheng Zhao
fe19e63fbc Update brightray for #1653 2015-05-20 13:54:15 +08:00
Cheng Zhao
efd8a8a624 spec: original-fs is available in forked scripts 2015-05-20 13:37:46 +08:00
Cheng Zhao
fa169ee7ff Remove the original-fs.js
It is acutally not needed.
2015-05-20 13:31:28 +08:00
Cheng Zhao
0e7bc6b8ec Make "original-fs" available as built-in module 2015-05-20 13:29:05 +08:00
deepak1556
f8185296f4 add test 2015-05-20 09:23:08 +05:30
Cheng Zhao
4129d45d21 Merge pull request #1596 from deepak1556/protocol_interceptor_patch
protocol: wrapping HttpJobFactory with a default protocol handler to intercept
2015-05-20 11:52:52 +08:00
Cheng Zhao
361505661f Merge pull request #1651 from magicae/ppapi-description-patch
ppapi: fix PPAPI flash plugin description as chromium does
2015-05-20 11:32:09 +08:00
Cheng Zhao
b558485394 Merge pull request #1732 from atom/web-preferences
Simplify how we find NativeWindow from WebContents
2015-05-20 10:45:01 +08:00
Cheng Zhao
a9a331938e Merge pull request #1587 from atom/agent-as-attribute
Allow User Agent on WebView to be set as an attribute
2015-05-20 10:32:09 +08:00
Cheng Zhao
7c69c2846b Simplify how we find NativeWindow from WebContents 2015-05-20 10:27:16 +08:00
Cheng Zhao
cda8b119e2 Upgrade brightray 2015-05-20 09:18:11 +08:00
Paul Betts
975978b414 Don't be so paranoid about empty opts 2015-05-19 14:27:15 -07:00
Paul Betts
5ee0ff9ee9 Fixup code review items 2015-05-19 14:27:15 -07:00
Paul Betts
ca63ea0882 Add documentation 2015-05-19 14:27:15 -07:00
Paul Betts
50c913fe92 Add a test for the user agent 2015-05-19 14:27:15 -07:00
Paul Betts
22f51372f5 Fix typo 2015-05-19 14:27:15 -07:00
Paul Betts
e4d90f747f Pass user agent along like http referrer and set user agent in C++ 2015-05-19 14:27:15 -07:00
Paul Betts
4a8d7c1819 Right before navigate, set the user agent 2015-05-19 14:27:15 -07:00
Paul Betts
3a81a5224d Set up a class for it in web-view-attributes 2015-05-19 14:27:14 -07:00
Paul Betts
3993161a63 Define a new useragent attribute on WebView tag 2015-05-19 14:27:14 -07:00
Jessica Lord
25019de690 Remove example 2015-05-19 11:18:22 -07:00
Jessica Lord
8fea373758 Use Electron repo search url 2015-05-19 11:08:43 -07:00
deepak1556
b0e8cafa00 navigation: adding clearHistory method 2015-05-19 22:41:03 +05:30
Magica
1a8c0230a7 doc: Add pepper flash tutorial link in README. 2015-05-19 20:29:04 +08:00
Magica
6980982e32 ppapi: Add pepper flash tutorial
Fix https://github.com/atom/electron/issues/1674
2015-05-19 20:27:12 +08:00
Cheng Zhao
ec5d05e226 Merge pull request #1670 from joshaber/infer-textured
Use the textured window if it's transparent
2015-05-19 15:51:22 +08:00
Jessica Lord
3387459be2 Start a contributing doc 2015-05-18 18:29:13 -07:00
deepak1556
9963ddc485 implement method on browser window 2015-05-18 20:08:08 +05:30
deepak1556
46d80e8f05 devtools: api to inspect service worker for current webcontents 2015-05-18 19:19:33 +05:30
deepak1556
ef30adcaef navigation: fix accessing url from history array for goToIndex 2015-05-17 03:31:24 +05:30
Kevin Mårtensson
36c376b1ec Add link to awesome-electron 2015-05-16 17:03:19 +02:00
Andy Dill
dcbc6a127b Explicitly null the crash reporter before assigning it to allow the EH to unregister. 2015-05-15 22:37:00 -07:00
Andy Dill
e4415f0021 compile-coffee.py searches for node even on non-windows systems 2015-05-15 22:35:49 -07:00
Paul Betts
b4403fa9ec Merge pull request #1703 from tommoor/patch-3
Small spelling mistake
2015-05-15 13:55:04 -07:00
Tom Moor
a725a49759 Small spelling mistake 2015-05-15 13:09:59 -07:00
Kevin Sawicki
76f1e6d526 Merge pull request #1696 from campersau/patch-1
docs: fixed casing of "Note"
2015-05-15 09:30:28 -07:00
campersau
d19ae50cad docs: fixed casing of "Note" 2015-05-15 17:46:25 +02:00
Charlie Hess
9f461aed68 Update docs. 2015-05-15 00:15:33 -07:00
Charlie Hess
3913e18447 Add WebContents API for PasteAndMatchStyle. 2015-05-15 00:15:19 -07:00
Charlie Hess
90fb7bc52d Merge branch 'master' of https://github.com/atom/atom-shell 2015-05-14 22:37:20 -07:00
joshaber
76d33c37d7 Use the textured window for the frameless case too. 2015-05-12 21:11:43 -04:00
joshaber
033f9bcced If the window's transparent it also needs to be textured. 2015-05-12 21:05:48 -04:00
joshaber
1c97fc79ad Merge remote-tracking branch 'atom/master' 2015-05-12 20:48:15 -04:00
Kyle Hornberg
0097f89adb Correct link of debugging UI
Using the link provided one receives a response of `Cannot GET /[object%20Object]`.

I've tested this on electron 0.25.3 using the example application and node-inspector version 0.10.0.
The url change is the url provided by node-inspector in the terminal window.
2015-05-12 10:29:00 -05:00
deepak1556
32ba219146 allowing file:// URI to access other file:// URIs for filesytem api use 2015-05-12 18:21:48 +05:30
deepak1556
add7f8a4aa add test 2015-05-12 18:03:00 +05:30
deepak1556
2785a4cc48 browser: create quota permission context to allow quota request 2015-05-12 17:52:30 +05:30
Cheng Zhao
827741a9c6 Bump v0.26.0 2015-05-12 17:24:00 +08:00
Cheng Zhao
ca623f16bf Merge pull request #1657 from atom/msvcrt
Link with DLL version of VC++ runtime
2015-05-12 17:23:25 +08:00
Cheng Zhao
3bd54b7920 Ship with vc++ redist files 2015-05-12 17:08:27 +08:00
Cheng Zhao
613a51f5fb Upgrade brightray to link with msvcrt dll 2015-05-12 17:00:36 +08:00
Cheng Zhao
e5d30636c2 Update libchromiumcontent for linking with msvcrt dll 2015-05-12 16:54:18 +08:00
Magica
e1beeb95e3 Fix PPAPI flash plugin description
Fix https://github.com/atom/electron/issues/1637
2015-05-12 06:02:42 +08:00
Cheng Zhao
4ca8039104 Merge pull request #1646 from atom/navigation-in-page
Fix handling in-page navigations
2015-05-11 19:47:15 +08:00
Cheng Zhao
e817192df3 Make history.go work 2015-05-11 16:44:01 +08:00
Cheng Zhao
2bb7497312 Handle when in-page entries are cleared 2015-05-11 16:37:53 +08:00
Cheng Zhao
82ffa4d2b1 Send history operations as asynchronous messages
Sending as sync message will cause weird results for
NavigationController
2015-05-11 16:03:25 +08:00
deepak1556
707503ac40 support https, ws, wss builtin schemes to be intercepted 2015-05-11 12:56:36 +05:30
deepak1556
7fee639edf protocol: wrapping httpjobfactory with a default protocol handler to intercept 2015-05-11 12:32:17 +05:30
Cheng Zhao
d1545a64ae Don't force restart renderer process for in-page navigation 2015-05-11 14:40:40 +08:00
Cheng Zhao
40631edb70 Use Chrome's navigation controller for in-page navigations 2015-05-11 14:30:26 +08:00
Cheng Zhao
4d1cd7e15f Redirect history operations in renderer to browser 2015-05-11 14:29:44 +08:00
Cheng Zhao
4c10925694 Add remote.getCurrentWebContents API 2015-05-11 14:05:20 +08:00
Cheng Zhao
fc2bc20572 Determine wheter a navigation entry is in-page 2015-05-11 13:51:52 +08:00
Cheng Zhao
4a195e6283 Merge pull request #1600 from deepak1556/protocol_error_patch
protocol: adding error job to log error with custom protocols
2015-05-11 13:15:14 +08:00
deepak1556
24bcd3b21e provide default error message 2015-05-11 10:24:44 +05:30
deepak1556
9ab53b0e4b protocol: adding error job to log error with custom protocols 2015-05-11 10:17:31 +05:30
Cheng Zhao
e5380fd671 Merge pull request #1642 from atom/archive-update-header
Keep asar archive's file opened in the archive's whole life time
2015-05-11 12:07:16 +08:00
Cheng Zhao
d9c769fa69 Reuse archive's fd in Node asar API 2015-05-11 11:10:50 +08:00
Cheng Zhao
d8d7e5b9bb Add Archive::GetFD 2015-05-11 11:02:17 +08:00
Cheng Zhao
f8e1dfbbc6 Keep archive's file opened in the archive's whole life time 2015-05-11 10:47:29 +08:00
Cheng Zhao
f02cae1b0a docs: app.terminate is deprecated 2015-05-11 10:22:19 +08:00
Cheng Zhao
fa7f900b2b Merge pull request #1634 from federicobond/patch-1
Fix wording in docs/api/remote.md
2015-05-10 23:27:43 +08:00
Cheng Zhao
75e5695317 Merge pull request #1554 from deepak1556/favicon_patch
webContents: removing getFavicon api
2015-05-10 21:22:01 +08:00
Cheng Zhao
66ef52197a mac: Make "standard-window" option default to true 2015-05-10 21:16:08 +08:00
Cheng Zhao
9e3f108fad Merge pull request #1585 from joshaber/no-texture
Use the standard window background
2015-05-10 21:09:38 +08:00
Cheng Zhao
1571c3537d Merge pull request #1601 from hokein/fix-out-of-bound
Fix a potential out-of-bound issue in Accelerator.
2015-05-10 21:04:45 +08:00
Cheng Zhao
18780487c2 Merge pull request #1636 from atom/ns-mainscreen
Don't use [NSScreen mainScreen]
2015-05-10 20:52:46 +08:00
Cheng Zhao
ce042d0524 mac: Don't use [NSScreen mainScreen] 2015-05-10 16:51:18 +08:00
Cheng Zhao
312b8c95ba Merge pull request #1635 from fengmk2/patch-1
Update China mirrors url
2015-05-10 16:45:51 +08:00
Cheng Zhao
6e8bc6a597 Merge pull request #1558 from deepak1556/ppapi_patch
Ppapi: plugin support
2015-05-10 16:28:14 +08:00
fengmk2
d9c90be1de Update China mirrors url
fixes #1497
2015-05-10 16:15:12 +08:00
Federico Bond
ed023a560e Fix wording in docs/api/remote.md 2015-05-10 02:54:37 -03:00
deepak1556
15ae6b8d36 fix lint errors and add documentation 2015-05-10 10:25:19 +05:30
deepak1556
853ce0bbd7 provide flag to set flash version 2015-05-10 09:22:09 +05:30
deepak1556
1c190388e5 flash_drm_host not required 2015-05-10 09:22:09 +05:30
deepak1556
3fdc4543b8 ppapi flash plugin support 2015-05-10 09:22:09 +05:30
Cheng Zhao
be06a3d562 Upgrade brightray for #1532 2015-05-10 11:41:02 +08:00
Cheng Zhao
95e72c24cc Merge pull request #1532 from hokein/win-print
Make Print API work on Windows.
2015-05-10 11:40:19 +08:00
joshaber
c8d0ef05a6 Docs. 2015-05-08 16:33:57 -04:00
joshaber
85119db81a Use a new option to opt into the standard window. 2015-05-08 16:28:24 -04:00
Cheng Zhao
4d9470c24e Bump v0.25.3 2015-05-08 14:28:30 +08:00
Cheng Zhao
2b1894f356 Merge pull request #1614 from atom/download-x64-directxsdk
Download 64bit directx sdk when building for 64bit target
2015-05-08 13:52:55 +08:00
Cheng Zhao
dca872d987 win: Download 64bit directx sdk when building for 64bit target 2015-05-08 13:42:18 +08:00
Cheng Zhao
4660d3c265 Merge pull request #1584 from atom/upload-mksnapshot
Upload mksnapshot to releases
2015-05-08 13:39:48 +08:00
Cheng Zhao
f2bf8d6db3 Merge pull request #1571 from deepak1556/basic_auth_patch
spec: add test for basic authentication
2015-05-07 19:45:35 +08:00
Cheng Zhao
ae8ac97f32 Upgrade brightray, fixes #1318 2015-05-07 19:44:06 +08:00
Haojian Wu
2b82e523bf Fix a potential out-of-bound issue in Accelerator. 2015-05-07 15:46:38 +08:00
Cheng Zhao
9d54092f41 Merge pull request #1512 from hokein/add-win-key
Add `Super` key support in global-shortcut API.
2015-05-07 10:35:56 +08:00
joshaber
5f357d39b2 If it's frameless then use the textured background. 2015-05-06 10:08:24 -04:00
Cheng Zhao
1817ddc18a Upload mksnapshot to releases 2015-05-06 09:17:40 +08:00
joshaber
102fb66461 Remove the textured background. 2015-05-05 20:53:26 -04:00
Haojian Wu
0f67b1866a Add Super key support in global-shortcut API. 2015-05-05 22:49:32 +08:00
Haojian Wu
f2853a0b89 Some cleanup. 2015-05-05 21:56:58 +08:00
Cheng Zhao
6c5429c7f0 Merge pull request #1579 from atom/upgrade-libchromiumcontent
Update libchromiumcontent
2015-05-05 16:37:59 +08:00
Cheng Zhao
a6ba0cd107 Update libchromiumcontent which includes pdf and ppapi libs 2015-05-05 16:07:47 +08:00
Cheng Zhao
57e6b75871 Merge pull request #1575 from atom/electron-rebuild-notes
Suggest electron-rebuild for building native modules
2015-05-05 15:10:18 +08:00
Paul Betts
904505bb21 Suggest electron-rebuild for building native modules 2015-05-04 22:39:55 -07:00
Cheng Zhao
56afe4dd5d win: Remove unused build setting 2015-05-05 10:25:56 +08:00
deepak1556
2d190b9952 spec: add test for basic authentication 2015-05-04 20:44:36 +05:30
Haojian Wu
298d3a0144 Fix compilation error on OS X. 2015-05-04 20:58:48 +08:00
deepak1556
22c50d0800 webContents: removing getFavicon api 2015-05-04 13:39:13 +05:30
Cheng Zhao
06834b723b Merge pull request #1568 from atom/tray-getposition
Pass bounds instead of position in "clicked" event of "tray"
2015-05-04 13:13:33 +08:00
Cheng Zhao
a04222f398 spec: Fix error when refreshing 2015-05-04 12:51:28 +08:00
Cheng Zhao
0d4d2080ca Implement size and position APIs with bounds API 2015-05-04 12:47:56 +08:00
Cheng Zhao
7142cae041 mac: Also use [NSScreen mainScreen] in other places 2015-05-04 12:33:51 +08:00
Cheng Zhao
921e7e0f91 Merge pull request #1565 from chicoxyzzy/patch-1
docs: fix typo
2015-05-04 12:18:04 +08:00
Cheng Zhao
f2fdc556a4 Merge pull request #1548 from MaxGraey/fix-docs
update using-native-node-modules doc
2015-05-04 12:11:47 +08:00
Cheng Zhao
1835d90bb7 Merge pull request #1551 from atom/log-preload-errors
Log errors in preload script instead of rethrowing
2015-05-04 12:10:21 +08:00
Cheng Zhao
f5cf3556b1 Pass bounds in clicked event of tray 2015-05-04 11:43:22 +08:00
Cheng Zhao
a53b1f7edf win: Mouse position is not notify icon's position 2015-05-04 11:37:23 +08:00
Cheng Zhao
f64dbbea3e docs: Pass bounds in clicked event of tray 2015-05-04 11:34:11 +08:00
Max Graey
6842ac98c3 revert changes of dist url 2015-05-04 10:13:43 +07:00
Cheng Zhao
294dbac869 Merge pull request #1543 from deepak1556/tray_icon_patch
tray: send tray icon position as payload onclick OSX and windows
2015-05-04 11:11:13 +08:00
Cheng Zhao
5f27bb597f Merge pull request #1545 from deepak1556/windows_patch
window: adding setBounds and getBounds api
2015-05-04 11:03:50 +08:00
Cheng Zhao
4c145f44a4 Merge pull request #1519 from atom/reenable-npapi
Reenable NPAPI by setting optional flag
2015-05-04 10:40:33 +08:00
Sergey R
abe63ebd84 docs: fix typo 2015-05-04 02:21:07 +03:00
Paul Betts
4f67415607 Enable NPAPI by default, trump Chromium's default 2015-05-01 16:59:40 -07:00
Paul Betts
e2ec50173f Log errors in preload script instead of rethrowing
At some point, unhandled errors in preload scripts stopped being logged
to console, meaning that preload scripts were very difficult to debug.
Instead, print the error to console (which is what we wanted to have
happen anyways)
2015-05-01 16:11:56 -07:00
Max Graey
d2ab8322b7 update using-native-node-modules doc 2015-05-02 01:28:17 +07:00
deepak1556
9ae59e8ac7 removed move utility and replaced with setbounds 2015-05-01 20:10:46 +05:30
deepak1556
6d7d068e49 tray: send tray icon position as payload onclick OSX 2015-05-01 19:30:01 +05:30
deepak1556
ae6a1b409f window: adding setBounds and getBounds api 2015-05-01 16:20:53 +05:30
Cheng Zhao
4608f5e9cd Bump v0.25.2 2015-05-01 14:57:25 +08:00
Cheng Zhao
9300859983 Merge pull request #1535 from deepak1556/contents_patch
webContents: adding serviceworker helper utilities
2015-05-01 14:56:35 +08:00
Cheng Zhao
52240750a1 Merge pull request #1540 from atom/webview-beforeunload
Make beforeunload handler work in webview
2015-05-01 14:55:52 +08:00
deepak1556
d76bd4a103 webContents: adding serviceworker helper utilities 2015-05-01 12:02:57 +05:30
Cheng Zhao
bfac7f7a17 Make beforeunload work in webview 2015-05-01 13:48:39 +08:00
Cheng Zhao
36d2512ff8 spec: Test beforeunload handler in webview 2015-05-01 13:48:23 +08:00
Cheng Zhao
ca7e2c4d96 Merge pull request #1538 from leemac/patch-1
Typo and missing comma in Desktop Integration doc page
2015-05-01 12:48:55 +08:00
Cheng Zhao
817dfbdc27 Merge pull request #1525 from deepak1556/dom_event_patch
webContents: providing dom-ready event
2015-05-01 12:08:03 +08:00
Lee McKinnon
5fa7ae7d72 Fixing typo in desktop-environment-integration.md
Missing comma in the 'setUserTasks' as well as a typo in the description under "User tasks (Windows)"
2015-04-30 15:40:30 -04:00
Cheng Zhao
c54eca8dff Update node to fix #1472 2015-04-30 17:07:20 +08:00
Cheng Zhao
72f5381c31 Merge pull request #1521 from deepak1556/title_patch
webContents: check for navigation entry before using
2015-04-30 16:54:14 +08:00
Cheng Zhao
7ca2363d78 Merge pull request #1533 from atom/iojs-headers
Upload io.js headers
2015-04-30 16:17:26 +08:00
Cheng Zhao
dec7c40fd8 Also upload iojs-*-.tar.gz 2015-04-30 16:01:54 +08:00
Cheng Zhao
a8846e0432 Also upload headers to iojs's locations 2015-04-30 15:36:54 +08:00
Haojian Wu
ff87592722 Make Print API work on Windows. 2015-04-30 13:42:08 +08:00
deepak1556
8c5f171a93 webContents: providing dom-ready event 2015-04-30 09:58:29 +05:30
Daniel Hengeveld
ea74e825c9 Merge pull request #1527 from frewsxcv/patch-1
Enable syntax highlighting in README
2015-04-29 12:28:52 -07:00
Corey Farwell
2b3ef714bd Enable syntax highlighting in README
Primarily to fade the comments in the code block
2015-04-29 13:56:31 -04:00
Cheng Zhao
23afffa46d Chaning src of webview should always do a load
Previously changing src to the same value won't have any effect, which
does not follow the behavior of browsers.
2015-04-29 17:57:16 +08:00
Cheng Zhao
129cdb7680 spec,win: Fix page-favicon-updated event spec 2015-04-29 17:31:56 +08:00
Cheng Zhao
8d3404d26c win: Fix compilation error 2015-04-29 15:13:46 +08:00
Cheng Zhao
05e0564426 Merge pull request #1477 from atom/dont-rig-app-name
Provide an optional way to explicitly set the AppUserModelID
2015-04-29 14:10:12 +08:00
deepak1556
d8be645d5a webContents: check for navigation entry before using 2015-04-29 08:57:49 +05:30
Cheng Zhao
3f499f69ff Merge pull request #1520 from atom/disable-auto-hide-cursor
Add option to disable hiding cursor when typing
2015-04-29 10:39:44 +08:00
Cheng Zhao
75b24c7d76 docs: disable-auto-hide-cursor option 2015-04-29 10:28:42 +08:00
Cheng Zhao
c6cf91d11f Add 'disable-auto-hide-cursor' option 2015-04-29 10:26:31 +08:00
Cheng Zhao
3a50c9e48c Update to the new patch for acceptsFirstMouse 2015-04-29 10:26:31 +08:00
Paul Betts
7c2b1468c8 Fix typo 2015-04-28 15:49:16 -07:00
Paul Betts
fb6c80d12e Create an explicit API for setting the App User Model ID 2015-04-28 12:23:58 -07:00
Kevin Sawicki
d826e1e5fb Merge pull request #1514 from mnquintana/patch-1
Logo png -> svg
2015-04-28 08:57:35 -07:00
Machiste N. Quintana
04a0aaa35f Logo png -> svg
Fixes broken image in Readme
2015-04-28 10:48:54 -04:00
Cheng Zhao
f5fbd52dbd Merge pull request #1505 from atom/default-help-menu
Add help menu to default app
2015-04-28 17:55:06 +08:00
Daniel Hengeveld
5575d17d0e Merge pull request #1495 from bendrucker/grammar
Fix grammar in NW.js comparison
2015-04-27 13:30:26 -07:00
Ben Drucker
0e7970fec5 Fix grammar in NW.js comparison 2015-04-27 15:55:25 -04:00
Kevin Sawicki
fdfd8807a0 Tweak path docs 2015-04-27 10:17:15 -07:00
Kevin Sawicki
da07e72f20 Add -h/--help usage message 2015-04-27 10:17:14 -07:00
Kevin Sawicki
f4a27f699a Add help menu to electron site 2015-04-27 10:17:14 -07:00
Kevin Sawicki
e3c21424de Add default help menu 2015-04-27 10:17:14 -07:00
Kevin Sawicki
b5aa2a31a1 Make full screen menu a toggler 2015-04-27 10:17:14 -07:00
Cheng Zhao
05ae1960d1 Merge pull request #1502 from atom/renderer-restart
Manage navigation history with JavaScript on user side
2015-04-27 22:00:23 +08:00
Cheng Zhao
dde791d475 Allow calling goBack for multiple times 2015-04-27 15:11:59 +08:00
Cheng Zhao
16b2f08cd3 Don't use Chromium's history list 2015-04-27 15:11:59 +08:00
Cheng Zhao
0143a45488 Implement our own NavigationController 2015-04-27 15:11:59 +08:00
Cheng Zhao
2f1683445b Only append command line params for renderer process 2015-04-27 15:11:59 +08:00
Cheng Zhao
4c78f98da6 Check if it is guest process before updating process ID 2015-04-27 15:11:59 +08:00
Cheng Zhao
3ff2959f0c spec: Native modules should work after navigation in webview 2015-04-27 15:11:59 +08:00
Cheng Zhao
36c4b1705d Update guest process id when navigating 2015-04-27 15:11:58 +08:00
Cheng Zhao
d8adbc0875 NULL => nullptr 2015-04-27 15:11:58 +08:00
Cheng Zhao
b527846ee4 Use our new way to restart renderer process
As a side effect, it will also restart the renderer process of webview
tag guests.
2015-04-27 15:11:58 +08:00
Cheng Zhao
ee45f0e8bc Upgrade libchromiumcontent 2015-04-27 15:11:58 +08:00
Cheng Zhao
ca5ee0fc81 Merge pull request #1491 from atom/minimal-mac-menu
Remove native actions in Mac default menu
2015-04-25 21:00:26 +08:00
Cheng Zhao
ecf29f72bc mac: Remove unused action handler 2015-04-25 20:41:12 +08:00
Cheng Zhao
c811beb1e2 mac: Remove all unnecessary default menu items 2015-04-25 20:36:09 +08:00
Cheng Zhao
0c091428d3 Merge pull request #1455 from deepak1556/fullscreen_patch
window: supports HTML5 fullscreen api
2015-04-25 16:16:57 +08:00
Cheng Zhao
858198a2bd Merge pull request #1461 from deepak1556/webview_devtools_patch
webview: add inspectElement method
2015-04-25 16:14:13 +08:00
Cheng Zhao
1649d8f900 Merge pull request #1438 from deepak1556/api_web_view_patch
webview: page-favicon-updated navigation event and getFavicon api
2015-04-25 13:04:43 +08:00
Cheng Zhao
eb42fdbbc6 Merge pull request #1453 from deepak1556/asar_patch
asar: make fs async methods create errors asynchronously
2015-04-25 13:04:35 +08:00
deepak1556
6cc571bdfe include headers only in places used 2015-04-25 10:13:52 +05:30
deepak1556
da648511b3 asar: make fs async methods create errors asynchronously 2015-04-25 10:08:02 +05:30
deepak1556
18b3dfa350 removed will-navigate and did-navigate events 2015-04-25 09:50:28 +05:30
deepak1556
05be71e9bc fix getFavcion api in webview to return dataUrl 2015-04-25 09:50:28 +05:30
deepak1556
36819e2638 added did-navigate event, getFavicon api and workaround webview spec 2015-04-25 09:50:28 +05:30
deepak1556
9b585458c1 webview: will-navigate and page-favicon-set navigation events 2015-04-25 09:50:28 +05:30
Cheng Zhao
c424d0e9f3 Upgrade CoffeeScript to 1.9.2 2015-04-25 10:45:28 +08:00
Cheng Zhao
81783b255e Increase timeout for some tests 2015-04-25 10:45:16 +08:00
Cheng Zhao
80c8ab4c39 Style fix 2015-04-25 10:35:28 +08:00
Cheng Zhao
826a4e0e48 Merge branch 'master' of https://github.com/MaxGraey/electron into MaxGraey-master 2015-04-25 10:29:34 +08:00
Cheng Zhao
7917748b21 ⬆️ asar@0.5.0 2015-04-24 13:06:49 +08:00
Daniel Hengeveld
b7f974f469 Merge pull request #1481 from bhargavrpatel/patch-1
Minor grammatical fixes
2015-04-23 17:18:26 -07:00
Bhargav Patel
5c5fd377f7 Minor grammatical fixes
Fixed some run-on sentances and changed structor of some.
2015-04-23 20:12:04 -04:00
Kevin Sawicki
0a995c3731 Mention new twitter account 2015-04-23 17:03:05 -07:00
Kevin Sawicki
47b754e914 Merge pull request #1480 from lazaruslarue/patch-1
fix minor text error
2015-04-23 16:50:05 -07:00
lazarus
00ef99826d fix minor text error 2015-04-23 16:32:41 -07:00
Kevin Sawicki
45943302ee Merge pull request #1476 from mnquintana/patch-2
Add david-dm dependency status badge to Readme
2015-04-23 14:02:47 -07:00
Machiste N. Quintana
2157f898bb Add david-dm dependency status badge to Readme 2015-04-23 17:00:40 -04:00
Kevin Sawicki
132c7aba2d Merge pull request #1475 from mnquintana/patch-1
Add Electron logo to Readme
2015-04-23 13:52:14 -07:00
Machiste N. Quintana
1ae88f0f0f 🎨 2015-04-23 16:50:43 -04:00
Machiste N. Quintana
c0f0fcba7b Add Electron logo to Readme 2015-04-23 16:46:48 -04:00
deepak1556
cdb1711fe1 webview: add inspectElement method 2015-04-23 15:18:13 +05:30
deepak1556
20b4cae980 window: supports HTML5 fullscreen api 2015-04-23 12:14:29 +05:30
Cheng Zhao
67bc4afe88 Bump v0.25.1 2015-04-23 13:29:34 +08:00
Cheng Zhao
fb78169396 Don't add tag in bump-version.py
It will be done by GitHub Releases.
2015-04-23 13:28:29 +08:00
Cheng Zhao
ba7e26539f Upgrade brightray for #1462 2015-04-23 13:27:11 +08:00
Cheng Zhao
500d15f53a Also remove user-defined search paths in renderer 2015-04-23 13:17:18 +08:00
Cheng Zhao
fad977e27d Simplify how we remove user-defined search paths 2015-04-23 13:13:58 +08:00
deepak1556
4983ef77bd module: remove system paths from search 2015-04-23 12:55:34 +08:00
Cheng Zhao
4a6066c69e Update native_mate 2015-04-23 10:22:09 +08:00
Cheng Zhao
1690df9bcf Merge branch 'api_content_tracing_patch' of https://github.com/deepak1556/atom-shell into deepak1556-api_content_tracing_patch 2015-04-23 10:21:15 +08:00
Kevin Sawicki
5c94f7ccd4 Merge pull request #1464 from bnvk/patch-1
updated bash path to ./Electron.app/Contents/MacOS/Electron
2015-04-22 14:08:09 -07:00
Kevin Sawicki
494c3f3255 Merge pull request #1466 from gappsby/master
node.js --> io.js
2015-04-22 14:04:29 -07:00
Florian Hämmerle
ec4d596189 Update quick-start.md 2015-04-22 22:14:50 +02:00
Brennan Novak
bc04e951cf updated bash path to ./Electron.app/Contents/MacOS/Electron
it had the trailing /Atom which no longer exists
2015-04-22 16:22:08 +02:00
Max Graey
916fa4b9a8 Merge pull request #1 from atom/master
Merge with forked
2015-04-21 04:39:54 +07:00
Max Graey
0d3cc8aaa7 Fix some draw issues in native mac os window
Fix some non-transparent corners and lacking redraw while resizing non-frame window
2015-04-18 19:08:22 +07:00
Charlie Hess
5b69421625 Revert "Update submodules"
This reverts commit 397a503da3.
2015-04-17 14:29:50 -07:00
Charlie Hess
397a503da3 Update submodules 2015-04-17 14:26:29 -07:00
deepak1556
51cadc6e90 nativemate: moved std::set converter 2015-04-18 01:29:57 +05:30
339 changed files with 14978 additions and 5924 deletions

5
.gitignore vendored
View File

@@ -4,8 +4,13 @@
/external_binaries/
/out/
/vendor/brightray/vendor/download/
/vendor/debian_wheezy_arm-sysroot/
/vendor/debian_wheezy_i386-sysroot/
/vendor/python_26/
/vendor/npm/
/vendor/llvm/
/vendor/llvm-build/
/vendor/.gclient
node_modules/
*.xcodeproj
*.swp

9
.gitmodules vendored
View File

@@ -13,3 +13,12 @@
[submodule "vendor/native_mate"]
path = vendor/native_mate
url = https://github.com/zcbenz/native-mate.git
[submodule "vendor/crashpad"]
path = vendor/crashpad
url = https://github.com/atom/crashpad.git
[submodule "vendor/requests"]
path = vendor/requests
url = https://github.com/kennethreitz/requests
[submodule "vendor/boto"]
path = vendor/boto
url = https://github.com/boto/boto.git

View File

@@ -1,15 +1,21 @@
git:
depth: 10
notifications:
email: false
language: cpp
compiler: clang
os:
- linux
- osx
env:
- TARGET_ARCH=x64
notifications:
email:
on_success: never
on_failure: change
matrix:
include:
- os: linux
env: TARGET_ARCH=arm
- os: linux
env: TARGET_ARCH=ia32
script: './script/cibuild'
git:
depth: 10

71
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,71 @@
# Contributing to Electron
:+1::tada: First off, thanks for taking the time to contribute! :tada::+1:
The following is a set of guidelines for contributing to Electron.
These are just guidelines, not rules, use your best judgment and feel free to
propose changes to this document in a pull request.
## Submitting Issues
* You can create an issue [here](https://github.com/atom/electron/issues/new),
but before doing that please read the notes below and include as many details as
possible with your report. If you can, please include:
* The version of Electron you are using
* The operating system you are using
* If applicable, what you were doing when the issue arose and what you
expected to happen
* Other things that will help resolve your issue:
* Screenshots and animated GIFs
* Error output that appears in your terminal, dev tools or as an alert
* Perform a [cursory search](https://github.com/atom/electron/issues?utf8=✓&q=is%3Aissue+)
to see if a similar issue has already been submitted
## Submitting Pull Requests
* Include screenshots and animated GIFs in your pull request whenever possible.
* Follow the CoffeeScript, JavaScript, C++ and Python [coding style defined in docs](/docs/development/coding-style.md).
* Write documentation in [Markdown](https://daringfireball.net/projects/markdown).
* Use short, present tense commit messages. See [Commit Message Styleguide](#git-commit-messages-styleguide).
## Styleguides
### General Code
* End files with a newline.
* Place requires in the following order:
* Built in Node Modules (such as `path`)
* Built in Electron Modules (such as `ipc`, `app`)
* Local Modules (using relative paths)
* Place class properties in the following order:
* Class methods and properties (methods starting with a `@`)
* Instance methods and properties
* Avoid platform-dependent code:
* Use `path.join()` to concatenate filenames.
* Use `os.tmpdir()` rather than `/tmp` when you need to reference the
temporary directory.
* Using a plain `return` when returning explicitly at the end of a function.
* Not `return null`, `return undefined`, `null`, or `undefined`
### Git Commit Messages
* Use the present tense ("Add feature" not "Added feature")
* Use the imperative mood ("Move cursor to..." not "Moves cursor to...")
* Limit the first line to 72 characters or less
* Reference issues and pull requests liberally
* Consider starting the commit message with an applicable emoji:
* :art: `:art:` when improving the format/structure of the code
* :racehorse: `:racehorse:` when improving performance
* :non-potable_water: `:non-potable_water:` when plugging memory leaks
* :memo: `:memo:` when writing docs
* :penguin: `:penguin:` when fixing something on Linux
* :apple: `:apple:` when fixing something on Mac OS
* :checkered_flag: `:checkered_flag:` when fixing something on Windows
* :bug: `:bug:` when fixing a bug
* :fire: `:fire:` when removing code or files
* :green_heart: `:green_heart:` when fixing the CI build
* :white_check_mark: `:white_check_mark:` when adding tests
* :lock: `:lock:` when dealing with security
* :arrow_up: `:arrow_up:` when upgrading dependencies
* :arrow_down: `:arrow_down:` when downgrading dependencies
* :shirt: `:shirt:` when removing linter warnings

43
README-ko.md Normal file
View File

@@ -0,0 +1,43 @@
[![Electron Logo](http://electron.atom.io/images/electron-logo.svg)](http://electron.atom.io/)
[![Build Status](https://travis-ci.org/atom/electron.svg?branch=master)](https://travis-ci.org/atom/electron)
[![devDependency Status](https://david-dm.org/atom/electron/dev-status.svg)](https://david-dm.org/atom/electron#info=devDependencies)
### [Electron](https://github.com/atom/electron/) 한국어 참조문서
:zap: *이전까지 Atom Shell로 알려져 있었습니다* :zap:
Electron은 JavaScript, HTML 그리고 CSS를 이용하여 Cross-Platform 데스크톱 어플리케이션을 개발할 수 있도록 해주는 프레임워크입니다. 이 프레임워크는 [io.js](http://iojs.org) 와
[Chromium](http://www.chromium.org) 을 기반으로 만들어 졌으며 [Atom Editor](https://github.com/atom/atom) 에 사용되고 있습니다.
Electron에 대한 중요한 알림을 받으려면 Twitter에서 [@ElectronJS](https://twitter.com/electronjs)를 Follow하세요.
## 다운로드
Linux, Windows, Mac용으로 미리 빌드된 Electron 바이너리와 디버그 심볼이 준비되어 있습니다. [releases](https://github.com/atom/electron/releases) 페이지에서 받아 볼 수 있습니다.
또한 [`npm`](https://docs.npmjs.com/)을 이용하여 미리 빌드된 Electron 바이너리를 받을 수 있습니다:
```sh
# $PATH에 `electron`을 등록하고 전역에 설치합니다.
npm install electron-prebuilt -g
# 개발용 dependency로 설치합니다.
npm install electron-prebuilt --save-dev
```
### 미러
- [China](https://npm.taobao.org/mirrors/electron)
## 참조문서
[docs](https://github.com/preco21/electron/tree/master/docs) 에 프레임워크 사용 가이드와 API 레퍼런스가 있습니다.
또한, Electron을 빌드 하는 방법과 프로젝트에 기여하는 방법 문서에 포함되어 있으니 참고바랍니다.
## 커뮤니티
[Atom 포럼내의 `electron` 카테고리](http://discuss.atom.io/category/electron) 와 Freenode `#atom-shell` 채팅채널이 있습니다.
[awesome-electron](https://github.com/sindresorhus/awesome-electron) 에 커뮤니티가 운영중인 유용한 예제 앱과 툴, 리소스가 있으니 한번 탐색해 보시기 바랍니다.

View File

@@ -1,4 +1,8 @@
# Electron [![Build Status](https://travis-ci.org/atom/electron.svg?branch=master)](https://travis-ci.org/atom/electron)
[![Electron Logo](http://electron.atom.io/images/electron-logo.svg)](http://electron.atom.io/)
[![Build Status](https://travis-ci.org/atom/electron.svg?branch=master)](https://travis-ci.org/atom/electron)
[![devDependency Status](https://david-dm.org/atom/electron/dev-status.svg)](https://david-dm.org/atom/electron#info=devDependencies)
[![Join the Electron Community on Slack](http://atom-slack.herokuapp.com/badge.svg)](http://atom-slack.herokuapp.com/)
:zap: *formerly known as Atom Shell* :zap:
@@ -7,6 +11,9 @@ using JavaScript, HTML and CSS. It is based on [io.js](http://iojs.org) and
[Chromium](http://www.chromium.org) and is used in the [Atom
editor](https://github.com/atom/atom).
Follow [@ElectronJS](https://twitter.com/electronjs) on Twitter for important
announcements.
## Downloads
Prebuilt binaries and debug symbols of Electron for Linux, Windows and Mac can
@@ -15,7 +22,7 @@ be found on the [releases](https://github.com/atom/electron/releases) page.
You can also use [`npm`](https://docs.npmjs.com/) to install prebuilt electron
binaries:
```
```sh
# Install the `electron` command globally in your $PATH
npm install electron-prebuilt -g
@@ -25,7 +32,7 @@ npm install electron-prebuilt --save-dev
### Mirrors
- [China](https://npm.taobao.org/mirrors/atom-shell)
- [China](https://npm.taobao.org/mirrors/electron)
## Documentation
@@ -37,3 +44,5 @@ contains documents describing how to build and contribute to Electron.
There is an [`electron` category on the Atom forums](http://discuss.atom.io/category/electron)
as well as an `#atom-shell` channel on Freenode.
Check out [awesome-electron](https://github.com/sindresorhus/awesome-electron) for a community maintained list of useful example apps, tools and resources.

View File

@@ -4,9 +4,7 @@
'product_name%': 'Electron',
'company_name%': 'GitHub, Inc',
'company_abbr%': 'github',
'version%': '0.25.0',
'atom_source_root': '<!(["python", "tools/atom_source_root.py"])',
'version%': '0.29.1',
},
'includes': [
'filenames.gypi',
@@ -17,8 +15,12 @@
'ATOM_PRODUCT_NAME="<(product_name)"',
'ATOM_PROJECT_NAME="<(project_name)"',
],
'mac_framework_dirs': [
'<(atom_source_root)/external_binaries',
'conditions': [
['OS=="mac"', {
'mac_framework_dirs': [
'<(source_root)/external_binaries',
],
}],
],
},
'targets': [
@@ -114,15 +116,6 @@
],
}], # OS!="mac"
['OS=="win"', {
'msvs_settings': {
'VCLinkerTool': {
'AdditionalOptions': [
# Force linking even though we have duplicate symbols between
# BoringSSL and OpenSSL.
'/FORCE:MULTIPLE',
],
},
},
'copies': [
{
'variables': {
@@ -133,7 +126,9 @@
'<@(libchromiumcontent_shared_v8_libraries)',
],
}, {
'copied_libraries': [],
'copied_libraries': [
'<(libchromiumcontent_dir)/pdf.dll',
],
}],
],
},
@@ -151,6 +146,9 @@
'<(libchromiumcontent_dir)/snapshot_blob.bin',
'external_binaries/d3dcompiler_47.dll',
'external_binaries/xinput1_3.dll',
'external_binaries/msvcp120.dll',
'external_binaries/msvcr120.dll',
'external_binaries/vccorlib120.dll',
],
},
{
@@ -160,6 +158,10 @@
]
},
],
}, {
'dependencies': [
'vendor/breakpad/breakpad.gyp:dump_syms#host',
],
}], # OS=="win"
['OS=="linux"', {
'copies': [
@@ -279,7 +281,8 @@
}], # OS=="win"
['OS=="mac"', {
'dependencies': [
'vendor/breakpad/breakpad.gyp:breakpad',
'vendor/crashpad/client/client.gyp:crashpad_client',
'vendor/crashpad/handler/handler.gyp:crashpad_handler',
],
}], # OS=="mac"
['OS=="linux"', {
@@ -434,8 +437,7 @@
{
'destination': '<(PRODUCT_DIR)/<(product_name) Framework.framework/Versions/A/Resources',
'files': [
'<(PRODUCT_DIR)/Inspector',
'<(PRODUCT_DIR)/crash_report_sender.app',
'<(PRODUCT_DIR)/crashpad_handler',
],
},
],
@@ -456,7 +458,6 @@
'tools/mac/create-framework-subdir-symlinks.sh',
'<(product_name) Framework',
'Libraries',
'Frameworks',
],
},
],

View File

@@ -8,9 +8,60 @@
#include <vector>
#include "atom/common/chrome_version.h"
#include "atom/common/options_switches.h"
#include "base/command_line.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/pepper_plugin_info.h"
#include "ppapi/shared_impl/ppapi_permissions.h"
namespace atom {
namespace {
content::PepperPluginInfo CreatePepperFlashInfo(const base::FilePath& path,
const std::string& version) {
content::PepperPluginInfo plugin;
plugin.is_out_of_process = true;
plugin.name = content::kFlashPluginName;
plugin.path = path;
plugin.permissions = ppapi::PERMISSION_ALL_BITS;
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. :(
else if (flash_version_numbers[0].empty())
flash_version_numbers[0] = "11";
if (flash_version_numbers.size() < 2)
flash_version_numbers.push_back("2");
if (flash_version_numbers.size() < 3)
flash_version_numbers.push_back("999");
if (flash_version_numbers.size() < 4)
flash_version_numbers.push_back("999");
// 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 = JoinString(flash_version_numbers, '.');
content::WebPluginMimeType swf_mime_type(
content::kFlashPluginSwfMimeType,
content::kFlashPluginSwfExtension,
content::kFlashPluginSwfDescription);
plugin.mime_types.push_back(swf_mime_type);
content::WebPluginMimeType spl_mime_type(
content::kFlashPluginSplMimeType,
content::kFlashPluginSplExtension,
content::kFlashPluginSplDescription);
plugin.mime_types.push_back(spl_mime_type);
return plugin;
}
} // namespace
AtomContentClient::AtomContentClient() {
}
@@ -24,7 +75,32 @@ std::string AtomContentClient::GetProduct() const {
void AtomContentClient::AddAdditionalSchemes(
std::vector<std::string>* standard_schemes,
std::vector<std::string>* savable_schemes) {
auto command_line = base::CommandLine::ForCurrentProcess();
auto custom_schemes = command_line->GetSwitchValueASCII(
switches::kRegisterStandardSchemes);
if (!custom_schemes.empty()) {
std::vector<std::string> schemes;
base::SplitString(custom_schemes, ',', &schemes);
standard_schemes->insert(standard_schemes->end(),
schemes.begin(),
schemes.end());
}
standard_schemes->push_back("chrome-extension");
}
void AtomContentClient::AddPepperPlugins(
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));
}
} // namespace atom

View File

@@ -23,6 +23,8 @@ class AtomContentClient : public brightray::ContentClient {
void AddAdditionalSchemes(
std::vector<std::string>* standard_schemes,
std::vector<std::string>* savable_schemes) override;
void AddPepperPlugins(
std::vector<content::PepperPluginInfo>* plugins) override;
private:
DISALLOW_COPY_AND_ASSIGN(AtomContentClient);

View File

@@ -4,9 +4,9 @@
#include "atom/app/atom_library_main.h"
#include "atom/app/atom_main_args.h"
#include "atom/app/atom_main_delegate.h"
#include "atom/app/node_main.h"
#include "atom/common/atom_command_line.h"
#include "base/at_exit.h"
#include "base/i18n/icu_util.h"
#include "base/mac/bundle_locations.h"

View File

@@ -3,7 +3,6 @@
// found in the LICENSE file.
#include "atom/app/atom_main.h"
#include "atom/app/atom_main_args.h"
#include <stdlib.h>
#include <string.h>
@@ -33,6 +32,7 @@
#endif // defined(OS_MACOSX)
#include "atom/app/node_main.h"
#include "atom/common/atom_command_line.h"
#include "base/i18n/icu_util.h"
#if defined(OS_WIN)

View File

@@ -10,6 +10,7 @@
#include "atom/browser/atom_browser_client.h"
#include "atom/common/google_api_key.h"
#include "atom/renderer/atom_renderer_client.h"
#include "atom/utility/atom_content_utility_client.h"
#include "base/command_line.h"
#include "base/debug/stack_trace.h"
#include "base/environment.h"
@@ -63,6 +64,10 @@ void AtomMainDelegate::PreSandboxStartup() {
std::string process_type = command_line->GetSwitchValueASCII(
switches::kProcessType);
if (process_type == switches::kUtilityProcess) {
AtomContentUtilityClient::PreSandboxStartup();
}
// Only append arguments for browser process.
if (!process_type.empty())
return;
@@ -77,6 +82,9 @@ void AtomMainDelegate::PreSandboxStartup() {
// Disable renderer sandbox for most of node's functions.
command_line->AppendSwitch(switches::kNoSandbox);
// Allow file:// URIs to read other file:// URIs by default.
command_line->AppendSwitch(switches::kAllowFileAccessFromFiles);
#if defined(OS_MACOSX)
// Enable AVFoundation.
command_line->AppendSwitch("enable-avfoundation");
@@ -94,6 +102,11 @@ content::ContentRendererClient*
return renderer_client_.get();
}
content::ContentUtilityClient* AtomMainDelegate::CreateContentUtilityClient() {
utility_client_.reset(new AtomContentUtilityClient);
return utility_client_.get();
}
scoped_ptr<brightray::ContentClient> AtomMainDelegate::CreateContentClient() {
return scoped_ptr<brightray::ContentClient>(new AtomContentClient).Pass();
}

View File

@@ -21,6 +21,7 @@ class AtomMainDelegate : public brightray::MainDelegate {
void PreSandboxStartup() override;
content::ContentBrowserClient* CreateContentBrowserClient() override;
content::ContentRendererClient* CreateContentRendererClient() override;
content::ContentUtilityClient* CreateContentUtilityClient() override;
// brightray::MainDelegate:
scoped_ptr<brightray::ContentClient> CreateContentClient() override;
@@ -35,6 +36,7 @@ class AtomMainDelegate : public brightray::MainDelegate {
brightray::ContentClient content_client_;
scoped_ptr<content::ContentBrowserClient> browser_client_;
scoped_ptr<content::ContentRendererClient> renderer_client_;
scoped_ptr<content::ContentUtilityClient> utility_client_;
DISALLOW_COPY_AND_ASSIGN(AtomMainDelegate);
};

View File

@@ -7,23 +7,32 @@
#include <string>
#include <vector>
#if defined(OS_WIN)
#include <shlobj.h>
#endif
#include "atom/browser/api/atom_api_menu.h"
#include "atom/browser/api/atom_api_session.h"
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/browser.h"
#include "atom/browser/api/atom_api_web_contents.h"
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "atom/common/native_mate_converters/gurl_converter.h"
#include "base/command_line.h"
#include "base/environment.h"
#include "base/files/file_path.h"
#include "base/path_service.h"
#include "brightray/browser/brightray_paths.h"
#include "content/public/browser/client_certificate_delegate.h"
#include "content/public/browser/gpu_data_manager.h"
#include "native_mate/callback.h"
#include "native_mate/dictionary.h"
#include "native_mate/object_template_builder.h"
#include "net/base/load_flags.h"
#include "net/proxy/proxy_service.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
#include "net/ssl/ssl_cert_request_info.h"
#if defined(OS_WIN)
#include "base/strings/utf_string_conversions.h"
#endif
#include "atom/common/node_includes.h"
@@ -34,7 +43,7 @@ namespace mate {
#if defined(OS_WIN)
template<>
struct Converter<Browser::UserTask> {
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
Browser::UserTask* out) {
mate::Dictionary dict;
if (!ConvertFromV8(isolate, val, &dict))
@@ -52,6 +61,21 @@ struct Converter<Browser::UserTask> {
};
#endif
template<>
struct Converter<scoped_refptr<net::X509Certificate>> {
static v8::Local<v8::Value> ToV8(
v8::Isolate* isolate,
const scoped_refptr<net::X509Certificate>& val) {
mate::Dictionary dict(isolate, v8::Object::New(isolate));
std::string encoded_data;
net::X509Certificate::GetPEMEncoded(
val->os_cert_handle(), &encoded_data);
dict.Set("data", encoded_data);
dict.Set("issuerName", val->issuer().GetDisplayName());
return dict.GetHandle();
}
};
} // namespace mate
@@ -85,50 +109,39 @@ int GetPathConstant(const std::string& name) {
return -1;
}
class ResolveProxyHelper {
public:
ResolveProxyHelper(const GURL& url, App::ResolveProxyCallback callback)
: callback_(callback) {
net::ProxyService* proxy_service = AtomBrowserContext::Get()->
url_request_context_getter()->GetURLRequestContext()->proxy_service();
// Start the request.
int result = proxy_service->ResolveProxy(
url, net::LOAD_NORMAL, &proxy_info_,
base::Bind(&ResolveProxyHelper::OnResolveProxyCompleted,
base::Unretained(this)),
&pac_req_, nullptr, net::BoundNetLog());
// Completed synchronously.
if (result != net::ERR_IO_PENDING)
OnResolveProxyCompleted(result);
void OnClientCertificateSelected(
v8::Isolate* isolate,
std::shared_ptr<content::ClientCertificateDelegate> delegate,
mate::Arguments* args) {
v8::Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
mate::Dictionary cert_data;
if (!(args->Length() == 1 && args->GetNext(&cert_data))) {
args->ThrowError();
return;
}
void OnResolveProxyCompleted(int result) {
std::string proxy;
if (result == net::OK)
proxy = proxy_info_.ToPacString();
callback_.Run(proxy);
std::string encoded_data;
cert_data.Get("data", &encoded_data);
delete this;
}
auto certs =
net::X509Certificate::CreateCertificateListFromBytes(
encoded_data.data(), encoded_data.size(),
net::X509Certificate::FORMAT_AUTO);
private:
App::ResolveProxyCallback callback_;
net::ProxyInfo proxy_info_;
net::ProxyService::PacRequest* pac_req_;
DISALLOW_COPY_AND_ASSIGN(ResolveProxyHelper);
};
delegate->ContinueWithCertificate(certs[0].get());
}
} // namespace
App::App() {
Browser::Get()->AddObserver(this);
content::GpuDataManager::GetInstance()->AddObserver(this);
}
App::~App() {
Browser::Get()->RemoveObserver(this);
content::GpuDataManager::GetInstance()->RemoveObserver(this);
}
void App::OnBeforeQuit(bool* prevent_default) {
@@ -164,9 +177,42 @@ void App::OnWillFinishLaunching() {
}
void App::OnFinishLaunching() {
// Create the defaultSession.
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
auto browser_context = static_cast<AtomBrowserContext*>(
AtomBrowserMainParts::Get()->browser_context());
auto handle = Session::CreateFrom(isolate(), browser_context);
default_session_.Reset(isolate(), handle.ToV8());
Emit("ready");
}
void App::OnSelectCertificate(
content::WebContents* web_contents,
net::SSLCertRequestInfo* cert_request_info,
scoped_ptr<content::ClientCertificateDelegate> delegate) {
std::shared_ptr<content::ClientCertificateDelegate>
shared_delegate(delegate.release());
bool prevent_default =
Emit("select-certificate",
api::WebContents::CreateFrom(isolate(), web_contents),
cert_request_info->host_and_port.ToString(),
cert_request_info->client_certs,
base::Bind(&OnClientCertificateSelected,
isolate(),
shared_delegate));
// Default to first certificate from the platform store.
if (!prevent_default)
shared_delegate->ContinueWithCertificate(
cert_request_info->client_certs[0].get());
}
void App::OnGpuProcessCrashed(base::TerminationStatus exit_code) {
Emit("gpu-process-crashed");
}
base::FilePath App::GetPath(mate::Arguments* args, const std::string& name) {
bool succeed = false;
base::FilePath path;
@@ -189,10 +235,6 @@ void App::SetPath(mate::Arguments* args,
args->ThrowError("Failed to set path");
}
void App::ResolveProxy(const GURL& url, ResolveProxyCallback callback) {
new ResolveProxyHelper(url, callback);
}
void App::SetDesktopName(const std::string& desktop_name) {
#if defined(OS_LINUX)
scoped_ptr<base::Environment> env(base::Environment::Create());
@@ -200,6 +242,20 @@ void App::SetDesktopName(const std::string& desktop_name) {
#endif
}
void App::SetAppUserModelId(const std::string& app_id) {
#if defined(OS_WIN)
base::string16 app_id_utf16 = base::UTF8ToUTF16(app_id);
SetCurrentProcessExplicitAppUserModelID(app_id_utf16.c_str());
#endif
}
v8::Local<v8::Value> App::DefaultSession(v8::Isolate* isolate) {
if (default_session_.IsEmpty())
return v8::Null(isolate);
else
return v8::Local<v8::Value>::New(isolate, default_session_);
}
mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
auto browser = base::Unretained(Browser::Get());
@@ -221,8 +277,9 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder(
#endif
.SetMethod("setPath", &App::SetPath)
.SetMethod("getPath", &App::GetPath)
.SetMethod("resolveProxy", &App::ResolveProxy)
.SetMethod("setDesktopName", &App::SetDesktopName);
.SetMethod("setDesktopName", &App::SetDesktopName)
.SetMethod("setAppUserModelId", &App::SetAppUserModelId)
.SetProperty("defaultSession", &App::DefaultSession);
}
// static
@@ -261,8 +318,8 @@ void DockSetMenu(atom::api::Menu* menu) {
}
#endif
void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
v8::Handle<v8::Context> context, void* priv) {
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
v8::Local<v8::Context> context, void* priv) {
v8::Isolate* isolate = context->GetIsolate();
auto command_line = base::CommandLine::ForCurrentProcess();

View File

@@ -9,11 +9,9 @@
#include "atom/browser/api/event_emitter.h"
#include "atom/browser/browser_observer.h"
#include "base/callback.h"
#include "content/public/browser/gpu_data_manager_observer.h"
#include "native_mate/handle.h"
class GURL;
namespace base {
class FilePath;
}
@@ -27,10 +25,9 @@ namespace atom {
namespace api {
class App : public mate::EventEmitter,
public BrowserObserver {
public BrowserObserver,
public content::GpuDataManagerObserver {
public:
typedef base::Callback<void(std::string)> ResolveProxyCallback;
static mate::Handle<App> Create(v8::Isolate* isolate);
protected:
@@ -47,6 +44,13 @@ class App : public mate::EventEmitter,
void OnActivateWithNoOpenWindows() override;
void OnWillFinishLaunching() override;
void OnFinishLaunching() override;
void OnSelectCertificate(
content::WebContents* web_contents,
net::SSLCertRequestInfo* cert_request_info,
scoped_ptr<content::ClientCertificateDelegate> delegate) override;
// content::GpuDataManagerObserver:
void OnGpuProcessCrashed(base::TerminationStatus exit_code) override;
// mate::Wrappable:
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
@@ -59,8 +63,11 @@ class App : public mate::EventEmitter,
const std::string& name,
const base::FilePath& path);
void ResolveProxy(const GURL& url, ResolveProxyCallback callback);
void SetDesktopName(const std::string& desktop_name);
void SetAppUserModelId(const std::string& app_id);
v8::Local<v8::Value> DefaultSession(v8::Isolate* isolate);
v8::Global<v8::Value> default_session_;
DISALLOW_COPY_AND_ASSIGN(App);
};

View File

@@ -77,8 +77,8 @@ mate::Handle<AutoUpdater> AutoUpdater::Create(v8::Isolate* isolate) {
namespace {
void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
v8::Handle<v8::Context> context, void* priv) {
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("autoUpdater", atom::api::AutoUpdater::Create(isolate));

View File

@@ -17,24 +17,10 @@ using content::TracingController;
namespace mate {
template<typename T>
struct Converter<std::set<T> > {
static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
const std::set<T>& val) {
v8::Handle<v8::Array> result = v8::Array::New(
isolate, static_cast<int>(val.size()));
typename std::set<T>::const_iterator it;
int i;
for (i = 0, it = val.begin(); it != val.end(); ++it, ++i)
result->Set(i, Converter<T>::ToV8(isolate, *it));
return result;
}
};
template<>
struct Converter<base::trace_event::CategoryFilter> {
static bool FromV8(v8::Isolate* isolate,
v8::Handle<v8::Value> val,
v8::Local<v8::Value> val,
base::trace_event::CategoryFilter* out) {
std::string filter;
if (!ConvertFromV8(isolate, val, &filter))
@@ -47,7 +33,7 @@ struct Converter<base::trace_event::CategoryFilter> {
template<>
struct Converter<base::trace_event::TraceOptions> {
static bool FromV8(v8::Isolate* isolate,
v8::Handle<v8::Value> val,
v8::Local<v8::Value> val,
base::trace_event::TraceOptions* out) {
std::string options;
if (!ConvertFromV8(isolate, val, &options))
@@ -60,8 +46,8 @@ struct Converter<base::trace_event::TraceOptions> {
namespace {
void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
v8::Handle<v8::Context> context, void* priv) {
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
v8::Local<v8::Context> context, void* priv) {
auto controller = base::Unretained(TracingController::GetInstance());
mate::Dictionary dict(context->GetIsolate(), exports);
dict.SetMethod("getCategories", base::Bind(

View File

@@ -0,0 +1,349 @@
// 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_cookies.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 "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "native_mate/callback.h"
#include "native_mate/dictionary.h"
#include "native_mate/object_template_builder.h"
#include "net/cookies/cookie_monster.h"
#include "net/cookies/cookie_store.h"
#include "net/cookies/cookie_util.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
#include "atom/common/node_includes.h"
using atom::api::Cookies;
using content::BrowserThread;
namespace {
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> {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
const net::CanonicalCookie& val) {
mate::Dictionary dict(isolate, v8::Object::New(isolate));
dict.Set("name", val.Name());
dict.Set("value", val.Value());
dict.Set("domain", val.Domain());
dict.Set("host_only", net::cookie_util::DomainIsHostOnly(val.Domain()));
dict.Set("path", val.Path());
dict.Set("secure", val.IsSecure());
dict.Set("http_only", val.IsHttpOnly());
dict.Set("session", val.IsPersistent());
if (!val.IsPersistent())
dict.Set("expirationDate", val.ExpiryDate().ToDoubleT());
return dict.GetHandle();
}
};
} // namespace mate
namespace atom {
namespace api {
Cookies::Cookies(content::BrowserContext* browser_context) :
browser_context_(browser_context) {
}
Cookies::~Cookies() {
}
void Cookies::Get(const base::DictionaryValue& options,
const CookiesCallback& callback) {
scoped_ptr<base::DictionaryValue> filter(
options.DeepCopyWithoutEmptyChildren());
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) {
net::CookieStore* cookie_store = browser_context_->GetRequestContext()
->GetURLRequestContext()->cookie_store();
std::string url;
filter->GetString("url", &url);
if (!GetCookieListFromStore(cookie_store, 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));
}
}
void Cookies::OnGetCookies(scoped_ptr<base::DictionaryValue> filter,
const CookiesCallback& callback,
const net::CookieList& cookie_list) {
net::CookieList result;
for (const auto& cookie : cookie_list) {
if (MatchesCookie(filter.get(), cookie))
result.push_back(cookie);
}
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
&RunGetCookiesCallbackOnUIThread, isolate(), "", result, 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) {
net::CookieStore* cookie_store = browser_context_->GetRequestContext()
->GetURLRequestContext()->cookie_store();
cookie_store->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;
std::string error_message;
if (!options.GetString("url", &url)) {
error_message = "The url field is required.";
}
GURL gurl(url);
if (error_message.empty() && !gurl.is_valid()) {
error_message = "Url is not valid.";
}
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));
}
void Cookies::SetCookiesOnIOThread(scoped_ptr<base::DictionaryValue> details,
const GURL& url,
const CookiesCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
net::CookieStore* cookie_store = browser_context_->GetRequestContext()
->GetURLRequestContext()->cookie_store();
std::string name, value, domain, path;
bool secure = false;
bool http_only = false;
double expiration_date;
details->GetString("name", &name);
details->GetString("value", &value);
details->GetString("domain", &domain);
details->GetString("path", &path);
details->GetBoolean("secure", &secure);
details->GetBoolean("http_only", &http_only);
base::Time expiration_time;
if (details->GetDouble("expirationDate", &expiration_date)) {
expiration_time = (expiration_date == 0) ?
base::Time::UnixEpoch() :
base::Time::FromDoubleT(expiration_date);
}
cookie_store->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));
}
void Cookies::OnSetCookies(const CookiesCallback& callback,
bool set_success) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::Bind(&RunSetCookiesCallbackOnUIThread, isolate(), "", set_success,
callback));
}
mate::ObjectTemplateBuilder Cookies::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
return mate::ObjectTemplateBuilder(isolate)
.SetMethod("get", &Cookies::Get)
.SetMethod("remove", &Cookies::Remove)
.SetMethod("set", &Cookies::Set);
}
// static
mate::Handle<Cookies> Cookies::Create(
v8::Isolate* isolate,
content::BrowserContext* browser_context) {
return mate::CreateHandle(isolate, new Cookies(browser_context));
}
} // namespace api
} // namespace atom

View File

@@ -0,0 +1,78 @@
// 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_COOKIES_H_
#define ATOM_BROWSER_API_ATOM_API_COOKIES_H_
#include <string>
#include "base/callback.h"
#include "base/values.h"
#include "native_mate/wrappable.h"
#include "native_mate/handle.h"
#include "native_mate/dictionary.h"
#include "net/cookies/canonical_cookie.h"
namespace content {
class BrowserContext;
}
namespace atom {
namespace api {
class Cookies : public mate::Wrappable {
public:
// 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);
protected:
explicit Cookies(content::BrowserContext* browser_context);
~Cookies();
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);
// mate::Wrappable implementations:
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) override;
private:
content::BrowserContext* browser_context_;
DISALLOW_COPY_AND_ASSIGN(Cookies);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_COOKIES_H_

View File

@@ -22,7 +22,7 @@ namespace mate {
template<>
struct Converter<file_dialog::Filter> {
static bool FromV8(v8::Isolate* isolate,
v8::Handle<v8::Value> val,
v8::Local<v8::Value> val,
file_dialog::Filter* out) {
mate::Dictionary dict;
if (!ConvertFromV8(isolate, val, &dict))
@@ -52,7 +52,7 @@ void ShowMessageBox(int type,
const std::string& message = texts[1];
const std::string& detail = texts[2];
v8::Handle<v8::Value> peek = args->PeekNext();
v8::Local<v8::Value> peek = args->PeekNext();
atom::MessageBoxCallback callback;
if (mate::Converter<atom::MessageBoxCallback>::FromV8(args->isolate(),
peek,
@@ -72,7 +72,7 @@ void ShowOpenDialog(const std::string& title,
int properties,
atom::NativeWindow* window,
mate::Arguments* args) {
v8::Handle<v8::Value> peek = args->PeekNext();
v8::Local<v8::Value> peek = args->PeekNext();
file_dialog::OpenDialogCallback callback;
if (mate::Converter<file_dialog::OpenDialogCallback>::FromV8(args->isolate(),
peek,
@@ -92,7 +92,7 @@ void ShowSaveDialog(const std::string& title,
const file_dialog::Filters& filters,
atom::NativeWindow* window,
mate::Arguments* args) {
v8::Handle<v8::Value> peek = args->PeekNext();
v8::Local<v8::Value> peek = args->PeekNext();
file_dialog::SaveDialogCallback callback;
if (mate::Converter<file_dialog::SaveDialogCallback>::FromV8(args->isolate(),
peek,
@@ -106,8 +106,8 @@ void ShowSaveDialog(const std::string& title,
}
}
void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
v8::Handle<v8::Context> context, void* priv) {
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
v8::Local<v8::Context> context, void* priv) {
mate::Dictionary dict(context->GetIsolate(), exports);
dict.SetMethod("showMessageBox", &ShowMessageBox);
dict.SetMethod("showErrorBox", &atom::ShowErrorBox);

View File

@@ -86,8 +86,8 @@ mate::Handle<GlobalShortcut> GlobalShortcut::Create(v8::Isolate* isolate) {
namespace {
void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
v8::Handle<v8::Context> context, void* priv) {
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("globalShortcut", atom::api::GlobalShortcut::Create(isolate));

View File

@@ -55,11 +55,10 @@ bool Menu::IsCommandIdVisible(int command_id) const {
bool Menu::GetAcceleratorForCommandId(int command_id,
ui::Accelerator* accelerator) {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
v8::Handle<v8::Value> val = get_accelerator_.Run(command_id);
return mate::ConvertFromV8(isolate, val, accelerator);
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
v8::Local<v8::Value> val = get_accelerator_.Run(command_id);
return mate::ConvertFromV8(isolate(), val, accelerator);
}
void Menu::ExecuteCommand(int command_id, int event_flags) {
@@ -70,10 +69,6 @@ void Menu::MenuWillShow(ui::SimpleMenuModel* source) {
menu_will_show_.Run();
}
void Menu::AttachToWindow(Window* window) {
window->window()->SetMenu(model_.get());
}
void Menu::InsertItemAt(
int index, int command_id, const base::string16& label) {
model_->InsertItemAt(index, command_id, label);
@@ -150,7 +145,7 @@ bool Menu::IsVisibleAt(int index) const {
// static
void Menu::BuildPrototype(v8::Isolate* isolate,
v8::Handle<v8::ObjectTemplate> prototype) {
v8::Local<v8::ObjectTemplate> prototype) {
mate::ObjectTemplateBuilder(isolate, prototype)
.SetMethod("insertItem", &Menu::InsertItemAt)
.SetMethod("insertCheckItem", &Menu::InsertCheckItemAt)
@@ -168,7 +163,6 @@ void Menu::BuildPrototype(v8::Isolate* isolate,
.SetMethod("isItemCheckedAt", &Menu::IsItemCheckedAt)
.SetMethod("isEnabledAt", &Menu::IsEnabledAt)
.SetMethod("isVisibleAt", &Menu::IsVisibleAt)
.SetMethod("attachToWindow", &Menu::AttachToWindow)
.SetMethod("_popup", &Menu::Popup)
.SetMethod("_popupAt", &Menu::PopupAt);
}
@@ -180,14 +174,14 @@ void Menu::BuildPrototype(v8::Isolate* isolate,
namespace {
void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
v8::Handle<v8::Context> context, void* priv) {
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
v8::Local<v8::Context> context, void* priv) {
using atom::api::Menu;
v8::Isolate* isolate = context->GetIsolate();
v8::Local<v8::Function> constructor = mate::CreateConstructor<Menu>(
isolate, "Menu", base::Bind(&Menu::Create));
mate::Dictionary dict(isolate, exports);
dict.Set("Menu", static_cast<v8::Handle<v8::Value>>(constructor));
dict.Set("Menu", static_cast<v8::Local<v8::Value>>(constructor));
#if defined(OS_MACOSX)
dict.SetMethod("setApplicationMenu", &Menu::SetApplicationMenu);
dict.SetMethod("sendActionToFirstResponder",

View File

@@ -23,7 +23,7 @@ class Menu : public mate::Wrappable,
static mate::Wrappable* Create();
static void BuildPrototype(v8::Isolate* isolate,
v8::Handle<v8::ObjectTemplate> prototype);
v8::Local<v8::ObjectTemplate> prototype);
#if defined(OS_MACOSX)
// Set the global menubar.
@@ -51,7 +51,6 @@ class Menu : public mate::Wrappable,
void ExecuteCommand(int command_id, int event_flags) override;
void MenuWillShow(ui::SimpleMenuModel* source) override;
virtual void AttachToWindow(Window* window);
virtual void Popup(Window* window) = 0;
virtual void PopupAt(Window* window, int x, int y) = 0;
@@ -88,7 +87,7 @@ class Menu : public mate::Wrappable,
base::Callback<bool(int)> is_checked_;
base::Callback<bool(int)> is_enabled_;
base::Callback<bool(int)> is_visible_;
base::Callback<v8::Handle<v8::Value>(int)> get_accelerator_;
base::Callback<v8::Local<v8::Value>(int)> get_accelerator_;
base::Callback<void(int)> execute_command_;
base::Callback<void()> menu_will_show_;
@@ -99,4 +98,27 @@ class Menu : public mate::Wrappable,
} // namespace atom
namespace mate {
template<>
struct Converter<ui::SimpleMenuModel*> {
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
ui::SimpleMenuModel** out) {
// null would be tranfered to NULL.
if (val->IsNull()) {
*out = nullptr;
return true;
}
atom::api::Menu* menu;
if (!Converter<atom::api::Menu*>::FromV8(isolate, val, &menu))
return false;
*out = menu->model();
return true;
}
};
} // namespace mate
#endif // ATOM_BROWSER_API_ATOM_API_MENU_H_

View File

@@ -22,7 +22,7 @@ void MenuMac::Popup(Window* window) {
NativeWindow* native_window = window->window();
if (!native_window)
return;
content::WebContents* web_contents = native_window->GetWebContents();
content::WebContents* web_contents = native_window->web_contents();
if (!web_contents)
return;
@@ -54,7 +54,7 @@ void MenuMac::PopupAt(Window* window, int x, int y) {
NativeWindow* native_window = window->window();
if (!native_window)
return;
content::WebContents* web_contents = native_window->GetWebContents();
content::WebContents* web_contents = native_window->web_contents();
if (!web_contents)
return;

View File

@@ -24,7 +24,7 @@ void MenuViews::PopupAt(Window* window, int x, int y) {
NativeWindow* native_window = static_cast<NativeWindow*>(window->window());
if (!native_window)
return;
content::WebContents* web_contents = native_window->GetWebContents();
content::WebContents* web_contents = native_window->web_contents();
if (!web_contents)
return;
content::RenderWidgetHostView* view = web_contents->GetRenderWidgetHostView();

View File

@@ -39,10 +39,11 @@ void PowerMonitor::OnResume() {
}
// static
v8::Handle<v8::Value> PowerMonitor::Create(v8::Isolate* isolate) {
v8::Local<v8::Value> PowerMonitor::Create(v8::Isolate* isolate) {
if (!Browser::Get()->is_ready()) {
node::ThrowError("Cannot initialize \"power-monitor\" module"
"before app is ready");
node::ThrowError(
isolate,
"Cannot initialize \"power-monitor\" module before app is ready");
return v8::Null(isolate);
}
@@ -56,8 +57,8 @@ v8::Handle<v8::Value> PowerMonitor::Create(v8::Isolate* isolate) {
namespace {
void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
v8::Handle<v8::Context> context, void* priv) {
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
v8::Local<v8::Context> context, void* priv) {
#if defined(OS_MACOSX)
base::PowerMonitorDeviceSource::AllocateSystemIOPorts();
#endif

View File

@@ -17,7 +17,7 @@ namespace api {
class PowerMonitor : public mate::EventEmitter,
public base::PowerObserver {
public:
static v8::Handle<v8::Value> Create(v8::Isolate* isolate);
static v8::Local<v8::Value> Create(v8::Isolate* isolate);
protected:
PowerMonitor();

View File

@@ -0,0 +1,128 @@
// 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_power_save_blocker.h"
#include <string>
#include "content/public/browser/power_save_blocker.h"
#include "native_mate/dictionary.h"
#include "atom/common/node_includes.h"
namespace mate {
template<>
struct Converter<content::PowerSaveBlocker::PowerSaveBlockerType> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
content::PowerSaveBlocker::PowerSaveBlockerType* out) {
using content::PowerSaveBlocker;
std::string type;
if (!ConvertFromV8(isolate, val, &type))
return false;
if (type == "prevent-app-suspension")
*out = PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension;
else if (type == "prevent-display-sleep")
*out = PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep;
else
return false;
return true;
}
};
} // namespace mate
namespace atom {
namespace api {
PowerSaveBlocker::PowerSaveBlocker()
: current_blocker_type_(
content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension) {
}
PowerSaveBlocker::~PowerSaveBlocker() {
}
void PowerSaveBlocker::UpdatePowerSaveBlocker() {
if (power_save_blocker_types_.empty()) {
power_save_blocker_.reset();
return;
}
// |kPowerSaveBlockPreventAppSuspension| keeps system active, but allows
// screen to be turned off.
// |kPowerSaveBlockPreventDisplaySleep| keeps system and screen active, has a
// higher precedence level than |kPowerSaveBlockPreventAppSuspension|.
//
// Only the highest-precedence blocker type takes effect.
content::PowerSaveBlocker::PowerSaveBlockerType new_blocker_type =
content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension;
for (const auto& element : power_save_blocker_types_) {
if (element.second ==
content::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep) {
new_blocker_type =
content::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep;
break;
}
}
if (!power_save_blocker_ || new_blocker_type != current_blocker_type_) {
scoped_ptr<content::PowerSaveBlocker> new_blocker =
content::PowerSaveBlocker::Create(
new_blocker_type,
content::PowerSaveBlocker::kReasonOther,
ATOM_PRODUCT_NAME);
power_save_blocker_.swap(new_blocker);
current_blocker_type_ = new_blocker_type;
}
}
int PowerSaveBlocker::Start(
content::PowerSaveBlocker::PowerSaveBlockerType type) {
static int count = 0;
power_save_blocker_types_[count] = type;
UpdatePowerSaveBlocker();
return count++;
}
bool PowerSaveBlocker::Stop(int id) {
bool success = power_save_blocker_types_.erase(id) > 0;
UpdatePowerSaveBlocker();
return success;
}
bool PowerSaveBlocker::IsStarted(int id) {
return power_save_blocker_types_.find(id) != power_save_blocker_types_.end();
}
mate::ObjectTemplateBuilder PowerSaveBlocker::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
return mate::ObjectTemplateBuilder(isolate)
.SetMethod("start", &PowerSaveBlocker::Start)
.SetMethod("stop", &PowerSaveBlocker::Stop)
.SetMethod("isStarted", &PowerSaveBlocker::IsStarted);
}
// static
mate::Handle<PowerSaveBlocker> PowerSaveBlocker::Create(v8::Isolate* isolate) {
return CreateHandle(isolate, new PowerSaveBlocker);
}
} // 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("powerSaveBlocker", atom::api::PowerSaveBlocker::Create(isolate));
}
} // namespace
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_power_save_blocker, Initialize);

View File

@@ -0,0 +1,59 @@
// 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_POWER_SAVE_BLOCKER_H_
#define ATOM_BROWSER_API_ATOM_API_POWER_SAVE_BLOCKER_H_
#include <map>
#include "base/memory/scoped_ptr.h"
#include "content/public/browser/power_save_blocker.h"
#include "native_mate/handle.h"
#include "native_mate/wrappable.h"
namespace mate {
class Dictionary;
}
namespace atom {
namespace api {
class PowerSaveBlocker : public mate::Wrappable {
public:
static mate::Handle<PowerSaveBlocker> Create(v8::Isolate* isolate);
protected:
PowerSaveBlocker();
virtual ~PowerSaveBlocker();
// mate::Wrappable implementations:
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) override;
private:
void UpdatePowerSaveBlocker();
int Start(content::PowerSaveBlocker::PowerSaveBlockerType type);
bool Stop(int id);
bool IsStarted(int id);
scoped_ptr<content::PowerSaveBlocker> power_save_blocker_;
// Currnet blocker type used by |power_save_blocker_|
content::PowerSaveBlocker::PowerSaveBlockerType current_blocker_type_;
// Map from id to the corresponding blocker type for each request.
using PowerSaveBlockerTypeMap =
std::map<int, content::PowerSaveBlocker::PowerSaveBlockerType>;
PowerSaveBlockerTypeMap power_save_blocker_types_;
DISALLOW_COPY_AND_ASSIGN(PowerSaveBlocker);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_POWER_SAVE_BLOCKER_H_

View File

@@ -4,10 +4,13 @@
#include "atom/browser/api/atom_api_protocol.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/net/adapter_request_job.h"
#include "atom/browser/net/atom_url_request_job_factory.h"
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "atom/common/native_mate_converters/gurl_converter.h"
#include "content/public/browser/browser_thread.h"
#include "native_mate/callback.h"
#include "native_mate/dictionary.h"
@@ -21,7 +24,7 @@ namespace mate {
template<>
struct Converter<const net::URLRequest*> {
static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
const net::URLRequest* val) {
return mate::ObjectTemplateBuilder(isolate)
.SetValue("method", val->method())
@@ -42,6 +45,14 @@ namespace {
typedef net::URLRequestJobFactory::ProtocolHandler ProtocolHandler;
scoped_refptr<base::RefCountedBytes> BufferToRefCountedBytes(
v8::Local<v8::Value> buf) {
scoped_refptr<base::RefCountedBytes> data(new base::RefCountedBytes);
auto start = reinterpret_cast<const unsigned char*>(node::Buffer::Data(buf));
data->data().assign(start, start + node::Buffer::Length(buf));
return data;
}
class CustomProtocolRequestJob : public AdapterRequestJob {
public:
CustomProtocolRequestJob(Protocol* registry,
@@ -56,14 +67,13 @@ class CustomProtocolRequestJob : public AdapterRequestJob {
void GetJobTypeInUI() override {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
v8::Locker locker(registry_->isolate());
v8::HandleScope handle_scope(registry_->isolate());
// Call the JS handler.
Protocol::JsProtocolHandler callback =
registry_->GetProtocolHandler(request()->url().scheme());
v8::Handle<v8::Value> result = callback.Run(request());
v8::Local<v8::Value> result = callback.Run(request());
// Determine the type of the job we are going to create.
if (result->IsString()) {
@@ -73,8 +83,8 @@ class CustomProtocolRequestJob : public AdapterRequestJob {
GetWeakPtr(), "text/plain", "UTF-8", data));
return;
} else if (result->IsObject()) {
v8::Handle<v8::Object> obj = result->ToObject();
mate::Dictionary dict(isolate, obj);
v8::Local<v8::Object> obj = result->ToObject();
mate::Dictionary dict(registry_->isolate(), obj);
std::string name = mate::V8ToString(obj->GetConstructorName());
if (name == "RequestStringJob") {
std::string mime_type, charset, data;
@@ -88,14 +98,15 @@ class CustomProtocolRequestJob : public AdapterRequestJob {
return;
} else if (name == "RequestBufferJob") {
std::string mime_type, encoding;
v8::Handle<v8::Value> buffer;
v8::Local<v8::Value> buffer;
dict.Get("mimeType", &mime_type);
dict.Get("encoding", &encoding);
dict.Get("data", &buffer);
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&AdapterRequestJob::CreateBufferJobAndStart,
GetWeakPtr(), mime_type, encoding, buffer->ToObject()));
GetWeakPtr(), mime_type, encoding,
BufferToRefCountedBytes(buffer)));
return;
} else if (name == "RequestFileJob") {
base::FilePath path;
@@ -105,6 +116,25 @@ class CustomProtocolRequestJob : public AdapterRequestJob {
base::Bind(&AdapterRequestJob::CreateFileJobAndStart,
GetWeakPtr(), path));
return;
} else if (name == "RequestErrorJob") {
int error = net::ERR_NOT_IMPLEMENTED;
dict.Get("error", &error);
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&AdapterRequestJob::CreateErrorJobAndStart,
GetWeakPtr(), error));
return;
} else if (name == "RequestHttpJob") {
GURL url;
std::string method, referrer;
dict.Get("url", &url);
dict.Get("method", &method);
dict.Get("referrer", &referrer);
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&AdapterRequestJob::CreateHttpJobAndStart, GetWeakPtr(),
registry_->browser_context(), url, method, referrer));
return;
}
}
@@ -161,8 +191,9 @@ class CustomProtocolHandler : public ProtocolHandler {
} // namespace
Protocol::Protocol()
: job_factory_(AtomBrowserContext::Get()->job_factory()) {
Protocol::Protocol(AtomBrowserContext* browser_context)
: browser_context_(browser_context),
job_factory_(browser_context->job_factory()) {
CHECK(job_factory_);
}
@@ -174,28 +205,20 @@ Protocol::JsProtocolHandler Protocol::GetProtocolHandler(
mate::ObjectTemplateBuilder Protocol::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
return mate::ObjectTemplateBuilder(isolate)
.SetMethod("registerProtocol",
base::Bind(&Protocol::RegisterProtocol,
base::Unretained(this)))
.SetMethod("unregisterProtocol",
base::Bind(&Protocol::UnregisterProtocol,
base::Unretained(this)))
.SetMethod("isHandledProtocol",
base::Bind(&Protocol::IsHandledProtocol,
base::Unretained(this)))
.SetMethod("interceptProtocol",
base::Bind(&Protocol::InterceptProtocol,
base::Unretained(this)))
.SetMethod("uninterceptProtocol",
base::Bind(&Protocol::UninterceptProtocol,
base::Unretained(this)));
.SetMethod("registerProtocol", &Protocol::RegisterProtocol)
.SetMethod("unregisterProtocol", &Protocol::UnregisterProtocol)
.SetMethod("registerStandardSchemes", &Protocol::RegisterStandardSchemes)
.SetMethod("isHandledProtocol", &Protocol::IsHandledProtocol)
.SetMethod("interceptProtocol", &Protocol::InterceptProtocol)
.SetMethod("uninterceptProtocol", &Protocol::UninterceptProtocol);
}
void Protocol::RegisterProtocol(const std::string& scheme,
void Protocol::RegisterProtocol(v8::Isolate* isolate,
const std::string& scheme,
const JsProtocolHandler& callback) {
if (ContainsKey(protocol_handlers_, scheme) ||
job_factory_->IsHandledProtocol(scheme))
return node::ThrowError("The scheme is already registered");
return node::ThrowError(isolate, "The scheme is already registered");
protocol_handlers_[scheme] = callback;
BrowserThread::PostTask(BrowserThread::IO,
@@ -204,10 +227,11 @@ void Protocol::RegisterProtocol(const std::string& scheme,
base::Unretained(this), scheme));
}
void Protocol::UnregisterProtocol(const std::string& scheme) {
void Protocol::UnregisterProtocol(v8::Isolate* isolate,
const std::string& scheme) {
ProtocolHandlersMap::iterator it(protocol_handlers_.find(scheme));
if (it == protocol_handlers_.end())
return node::ThrowError("The scheme has not been registered");
return node::ThrowError(isolate, "The scheme has not been registered");
protocol_handlers_.erase(it);
BrowserThread::PostTask(BrowserThread::IO,
@@ -216,17 +240,23 @@ void Protocol::UnregisterProtocol(const std::string& scheme) {
base::Unretained(this), scheme));
}
void Protocol::RegisterStandardSchemes(
const std::vector<std::string>& schemes) {
atom::AtomBrowserClient::SetCustomSchemes(schemes);
}
bool Protocol::IsHandledProtocol(const std::string& scheme) {
return job_factory_->IsHandledProtocol(scheme);
}
void Protocol::InterceptProtocol(const std::string& scheme,
void Protocol::InterceptProtocol(v8::Isolate* isolate,
const std::string& scheme,
const JsProtocolHandler& callback) {
if (!job_factory_->HasProtocolHandler(scheme))
return node::ThrowError("Scheme does not exist.");
return node::ThrowError(isolate, "Scheme does not exist.");
if (ContainsKey(protocol_handlers_, scheme))
return node::ThrowError("Cannot intercept custom procotols");
return node::ThrowError(isolate, "Cannot intercept custom procotols");
protocol_handlers_[scheme] = callback;
BrowserThread::PostTask(BrowserThread::IO,
@@ -235,10 +265,11 @@ void Protocol::InterceptProtocol(const std::string& scheme,
base::Unretained(this), scheme));
}
void Protocol::UninterceptProtocol(const std::string& scheme) {
void Protocol::UninterceptProtocol(v8::Isolate* isolate,
const std::string& scheme) {
ProtocolHandlersMap::iterator it(protocol_handlers_.find(scheme));
if (it == protocol_handlers_.end())
return node::ThrowError("The scheme has not been registered");
return node::ThrowError(isolate, "The scheme has not been registered");
protocol_handlers_.erase(it);
BrowserThread::PostTask(BrowserThread::IO,
@@ -320,8 +351,9 @@ void Protocol::EmitEventInUI(const std::string& event,
}
// static
mate::Handle<Protocol> Protocol::Create(v8::Isolate* isolate) {
return CreateHandle(isolate, new Protocol);
mate::Handle<Protocol> Protocol::Create(
v8::Isolate* isolate, AtomBrowserContext* browser_context) {
return mate::CreateHandle(isolate, new Protocol(browser_context));
}
} // namespace api
@@ -330,11 +362,13 @@ mate::Handle<Protocol> Protocol::Create(v8::Isolate* isolate) {
namespace {
void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
v8::Handle<v8::Context> context, void* priv) {
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("protocol", atom::api::Protocol::Create(isolate));
auto browser_context = static_cast<atom::AtomBrowserContext*>(
atom::AtomBrowserMainParts::Get()->browser_context());
dict.Set("protocol", atom::api::Protocol::Create(isolate, browser_context));
}
} // namespace

View File

@@ -7,6 +7,7 @@
#include <string>
#include <map>
#include <vector>
#include "atom/browser/api/event_emitter.h"
#include "base/callback.h"
@@ -18,21 +19,25 @@ class URLRequest;
namespace atom {
class AtomBrowserContext;
class AtomURLRequestJobFactory;
namespace api {
class Protocol : public mate::EventEmitter {
public:
typedef base::Callback<v8::Handle<v8::Value>(const net::URLRequest*)>
typedef base::Callback<v8::Local<v8::Value>(const net::URLRequest*)>
JsProtocolHandler;
static mate::Handle<Protocol> Create(v8::Isolate* isolate);
static mate::Handle<Protocol> Create(
v8::Isolate* isolate, AtomBrowserContext* browser_context);
JsProtocolHandler GetProtocolHandler(const std::string& scheme);
AtomBrowserContext* browser_context() const { return browser_context_; }
protected:
Protocol();
explicit Protocol(AtomBrowserContext* browser_context);
// mate::Wrappable implementations:
virtual mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
@@ -41,11 +46,15 @@ class Protocol : public mate::EventEmitter {
private:
typedef std::map<std::string, JsProtocolHandler> ProtocolHandlersMap;
// Register schemes to standard scheme list.
void RegisterStandardSchemes(const std::vector<std::string>& schemes);
// Register/unregister an networking |scheme| which would be handled by
// |callback|.
void RegisterProtocol(const std::string& scheme,
void RegisterProtocol(v8::Isolate* isolate,
const std::string& scheme,
const JsProtocolHandler& callback);
void UnregisterProtocol(const std::string& scheme);
void UnregisterProtocol(v8::Isolate* isolate, const std::string& scheme);
// Returns whether a scheme has been registered.
// FIXME Should accept a callback and be asynchronous so we do not have to use
@@ -53,9 +62,10 @@ class Protocol : public mate::EventEmitter {
bool IsHandledProtocol(const std::string& scheme);
// Intercept/unintercept an existing protocol handler.
void InterceptProtocol(const std::string& scheme,
void InterceptProtocol(v8::Isolate* isolate,
const std::string& scheme,
const JsProtocolHandler& callback);
void UninterceptProtocol(const std::string& scheme);
void UninterceptProtocol(v8::Isolate* isolate, const std::string& scheme);
// The networking related operations have to be done in IO thread.
void RegisterProtocolInIO(const std::string& scheme);
@@ -66,6 +76,7 @@ class Protocol : public mate::EventEmitter {
// Do protocol.emit(event, parameter) under UI thread.
void EmitEventInUI(const std::string& event, const std::string& parameter);
AtomBrowserContext* browser_context_;
AtomURLRequestJobFactory* job_factory_;
ProtocolHandlersMap protocol_handlers_;

View File

@@ -48,6 +48,7 @@ std::vector<std::string> MetricsToArray(uint32_t metrics) {
} // namespace
Screen::Screen(gfx::Screen* screen) : screen_(screen) {
displays_ = screen_->GetAllDisplays();
screen_->AddObserver(this);
}
@@ -64,11 +65,6 @@ gfx::Display Screen::GetPrimaryDisplay() {
}
std::vector<gfx::Display> Screen::GetAllDisplays() {
// The Screen::GetAllDisplays doesn't update when there is display added or
// removed, so we have to manually maintain the displays_ to make it up to
// date.
if (displays_.size() == 0)
displays_ = screen_->GetAllDisplays();
return displays_;
}
@@ -115,15 +111,16 @@ mate::ObjectTemplateBuilder Screen::GetObjectTemplateBuilder(
}
// static
v8::Handle<v8::Value> Screen::Create(v8::Isolate* isolate) {
v8::Local<v8::Value> Screen::Create(v8::Isolate* isolate) {
if (!Browser::Get()->is_ready()) {
node::ThrowError("Cannot initialize \"screen\" module before app is ready");
node::ThrowError(isolate,
"Cannot initialize \"screen\" module before app is ready");
return v8::Null(isolate);
}
gfx::Screen* screen = gfx::Screen::GetNativeScreen();
if (!screen) {
node::ThrowError("Failed to get screen information");
node::ThrowError(isolate, "Failed to get screen information");
return v8::Null(isolate);
}
@@ -136,8 +133,8 @@ v8::Handle<v8::Value> Screen::Create(v8::Isolate* isolate) {
namespace {
void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
v8::Handle<v8::Context> context, void* priv) {
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
v8::Local<v8::Context> context, void* priv) {
mate::Dictionary dict(context->GetIsolate(), exports);
dict.Set("screen", atom::api::Screen::Create(context->GetIsolate()));
}

View File

@@ -24,7 +24,7 @@ namespace api {
class Screen : public mate::EventEmitter,
public gfx::DisplayObserver {
public:
static v8::Handle<v8::Value> Create(v8::Isolate* isolate);
static v8::Local<v8::Value> Create(v8::Isolate* isolate);
protected:
explicit Screen(gfx::Screen* screen);

View File

@@ -0,0 +1,125 @@
// 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_session.h"
#include <string>
#include "atom/browser/api/atom_api_cookies.h"
#include "atom/browser/atom_browser_context.h"
#include "atom/common/native_mate_converters/gurl_converter.h"
#include "base/thread_task_runner_handle.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/storage_partition.h"
#include "native_mate/callback.h"
#include "native_mate/object_template_builder.h"
#include "net/base/load_flags.h"
#include "net/proxy/proxy_service.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
#include "atom/common/node_includes.h"
namespace atom {
namespace api {
namespace {
class ResolveProxyHelper {
public:
ResolveProxyHelper(AtomBrowserContext* browser_context,
const GURL& url,
Session::ResolveProxyCallback callback)
: callback_(callback),
original_thread_(base::ThreadTaskRunnerHandle::Get()) {
scoped_refptr<net::URLRequestContextGetter> context_getter =
browser_context->GetRequestContext();
context_getter->GetNetworkTaskRunner()->PostTask(
FROM_HERE,
base::Bind(&ResolveProxyHelper::ResolveProxy,
base::Unretained(this), context_getter, url));
}
void OnResolveProxyCompleted(int result) {
std::string proxy;
if (result == net::OK)
proxy = proxy_info_.ToPacString();
original_thread_->PostTask(FROM_HERE,
base::Bind(callback_, proxy));
delete this;
}
private:
void ResolveProxy(scoped_refptr<net::URLRequestContextGetter> context_getter,
const GURL& url) {
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
net::ProxyService* proxy_service =
context_getter->GetURLRequestContext()->proxy_service();
net::CompletionCallback completion_callback =
base::Bind(&ResolveProxyHelper::OnResolveProxyCompleted,
base::Unretained(this));
// Start the request.
int result = proxy_service->ResolveProxy(
url, net::LOAD_NORMAL, &proxy_info_, completion_callback,
&pac_req_, nullptr, net::BoundNetLog());
// Completed synchronously.
if (result != net::ERR_IO_PENDING)
completion_callback.Run(result);
}
Session::ResolveProxyCallback callback_;
net::ProxyInfo proxy_info_;
net::ProxyService::PacRequest* pac_req_;
scoped_refptr<base::SingleThreadTaskRunner> original_thread_;
DISALLOW_COPY_AND_ASSIGN(ResolveProxyHelper);
};
} // namespace
Session::Session(AtomBrowserContext* browser_context)
: browser_context_(browser_context) {
AttachAsUserData(browser_context);
}
Session::~Session() {
}
void Session::ResolveProxy(const GURL& url, ResolveProxyCallback callback) {
new ResolveProxyHelper(browser_context_, url, callback);
}
v8::Local<v8::Value> Session::Cookies(v8::Isolate* isolate) {
if (cookies_.IsEmpty()) {
auto handle = atom::api::Cookies::Create(isolate, browser_context_);
cookies_.Reset(isolate, handle.ToV8());
}
return v8::Local<v8::Value>::New(isolate, cookies_);
}
mate::ObjectTemplateBuilder Session::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
return mate::ObjectTemplateBuilder(isolate)
.SetMethod("resolveProxy", &Session::ResolveProxy)
.SetProperty("cookies", &Session::Cookies);
}
// static
mate::Handle<Session> Session::CreateFrom(
v8::Isolate* isolate,
AtomBrowserContext* browser_context) {
auto existing = TrackableObject::FromWrappedClass(isolate, browser_context);
if (existing)
return mate::CreateHandle(isolate, static_cast<Session*>(existing));
return mate::CreateHandle(isolate, new Session(browser_context));
}
} // namespace api
} // namespace atom

View File

@@ -0,0 +1,53 @@
// 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_SESSION_H_
#define ATOM_BROWSER_API_ATOM_API_SESSION_H_
#include <string>
#include "atom/browser/api/trackable_object.h"
#include "base/callback.h"
#include "native_mate/handle.h"
class GURL;
namespace atom {
class AtomBrowserContext;
namespace api {
class Session: public mate::TrackableObject<Session> {
public:
using ResolveProxyCallback = base::Callback<void(std::string)>;
// Gets or creates Session from the |browser_context|.
static mate::Handle<Session> CreateFrom(
v8::Isolate* isolate, AtomBrowserContext* browser_context);
protected:
explicit Session(AtomBrowserContext* browser_context);
~Session();
// mate::Wrappable implementations:
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) override;
private:
void ResolveProxy(const GURL& url, ResolveProxyCallback callback);
v8::Local<v8::Value> Cookies(v8::Isolate* isolate);
v8::Global<v8::Value> cookies_;
AtomBrowserContext* browser_context_; // weak ref
DISALLOW_COPY_AND_ASSIGN(Session);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_SESSION_H_

View File

@@ -9,6 +9,7 @@
#include "atom/browser/api/atom_api_menu.h"
#include "atom/browser/browser.h"
#include "atom/browser/ui/tray_icon.h"
#include "atom/common/native_mate_converters/gfx_converter.h"
#include "atom/common/native_mate_converters/image_converter.h"
#include "atom/common/native_mate_converters/string16_converter.h"
#include "native_mate/constructor.h"
@@ -31,16 +32,16 @@ Tray::~Tray() {
}
// static
mate::Wrappable* Tray::New(const gfx::Image& image) {
mate::Wrappable* Tray::New(v8::Isolate* isolate, const gfx::Image& image) {
if (!Browser::Get()->is_ready()) {
node::ThrowError("Cannot create Tray before app is ready");
node::ThrowError(isolate, "Cannot create Tray before app is ready");
return nullptr;
}
return new Tray(image);
}
void Tray::OnClicked() {
Emit("clicked");
void Tray::OnClicked(const gfx::Rect& bounds) {
Emit("clicked", bounds);
}
void Tray::OnDoubleClicked() {
@@ -127,7 +128,7 @@ bool Tray::CheckTrayLife(mate::Arguments* args) {
// static
void Tray::BuildPrototype(v8::Isolate* isolate,
v8::Handle<v8::ObjectTemplate> prototype) {
v8::Local<v8::ObjectTemplate> prototype) {
mate::ObjectTemplateBuilder(isolate, prototype)
.SetMethod("destroy", &Tray::Destroy)
.SetMethod("setImage", &Tray::SetImage)
@@ -146,14 +147,14 @@ void Tray::BuildPrototype(v8::Isolate* isolate,
namespace {
void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
v8::Handle<v8::Context> context, void* priv) {
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
v8::Local<v8::Context> context, void* priv) {
using atom::api::Tray;
v8::Isolate* isolate = context->GetIsolate();
v8::Handle<v8::Function> constructor = mate::CreateConstructor<Tray>(
v8::Local<v8::Function> constructor = mate::CreateConstructor<Tray>(
isolate, "Tray", base::Bind(&Tray::New));
mate::Dictionary dict(isolate, exports);
dict.Set("Tray", static_cast<v8::Handle<v8::Value>>(constructor));
dict.Set("Tray", static_cast<v8::Local<v8::Value>>(constructor));
}
} // namespace

View File

@@ -31,17 +31,17 @@ class Menu;
class Tray : public mate::EventEmitter,
public TrayIconObserver {
public:
static mate::Wrappable* New(const gfx::Image& image);
static mate::Wrappable* New(v8::Isolate* isolate, const gfx::Image& image);
static void BuildPrototype(v8::Isolate* isolate,
v8::Handle<v8::ObjectTemplate> prototype);
v8::Local<v8::ObjectTemplate> prototype);
protected:
explicit Tray(const gfx::Image& image);
virtual ~Tray();
// TrayIconObserver:
void OnClicked() override;
void OnClicked(const gfx::Rect&) override;
void OnDoubleClicked() override;
void OnBalloonShow() override;
void OnBalloonClicked() override;

View File

@@ -4,32 +4,111 @@
#include "atom/browser/api/atom_api_web_contents.h"
#include <set>
#include "atom/browser/api/atom_api_session.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_dialog_helper.h"
#include "atom/browser/web_view_manager.h"
#include "atom/browser/web_view_guest_delegate.h"
#include "atom/common/api/api_messages.h"
#include "atom/common/event_emitter_caller.h"
#include "atom/common/native_mate_converters/gfx_converter.h"
#include "atom/common/native_mate_converters/gurl_converter.h"
#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 "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "brightray/browser/inspectable_web_contents.h"
#include "chrome/browser/printing/print_view_manager_basic.h"
#include "chrome/browser/printing/print_preview_message_handler.h"
#include "content/public/browser/favicon_status.h"
#include "content/public/browser/navigation_details.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/plugin_service.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/render_widget_host_view.h"
#include "content/public/browser/resource_request_details.h"
#include "content/public/browser/service_worker_context.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/site_instance.h"
#include "content/public/browser/web_contents.h"
#include "native_mate/callback.h"
#include "native_mate/dictionary.h"
#include "native_mate/object_template_builder.h"
#include "vendor/brightray/browser/media/media_stream_devices_controller.h"
#include "net/http/http_response_headers.h"
#include "net/url_request/url_request_context.h"
#include "atom/common/node_includes.h"
namespace {
struct PrintSettings {
bool silent;
bool print_background;
};
} // namespace
namespace mate {
template<>
struct Converter<atom::SetSizeParams> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
atom::SetSizeParams* out) {
mate::Dictionary params;
if (!ConvertFromV8(isolate, val, &params))
return false;
bool autosize;
if (params.Get("enableAutoSize", &autosize))
out->enable_auto_size.reset(new bool(true));
gfx::Size size;
if (params.Get("min", &size))
out->min_size.reset(new gfx::Size(size));
if (params.Get("max", &size))
out->max_size.reset(new gfx::Size(size));
if (params.Get("normal", &size))
out->normal_size.reset(new gfx::Size(size));
return true;
}
};
template<>
struct Converter<PrintSettings> {
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
PrintSettings* out) {
mate::Dictionary dict;
if (!ConvertFromV8(isolate, val, &dict))
return false;
dict.Get("silent", &(out->silent));
dict.Get("printBackground", &(out->print_background));
return true;
}
};
template<>
struct Converter<WindowOpenDisposition> {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
WindowOpenDisposition val) {
std::string disposition = "other";
switch (val) {
case CURRENT_TAB: disposition = "default"; break;
case NEW_FOREGROUND_TAB: disposition = "foreground-tab"; break;
case NEW_BACKGROUND_TAB: disposition = "background-tab"; break;
case NEW_POPUP: case NEW_WINDOW: disposition = "new-window"; break;
default: break;
}
return mate::ConvertToV8(isolate, disposition);
}
};
} // namespace mate
namespace atom {
namespace api {
@@ -38,48 +117,71 @@ namespace {
v8::Persistent<v8::ObjectTemplate> template_;
// Get the window that has the |guest| embedded.
NativeWindow* GetWindowFromGuest(const content::WebContents* guest) {
WebViewManager::WebViewInfo info;
if (WebViewManager::GetInfoForProcess(guest->GetRenderProcessHost(), &info))
return NativeWindow::FromRenderView(
info.embedder->GetRenderProcessHost()->GetID(),
info.embedder->GetRoutingID());
else
// The wrapWebContents funtion which is implemented in JavaScript
using WrapWebContentsCallback = base::Callback<void(v8::Local<v8::Value>)>;
WrapWebContentsCallback g_wrap_web_contents;
content::ServiceWorkerContext* GetServiceWorkerContext(
const content::WebContents* web_contents) {
auto context = web_contents->GetBrowserContext();
auto site_instance = web_contents->GetSiteInstance();
if (!context || !site_instance)
return nullptr;
auto storage_partition =
content::BrowserContext::GetStoragePartition(context, site_instance);
if (!storage_partition)
return nullptr;
return storage_partition->GetServiceWorkerContext();
}
} // namespace
WebContents::WebContents(content::WebContents* web_contents)
: content::WebContentsObserver(web_contents),
guest_instance_id_(-1),
element_instance_id_(-1),
guest_opaque_(true),
guest_sizer_(nullptr),
auto_size_enabled_(false) {
type_(REMOTE) {
AttachAsUserData(web_contents);
}
WebContents::WebContents(const mate::Dictionary& options)
: guest_instance_id_(-1),
element_instance_id_(-1),
guest_opaque_(true),
guest_sizer_(nullptr),
auto_size_enabled_(false) {
options.Get("guestInstanceId", &guest_instance_id_);
WebContents::WebContents(const mate::Dictionary& options) {
bool is_guest = false;
options.Get("isGuest", &is_guest);
auto browser_context = AtomBrowserContext::Get();
content::SiteInstance* site_instance = content::SiteInstance::CreateForURL(
browser_context, GURL("chrome-guest://fake-host"));
type_ = is_guest ? WEB_VIEW : BROWSER_WINDOW;
content::WebContents::CreateParams params(browser_context, site_instance);
bool is_guest;
if (options.Get("isGuest", &is_guest) && is_guest)
params.guest_delegate = this;
auto browser_context = AtomBrowserMainParts::Get()->browser_context();
content::WebContents* web_contents;
if (is_guest) {
content::SiteInstance* site_instance = content::SiteInstance::CreateForURL(
browser_context, GURL("chrome-guest://fake-host"));
content::WebContents::CreateParams params(browser_context, site_instance);
guest_delegate_.reset(new WebViewGuestDelegate);
params.guest_delegate = guest_delegate_.get();
web_contents = content::WebContents::Create(params);
} else {
content::WebContents::CreateParams params(browser_context);
web_contents = content::WebContents::Create(params);
}
storage_.reset(brightray::InspectableWebContents::Create(params));
Observe(storage_->GetWebContents());
web_contents()->SetDelegate(this);
Observe(web_contents);
AttachAsUserData(web_contents);
InitWithWebContents(web_contents);
if (is_guest) {
guest_delegate_->Initialize(this);
NativeWindow* owner_window = nullptr;
WebContents* embedder = nullptr;
if (options.Get("embedder", &embedder) && embedder) {
// New WebContents's owner_window is the embedder's owner_window.
auto relay = NativeWindowRelay::FromWebContents(embedder->web_contents());
if (relay)
owner_window = relay->window.get();
}
if (owner_window)
SetOwnerWindow(owner_window);
}
}
WebContents::~WebContents() {
@@ -91,8 +193,12 @@ bool WebContents::AddMessageToConsole(content::WebContents* source,
const base::string16& message,
int32 line_no,
const base::string16& source_id) {
Emit("console-message", level, message, line_no, source_id);
return true;
if (type_ == BROWSER_WINDOW) {
return false;
} else {
Emit("console-message", level, message, line_no, source_id);
return true;
}
}
bool WebContents::ShouldCreateWebContents(
@@ -104,22 +210,21 @@ bool WebContents::ShouldCreateWebContents(
const GURL& target_url,
const std::string& partition_id,
content::SessionStorageNamespace* session_storage_namespace) {
Emit("-new-window",
target_url,
frame_name,
static_cast<int>(NEW_FOREGROUND_TAB));
if (type_ == BROWSER_WINDOW)
Emit("-new-window", target_url, frame_name, NEW_FOREGROUND_TAB);
else
Emit("new-window", target_url, frame_name, NEW_FOREGROUND_TAB);
return false;
}
void WebContents::CloseContents(content::WebContents* source) {
Emit("close");
}
content::WebContents* WebContents::OpenURLFromTab(
content::WebContents* source,
const content::OpenURLParams& params) {
if (params.disposition != CURRENT_TAB) {
Emit("-new-window", params.url, "", static_cast<int>(params.disposition));
if (type_ == BROWSER_WINDOW)
Emit("-new-window", params.url, "", params.disposition);
else
Emit("new-window", params.url, "", params.disposition);
return nullptr;
}
@@ -127,70 +232,108 @@ content::WebContents* WebContents::OpenURLFromTab(
if (Emit("will-navigate", params.url))
return nullptr;
content::NavigationController::LoadURLParams load_url_params(params.url);
load_url_params.referrer = params.referrer;
load_url_params.transition_type = params.transition;
load_url_params.extra_headers = params.extra_headers;
load_url_params.should_replace_current_entry =
params.should_replace_current_entry;
load_url_params.is_renderer_initiated = params.is_renderer_initiated;
load_url_params.transferred_global_request_id =
params.transferred_global_request_id;
web_contents()->GetController().LoadURLWithParams(load_url_params);
return web_contents();
return CommonWebContentsDelegate::OpenURLFromTab(source, params);
}
void WebContents::RunFileChooser(content::WebContents* guest,
const content::FileChooserParams& params) {
if (!web_dialog_helper_)
web_dialog_helper_.reset(new WebDialogHelper(GetWindowFromGuest(guest)));
web_dialog_helper_->RunFileChooser(guest, params);
void WebContents::BeforeUnloadFired(content::WebContents* tab,
bool proceed,
bool* proceed_to_fire_unload) {
if (type_ == BROWSER_WINDOW)
*proceed_to_fire_unload = proceed;
else
*proceed_to_fire_unload = true;
}
void WebContents::EnumerateDirectory(content::WebContents* guest,
int request_id,
const base::FilePath& path) {
if (!web_dialog_helper_)
web_dialog_helper_.reset(new WebDialogHelper(GetWindowFromGuest(guest)));
web_dialog_helper_->EnumerateDirectory(guest, request_id, path);
void WebContents::MoveContents(content::WebContents* source,
const gfx::Rect& pos) {
Emit("move", pos);
}
bool WebContents::CheckMediaAccessPermission(content::WebContents* web_contents,
const GURL& security_origin,
content::MediaStreamType type) {
return true;
void WebContents::CloseContents(content::WebContents* source) {
Emit("closed");
if (type_ == BROWSER_WINDOW)
owner_window()->CloseContents(source);
}
void WebContents::RequestMediaAccessPermission(
content::WebContents*,
const content::MediaStreamRequest& request,
const content::MediaResponseCallback& callback) {
brightray::MediaStreamDevicesController controller(request, callback);
controller.TakeAction();
void WebContents::ActivateContents(content::WebContents* source) {
Emit("activate");
}
bool WebContents::IsPopupOrPanel(const content::WebContents* source) const {
return type_ == BROWSER_WINDOW;
}
void WebContents::HandleKeyboardEvent(
content::WebContents* source,
const content::NativeWebKeyboardEvent& event) {
if (!attached())
return;
if (type_ == BROWSER_WINDOW) {
owner_window()->HandleKeyboardEvent(source, event);
} else if (type_ == WEB_VIEW && guest_delegate_) {
// Send the unhandled keyboard events back to the embedder.
guest_delegate_->HandleKeyboardEvent(source, event);
}
}
// Send the unhandled keyboard events back to the embedder to reprocess them.
embedder_web_contents_->GetDelegate()->HandleKeyboardEvent(
web_contents(), event);
void WebContents::EnterFullscreenModeForTab(content::WebContents* source,
const GURL& origin) {
CommonWebContentsDelegate::EnterFullscreenModeForTab(source, origin);
Emit("enter-html-full-screen");
}
void WebContents::ExitFullscreenModeForTab(content::WebContents* source) {
CommonWebContentsDelegate::ExitFullscreenModeForTab(source);
Emit("leave-html-full-screen");
}
void WebContents::RendererUnresponsive(content::WebContents* source) {
Emit("unresponsive");
if (type_ == BROWSER_WINDOW)
owner_window()->RendererUnresponsive(source);
}
void WebContents::RendererResponsive(content::WebContents* source) {
Emit("responsive");
if (type_ == BROWSER_WINDOW)
owner_window()->RendererResponsive(source);
}
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.
}
void WebContents::RenderViewDeleted(content::RenderViewHost* render_view_host) {
Emit("render-view-deleted",
render_view_host->GetProcess()->GetID(),
render_view_host->GetRoutingID());
int process_id = render_view_host->GetProcess()->GetID();
Emit("render-view-deleted", process_id);
// process.emit('ATOM_BROWSER_RELEASE_RENDER_VIEW', processId);
// Tell the rpc server that a render view has been deleted and we need to
// release all objects owned by it.
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
node::Environment* env = node::Environment::GetCurrent(isolate());
mate::EmitEvent(isolate(), env->process_object(),
"ATOM_BROWSER_RELEASE_RENDER_VIEW", process_id);
}
void WebContents::RenderProcessGone(base::TerminationStatus status) {
Emit("crashed");
}
void WebContents::PluginCrashed(const base::FilePath& plugin_path,
base::ProcessId plugin_pid) {
content::WebPluginInfo info;
auto plugin_service = content::PluginService::GetInstance();
plugin_service->GetPluginInfoByPath(plugin_path, &info);
Emit("plugin-crashed", info.name, info.version);
}
void WebContents::DocumentLoadedInFrame(
content::RenderFrameHost* render_frame_host) {
if (!render_frame_host->GetParent())
Emit("dom-ready");
}
void WebContents::DidFinishLoad(content::RenderFrameHost* render_frame_host,
const GURL& validated_url) {
bool is_main_frame = !render_frame_host->GetParent();
@@ -216,23 +359,48 @@ void WebContents::DidFailLoad(content::RenderFrameHost* render_frame_host,
Emit("did-fail-load", error_code, error_description);
}
void WebContents::DidStartLoading(content::RenderViewHost* render_view_host) {
void WebContents::DidStartLoading() {
Emit("did-start-loading");
}
void WebContents::DidStopLoading(content::RenderViewHost* render_view_host) {
void WebContents::DidStopLoading() {
Emit("did-stop-loading");
}
void WebContents::DidGetResourceResponseStart(
const content::ResourceRequestDetails& details) {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
base::DictionaryValue response_headers;
net::HttpResponseHeaders* headers = details.headers.get();
if (!headers)
return;
void* iter = nullptr;
std::string key;
std::string value;
while (headers->EnumerateHeaderLines(&iter, &key, &value)) {
key = base::StringToLowerASCII(key);
value = base::StringToLowerASCII(value);
if (response_headers.HasKey(key)) {
base::ListValue* values = nullptr;
if (response_headers.GetList(key, &values))
values->AppendString(value);
} else {
scoped_ptr<base::ListValue> values(new base::ListValue());
values->AppendString(value);
response_headers.Set(key, values.Pass());
}
}
Emit("did-get-response-details",
details.socket_address.IsEmpty(),
details.url,
details.original_url,
details.http_response_code,
details.method,
details.referrer);
details.referrer,
response_headers);
}
void WebContents::DidGetRedirectForResourceRequest(
@@ -253,7 +421,22 @@ void WebContents::DidNavigateMainFrame(
void WebContents::TitleWasSet(content::NavigationEntry* entry,
bool explicit_set) {
Emit("page-title-set", entry->GetTitle(), explicit_set);
// Back/Forward navigation may have pruned entries.
if (entry)
Emit("page-title-set", entry->GetTitle(), explicit_set);
}
void WebContents::DidUpdateFaviconURL(
const std::vector<content::FaviconURL>& urls) {
std::set<GURL> unique_urls;
for (auto iter = urls.begin(); iter != urls.end(); ++iter) {
if (iter->icon_type != content::FaviconURL::FAVICON)
continue;
const GURL& url = iter->icon_url;
if (url.is_valid())
unique_urls.insert(url);
}
Emit("page-favicon-updated", unique_urls);
}
bool WebContents::OnMessageReceived(const IPC::Message& message) {
@@ -268,86 +451,28 @@ bool WebContents::OnMessageReceived(const IPC::Message& message) {
return handled;
}
void WebContents::RenderViewReady() {
if (!is_guest())
return;
// We don't want to accidentally set the opacity of an interstitial page.
// WebContents::GetRenderWidgetHostView will return the RWHV of an
// interstitial page if one is showing at this time. We only want opacity
// to apply to web pages.
if (guest_opaque_) {
web_contents()
->GetRenderViewHost()
->GetView()
->SetBackgroundColorToDefault();
} else {
web_contents()->GetRenderViewHost()->GetView()->SetBackgroundColor(
SK_ColorTRANSPARENT);
}
}
void WebContents::WebContentsDestroyed() {
// The RenderViewDeleted was not called when the WebContents is destroyed.
RenderViewDeleted(web_contents()->GetRenderViewHost());
Emit("destroyed");
RemoveFromWeakMap();
}
void WebContents::NavigationEntryCommitted(
const content::LoadCommittedDetails& load_details) {
auto entry = web_contents()->GetController().GetLastCommittedEntry();
entry->SetVirtualURL(load_details.entry->GetOriginalRequestURL());
}
void WebContents::DidAttach(int guest_proxy_routing_id) {
Emit("did-attach");
}
void WebContents::ElementSizeChanged(const gfx::Size& size) {
element_size_ = size;
// Only resize if needed.
if (!size.IsEmpty())
guest_sizer_->SizeContents(size);
}
content::WebContents* WebContents::GetOwnerWebContents() const {
return embedder_web_contents_;
}
void WebContents::GuestSizeChanged(const gfx::Size& new_size) {
if (!auto_size_enabled_)
return;
GuestSizeChangedDueToAutoSize(guest_size_, new_size);
guest_size_ = new_size;
}
void WebContents::RegisterDestructionCallback(
const DestructionCallback& callback) {
destruction_callback_ = callback;
}
void WebContents::SetGuestSizer(content::GuestSizer* guest_sizer) {
guest_sizer_ = guest_sizer;
}
void WebContents::WillAttach(content::WebContents* embedder_web_contents,
int element_instance_id,
bool is_full_page_plugin) {
embedder_web_contents_ = embedder_web_contents;
element_instance_id_ = element_instance_id;
const content::LoadCommittedDetails& details) {
Emit("navigation-entry-commited", details.entry->GetURL(),
details.is_in_page, details.did_replace_entry);
}
void WebContents::Destroy() {
if (storage_) {
if (!destruction_callback_.is_null())
destruction_callback_.Run();
if (type_ == WEB_VIEW && managed_web_contents()) {
// When force destroying the "destroyed" event is not emitted.
WebContentsDestroyed();
guest_delegate_->Destroy();
Observe(nullptr);
storage_.reset();
DestroyWebContents();
}
}
@@ -355,26 +480,32 @@ bool WebContents::IsAlive() const {
return web_contents() != NULL;
}
int WebContents::GetID() const {
return web_contents()->GetRenderProcessHost()->GetID();
}
bool WebContents::Equal(const WebContents* web_contents) const {
return GetID() == web_contents->GetID();
}
void WebContents::LoadURL(const GURL& url, const mate::Dictionary& options) {
content::NavigationController::LoadURLParams params(url);
GURL http_referrer;
if (options.Get("httpreferrer", &http_referrer))
if (options.Get("httpReferrer", &http_referrer))
params.referrer = content::Referrer(http_referrer.GetAsReferrer(),
blink::WebReferrerPolicyDefault);
std::string user_agent;
if (options.Get("userAgent", &user_agent))
SetUserAgent(user_agent);
params.transition_type = ui::PAGE_TRANSITION_TYPED;
params.should_clear_history_list = true;
params.override_user_agent = content::NavigationController::UA_OVERRIDE_TRUE;
web_contents()->GetController().LoadURLWithParams(params);
}
GURL WebContents::GetURL() const {
auto entry = web_contents()->GetController().GetLastCommittedEntry();
if (!entry)
return GURL::EmptyGURL();
return entry->GetVirtualURL();
}
base::string16 WebContents::GetTitle() const {
return web_contents()->GetTitle();
}
@@ -391,56 +522,25 @@ void WebContents::Stop() {
web_contents()->Stop();
}
void WebContents::Reload(const mate::Dictionary& options) {
// Navigating to a URL would always restart the renderer process, we want this
// because normal reloading will break our node integration.
// This is done by AtomBrowserClient::ShouldSwapProcessesForNavigation.
LoadURL(GetURL(), options);
}
void WebContents::ReloadIgnoringCache(const mate::Dictionary& options) {
// Hack to remove pending entries that ignores cache and treated as a fresh
// load.
void WebContents::ReloadIgnoringCache() {
web_contents()->GetController().ReloadIgnoringCache(false);
Reload(options);
}
bool WebContents::CanGoBack() const {
return web_contents()->GetController().CanGoBack();
}
bool WebContents::CanGoForward() const {
return web_contents()->GetController().CanGoForward();
}
bool WebContents::CanGoToOffset(int offset) const {
return web_contents()->GetController().CanGoToOffset(offset);
}
void WebContents::GoBack() {
atom::AtomBrowserClient::SuppressRendererProcessRestartForOnce();
web_contents()->GetController().GoBack();
}
void WebContents::GoForward() {
atom::AtomBrowserClient::SuppressRendererProcessRestartForOnce();
web_contents()->GetController().GoForward();
}
void WebContents::GoToIndex(int index) {
web_contents()->GetController().GoToIndex(index);
}
void WebContents::GoToOffset(int offset) {
atom::AtomBrowserClient::SuppressRendererProcessRestartForOnce();
web_contents()->GetController().GoToOffset(offset);
}
int WebContents::GetRoutingID() const {
return web_contents()->GetRoutingID();
}
int WebContents::GetProcessID() const {
return web_contents()->GetRenderProcessHost()->GetID();
}
bool WebContents::IsCrashed() const {
return web_contents()->IsCrashed();
}
@@ -457,17 +557,120 @@ void WebContents::ExecuteJavaScript(const base::string16& code) {
web_contents()->GetMainFrame()->ExecuteJavaScript(code);
}
void WebContents::OpenDevTools() {
storage_->SetCanDock(false);
storage_->ShowDevTools();
void WebContents::OpenDevTools(mate::Arguments* args) {
if (type_ == REMOTE)
return;
bool detach = false;
if (type_ == WEB_VIEW) {
detach = true;
} else if (args && args->Length() == 1) {
mate::Dictionary options;
args->GetNext(&options) && options.Get("detach", &detach);
}
managed_web_contents()->SetCanDock(!detach);
managed_web_contents()->ShowDevTools();
}
void WebContents::CloseDevTools() {
storage_->CloseDevTools();
if (type_ == REMOTE)
return;
managed_web_contents()->CloseDevTools();
}
bool WebContents::IsDevToolsOpened() {
return storage_->IsDevToolsViewShowing();
if (type_ == REMOTE)
return false;
return managed_web_contents()->IsDevToolsViewShowing();
}
void WebContents::ToggleDevTools() {
if (IsDevToolsOpened())
CloseDevTools();
else
OpenDevTools(nullptr);
}
void WebContents::InspectElement(int x, int y) {
if (type_ == REMOTE)
return;
OpenDevTools(nullptr);
scoped_refptr<content::DevToolsAgentHost> agent(
content::DevToolsAgentHost::GetOrCreateFor(web_contents()));
agent->InspectElement(x, y);
}
void WebContents::InspectServiceWorker() {
if (type_ == REMOTE)
return;
for (const auto& agent_host : content::DevToolsAgentHost::GetOrCreateAll()) {
if (agent_host->GetType() ==
content::DevToolsAgentHost::TYPE_SERVICE_WORKER) {
OpenDevTools(nullptr);
managed_web_contents()->AttachTo(agent_host);
break;
}
}
}
v8::Local<v8::Value> WebContents::Session(v8::Isolate* isolate) {
if (session_.IsEmpty()) {
mate::Handle<api::Session> handle = Session::CreateFrom(
isolate,
static_cast<AtomBrowserContext*>(web_contents()->GetBrowserContext()));
session_.Reset(isolate, handle.ToV8());
}
return v8::Local<v8::Value>::New(isolate, session_);
}
void WebContents::HasServiceWorker(
const base::Callback<void(bool)>& callback) {
auto context = GetServiceWorkerContext(web_contents());
if (!context)
return;
context->CheckHasServiceWorker(web_contents()->GetLastCommittedURL(),
GURL::EmptyGURL(),
callback);
}
void WebContents::UnregisterServiceWorker(
const base::Callback<void(bool)>& callback) {
auto context = GetServiceWorkerContext(web_contents());
if (!context)
return;
context->UnregisterServiceWorker(web_contents()->GetLastCommittedURL(),
callback);
}
void WebContents::SetAudioMuted(bool muted) {
web_contents()->SetAudioMuted(muted);
}
bool WebContents::IsAudioMuted() {
return web_contents()->IsAudioMuted();
}
void WebContents::Print(mate::Arguments* args) {
PrintSettings settings = { false, false };
if (args->Length() == 1 && !args->GetNext(&settings)) {
args->ThrowError();
return;
}
printing::PrintViewManagerBasic::FromWebContents(web_contents())->
PrintNow(settings.silent, settings.print_background);
}
void WebContents::PrintToPDF(const base::DictionaryValue& setting,
const PrintToPDFCallback& callback) {
printing::PrintPreviewMessageHandler::FromWebContents(web_contents())->
PrintToPDF(setting, callback);
}
void WebContents::Undo() {
@@ -490,6 +693,10 @@ void WebContents::Paste() {
web_contents()->Paste();
}
void WebContents::PasteAndMatchStyle() {
web_contents()->PasteAndMatchStyle();
}
void WebContents::Delete() {
web_contents()->Delete();
}
@@ -515,50 +722,18 @@ bool WebContents::SendIPCMessage(const base::string16& channel,
return Send(new AtomViewMsg_Message(routing_id(), channel, args));
}
void WebContents::SetAutoSize(bool enabled,
const gfx::Size& min_size,
const gfx::Size& max_size) {
min_auto_size_ = min_size;
min_auto_size_.SetToMin(max_size);
max_auto_size_ = max_size;
max_auto_size_.SetToMax(min_size);
enabled &= !min_auto_size_.IsEmpty() && !max_auto_size_.IsEmpty();
if (!enabled && !auto_size_enabled_)
return;
auto_size_enabled_ = enabled;
if (!attached())
return;
content::RenderViewHost* rvh = web_contents()->GetRenderViewHost();
if (auto_size_enabled_) {
rvh->EnableAutoResize(min_auto_size_, max_auto_size_);
} else {
rvh->DisableAutoResize(element_size_);
guest_size_ = element_size_;
GuestSizeChangedDueToAutoSize(guest_size_, element_size_);
}
void WebContents::SetSize(const SetSizeParams& params) {
if (guest_delegate_)
guest_delegate_->SetSize(params);
}
void WebContents::SetAllowTransparency(bool allow) {
if (guest_opaque_ != allow)
return;
if (guest_delegate_)
guest_delegate_->SetAllowTransparency(allow);
}
guest_opaque_ = !allow;
if (!web_contents()->GetRenderViewHost()->GetView())
return;
if (guest_opaque_) {
web_contents()
->GetRenderViewHost()
->GetView()
->SetBackgroundColorToDefault();
} else {
web_contents()->GetRenderViewHost()->GetView()->SetBackgroundColor(
SK_ColorTRANSPARENT);
}
bool WebContents::IsGuest() const {
return type_ == WEB_VIEW;
}
mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder(
@@ -567,23 +742,17 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder(
template_.Reset(isolate, mate::ObjectTemplateBuilder(isolate)
.SetMethod("destroy", &WebContents::Destroy)
.SetMethod("isAlive", &WebContents::IsAlive)
.SetMethod("getId", &WebContents::GetID)
.SetMethod("equal", &WebContents::Equal)
.SetMethod("_loadUrl", &WebContents::LoadURL)
.SetMethod("getUrl", &WebContents::GetURL)
.SetMethod("getTitle", &WebContents::GetTitle)
.SetMethod("isLoading", &WebContents::IsLoading)
.SetMethod("isWaitingForResponse", &WebContents::IsWaitingForResponse)
.SetMethod("stop", &WebContents::Stop)
.SetMethod("_reload", &WebContents::Reload)
.SetMethod("_stop", &WebContents::Stop)
.SetMethod("_reloadIgnoringCache", &WebContents::ReloadIgnoringCache)
.SetMethod("canGoBack", &WebContents::CanGoBack)
.SetMethod("canGoForward", &WebContents::CanGoForward)
.SetMethod("canGoToOffset", &WebContents::CanGoToOffset)
.SetMethod("goBack", &WebContents::GoBack)
.SetMethod("goForward", &WebContents::GoForward)
.SetMethod("goToIndex", &WebContents::GoToIndex)
.SetMethod("goToOffset", &WebContents::GoToOffset)
.SetMethod("getRoutingId", &WebContents::GetRoutingID)
.SetMethod("getProcessId", &WebContents::GetProcessID)
.SetMethod("_goBack", &WebContents::GoBack)
.SetMethod("_goForward", &WebContents::GoForward)
.SetMethod("_goToOffset", &WebContents::GoToOffset)
.SetMethod("isCrashed", &WebContents::IsCrashed)
.SetMethod("setUserAgent", &WebContents::SetUserAgent)
.SetMethod("insertCSS", &WebContents::InsertCSS)
@@ -591,20 +760,32 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder(
.SetMethod("openDevTools", &WebContents::OpenDevTools)
.SetMethod("closeDevTools", &WebContents::CloseDevTools)
.SetMethod("isDevToolsOpened", &WebContents::IsDevToolsOpened)
.SetMethod("toggleDevTools", &WebContents::ToggleDevTools)
.SetMethod("inspectElement", &WebContents::InspectElement)
.SetMethod("setAudioMuted", &WebContents::SetAudioMuted)
.SetMethod("isAudioMuted", &WebContents::IsAudioMuted)
.SetMethod("undo", &WebContents::Undo)
.SetMethod("redo", &WebContents::Redo)
.SetMethod("cut", &WebContents::Cut)
.SetMethod("copy", &WebContents::Copy)
.SetMethod("paste", &WebContents::Paste)
.SetMethod("pasteAndMatchStyle", &WebContents::PasteAndMatchStyle)
.SetMethod("delete", &WebContents::Delete)
.SetMethod("selectAll", &WebContents::SelectAll)
.SetMethod("unselect", &WebContents::Unselect)
.SetMethod("replace", &WebContents::Replace)
.SetMethod("replaceMisspelling", &WebContents::ReplaceMisspelling)
.SetMethod("_send", &WebContents::SendIPCMessage)
.SetMethod("setAutoSize", &WebContents::SetAutoSize)
.SetMethod("setSize", &WebContents::SetSize)
.SetMethod("setAllowTransparency", &WebContents::SetAllowTransparency)
.SetMethod("isGuest", &WebContents::is_guest)
.SetMethod("isGuest", &WebContents::IsGuest)
.SetMethod("hasServiceWorker", &WebContents::HasServiceWorker)
.SetMethod("unregisterServiceWorker",
&WebContents::UnregisterServiceWorker)
.SetMethod("inspectServiceWorker", &WebContents::InspectServiceWorker)
.SetMethod("print", &WebContents::Print)
.SetMethod("_printToPDF", &WebContents::PrintToPDF)
.SetProperty("session", &WebContents::Session)
.Build());
return mate::ObjectTemplateBuilder(
@@ -624,23 +805,34 @@ void WebContents::OnRendererMessageSync(const base::string16& channel,
EmitWithSender(base::UTF16ToUTF8(channel), web_contents(), message, args);
}
void WebContents::GuestSizeChangedDueToAutoSize(const gfx::Size& old_size,
const gfx::Size& new_size) {
Emit("size-changed",
old_size.width(), old_size.height(),
new_size.width(), new_size.height());
}
// static
mate::Handle<WebContents> WebContents::CreateFrom(
v8::Isolate* isolate, content::WebContents* web_contents) {
return mate::CreateHandle(isolate, new WebContents(web_contents));
// We have an existing WebContents object in JS.
auto existing = TrackableObject::FromWrappedClass(isolate, web_contents);
if (existing)
return mate::CreateHandle(isolate, static_cast<WebContents*>(existing));
// Otherwise create a new WebContents wrapper object.
auto handle = mate::CreateHandle(isolate, new WebContents(web_contents));
g_wrap_web_contents.Run(handle.ToV8());
return handle;
}
// static
mate::Handle<WebContents> WebContents::Create(
v8::Isolate* isolate, const mate::Dictionary& options) {
return mate::CreateHandle(isolate, new WebContents(options));
auto handle = mate::CreateHandle(isolate, new WebContents(options));
g_wrap_web_contents.Run(handle.ToV8());
return handle;
}
void SetWrapWebContents(const WrapWebContentsCallback& callback) {
g_wrap_web_contents = callback;
}
void ClearWrapWebContents() {
g_wrap_web_contents.Reset();
}
} // namespace api
@@ -650,11 +842,13 @@ mate::Handle<WebContents> WebContents::Create(
namespace {
void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
v8::Handle<v8::Context> context, void* priv) {
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("create", &atom::api::WebContents::Create);
dict.SetMethod("_setWrapWebContents", &atom::api::SetWrapWebContents);
dict.SetMethod("_clearWrapWebContents", &atom::api::ClearWrapWebContents);
}
} // namespace

View File

@@ -6,33 +6,39 @@
#define ATOM_BROWSER_API_ATOM_API_WEB_CONTENTS_H_
#include <string>
#include <vector>
#include "atom/browser/api/event_emitter.h"
#include "brightray/browser/default_web_contents_delegate.h"
#include "content/public/browser/browser_plugin_guest_delegate.h"
#include "content/public/browser/web_contents_delegate.h"
#include "atom/browser/api/trackable_object.h"
#include "atom/browser/common_web_contents_delegate.h"
#include "content/public/common/favicon_url.h"
#include "content/public/browser/web_contents_observer.h"
#include "native_mate/handle.h"
#include "ui/gfx/image/image.h"
namespace brightray {
class InspectableWebContents;
}
namespace mate {
class Arguments;
class Dictionary;
}
namespace atom {
class WebDialogHelper;
struct SetSizeParams;
class WebViewGuestDelegate;
namespace api {
class WebContents : public mate::EventEmitter,
public content::BrowserPluginGuestDelegate,
public content::WebContentsDelegate,
class WebContents : public mate::TrackableObject<WebContents>,
public CommonWebContentsDelegate,
public content::WebContentsObserver {
public:
// For node.js callback function type: function(error, buffer)
typedef base::Callback<void(v8::Local<v8::Value>, v8::Local<v8::Value>)>
PrintToPDFCallback;
// Create from an existing WebContents.
static mate::Handle<WebContents> CreateFrom(
v8::Isolate* isolate, content::WebContents* web_contents);
@@ -43,30 +49,37 @@ class WebContents : public mate::EventEmitter,
void Destroy();
bool IsAlive() const;
int GetID() const;
bool Equal(const WebContents* web_contents) const;
void LoadURL(const GURL& url, const mate::Dictionary& options);
GURL GetURL() const;
base::string16 GetTitle() const;
bool IsLoading() const;
bool IsWaitingForResponse() const;
void Stop();
void Reload(const mate::Dictionary& options);
void ReloadIgnoringCache(const mate::Dictionary& options);
bool CanGoBack() const;
bool CanGoForward() const;
bool CanGoToOffset(int offset) const;
void ReloadIgnoringCache();
void GoBack();
void GoForward();
void GoToIndex(int index);
void GoToOffset(int offset);
int GetRoutingID() const;
int GetProcessID() const;
bool IsCrashed() const;
void SetUserAgent(const std::string& user_agent);
void InsertCSS(const std::string& css);
void ExecuteJavaScript(const base::string16& code);
void OpenDevTools();
void OpenDevTools(mate::Arguments* args);
void CloseDevTools();
bool IsDevToolsOpened();
void ToggleDevTools();
void InspectElement(int x, int y);
void InspectServiceWorker();
v8::Local<v8::Value> Session(v8::Isolate* isolate);
void HasServiceWorker(const base::Callback<void(bool)>&);
void UnregisterServiceWorker(const base::Callback<void(bool)>&);
void SetAudioMuted(bool muted);
bool IsAudioMuted();
void Print(mate::Arguments* args);
// Print current page as PDF.
void PrintToPDF(const base::DictionaryValue& setting,
const PrintToPDFCallback& callback);
// Editing commands.
void Undo();
@@ -74,6 +87,7 @@ class WebContents : public mate::EventEmitter,
void Cut();
void Copy();
void Paste();
void PasteAndMatchStyle();
void Delete();
void SelectAll();
void Unselect();
@@ -84,23 +98,10 @@ class WebContents : public mate::EventEmitter,
bool SendIPCMessage(const base::string16& channel,
const base::ListValue& args);
// Toggles autosize mode for corresponding <webview>.
void SetAutoSize(bool enabled,
const gfx::Size& min_size,
const gfx::Size& max_size);
// Sets the transparency of the guest.
// Methods for creating <webview>.
void SetSize(const SetSizeParams& params);
void SetAllowTransparency(bool allow);
// Returns whether this is a guest view.
bool is_guest() const { return guest_instance_id_ != -1; }
// Returns whether this guest has an associated embedder.
bool attached() const { return !!embedder_web_contents_; }
content::WebContents* web_contents() const {
return content::WebContentsObserver::web_contents();
}
bool IsGuest() const;
protected:
explicit WebContents(content::WebContents* web_contents);
@@ -126,29 +127,32 @@ class WebContents : public mate::EventEmitter,
const GURL& target_url,
const std::string& partition_id,
content::SessionStorageNamespace* session_storage_namespace) override;
void CloseContents(content::WebContents* source) override;
content::WebContents* OpenURLFromTab(
content::WebContents* source,
const content::OpenURLParams& params) override;
void RunFileChooser(content::WebContents* web_contents,
const content::FileChooserParams& params) override;
void EnumerateDirectory(content::WebContents* web_contents,
int request_id,
const base::FilePath& path) override;
bool CheckMediaAccessPermission(content::WebContents* web_contents,
const GURL& security_origin,
content::MediaStreamType type) override;
void RequestMediaAccessPermission(
content::WebContents*,
const content::MediaStreamRequest&,
const content::MediaResponseCallback&) override;
void BeforeUnloadFired(content::WebContents* tab,
bool proceed,
bool* proceed_to_fire_unload) override;
void MoveContents(content::WebContents* source,
const gfx::Rect& pos) override;
void CloseContents(content::WebContents* source) override;
void ActivateContents(content::WebContents* contents) override;
bool IsPopupOrPanel(const content::WebContents* source) const override;
void HandleKeyboardEvent(
content::WebContents* source,
const content::NativeWebKeyboardEvent& event) override;
void EnterFullscreenModeForTab(content::WebContents* source,
const GURL& origin) override;
void ExitFullscreenModeForTab(content::WebContents* source) override;
void RendererUnresponsive(content::WebContents* source) override;
void RendererResponsive(content::WebContents* source) override;
// content::WebContentsObserver:
void BeforeUnloadFired(const base::TimeTicks& proceed_time) override;
void RenderViewDeleted(content::RenderViewHost*) override;
void RenderProcessGone(base::TerminationStatus status) override;
void DocumentLoadedInFrame(
content::RenderFrameHost* render_frame_host) override;
void DidFinishLoad(content::RenderFrameHost* render_frame_host,
const GURL& validated_url) override;
void DidFailLoad(content::RenderFrameHost* render_frame_host,
@@ -159,8 +163,8 @@ class WebContents : public mate::EventEmitter,
const GURL& validated_url,
int error_code,
const base::string16& error_description) override;
void DidStartLoading(content::RenderViewHost* render_view_host) override;
void DidStopLoading(content::RenderViewHost* render_view_host) override;
void DidStartLoading() override;
void DidStopLoading() override;
void DidGetResourceResponseStart(
const content::ResourceRequestDetails& details) override;
void DidGetRedirectForResourceRequest(
@@ -170,24 +174,22 @@ class WebContents : public mate::EventEmitter,
const content::LoadCommittedDetails& details,
const content::FrameNavigateParams& params) override;
bool OnMessageReceived(const IPC::Message& message) override;
void RenderViewReady() override;
void WebContentsDestroyed() override;
void NavigationEntryCommitted(
const content::LoadCommittedDetails& load_details) override;
void TitleWasSet(content::NavigationEntry* entry, bool explicit_set) override;
// content::BrowserPluginGuestDelegate:
void DidAttach(int guest_proxy_routing_id) final;
void ElementSizeChanged(const gfx::Size& size) final;
content::WebContents* GetOwnerWebContents() const final;
void GuestSizeChanged(const gfx::Size& new_size) final;
void RegisterDestructionCallback(const DestructionCallback& callback) final;
void SetGuestSizer(content::GuestSizer* guest_sizer) final;
void WillAttach(content::WebContents* embedder_web_contents,
int element_instance_id,
bool is_full_page_plugin) final;
void DidUpdateFaviconURL(
const std::vector<content::FaviconURL>& urls) override;
void PluginCrashed(const base::FilePath& plugin_path,
base::ProcessId plugin_pid) override;
private:
enum Type {
BROWSER_WINDOW, // Used by BrowserWindow.
WEB_VIEW, // Used by <webview>.
REMOTE, // Thin wrap around an existing WebContents.
};
// Called when received a message from renderer.
void OnRendererMessage(const base::string16& channel,
const base::ListValue& args);
@@ -197,47 +199,12 @@ class WebContents : public mate::EventEmitter,
const base::ListValue& args,
IPC::Message* message);
void GuestSizeChangedDueToAutoSize(const gfx::Size& old_size,
const gfx::Size& new_size);
v8::Global<v8::Value> session_;
scoped_ptr<WebDialogHelper> web_dialog_helper_;
scoped_ptr<WebViewGuestDelegate> guest_delegate_;
// Unique ID for a guest WebContents.
int guest_instance_id_;
// |element_instance_id_| is an identifer that's unique to a particular
// element.
int element_instance_id_;
DestructionCallback destruction_callback_;
// Stores whether the contents of the guest can be transparent.
bool guest_opaque_;
// Stores the WebContents that managed by this class.
scoped_ptr<brightray::InspectableWebContents> storage_;
// The WebContents that attaches this guest view.
content::WebContents* embedder_web_contents_;
// The size of the container element.
gfx::Size element_size_;
// The size of the guest content. Note: In autosize mode, the container
// element may not match the size of the guest.
gfx::Size guest_size_;
// A pointer to the guest_sizer.
content::GuestSizer* guest_sizer_;
// Indicates whether autosize mode is enabled or not.
bool auto_size_enabled_;
// The maximum size constraints of the container element in autosize mode.
gfx::Size max_auto_size_;
// The minimum size constraints of the container element in autosize mode.
gfx::Size min_auto_size_;
// The type of current WebContents.
Type type_;
DISALLOW_COPY_AND_ASSIGN(WebContents);
};

View File

@@ -15,7 +15,7 @@ namespace mate {
template<>
struct Converter<content::WebContents*> {
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
content::WebContents** out) {
atom::api::WebContents* contents;
if (!Converter<atom::api::WebContents*>::FromV8(isolate, val, &contents))
@@ -27,7 +27,7 @@ struct Converter<content::WebContents*> {
template<>
struct Converter<atom::WebViewManager::WebViewInfo> {
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
atom::WebViewManager::WebViewInfo* out) {
Dictionary options;
if (!ConvertFromV8(isolate, val, &options))
@@ -81,8 +81,8 @@ void RemoveGuest(content::WebContents* embedder, int guest_instance_id) {
manager->RemoveGuest(guest_instance_id);
}
void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
v8::Handle<v8::Context> context, void* priv) {
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
v8::Local<v8::Context> context, void* priv) {
mate::Dictionary dict(context->GetIsolate(), exports);
dict.SetMethod("addGuest", &AddGuest);
dict.SetMethod("removeGuest", &RemoveGuest);

View File

@@ -4,6 +4,7 @@
#include "atom/browser/api/atom_api_window.h"
#include "atom/browser/api/atom_api_menu.h"
#include "atom/browser/api/atom_api_web_contents.h"
#include "atom/browser/browser.h"
#include "atom/browser/native_window.h"
@@ -15,35 +16,10 @@
#include "native_mate/callback.h"
#include "native_mate/constructor.h"
#include "native_mate/dictionary.h"
#include "ui/gfx/geometry/rect.h"
#include "atom/common/node_includes.h"
namespace {
struct PrintSettings {
bool silent;
bool print_background;
};
} // namespace
namespace mate {
template<>
struct Converter<PrintSettings> {
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
PrintSettings* out) {
mate::Dictionary dict;
if (!ConvertFromV8(isolate, val, &dict))
return false;
dict.Get("silent", &(out->silent));
dict.Get("printBackground", &(out->print_background));
return true;
}
};
} // namespace mate
namespace atom {
namespace api {
@@ -62,8 +38,17 @@ void OnCapturePageDone(
} // namespace
Window::Window(const mate::Dictionary& options)
: window_(NativeWindow::Create(options)) {
Window::Window(v8::Isolate* isolate, const mate::Dictionary& options) {
// Creates the WebContents used by BrowserWindow.
mate::Dictionary web_contents_options(isolate, v8::Object::New(isolate));
auto web_contents = WebContents::Create(isolate, web_contents_options);
web_contents_.Reset(isolate, web_contents.ToV8());
api_web_contents_ = web_contents.get();
// Creates BrowserWindow.
window_.reset(NativeWindow::Create(web_contents->managed_web_contents(),
options));
web_contents->SetOwnerWindow(window_.get());
window_->InitFromOptions(options);
window_->AddObserver(this);
}
@@ -78,25 +63,21 @@ void Window::OnPageTitleUpdated(bool* prevent_default,
*prevent_default = Emit("page-title-updated", title);
}
void Window::WillCreatePopupWindow(const base::string16& frame_name,
const GURL& target_url,
const std::string& partition_id,
WindowOpenDisposition disposition) {
Emit("-new-window", target_url, frame_name, static_cast<int>(disposition));
}
void Window::WillNavigate(bool* prevent_default, const GURL& url) {
*prevent_default = Emit("-will-navigate", url);
}
void Window::WillCloseWindow(bool* prevent_default) {
*prevent_default = Emit("close");
}
void Window::OnWindowClosed() {
Emit("closed");
if (api_web_contents_) {
api_web_contents_->DestroyWebContents();
api_web_contents_ = nullptr;
web_contents_.Reset();
}
RemoveFromWeakMap();
window_->RemoveObserver(this);
Emit("closed");
}
void Window::OnWindowBlur() {
@@ -123,6 +104,18 @@ void Window::OnWindowRestore() {
Emit("restore");
}
void Window::OnWindowResize() {
Emit("resize");
}
void Window::OnWindowMove() {
Emit("move");
}
void Window::OnWindowMoved() {
Emit("moved");
}
void Window::OnWindowEnterFullScreen() {
Emit("enter-full-screen");
}
@@ -131,6 +124,14 @@ void Window::OnWindowLeaveFullScreen() {
Emit("leave-full-screen");
}
void Window::OnWindowEnterHtmlFullScreen() {
Emit("enter-html-full-screen");
}
void Window::OnWindowLeaveHtmlFullScreen() {
Emit("leave-html-full-screen");
}
void Window::OnRendererUnresponsive() {
Emit("unresponsive");
}
@@ -143,19 +144,41 @@ void Window::OnDevToolsFocus() {
Emit("devtools-focused");
}
void Window::OnDevToolsOpened() {
Emit("devtools-opened");
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
auto handle = WebContents::CreateFrom(
isolate(), api_web_contents_->GetDevToolsWebContents());
devtools_web_contents_.Reset(isolate(), handle.ToV8());
}
void Window::OnDevToolsClosed() {
Emit("devtools-closed");
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
devtools_web_contents_.Reset();
}
void Window::OnExecuteWindowsCommand(const std::string& command_name) {
Emit("app-command", command_name);
}
// static
mate::Wrappable* Window::New(v8::Isolate* isolate,
const mate::Dictionary& options) {
if (!Browser::Get()->is_ready()) {
node::ThrowError("Cannot create BrowserWindow before app is ready");
node::ThrowError(isolate,
"Cannot create BrowserWindow before app is ready");
return nullptr;
}
return new Window(options);
return new Window(isolate, options);
}
void Window::Destroy() {
window_->DestroyWebContents();
window_->CloseImmediately();
window_->CloseContents(nullptr);
}
void Window::Close() {
@@ -222,6 +245,14 @@ bool Window::IsFullscreen() {
return window_->IsFullscreen();
}
void Window::SetBounds(const gfx::Rect& bounds) {
window_->SetBounds(bounds);
}
gfx::Rect Window::GetBounds() {
return window_->GetBounds();
}
void Window::SetSize(int width, int height) {
window_->SetSize(gfx::Size(width, height));
}
@@ -326,22 +357,6 @@ bool Window::IsKiosk() {
return window_->IsKiosk();
}
void Window::OpenDevTools(bool can_dock) {
window_->OpenDevTools(can_dock);
}
void Window::CloseDevTools() {
window_->CloseDevTools();
}
bool Window::IsDevToolsOpened() {
return window_->IsDevToolsOpened();
}
void Window::InspectElement(int x, int y) {
window_->InspectElement(x, y);
}
void Window::FocusOnWebView() {
window_->FocusOnWebView();
}
@@ -385,16 +400,6 @@ void Window::CapturePage(mate::Arguments* args) {
rect, base::Bind(&OnCapturePageDone, args->isolate(), callback));
}
void Window::Print(mate::Arguments* args) {
PrintSettings settings = { false, false };;
if (args->Length() == 1 && !args->GetNext(&settings)) {
args->ThrowError();
return;
}
window_->Print(settings.silent, settings.print_background);
}
void Window::SetProgressBar(double progress) {
window_->SetProgressBar(progress);
}
@@ -404,6 +409,22 @@ void Window::SetOverlayIcon(const gfx::Image& overlay,
window_->SetOverlayIcon(overlay, description);
}
void Window::SetMenu(v8::Isolate* isolate, v8::Local<v8::Value> value) {
mate::Handle<Menu> menu;
if (value->IsObject() &&
mate::V8ToString(value->ToObject()->GetConstructorName()) == "Menu" &&
mate::ConvertFromV8(isolate, value, &menu)) {
menu_.Reset(isolate, menu.ToV8());
window_->SetMenu(menu->model());
} else if (value->IsNull()) {
menu_.Reset();
window_->SetMenu(nullptr);
} else {
isolate->ThrowException(v8::Exception::TypeError(
mate::StringToV8(isolate, "Invalid Menu")));
}
}
void Window::SetAutoHideMenuBar(bool auto_hide) {
window_->SetAutoHideMenuBar(auto_hide);
}
@@ -434,18 +455,27 @@ bool Window::IsVisibleOnAllWorkspaces() {
return window_->IsVisibleOnAllWorkspaces();
}
mate::Handle<WebContents> Window::GetWebContents(v8::Isolate* isolate) const {
return WebContents::CreateFrom(isolate, window_->GetWebContents());
int32_t Window::ID() const {
return weak_map_id();
}
mate::Handle<WebContents> Window::GetDevToolsWebContents(
v8::Isolate* isolate) const {
return WebContents::CreateFrom(isolate, window_->GetDevToolsWebContents());
v8::Local<v8::Value> Window::WebContents(v8::Isolate* isolate) {
if (web_contents_.IsEmpty())
return v8::Null(isolate);
else
return v8::Local<v8::Value>::New(isolate, web_contents_);
}
v8::Local<v8::Value> Window::DevToolsWebContents(v8::Isolate* isolate) {
if (devtools_web_contents_.IsEmpty())
return v8::Null(isolate);
else
return v8::Local<v8::Value>::New(isolate, devtools_web_contents_);
}
// static
void Window::BuildPrototype(v8::Isolate* isolate,
v8::Handle<v8::ObjectTemplate> prototype) {
v8::Local<v8::ObjectTemplate> prototype) {
mate::ObjectTemplateBuilder(isolate, prototype)
.SetMethod("destroy", &Window::Destroy)
.SetMethod("close", &Window::Close)
@@ -464,6 +494,8 @@ void Window::BuildPrototype(v8::Isolate* isolate,
.SetMethod("isMinimized", &Window::IsMinimized)
.SetMethod("setFullScreen", &Window::SetFullScreen)
.SetMethod("isFullScreen", &Window::IsFullscreen)
.SetMethod("getBounds", &Window::GetBounds)
.SetMethod("setBounds", &Window::SetBounds)
.SetMethod("getSize", &Window::GetSize)
.SetMethod("setSize", &Window::SetSize)
.SetMethod("getContentSize", &Window::GetContentSize)
@@ -489,17 +521,13 @@ void Window::BuildPrototype(v8::Isolate* isolate,
.SetMethod("getRepresentedFilename", &Window::GetRepresentedFilename)
.SetMethod("setDocumentEdited", &Window::SetDocumentEdited)
.SetMethod("isDocumentEdited", &Window::IsDocumentEdited)
.SetMethod("_openDevTools", &Window::OpenDevTools)
.SetMethod("closeDevTools", &Window::CloseDevTools)
.SetMethod("isDevToolsOpened", &Window::IsDevToolsOpened)
.SetMethod("inspectElement", &Window::InspectElement)
.SetMethod("focusOnWebView", &Window::FocusOnWebView)
.SetMethod("blurWebView", &Window::BlurWebView)
.SetMethod("isWebViewFocused", &Window::IsWebViewFocused)
.SetMethod("capturePage", &Window::CapturePage)
.SetMethod("print", &Window::Print)
.SetMethod("setProgressBar", &Window::SetProgressBar)
.SetMethod("setOverlayIcon", &Window::SetOverlayIcon)
.SetMethod("setMenu", &Window::SetMenu)
.SetMethod("setAutoHideMenuBar", &Window::SetAutoHideMenuBar)
.SetMethod("isMenuBarAutoHide", &Window::IsMenuBarAutoHide)
.SetMethod("setMenuBarVisibility", &Window::SetMenuBarVisibility)
@@ -512,8 +540,9 @@ void Window::BuildPrototype(v8::Isolate* isolate,
.SetMethod("showDefinitionForSelection",
&Window::ShowDefinitionForSelection)
#endif
.SetMethod("_getWebContents", &Window::GetWebContents)
.SetMethod("_getDevToolsWebContents", &Window::GetDevToolsWebContents);
.SetProperty("id", &Window::ID)
.SetProperty("webContents", &Window::WebContents)
.SetProperty("devToolsWebContents", &Window::DevToolsWebContents);
}
} // namespace api
@@ -523,14 +552,21 @@ void Window::BuildPrototype(v8::Isolate* isolate,
namespace {
void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
v8::Handle<v8::Context> context, void* priv) {
using atom::api::Window;
using atom::api::Window;
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
v8::Local<v8::Context> context, void* priv) {
v8::Isolate* isolate = context->GetIsolate();
v8::Local<v8::Function> constructor = mate::CreateConstructor<Window>(
isolate, "BrowserWindow", base::Bind(&Window::New));
mate::Dictionary browser_window(isolate, constructor);
browser_window.SetMethod("fromId",
&mate::TrackableObject<Window>::FromWeakMapID);
browser_window.SetMethod("getAllWindows",
&mate::TrackableObject<Window>::GetAll);
mate::Dictionary dict(isolate, exports);
dict.Set("BrowserWindow", static_cast<v8::Handle<v8::Value>>(constructor));
dict.Set("BrowserWindow", browser_window);
}
} // namespace

View File

@@ -10,12 +10,16 @@
#include "base/memory/scoped_ptr.h"
#include "ui/gfx/image/image.h"
#include "atom/browser/api/trackable_object.h"
#include "atom/browser/native_window_observer.h"
#include "atom/browser/api/event_emitter.h"
#include "native_mate/handle.h"
class GURL;
namespace gfx {
class Rect;
}
namespace mate {
class Arguments;
class Dictionary;
@@ -29,29 +33,24 @@ namespace api {
class WebContents;
class Window : public mate::EventEmitter,
class Window : public mate::TrackableObject<Window>,
public NativeWindowObserver {
public:
static mate::Wrappable* New(v8::Isolate* isolate,
const mate::Dictionary& options);
static void BuildPrototype(v8::Isolate* isolate,
v8::Handle<v8::ObjectTemplate> prototype);
v8::Local<v8::ObjectTemplate> prototype);
NativeWindow* window() const { return window_.get(); }
protected:
explicit Window(const mate::Dictionary& options);
Window(v8::Isolate* isolate, const mate::Dictionary& options);
virtual ~Window();
// NativeWindowObserver:
void OnPageTitleUpdated(bool* prevent_default,
const std::string& title) override;
void WillCreatePopupWindow(const base::string16& frame_name,
const GURL& target_url,
const std::string& partition_id,
WindowOpenDisposition disposition) override;
void WillNavigate(bool* prevent_default, const GURL& url) override;
void WillCloseWindow(bool* prevent_default) override;
void OnWindowClosed() override;
void OnWindowBlur() override;
@@ -60,11 +59,19 @@ class Window : public mate::EventEmitter,
void OnWindowUnmaximize() override;
void OnWindowMinimize() override;
void OnWindowRestore() override;
void OnWindowResize() override;
void OnWindowMove() override;
void OnWindowMoved() override;
void OnWindowEnterFullScreen() override;
void OnWindowLeaveFullScreen() override;
void OnWindowEnterHtmlFullScreen() override;
void OnWindowLeaveHtmlFullScreen() override;
void OnRendererUnresponsive() override;
void OnRendererResponsive() override;
void OnDevToolsFocus() override;
void OnDevToolsOpened() override;
void OnDevToolsClosed() override;
void OnExecuteWindowsCommand(const std::string& command_name) override;
private:
// APIs for NativeWindow.
@@ -85,6 +92,8 @@ class Window : public mate::EventEmitter,
bool IsMinimized();
void SetFullScreen(bool fullscreen);
bool IsFullscreen();
void SetBounds(const gfx::Rect& bounds);
gfx::Rect GetBounds();
void SetSize(int width, int height);
std::vector<int> GetSize();
void SetContentSize(int width, int height);
@@ -106,10 +115,6 @@ class Window : public mate::EventEmitter,
void SetSkipTaskbar(bool skip);
void SetKiosk(bool kiosk);
bool IsKiosk();
void OpenDevTools(bool can_dock);
void CloseDevTools();
bool IsDevToolsOpened();
void InspectElement(int x, int y);
void FocusOnWebView();
void BlurWebView();
bool IsWebViewFocused();
@@ -118,10 +123,10 @@ class Window : public mate::EventEmitter,
void SetDocumentEdited(bool edited);
bool IsDocumentEdited();
void CapturePage(mate::Arguments* args);
void Print(mate::Arguments* args);
void SetProgressBar(double progress);
void SetOverlayIcon(const gfx::Image& overlay,
const std::string& description);
void SetMenu(v8::Isolate* isolate, v8::Local<v8::Value> menu);
void SetAutoHideMenuBar(bool auto_hide);
bool IsMenuBarAutoHide();
void SetMenuBarVisibility(bool visible);
@@ -134,9 +139,15 @@ class Window : public mate::EventEmitter,
void SetVisibleOnAllWorkspaces(bool visible);
bool IsVisibleOnAllWorkspaces();
// APIs for WebContents.
mate::Handle<WebContents> GetWebContents(v8::Isolate* isolate) const;
mate::Handle<WebContents> GetDevToolsWebContents(v8::Isolate* isolate) const;
int32_t ID() const;
v8::Local<v8::Value> WebContents(v8::Isolate* isolate);
v8::Local<v8::Value> DevToolsWebContents(v8::Isolate* isolate);
v8::Global<v8::Value> web_contents_;
v8::Global<v8::Value> devtools_web_contents_;
v8::Global<v8::Value> menu_;
api::WebContents* api_web_contents_;
scoped_ptr<NativeWindow> window_;
@@ -152,7 +163,7 @@ namespace mate {
template<>
struct Converter<atom::NativeWindow*> {
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
atom::NativeWindow** out) {
// null would be tranfered to NULL.
if (val->IsNull()) {

View File

@@ -6,10 +6,9 @@
#include "atom/browser/api/event.h"
#include "native_mate/arguments.h"
#include "native_mate/dictionary.h"
#include "native_mate/object_template_builder.h"
#include "atom/common/node_includes.h"
namespace mate {
namespace {
@@ -17,8 +16,8 @@ namespace {
v8::Persistent<v8::ObjectTemplate> event_template;
void PreventDefault(mate::Arguments* args) {
args->GetThis()->Set(StringToV8(args->isolate(), "defaultPrevented"),
v8::True(args->isolate()));
mate::Dictionary self(args->isolate(), args->GetThis());
self.Set("defaultPrevented", true);
}
// Create a pure JavaScript Event object.
@@ -38,31 +37,21 @@ v8::Local<v8::Object> CreateEventObject(v8::Isolate* isolate) {
EventEmitter::EventEmitter() {
}
bool EventEmitter::CallEmit(v8::Isolate* isolate,
const base::StringPiece& name,
content::WebContents* sender,
IPC::Message* message,
ValueArray args) {
v8::Handle<v8::Object> event;
v8::Local<v8::Object> EventEmitter::CreateJSEvent(v8::Isolate* isolate,
content::WebContents* sender,
IPC::Message* message) {
v8::Local<v8::Object> event;
bool use_native_event = sender && message;
if (use_native_event) {
mate::Handle<mate::Event> native_event = mate::Event::Create(isolate);
native_event->SetSenderAndMessage(sender, message);
event = v8::Handle<v8::Object>::Cast(native_event.ToV8());
event = v8::Local<v8::Object>::Cast(native_event.ToV8());
} else {
event = CreateEventObject(isolate);
}
// args = [name, event, args...];
args.insert(args.begin(), event);
args.insert(args.begin(), mate::StringToV8(isolate, name));
// this.emit.apply(this, args);
node::MakeCallback(isolate, GetWrapper(isolate), "emit", args.size(),
&args[0]);
return event->Get(StringToV8(isolate, "defaultPrevented"))->BooleanValue();
mate::Dictionary(isolate, event).Set("sender", GetWrapper(isolate));
return event;
}
} // namespace mate

View File

@@ -7,6 +7,7 @@
#include <vector>
#include "atom/common/event_emitter_caller.h"
#include "native_mate/wrappable.h"
namespace content {
@@ -22,10 +23,7 @@ namespace mate {
// Provide helperers to emit event in JavaScript.
class EventEmitter : public Wrappable {
public:
typedef std::vector<v8::Handle<v8::Value>> ValueArray;
protected:
EventEmitter();
typedef std::vector<v8::Local<v8::Value>> ValueArray;
// this.emit(name, new Event(), args...);
template<typename... Args>
@@ -39,21 +37,21 @@ class EventEmitter : public Wrappable {
content::WebContents* sender,
IPC::Message* message,
const Args&... args) {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
ValueArray converted = { ConvertToV8(isolate, args)... };
return CallEmit(isolate, name, sender, message, converted);
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
v8::Local<v8::Object> event = CreateJSEvent(isolate(), sender, message);
EmitEvent(isolate(), GetWrapper(isolate()), name, event, args...);
return event->Get(
StringToV8(isolate(), "defaultPrevented"))->BooleanValue();
}
protected:
EventEmitter();
private:
// Lower level implementations.
bool CallEmit(v8::Isolate* isolate,
const base::StringPiece& name,
content::WebContents* sender,
IPC::Message* message,
ValueArray args);
v8::Local<v8::Object> CreateJSEvent(v8::Isolate* isolate,
content::WebContents* sender,
IPC::Message* message);
DISALLOW_COPY_AND_ASSIGN(EventEmitter);
};

View File

@@ -26,12 +26,13 @@ if process.platform is 'darwin'
setMenu: bindings.dockSetMenu
# Be compatible with old API.
app.once 'ready', -> app.emit 'finish-launching'
app.once 'ready', -> @emit 'finish-launching'
app.terminate = app.quit
app.exit = process.exit
app.getHomeDir = -> app.getPath 'home'
app.getDataPath = -> app.getPath 'userData'
app.setDataPath = (path) -> app.setPath 'userData', path
app.getHomeDir = -> @getPath 'home'
app.getDataPath = -> @getPath 'userData'
app.setDataPath = (path) -> @setPath 'userData', path
app.resolveProxy = -> @defaultSession.resolveProxy.apply @defaultSession, arguments
# Only one App object pemitted.
module.exports = app

View File

@@ -1,78 +1,35 @@
EventEmitter = require('events').EventEmitter
IDWeakMap = require 'id-weak-map'
app = require 'app'
ipc = require 'ipc'
wrapWebContents = require('web-contents').wrap
BrowserWindow = process.atomBinding('window').BrowserWindow
BrowserWindow::__proto__ = EventEmitter.prototype
# Store all created windows in the weak map.
BrowserWindow.windows = new IDWeakMap
BrowserWindow::_init = ->
# Simulate the application menu on platforms other than OS X.
if process.platform isnt 'darwin'
menu = app.getApplicationMenu()
@setMenu menu if menu?
@webContents = @getWebContents()
@devToolsWebContents = null
@webContents.once 'destroyed', => @webContents = null
# Remember the window ID.
Object.defineProperty this, 'id',
value: BrowserWindow.windows.add(this)
enumerable: true
# Make new windows requested by links behave like "window.open"
@on '-new-window', (event, url, frameName) =>
event.sender = @webContents
@webContents.on '-new-window', (event, url, frameName) ->
options = show: true, width: 800, height: 600
ipc.emit 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPEN', event, url, frameName, options
# Redirect "will-navigate" to webContents.
@on '-will-navigate', (event, url) =>
@webContents.emit 'will-navigate', event, url
# window.move(...)
@webContents.on 'move', (event, size) =>
@setSize size
# Remove the window from weak map immediately when it's destroyed, since we
# could be iterating windows before GC happened.
@once 'closed', =>
BrowserWindow.windows.remove @id if BrowserWindow.windows.has @id
# Hide the auto-hide menu when webContents is focused.
@webContents.on 'activate', =>
if process.platform isnt 'darwin' and @isMenuBarAutoHide() and @isMenuBarVisible()
@setMenuBarVisibility false
BrowserWindow::openDevTools = (options={}) ->
options.detach ?= false
@_openDevTools !options.detach
# Force devToolsWebContents to be created.
@devToolsWebContents = @getDevToolsWebContents()
@devToolsWebContents.once 'destroyed', => @devToolsWebContents = null
# Emit devtools events.
@devToolsWebContents.once 'did-finish-load', => @emit 'devtools-opened'
@devToolsWebContents.once 'destroyed', => @emit 'devtools-closed'
BrowserWindow::toggleDevTools = ->
if @isDevToolsOpened() then @closeDevTools() else @openDevTools()
BrowserWindow::getWebContents = ->
wrapWebContents @_getWebContents()
BrowserWindow::getDevToolsWebContents = ->
wrapWebContents @_getDevToolsWebContents()
BrowserWindow::setMenu = (menu) ->
if process.platform is 'darwin'
throw new Error('BrowserWindow.setMenu is not available on OS X')
throw new TypeError('Invalid menu') unless menu?.constructor?.name is 'Menu'
@menu = menu # Keep a reference of menu in case of GC.
@menu.attachToWindow this
BrowserWindow.getAllWindows = ->
windows = BrowserWindow.windows
windows.get key for key in windows.keys()
# 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
BrowserWindow.getFocusedWindow = ->
windows = BrowserWindow.getAllWindows()
@@ -80,14 +37,11 @@ BrowserWindow.getFocusedWindow = ->
BrowserWindow.fromWebContents = (webContents) ->
windows = BrowserWindow.getAllWindows()
return window for window in windows when webContents.equal window.webContents
return window for window in windows when window.webContents?.equal webContents
BrowserWindow.fromDevToolsWebContents = (webContents) ->
windows = BrowserWindow.getAllWindows()
return window for window in windows when webContents.equal window.devToolsWebContents
BrowserWindow.fromId = (id) ->
BrowserWindow.windows.get id
return window for window in windows when window.devToolsWebContents?.equal webContents
# Helpers.
BrowserWindow::loadUrl = -> @webContents.loadUrl.apply @webContents, arguments
@@ -102,10 +56,15 @@ BrowserWindow::getPageTitle = -> @webContents.getTitle()
BrowserWindow::isLoading = -> @webContents.isLoading()
BrowserWindow::isWaitingForResponse = -> @webContents.isWaitingForResponse()
BrowserWindow::stop = -> @webContents.stop()
BrowserWindow::getRoutingId = -> @webContents.getRoutingId()
BrowserWindow::getProcessId = -> @webContents.getProcessId()
BrowserWindow::isCrashed = -> @webContents.isCrashed()
BrowserWindow::executeJavaScriptInDevTools = (code) ->
@devToolsWebContents.executeJavaScript code
BrowserWindow::executeJavaScriptInDevTools = (code) -> @devToolsWebContents?.executeJavaScript code
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()
BrowserWindow::print = -> @webContents.print.apply @webContents, arguments
BrowserWindow::printToPDF = -> @webContents.printToPDF.apply @webContents, arguments
module.exports = BrowserWindow

View File

@@ -130,10 +130,11 @@ Menu::_callMenuWillShow = ->
applicationMenu = null
Menu.setApplicationMenu = (menu) ->
throw new TypeError('Invalid menu') unless menu?.constructor is 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

View File

@@ -0,0 +1,116 @@
ipc = require 'ipc'
# The history operation in renderer is redirected to browser.
ipc.on 'ATOM_SHELL_NAVIGATION_CONTROLLER', (event, method, args...) ->
event.sender[method] args...
ipc.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.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
getUrl: ->
if @currentIndex is -1
''
else
@history[@currentIndex]
stop: ->
@pendingIndex = -1
@webContents._stop()
reload: ->
@pendingIndex = @currentIndex
@webContents._loadUrl @getUrl(), {}
reloadIgnoringCache: ->
@webContents._reloadIgnoringCache() # Rely on WebContents to clear cache.
@reload()
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

View File

@@ -0,0 +1,3 @@
bindings = process.atomBinding 'power_save_blocker'
module.exports = bindings.powerSaveBlocker

View File

@@ -30,4 +30,12 @@ protocol.RequestFileJob =
class RequestFileJob
constructor: (@path) ->
protocol.RequestErrorJob =
class RequestErrorJob
constructor: (@error) ->
protocol.RequestHttpJob =
class RequestHttpJob
constructor: ({@url, @method, @referrer}) ->
module.exports = protocol

View File

@@ -1,10 +1,12 @@
EventEmitter = require('events').EventEmitter
NavigationController = require './navigation-controller'
binding = process.atomBinding 'web_contents'
ipc = require 'ipc'
module.exports.wrap = (webContents) ->
return null unless webContents.isAlive()
nextId = 0
getNextId = -> ++nextId
wrapWebContents = (webContents) ->
# webContents is an EventEmitter.
webContents.__proto__ = EventEmitter.prototype
@@ -22,43 +24,63 @@ module.exports.wrap = (webContents) ->
else
webContents.once 'did-finish-load', @_executeJavaScript.bind(this, code)
# The processId and routingId and identify a webContents.
webContents.getId = -> "#{@getProcessId()}-#{@getRoutingId()}"
webContents.equal = (other) -> @getId() is other.getId()
# Provide a default parameter for |urlOptions|.
webContents.loadUrl = (url, urlOptions={}) -> @_loadUrl url, urlOptions
webContents.reload = (urlOptions={}) -> @_reload urlOptions
webContents.reloadIgnoringCache = (urlOptions={}) -> @_reloadIgnoringCache urlOptions
# Translate |disposition| to string for 'new-window' event.
webContents.on '-new-window', (args..., disposition) ->
disposition =
switch disposition
when 2 then 'default'
when 4 then 'foreground-tab'
when 5 then 'background-tab'
when 6, 7 then 'new-window'
else 'other'
@emit 'new-window', args..., disposition
# Tell the rpc server that a render view has been deleted and we need to
# release all objects owned by it.
webContents.on 'render-view-deleted', (event, processId, routingId) ->
process.emit 'ATOM_BROWSER_RELEASE_RENDER_VIEW', "#{processId}-#{routingId}"
# 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
Object.defineProperty event, 'sender', value: webContents
ipc.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)
Object.defineProperty event, 'sender', value: webContents
ipc.emit channel, event, args...
webContents
webContents.printToPDF = (options, callback) ->
printingSetting =
pageRage:[],
mediaSize:
height_microns:297000,
is_default:true,
name:"ISO_A4",
width_microns:210000,
custom_display_name:"A4",
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.printBackgrounds
printingSetting.shouldPrintBackgrounds = options.printBackground
@_printToPDF printingSetting, callback
binding._setWrapWebContents wrapWebContents
process.once 'exit', binding._clearWrapWebContents
module.exports.create = (options={}) ->
@wrap binding.create(options)
binding.create(options)

View File

@@ -0,0 +1,68 @@
// 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/trackable_object.h"
#include "atom/browser/atom_browser_main_parts.h"
#include "base/bind.h"
#include "base/supports_user_data.h"
namespace mate {
namespace {
const char* kTrackedObjectKey = "TrackedObjectKey";
class IDUserData : public base::SupportsUserData::Data {
public:
explicit IDUserData(int32_t id) : id_(id) {}
operator int32_t() const { return id_; }
private:
int32_t id_;
DISALLOW_COPY_AND_ASSIGN(IDUserData);
};
} // namespace
TrackableObjectBase::TrackableObjectBase()
: weak_map_id_(0), wrapped_(nullptr) {
}
TrackableObjectBase::~TrackableObjectBase() {
}
void TrackableObjectBase::AfterInit(v8::Isolate* isolate) {
if (wrapped_)
AttachAsUserData(wrapped_);
}
void TrackableObjectBase::AttachAsUserData(base::SupportsUserData* wrapped) {
if (weak_map_id_ != 0) {
wrapped->SetUserData(kTrackedObjectKey, new IDUserData(weak_map_id_));
wrapped_ = nullptr;
} else {
// If the TrackableObjectBase is not ready yet then delay SetUserData until
// AfterInit is called.
wrapped_ = wrapped;
}
}
// static
int32_t TrackableObjectBase::GetIDFromWrappedClass(base::SupportsUserData* w) {
auto id = static_cast<IDUserData*>(w->GetUserData(kTrackedObjectKey));
if (id)
return *id;
else
return 0;
}
// static
void TrackableObjectBase::RegisterDestructionCallback(void (*c)()) {
atom::AtomBrowserMainParts::Get()->RegisterDestructionCallback(base::Bind(c));
}
} // namespace mate

View File

@@ -0,0 +1,116 @@
// 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_TRACKABLE_OBJECT_H_
#define ATOM_BROWSER_API_TRACKABLE_OBJECT_H_
#include <vector>
#include "atom/browser/api/event_emitter.h"
#include "atom/common/id_weak_map.h"
namespace base {
class SupportsUserData;
}
namespace mate {
// Users should use TrackableObject instead.
class TrackableObjectBase : public mate::EventEmitter {
public:
TrackableObjectBase();
// The ID in weak map.
int32_t weak_map_id() const { return weak_map_id_; }
// Wrap TrackableObject into a class that SupportsUserData.
void AttachAsUserData(base::SupportsUserData* wrapped);
protected:
~TrackableObjectBase() override;
// mate::Wrappable:
void AfterInit(v8::Isolate* isolate) override;
// Get the weak_map_id from SupportsUserData.
static int32_t GetIDFromWrappedClass(base::SupportsUserData* wrapped);
// Register a callback that should be destroyed before JavaScript environment
// gets destroyed.
static void RegisterDestructionCallback(void (*callback)());
int32_t weak_map_id_;
base::SupportsUserData* wrapped_;
private:
DISALLOW_COPY_AND_ASSIGN(TrackableObjectBase);
};
// All instances of TrackableObject will be kept in a weak map and can be got
// from its ID.
template<typename T>
class TrackableObject : public TrackableObjectBase {
public:
// Finds out the TrackableObject from its ID in weak map.
static T* FromWeakMapID(v8::Isolate* isolate, int32_t id) {
v8::MaybeLocal<v8::Object> object = weak_map_.Get(isolate, id);
if (object.IsEmpty())
return nullptr;
T* self = nullptr;
mate::ConvertFromV8(isolate, object.ToLocalChecked(), &self);
return self;
}
// Finds out the TrackableObject from the class it wraps.
static T* FromWrappedClass(v8::Isolate* isolate,
base::SupportsUserData* wrapped) {
int32_t id = GetIDFromWrappedClass(wrapped);
if (!id)
return nullptr;
return FromWeakMapID(isolate, id);
}
// Returns all objects in this class's weak map.
static std::vector<v8::Local<v8::Object>> GetAll(v8::Isolate* isolate) {
return weak_map_.Values(isolate);
}
TrackableObject() {
RegisterDestructionCallback(&TrackableObject<T>::ReleaseAllWeakReferences);
}
// Removes this instance from the weak map.
void RemoveFromWeakMap() {
if (weak_map_.Has(weak_map_id()))
weak_map_.Remove(weak_map_id());
}
protected:
~TrackableObject() override {
RemoveFromWeakMap();
}
void AfterInit(v8::Isolate* isolate) override {
weak_map_id_ = weak_map_.Add(isolate, GetWrapper(isolate));
TrackableObjectBase::AfterInit(isolate);
}
private:
// Releases all weak references in weak map, called when app is terminating.
static void ReleaseAllWeakReferences() {
weak_map_.Clear();
}
static atom::IDWeakMap weak_map_;
DISALLOW_COPY_AND_ASSIGN(TrackableObject);
};
template<typename T>
atom::IDWeakMap TrackableObject<T>::weak_map_;
} // namespace mate
#endif // ATOM_BROWSER_API_TRACKABLE_OBJECT_H_

View File

@@ -7,6 +7,7 @@
#include <utility>
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/common/google_api_key.h"
namespace atom {
@@ -39,8 +40,8 @@ void AtomAccessTokenStore::LoadAccessTokens(
token_pair.first = GURL(kGeolocationProviderUrl);
access_token_set.insert(token_pair);
callback.Run(access_token_set,
AtomBrowserContext::Get()->url_request_context_getter());
auto browser_context = AtomBrowserMainParts::Get()->browser_context();
callback.Run(access_token_set, browser_context->url_request_context_getter());
}
void AtomAccessTokenStore::SaveAccessToken(const GURL& server_url,

View File

@@ -7,49 +7,108 @@
#include "atom/browser/atom_access_token_store.h"
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/atom_resource_dispatcher_host_delegate.h"
#include "atom/browser/atom_quota_permission_context.h"
#include "atom/browser/atom_speech_recognition_manager_delegate.h"
#include "atom/browser/browser.h"
#include "atom/browser/native_window.h"
#include "atom/browser/web_view_manager.h"
#include "atom/browser/window_list.h"
#include "atom/common/options_switches.h"
#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/strings/string_util.h"
#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/speech/tts_message_filter.h"
#include "content/public/browser/browser_ppapi_host.h"
#include "content/public/browser/client_certificate_delegate.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/resource_dispatcher_host.h"
#include "content/public/browser/site_instance.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/web_preferences.h"
#include "net/cert/x509_certificate.h"
#include "net/ssl/ssl_cert_request_info.h"
#include "ppapi/host/ppapi_host.h"
#include "ui/base/l10n/l10n_util.h"
namespace atom {
namespace {
struct FindByProcessId {
explicit FindByProcessId(int child_process_id)
: child_process_id_(child_process_id) {
}
// The default routing id of WebContents.
// In Electron each RenderProcessHost only has one WebContents, so this ID is
// same for every WebContents.
int kDefaultRoutingID = 2;
bool operator() (NativeWindow* const window) {
content::WebContents* web_contents = window->GetWebContents();
if (!web_contents)
return false;
// Next navigation should not restart renderer process.
bool g_suppress_renderer_process_restart = false;
int id = window->GetWebContents()->GetRenderProcessHost()->GetID();
return id == child_process_id_;
}
// Custom schemes to be registered to standard.
std::string g_custom_schemes = "";
int child_process_id_;
// Find out the owner of the child process according to |process_id|.
enum ProcessOwner {
OWNER_NATIVE_WINDOW,
OWNER_GUEST_WEB_CONTENTS,
OWNER_NONE, // it might be devtools though.
};
ProcessOwner GetProcessOwner(int process_id,
NativeWindow** window,
WebViewManager::WebViewInfo* info) {
auto web_contents = content::WebContents::FromRenderViewHost(
content::RenderViewHost::FromID(process_id, kDefaultRoutingID));
if (!web_contents)
return OWNER_NONE;
// First search for NativeWindow.
for (auto native_window : *WindowList::GetInstance())
if (web_contents == native_window->web_contents()) {
*window = native_window;
return OWNER_NATIVE_WINDOW;
}
// Then search for guest WebContents.
if (WebViewManager::GetInfoForWebContents(web_contents, info))
return OWNER_GUEST_WEB_CONTENTS;
return OWNER_NONE;
}
scoped_refptr<net::X509Certificate> ImportCertFromFile(
const base::FilePath& path) {
if (path.empty())
return nullptr;
std::string cert_data;
if (!base::ReadFileToString(path, &cert_data))
return nullptr;
net::CertificateList certs =
net::X509Certificate::CreateCertificateListFromBytes(
cert_data.data(), cert_data.size(),
net::X509Certificate::FORMAT_AUTO);
if (certs.empty())
return nullptr;
return certs[0];
}
} // namespace
AtomBrowserClient::AtomBrowserClient()
: dying_render_process_(NULL) {
// static
void AtomBrowserClient::SuppressRendererProcessRestartForOnce() {
g_suppress_renderer_process_restart = true;
}
void AtomBrowserClient::SetCustomSchemes(
const std::vector<std::string>& schemes) {
g_custom_schemes = JoinString(schemes, ',');
}
AtomBrowserClient::AtomBrowserClient() {
}
AtomBrowserClient::~AtomBrowserClient() {
@@ -57,9 +116,9 @@ AtomBrowserClient::~AtomBrowserClient() {
void AtomBrowserClient::RenderProcessWillLaunch(
content::RenderProcessHost* host) {
int id = host->GetID();
host->AddFilter(new printing::PrintingMessageFilter(host->GetID()));
host->AddFilter(new TtsMessageFilter(id, host->GetBrowserContext()));
int process_id = host->GetID();
host->AddFilter(new printing::PrintingMessageFilter(process_id));
host->AddFilter(new TtsMessageFilter(process_id, host->GetBrowserContext()));
}
content::SpeechRecognitionManagerDelegate*
@@ -71,15 +130,8 @@ content::AccessTokenStore* AtomBrowserClient::CreateAccessTokenStore() {
return new AtomAccessTokenStore;
}
void AtomBrowserClient::ResourceDispatcherHostCreated() {
resource_dispatcher_delegate_.reset(new AtomResourceDispatcherHostDelegate);
content::ResourceDispatcherHost::Get()->SetDelegate(
resource_dispatcher_delegate_.get());
}
void AtomBrowserClient::OverrideWebkitPrefs(
content::RenderViewHost* render_view_host,
content::WebPreferences* prefs) {
content::RenderViewHost* host, content::WebPreferences* prefs) {
prefs->javascript_enabled = true;
prefs->web_security_enabled = true;
prefs->javascript_can_open_windows_automatically = true;
@@ -97,90 +149,102 @@ void AtomBrowserClient::OverrideWebkitPrefs(
prefs->allow_displaying_insecure_content = false;
prefs->allow_running_insecure_content = false;
// Turn off web security for devtools.
auto web_contents = content::WebContents::FromRenderViewHost(
render_view_host);
if (web_contents && web_contents->GetURL().SchemeIs("chrome-devtools")) {
prefs->web_security_enabled = false;
return;
}
// Custom preferences of guest page.
auto process = render_view_host->GetProcess();
auto web_contents = content::WebContents::FromRenderViewHost(host);
WebViewManager::WebViewInfo info;
if (WebViewManager::GetInfoForProcess(process, &info)) {
if (WebViewManager::GetInfoForWebContents(web_contents, &info)) {
prefs->web_security_enabled = !info.disable_web_security;
return;
}
NativeWindow* window = NativeWindow::FromRenderView(
process->GetID(), render_view_host->GetRoutingID());
NativeWindow* window = NativeWindow::FromWebContents(web_contents);
if (window)
window->OverrideWebkitPrefs(prefs);
}
bool AtomBrowserClient::ShouldSwapBrowsingInstancesForNavigation(
content::SiteInstance* site_instance,
const GURL& current_url,
const GURL& new_url) {
if (site_instance->HasProcess())
dying_render_process_ = site_instance->GetProcess();
// Restart renderer process for all navigations, this relies on a patch to
// Chromium: http://git.io/_PaNyg.
return true;
}
std::string AtomBrowserClient::GetApplicationLocale() {
return l10n_util::GetApplicationLocale("");
}
void AtomBrowserClient::OverrideSiteInstanceForNavigation(
content::BrowserContext* browser_context,
content::SiteInstance* current_instance,
const GURL& url,
content::SiteInstance** new_instance) {
if (g_suppress_renderer_process_restart) {
g_suppress_renderer_process_restart = false;
return;
}
// Restart renderer process for all navigations except "javacript:" scheme.
if (url.SchemeIs(url::kJavaScriptScheme))
return;
*new_instance = content::SiteInstance::CreateForURL(browser_context, url);
}
void AtomBrowserClient::AppendExtraCommandLineSwitches(
base::CommandLine* command_line,
int child_process_id) {
WindowList* list = WindowList::GetInstance();
NativeWindow* window = NULL;
int process_id) {
std::string process_type = command_line->GetSwitchValueASCII("type");
if (process_type != "renderer")
return;
// Find the owner of this child process.
WindowList::const_iterator iter = std::find_if(
list->begin(), list->end(), FindByProcessId(child_process_id));
if (iter != list->end())
window = *iter;
if (!g_custom_schemes.empty())
command_line->AppendSwitchASCII(switches::kRegisterStandardSchemes,
g_custom_schemes);
// If the render process is a newly started one, which means the window still
// uses the old going-to-be-swapped render process, then we try to find the
// window from the swapped render process.
if (window == NULL && dying_render_process_ != NULL) {
child_process_id = dying_render_process_->GetID();
WindowList::const_iterator iter = std::find_if(
list->begin(), list->end(), FindByProcessId(child_process_id));
if (iter != list->end())
window = *iter;
NativeWindow* window;
WebViewManager::WebViewInfo info;
ProcessOwner owner = GetProcessOwner(process_id, &window, &info);
if (owner == OWNER_NATIVE_WINDOW) {
window->AppendExtraCommandLineSwitches(command_line);
} else if (owner == OWNER_GUEST_WEB_CONTENTS) {
command_line->AppendSwitchASCII(
switches::kGuestInstanceID, base::IntToString(info.guest_instance_id));
command_line->AppendSwitchASCII(
switches::kNodeIntegration, info.node_integration ? "true" : "false");
if (info.plugins)
command_line->AppendSwitch(switches::kEnablePlugins);
if (!info.preload_script.empty())
command_line->AppendSwitchPath(
switches::kPreloadScript, info.preload_script);
}
}
void AtomBrowserClient::DidCreatePpapiPlugin(
content::BrowserPpapiHost* host) {
auto command_line = base::CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(switches::kEnablePlugins)) {
host->GetPpapiHost()->AddHostFactoryFilter(
make_scoped_ptr(new chrome::ChromeBrowserPepperHostFactory(host)));
}
}
content::QuotaPermissionContext*
AtomBrowserClient::CreateQuotaPermissionContext() {
return new AtomQuotaPermissionContext;
}
void AtomBrowserClient::SelectClientCertificate(
content::WebContents* web_contents,
net::SSLCertRequestInfo* cert_request_info,
scoped_ptr<content::ClientCertificateDelegate> delegate) {
// --client-certificate=`path`
auto cmd = base::CommandLine::ForCurrentProcess();
if (cmd->HasSwitch(switches::kClientCertificate)) {
auto cert_path = cmd->GetSwitchValuePath(switches::kClientCertificate);
auto certificate = ImportCertFromFile(cert_path);
if (certificate.get())
delegate->ContinueWithCertificate(certificate.get());
return;
}
if (window != NULL) {
window->AppendExtraCommandLineSwitches(command_line, child_process_id);
} else {
// Append commnad line arguments for guest web view.
auto child_process = content::RenderProcessHost::FromID(child_process_id);
WebViewManager::WebViewInfo info;
if (WebViewManager::GetInfoForProcess(child_process, &info)) {
command_line->AppendSwitchASCII(
switches::kGuestInstanceID,
base::IntToString(info.guest_instance_id));
command_line->AppendSwitchASCII(
switches::kNodeIntegration,
info.node_integration ? "true" : "false");
if (info.plugins)
command_line->AppendSwitch(switches::kEnablePlugins);
if (!info.preload_script.empty())
command_line->AppendSwitchPath(
switches::kPreloadScript,
info.preload_script);
}
}
dying_render_process_ = NULL;
if (!cert_request_info->client_certs.empty())
Browser::Get()->ClientCertificateSelector(web_contents,
cert_request_info,
delegate.Pass());
}
brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts(

View File

@@ -6,44 +6,58 @@
#define ATOM_BROWSER_ATOM_BROWSER_CLIENT_H_
#include <string>
#include <vector>
#include "brightray/browser/browser_client.h"
namespace atom {
namespace content {
class QuotaPermissionContext;
class ClientCertificateDelegate;
}
class AtomResourceDispatcherHostDelegate;
namespace net {
class SSLCertRequestInfo;
}
namespace atom {
class AtomBrowserClient : public brightray::BrowserClient {
public:
AtomBrowserClient();
virtual ~AtomBrowserClient();
// Don't force renderer process to restart for once.
static void SuppressRendererProcessRestartForOnce();
// Custom schemes to be registered to standard.
static void SetCustomSchemes(const std::vector<std::string>& schemes);
protected:
// content::ContentBrowserClient:
void RenderProcessWillLaunch(content::RenderProcessHost* host) override;
content::SpeechRecognitionManagerDelegate*
CreateSpeechRecognitionManagerDelegate() override;
content::AccessTokenStore* CreateAccessTokenStore() override;
void ResourceDispatcherHostCreated() override;
void OverrideWebkitPrefs(content::RenderViewHost* render_view_host,
content::WebPreferences* prefs) override;
bool ShouldSwapBrowsingInstancesForNavigation(
content::SiteInstance* site_instance,
const GURL& current_url,
const GURL& new_url) override;
std::string GetApplicationLocale() override;
void OverrideSiteInstanceForNavigation(
content::BrowserContext* browser_context,
content::SiteInstance* current_instance,
const GURL& dest_url,
content::SiteInstance** new_instance) override;
void AppendExtraCommandLineSwitches(base::CommandLine* command_line,
int child_process_id) override;
void DidCreatePpapiPlugin(content::BrowserPpapiHost* browser_host) override;
content::QuotaPermissionContext* CreateQuotaPermissionContext() override;
void SelectClientCertificate(
content::WebContents* web_contents,
net::SSLCertRequestInfo* cert_request_info,
scoped_ptr<content::ClientCertificateDelegate> delegate) override;
private:
brightray::BrowserMainParts* OverrideCreateBrowserMainParts(
const content::MainFunctionParams&) override;
scoped_ptr<AtomResourceDispatcherHostDelegate> resource_dispatcher_delegate_;
// The render process which would be swapped out soon.
content::RenderProcessHost* dying_render_process_;
DISALLOW_COPY_AND_ASSIGN(AtomBrowserClient);
};

View File

@@ -5,18 +5,22 @@
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/atom_download_manager_delegate.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/web_view_manager.h"
#include "atom/common/options_switches.h"
#include "base/command_line.h"
#include "base/threading/sequenced_worker_pool.h"
#include "base/threading/worker_pool.h"
#include "chrome/browser/browser_process.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/url_constants.h"
#include "net/ftp/ftp_network_layer.h"
#include "net/url_request/data_protocol_handler.h"
#include "net/url_request/ftp_protocol_handler.h"
#include "net/url_request/url_request_intercepting_job_factory.h"
#include "net/url_request/url_request_context.h"
#include "url/url_constants.h"
using content::BrowserThread;
@@ -36,8 +40,7 @@ class NoCacheBackend : public net::HttpCache::BackendFactory {
} // namespace
AtomBrowserContext::AtomBrowserContext()
: fake_browser_process_(new BrowserProcess),
job_factory_(new AtomURLRequestJobFactory) {
: job_factory_(new AtomURLRequestJobFactory) {
}
AtomBrowserContext::~AtomBrowserContext() {
@@ -59,6 +62,21 @@ net::URLRequestJobFactory* AtomBrowserContext::CreateURLRequestJobFactory(
url::kFileScheme, new asar::AsarProtocolHandler(
BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)));
job_factory->SetProtocolHandler(
url::kHttpScheme, new HttpProtocolHandler(url::kHttpScheme));
job_factory->SetProtocolHandler(
url::kHttpsScheme, new HttpProtocolHandler(url::kHttpsScheme));
job_factory->SetProtocolHandler(
url::kWsScheme, new HttpProtocolHandler(url::kWsScheme));
job_factory->SetProtocolHandler(
url::kWssScheme, new HttpProtocolHandler(url::kWssScheme));
auto host_resolver = url_request_context_getter()
->GetURLRequestContext()
->host_resolver();
job_factory->SetProtocolHandler(
url::kFtpScheme, new net::FtpProtocolHandler(
new net::FtpNetworkLayer(host_resolver)));
// Set up interceptors in the reverse order.
scoped_ptr<net::URLRequestJobFactory> top_job_factory = job_factory.Pass();
@@ -81,16 +99,20 @@ AtomBrowserContext::CreateHttpCacheBackendFactory(
return brightray::BrowserContext::CreateHttpCacheBackendFactory(base_path);
}
content::DownloadManagerDelegate*
AtomBrowserContext::GetDownloadManagerDelegate() {
if (!download_manager_delegate_.get()) {
auto download_manager = content::BrowserContext::GetDownloadManager(this);
download_manager_delegate_.reset(
new AtomDownloadManagerDelegate(download_manager));
}
return download_manager_delegate_.get();
}
content::BrowserPluginGuestManager* AtomBrowserContext::GetGuestManager() {
if (!guest_manager_)
guest_manager_.reset(new WebViewManager(this));
return guest_manager_.get();
}
// static
AtomBrowserContext* AtomBrowserContext::Get() {
return static_cast<AtomBrowserContext*>(
AtomBrowserMainParts::Get()->browser_context());
}
} // namespace atom

View File

@@ -7,10 +7,9 @@
#include "brightray/browser/browser_context.h"
class BrowserProcess;
namespace atom {
class AtomDownloadManagerDelegate;
class AtomURLRequestJobFactory;
class WebViewManager;
@@ -19,9 +18,6 @@ class AtomBrowserContext : public brightray::BrowserContext {
AtomBrowserContext();
virtual ~AtomBrowserContext();
// Returns the browser context singleton.
static AtomBrowserContext* Get();
// brightray::URLRequestContextGetter::Delegate:
net::URLRequestJobFactory* CreateURLRequestJobFactory(
content::ProtocolHandlerMap* handlers,
@@ -30,13 +26,13 @@ class AtomBrowserContext : public brightray::BrowserContext {
const base::FilePath& base_path) override;
// content::BrowserContext:
content::DownloadManagerDelegate* GetDownloadManagerDelegate() override;
content::BrowserPluginGuestManager* GetGuestManager() override;
AtomURLRequestJobFactory* job_factory() const { return job_factory_; }
private:
// A fake BrowserProcess object that used to feed the source code from chrome.
scoped_ptr<BrowserProcess> fake_browser_process_;
scoped_ptr<AtomDownloadManagerDelegate> download_manager_delegate_;
scoped_ptr<WebViewManager> guest_manager_;
AtomURLRequestJobFactory* job_factory_; // Weak reference.

View File

@@ -4,6 +4,7 @@
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/api/trackable_object.h"
#include "atom/browser/atom_browser_client.h"
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/browser.h"
@@ -11,6 +12,7 @@
#include "atom/common/api/atom_bindings.h"
#include "atom/common/node_bindings.h"
#include "base/command_line.h"
#include "chrome/browser/browser_process.h"
#include "v8/include/v8-debug.h"
#if defined(USE_X11)
@@ -25,7 +27,8 @@ namespace atom {
AtomBrowserMainParts* AtomBrowserMainParts::self_ = NULL;
AtomBrowserMainParts::AtomBrowserMainParts()
: browser_(new Browser),
: fake_browser_process_(new BrowserProcess),
browser_(new Browser),
node_bindings_(NodeBindings::Create(true)),
atom_bindings_(new AtomBindings),
gc_timer_(true, true) {
@@ -34,6 +37,8 @@ AtomBrowserMainParts::AtomBrowserMainParts()
}
AtomBrowserMainParts::~AtomBrowserMainParts() {
for (const auto& callback : destruction_callbacks_)
callback.Run();
}
// static
@@ -42,6 +47,11 @@ AtomBrowserMainParts* AtomBrowserMainParts::Get() {
return self_;
}
void AtomBrowserMainParts::RegisterDestructionCallback(
const base::Closure& callback) {
destruction_callbacks_.push_back(callback);
}
brightray::BrowserContext* AtomBrowserMainParts::CreateBrowserContext() {
return new AtomBrowserContext();
}

View File

@@ -5,9 +5,14 @@
#ifndef ATOM_BROWSER_ATOM_BROWSER_MAIN_PARTS_H_
#define ATOM_BROWSER_ATOM_BROWSER_MAIN_PARTS_H_
#include <list>
#include "base/callback.h"
#include "base/timer/timer.h"
#include "brightray/browser/browser_main_parts.h"
class BrowserProcess;
namespace atom {
class AtomBindings;
@@ -22,6 +27,10 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
static AtomBrowserMainParts* Get();
// Register a callback that should be destroyed before JavaScript environment
// gets destroyed.
void RegisterDestructionCallback(const base::Closure& callback);
Browser* browser() { return browser_.get(); }
protected:
@@ -41,6 +50,9 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
void SetDPIFromGSettings();
#endif
// A fake BrowserProcess object that used to feed the source code from chrome.
scoped_ptr<BrowserProcess> fake_browser_process_;
scoped_ptr<Browser> browser_;
scoped_ptr<JavascriptEnvironment> js_env_;
scoped_ptr<NodeBindings> node_bindings_;
@@ -48,6 +60,9 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
base::Timer gc_timer_;
// List of callbacks should be executed before destroying JS env.
std::list<base::Closure> destruction_callbacks_;
static AtomBrowserMainParts* self_;
DISALLOW_COPY_AND_ASSIGN(AtomBrowserMainParts);

View File

@@ -0,0 +1,138 @@
// 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/atom_download_manager_delegate.h"
#include <string>
#include "atom/browser/native_window.h"
#include "atom/browser/ui/file_dialog.h"
#include "base/bind.h"
#include "base/files/file_util.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/download_manager.h"
#include "net/base/filename_util.h"
namespace atom {
AtomDownloadManagerDelegate::AtomDownloadManagerDelegate(
content::DownloadManager* manager)
: download_manager_(manager),
weak_ptr_factory_(this) {}
AtomDownloadManagerDelegate::~AtomDownloadManagerDelegate() {
if (download_manager_) {
DCHECK_EQ(static_cast<content::DownloadManagerDelegate*>(this),
download_manager_->GetDelegate());
download_manager_->SetDelegate(nullptr);
download_manager_ = nullptr;
}
}
void AtomDownloadManagerDelegate::CreateDownloadPath(
const GURL& url,
const std::string& content_disposition,
const std::string& suggested_filename,
const std::string& mime_type,
const base::FilePath& default_download_path,
const CreateDownloadPathCallback& callback) {
DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
auto generated_name = net::GenerateFileName(url,
content_disposition,
std::string(),
suggested_filename,
mime_type,
std::string());
if (!base::PathExists(default_download_path))
base::CreateDirectory(default_download_path);
base::FilePath path(default_download_path.Append(generated_name));
content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
base::Bind(callback, path));
}
void AtomDownloadManagerDelegate::OnDownloadPathGenerated(
uint32 download_id,
const content::DownloadTargetCallback& callback,
const base::FilePath& default_path) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
auto item = download_manager_->GetDownload(download_id);
if (!item)
return;
NativeWindow* window = nullptr;
auto relay = NativeWindowRelay::FromWebContents(item->GetWebContents());
if (relay)
window = relay->window.get();
file_dialog::Filters filters;
base::FilePath path;
if (!file_dialog::ShowSaveDialog(window, item->GetURL().spec(), default_path,
filters, &path)) {
return;
}
callback.Run(path,
content::DownloadItem::TARGET_DISPOSITION_PROMPT,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, path);
}
void AtomDownloadManagerDelegate::Shutdown() {
weak_ptr_factory_.InvalidateWeakPtrs();
download_manager_ = nullptr;
}
bool AtomDownloadManagerDelegate::DetermineDownloadTarget(
content::DownloadItem* download,
const content::DownloadTargetCallback& callback) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
if (default_download_path_.empty()) {
auto path = download_manager_->GetBrowserContext()->GetPath();
default_download_path_ = path.Append(FILE_PATH_LITERAL("Downloads"));
}
if (!download->GetForcedFilePath().empty()) {
callback.Run(download->GetForcedFilePath(),
content::DownloadItem::TARGET_DISPOSITION_OVERWRITE,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
download->GetForcedFilePath());
return true;
}
CreateDownloadPathCallback download_path_callback =
base::Bind(&AtomDownloadManagerDelegate::OnDownloadPathGenerated,
weak_ptr_factory_.GetWeakPtr(),
download->GetId(), callback);
content::BrowserThread::PostTask(
content::BrowserThread::FILE, FROM_HERE,
base::Bind(&AtomDownloadManagerDelegate::CreateDownloadPath,
weak_ptr_factory_.GetWeakPtr(),
download->GetURL(),
download->GetContentDisposition(),
download->GetSuggestedFilename(),
download->GetMimeType(),
default_download_path_,
download_path_callback));
return true;
}
bool AtomDownloadManagerDelegate::ShouldOpenDownload(
content::DownloadItem* download,
const content::DownloadOpenDelayedCallback& callback) {
return true;
}
void AtomDownloadManagerDelegate::GetNextId(
const content::DownloadIdCallback& callback) {
static uint32 next_id = content::DownloadItem::kInvalidId + 1;
callback.Run(next_id++);
}
} // namespace atom

View File

@@ -0,0 +1,58 @@
// 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_ATOM_DOWNLOAD_MANAGER_DELEGATE_H_
#define ATOM_BROWSER_ATOM_DOWNLOAD_MANAGER_DELEGATE_H_
#include <string>
#include "base/memory/weak_ptr.h"
#include "content/public/browser/download_manager_delegate.h"
namespace content {
class DownloadManager;
}
namespace atom {
class AtomDownloadManagerDelegate : public content::DownloadManagerDelegate {
public:
using CreateDownloadPathCallback =
base::Callback<void(const base::FilePath&)>;
explicit AtomDownloadManagerDelegate(content::DownloadManager* manager);
virtual ~AtomDownloadManagerDelegate();
// Generate default file path to save the download.
void CreateDownloadPath(const GURL& url,
const std::string& suggested_filename,
const std::string& content_disposition,
const std::string& mime_type,
const base::FilePath& path,
const CreateDownloadPathCallback& callback);
void OnDownloadPathGenerated(uint32 download_id,
const content::DownloadTargetCallback& callback,
const base::FilePath& default_path);
// content::DownloadManagerDelegate:
void Shutdown() override;
bool DetermineDownloadTarget(
content::DownloadItem* download,
const content::DownloadTargetCallback& callback) override;
bool ShouldOpenDownload(
content::DownloadItem* download,
const content::DownloadOpenDelayedCallback& callback) override;
void GetNextId(const content::DownloadIdCallback& callback) override;
private:
content::DownloadManager* download_manager_;
base::FilePath default_download_path_;
base::WeakPtrFactory<AtomDownloadManagerDelegate> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(AtomDownloadManagerDelegate);
};
} // namespace atom
#endif // ATOM_BROWSER_ATOM_DOWNLOAD_MANAGER_DELEGATE_H_

View File

@@ -27,7 +27,6 @@ void AtomJavaScriptDialogManager::RunBeforeUnloadDialog(
const base::string16& message_text,
bool is_reload,
const DialogClosedCallback& callback) {
bool prevent_reload = message_text.empty() ||
message_text == base::ASCIIToUTF16("false");
callback.Run(!prevent_reload, message_text);

View File

@@ -30,7 +30,7 @@ class AtomJavaScriptDialogManager : public content::JavaScriptDialogManager {
const DialogClosedCallback& callback) override;
void CancelActiveAndPendingDialogs(
content::WebContents* web_contents) override {}
void WebContentsDestroyed(content::WebContents* web_contents) override {}
void ResetDialogState(content::WebContents* web_contents) override {};
};
} // namespace atom

View File

@@ -0,0 +1,24 @@
// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/atom_quota_permission_context.h"
#include "storage/common/quota/quota_types.h"
namespace atom {
AtomQuotaPermissionContext::AtomQuotaPermissionContext() {
}
AtomQuotaPermissionContext::~AtomQuotaPermissionContext() {
}
void AtomQuotaPermissionContext::RequestQuotaPermission(
const content::StorageQuotaParams& params,
int render_process_id,
const PermissionCallback& callback) {
callback.Run(response::QUOTA_PERMISSION_RESPONSE_ALLOW);
}
} // namespace atom

View File

@@ -0,0 +1,31 @@
// 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_ATOM_QUOTA_PERMISSION_CONTEXT_H_
#define ATOM_BROWSER_ATOM_QUOTA_PERMISSION_CONTEXT_H_
#include "content/public/browser/quota_permission_context.h"
namespace atom {
class AtomQuotaPermissionContext : public content::QuotaPermissionContext {
public:
typedef content::QuotaPermissionContext::QuotaPermissionResponse response;
AtomQuotaPermissionContext();
virtual ~AtomQuotaPermissionContext();
// content::QuotaPermissionContext:
void RequestQuotaPermission(
const content::StorageQuotaParams& params,
int render_process_id,
const PermissionCallback& callback) override;
private:
DISALLOW_COPY_AND_ASSIGN(AtomQuotaPermissionContext);
};
} // namespace atom
#endif // ATOM_BROWSER_ATOM_QUOTA_PERMISSION_CONTEXT_H_

View File

@@ -1,33 +0,0 @@
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/atom_resource_dispatcher_host_delegate.h"
#include <string>
#include "base/logging.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/resource_request_info.h"
#include "net/http/http_response_headers.h"
#include "net/url_request/url_request.h"
namespace atom {
AtomResourceDispatcherHostDelegate::AtomResourceDispatcherHostDelegate() {
}
void AtomResourceDispatcherHostDelegate::OnResponseStarted(
net::URLRequest* request,
content::ResourceContext* resource_context,
content::ResourceResponse* response,
IPC::Sender* sender) {
// Remove the "X-Frame-Options" from response headers for devtools.
if (request->url().SchemeIs("chrome-devtools")) {
net::HttpResponseHeaders* response_headers = request->response_headers();
if (response_headers && response_headers->HasHeader("x-frame-options"))
response_headers->RemoveHeader("x-frame-options");
}
}
} // namespace atom

View File

@@ -1,30 +0,0 @@
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_ATOM_RESOURCE_DISPATCHER_HOST_DELEGATE_H_
#define ATOM_BROWSER_ATOM_RESOURCE_DISPATCHER_HOST_DELEGATE_H_
#include "base/compiler_specific.h"
#include "content/public/browser/resource_dispatcher_host_delegate.h"
namespace atom {
class AtomResourceDispatcherHostDelegate
: public content::ResourceDispatcherHostDelegate {
public:
AtomResourceDispatcherHostDelegate();
// content::ResourceDispatcherHostDelegate:
void OnResponseStarted(net::URLRequest* request,
content::ResourceContext* resource_context,
content::ResourceResponse* response,
IPC::Sender* sender) override;
private:
DISALLOW_COPY_AND_ASSIGN(AtomResourceDispatcherHostDelegate);
};
} // namespace atom
#endif // ATOM_BROWSER_ATOM_RESOURCE_DISPATCHER_HOST_DELEGATE_H_

View File

@@ -9,6 +9,8 @@
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/window_list.h"
#include "base/message_loop/message_loop.h"
#include "content/public/browser/client_certificate_delegate.h"
#include "net/ssl/ssl_cert_request_info.h"
namespace atom {
@@ -104,6 +106,17 @@ void Browser::DidFinishLaunching() {
FOR_EACH_OBSERVER(BrowserObserver, observers_, OnFinishLaunching());
}
void Browser::ClientCertificateSelector(
content::WebContents* web_contents,
net::SSLCertRequestInfo* cert_request_info,
scoped_ptr<content::ClientCertificateDelegate> delegate) {
FOR_EACH_OBSERVER(BrowserObserver,
observers_,
OnSelectCertificate(web_contents,
cert_request_info,
delegate.Pass()));
}
void Browser::NotifyAndShutdown() {
bool prevent_default = false;
FOR_EACH_OBSERVER(BrowserObserver, observers_, OnWillQuit(&prevent_default));

View File

@@ -115,6 +115,12 @@ class Browser : public WindowListObserver {
void WillFinishLaunching();
void DidFinishLaunching();
// Called when client certificate is required.
void ClientCertificateSelector(
content::WebContents* web_contents,
net::SSLCertRequestInfo* cert_request_info,
scoped_ptr<content::ClientCertificateDelegate> delegate);
void AddObserver(BrowserObserver* obs) {
observers_.AddObserver(obs);
}

View File

@@ -7,6 +7,17 @@
#include <string>
#include "base/memory/scoped_ptr.h"
#include "content/public/browser/client_certificate_delegate.h"
namespace content {
class WebContents;
}
namespace net {
class SSLCertRequestInfo;
}
namespace atom {
class BrowserObserver {
@@ -40,6 +51,12 @@ class BrowserObserver {
virtual void OnWillFinishLaunching() {}
virtual void OnFinishLaunching() {}
// The browser requires client certificate.
virtual void OnSelectCertificate(
content::WebContents* web_contents,
net::SSLCertRequestInfo* cert_request_info,
scoped_ptr<content::ClientCertificateDelegate> delegate) {}
protected:
virtual ~BrowserObserver() {}
};

View File

@@ -0,0 +1,372 @@
// 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/common_web_contents_delegate.h"
#include <string>
#include <vector>
#include "atom/browser/atom_javascript_dialog_manager.h"
#include "atom/browser/native_window.h"
#include "atom/browser/ui/file_dialog.h"
#include "atom/browser/web_dialog_helper.h"
#include "base/files/file_util.h"
#include "chrome/browser/printing/print_preview_message_handler.h"
#include "chrome/browser/printing/print_view_manager_basic.h"
#include "chrome/browser/ui/browser_dialogs.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "storage/browser/fileapi/isolated_context.h"
using content::BrowserThread;
namespace atom {
namespace {
struct FileSystem {
FileSystem() {
}
FileSystem(const std::string& file_system_name,
const std::string& root_url,
const std::string& file_system_path)
: file_system_name(file_system_name),
root_url(root_url),
file_system_path(file_system_path) {
}
std::string file_system_name;
std::string root_url;
std::string file_system_path;
};
std::string RegisterFileSystem(content::WebContents* web_contents,
const base::FilePath& path,
std::string* registered_name) {
auto isolated_context = storage::IsolatedContext::GetInstance();
std::string file_system_id = isolated_context->RegisterFileSystemForPath(
storage::kFileSystemTypeNativeLocal,
std::string(),
path,
registered_name);
content::ChildProcessSecurityPolicy* policy =
content::ChildProcessSecurityPolicy::GetInstance();
content::RenderViewHost* render_view_host = web_contents->GetRenderViewHost();
int renderer_id = render_view_host->GetProcess()->GetID();
policy->GrantReadFileSystem(renderer_id, file_system_id);
policy->GrantWriteFileSystem(renderer_id, file_system_id);
policy->GrantCreateFileForFileSystem(renderer_id, file_system_id);
policy->GrantDeleteFromFileSystem(renderer_id, file_system_id);
if (!policy->CanReadFile(renderer_id, path))
policy->GrantReadFile(renderer_id, path);
return file_system_id;
}
FileSystem CreateFileSystemStruct(
content::WebContents* web_contents,
const std::string& file_system_id,
const std::string& registered_name,
const std::string& file_system_path) {
const GURL origin = web_contents->GetURL().GetOrigin();
std::string file_system_name =
storage::GetIsolatedFileSystemName(origin, file_system_id);
std::string root_url = storage::GetIsolatedFileSystemRootURIString(
origin, file_system_id, registered_name);
return FileSystem(file_system_name, root_url, file_system_path);
}
base::DictionaryValue* CreateFileSystemValue(const FileSystem& file_system) {
base::DictionaryValue* file_system_value = new base::DictionaryValue();
file_system_value->SetString("fileSystemName", file_system.file_system_name);
file_system_value->SetString("rootURL", file_system.root_url);
file_system_value->SetString("fileSystemPath", file_system.file_system_path);
return file_system_value;
}
void WriteToFile(const base::FilePath& path,
const std::string& content) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(!path.empty());
base::WriteFile(path, content.data(), content.size());
}
void AppendToFile(const base::FilePath& path,
const std::string& content) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(!path.empty());
base::AppendToFile(path, content.data(), content.size());
}
} // namespace
CommonWebContentsDelegate::CommonWebContentsDelegate()
: html_fullscreen_(false),
native_fullscreen_(false) {
}
CommonWebContentsDelegate::~CommonWebContentsDelegate() {
}
void CommonWebContentsDelegate::InitWithWebContents(
content::WebContents* web_contents) {
web_contents->SetDelegate(this);
printing::PrintViewManagerBasic::CreateForWebContents(web_contents);
printing::PrintPreviewMessageHandler::CreateForWebContents(web_contents);
// Create InspectableWebContents.
web_contents_.reset(brightray::InspectableWebContents::Create(web_contents));
web_contents_->SetDelegate(this);
}
void CommonWebContentsDelegate::SetOwnerWindow(NativeWindow* owner_window) {
content::WebContents* web_contents = GetWebContents();
owner_window_ = owner_window->GetWeakPtr();
NativeWindowRelay* relay = new NativeWindowRelay(owner_window_);
web_contents->SetUserData(relay->key, relay);
}
void CommonWebContentsDelegate::DestroyWebContents() {
web_contents_.reset();
}
content::WebContents* CommonWebContentsDelegate::GetWebContents() const {
if (!web_contents_)
return nullptr;
return web_contents_->GetWebContents();
}
content::WebContents*
CommonWebContentsDelegate::GetDevToolsWebContents() const {
if (!web_contents_)
return nullptr;
return web_contents_->GetDevToolsWebContents();
}
content::WebContents* CommonWebContentsDelegate::OpenURLFromTab(
content::WebContents* source,
const content::OpenURLParams& params) {
content::NavigationController::LoadURLParams load_url_params(params.url);
load_url_params.referrer = params.referrer;
load_url_params.transition_type = params.transition;
load_url_params.extra_headers = params.extra_headers;
load_url_params.should_replace_current_entry =
params.should_replace_current_entry;
load_url_params.is_renderer_initiated = params.is_renderer_initiated;
load_url_params.transferred_global_request_id =
params.transferred_global_request_id;
load_url_params.should_clear_history_list = true;
source->GetController().LoadURLWithParams(load_url_params);
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;
}
content::JavaScriptDialogManager*
CommonWebContentsDelegate::GetJavaScriptDialogManager(
content::WebContents* source) {
if (!dialog_manager_)
dialog_manager_.reset(new AtomJavaScriptDialogManager);
return dialog_manager_.get();
}
content::ColorChooser* CommonWebContentsDelegate::OpenColorChooser(
content::WebContents* web_contents,
SkColor color,
const std::vector<content::ColorSuggestion>& suggestions) {
return chrome::ShowColorChooser(web_contents, color);
}
void CommonWebContentsDelegate::RunFileChooser(
content::WebContents* guest,
const content::FileChooserParams& params) {
if (!web_dialog_helper_)
web_dialog_helper_.reset(new WebDialogHelper(owner_window()));
web_dialog_helper_->RunFileChooser(guest, params);
}
void CommonWebContentsDelegate::EnumerateDirectory(content::WebContents* guest,
int request_id,
const base::FilePath& path) {
if (!web_dialog_helper_)
web_dialog_helper_.reset(new WebDialogHelper(owner_window()));
web_dialog_helper_->EnumerateDirectory(guest, request_id, path);
}
void CommonWebContentsDelegate::EnterFullscreenModeForTab(
content::WebContents* source, const GURL& origin) {
if (!owner_window_)
return;
SetHtmlApiFullscreen(true);
owner_window_->NotifyWindowEnterHtmlFullScreen();
source->GetRenderViewHost()->WasResized();
}
void CommonWebContentsDelegate::ExitFullscreenModeForTab(
content::WebContents* source) {
if (!owner_window_)
return;
SetHtmlApiFullscreen(false);
owner_window_->NotifyWindowLeaveHtmlFullScreen();
source->GetRenderViewHost()->WasResized();
}
bool CommonWebContentsDelegate::IsFullscreenForTabOrPending(
const content::WebContents* source) const {
return html_fullscreen_;
}
void CommonWebContentsDelegate::DevToolsSaveToFile(
const std::string& url, const std::string& content, bool save_as) {
base::FilePath path;
PathsMap::iterator it = saved_files_.find(url);
if (it != saved_files_.end() && !save_as) {
path = it->second;
} else {
file_dialog::Filters filters;
base::FilePath default_path(base::FilePath::FromUTF8Unsafe(url));
if (!file_dialog::ShowSaveDialog(owner_window(), url, default_path,
filters, &path)) {
base::StringValue url_value(url);
web_contents_->CallClientFunction(
"DevToolsAPI.canceledSaveURL", &url_value, nullptr, nullptr);
return;
}
}
saved_files_[url] = path;
BrowserThread::PostTaskAndReply(
BrowserThread::FILE, FROM_HERE,
base::Bind(&WriteToFile, path, content),
base::Bind(&CommonWebContentsDelegate::OnDevToolsSaveToFile,
base::Unretained(this), url));
}
void CommonWebContentsDelegate::DevToolsAppendToFile(
const std::string& url, const std::string& content) {
PathsMap::iterator it = saved_files_.find(url);
if (it == saved_files_.end())
return;
BrowserThread::PostTaskAndReply(
BrowserThread::FILE, FROM_HERE,
base::Bind(&AppendToFile, it->second, content),
base::Bind(&CommonWebContentsDelegate::OnDevToolsAppendToFile,
base::Unretained(this), url));
}
void CommonWebContentsDelegate::DevToolsAddFileSystem() {
file_dialog::Filters filters;
base::FilePath default_path;
std::vector<base::FilePath> paths;
int flag = file_dialog::FILE_DIALOG_OPEN_DIRECTORY;
if (!file_dialog::ShowOpenDialog(owner_window(), "", default_path,
filters, flag, &paths))
return;
base::FilePath path = paths[0];
std::string registered_name;
std::string file_system_id = RegisterFileSystem(GetDevToolsWebContents(),
path,
&registered_name);
WorkspaceMap::iterator it = saved_paths_.find(file_system_id);
if (it != saved_paths_.end())
return;
saved_paths_[file_system_id] = path;
FileSystem file_system = CreateFileSystemStruct(GetDevToolsWebContents(),
file_system_id,
registered_name,
path.AsUTF8Unsafe());
scoped_ptr<base::StringValue> error_string_value(
new base::StringValue(std::string()));
scoped_ptr<base::DictionaryValue> file_system_value;
if (!file_system.file_system_path.empty())
file_system_value.reset(CreateFileSystemValue(file_system));
web_contents_->CallClientFunction(
"DevToolsAPI.fileSystemAdded",
error_string_value.get(),
file_system_value.get(),
nullptr);
}
void CommonWebContentsDelegate::DevToolsRemoveFileSystem(
const std::string& file_system_path) {
if (!web_contents_)
return;
base::FilePath path = base::FilePath::FromUTF8Unsafe(file_system_path);
storage::IsolatedContext::GetInstance()->RevokeFileSystemByPath(path);
for (auto it = saved_paths_.begin(); it != saved_paths_.end(); ++it)
if (it->second == path) {
saved_paths_.erase(it);
break;
}
base::StringValue file_system_path_value(file_system_path);
web_contents_->CallClientFunction(
"DevToolsAPI.fileSystemRemoved",
&file_system_path_value,
nullptr,
nullptr);
}
void CommonWebContentsDelegate::OnDevToolsSaveToFile(
const std::string& url) {
// Notify DevTools.
base::StringValue url_value(url);
web_contents_->CallClientFunction(
"DevToolsAPI.savedURL", &url_value, nullptr, nullptr);
}
void CommonWebContentsDelegate::OnDevToolsAppendToFile(
const std::string& url) {
// Notify DevTools.
base::StringValue url_value(url);
web_contents_->CallClientFunction(
"DevToolsAPI.appendedToURL", &url_value, nullptr, nullptr);
}
void CommonWebContentsDelegate::SetHtmlApiFullscreen(bool enter_fullscreen) {
// Window is already in fullscreen mode, save the state.
if (enter_fullscreen && owner_window_->IsFullscreen()) {
native_fullscreen_ = true;
html_fullscreen_ = true;
return;
}
// Exit html fullscreen state but not window's fullscreen mode.
if (!enter_fullscreen && native_fullscreen_) {
html_fullscreen_ = false;
return;
}
owner_window_->SetFullScreen(enter_fullscreen);
html_fullscreen_ = enter_fullscreen;
native_fullscreen_ = false;
}
} // namespace atom

View File

@@ -0,0 +1,128 @@
// 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_COMMON_WEB_CONTENTS_DELEGATE_H_
#define ATOM_BROWSER_COMMON_WEB_CONTENTS_DELEGATE_H_
#include <map>
#include <string>
#include <vector>
#include "brightray/browser/default_web_contents_delegate.h"
#include "brightray/browser/inspectable_web_contents_impl.h"
#include "brightray/browser/inspectable_web_contents_delegate.h"
namespace atom {
class AtomJavaScriptDialogManager;
class NativeWindow;
class WebDialogHelper;
class CommonWebContentsDelegate
: public brightray::DefaultWebContentsDelegate,
public brightray::InspectableWebContentsDelegate {
public:
CommonWebContentsDelegate();
virtual ~CommonWebContentsDelegate();
// Creates a InspectableWebContents object and takes onwership of
// |web_contents|.
void InitWithWebContents(content::WebContents* web_contents);
// Set the window as owner window.
void SetOwnerWindow(NativeWindow* owner_window);
// Destroy the managed InspectableWebContents object.
void DestroyWebContents();
// Returns the WebContents managed by this delegate.
content::WebContents* GetWebContents() const;
// Returns the WebContents of devtools.
content::WebContents* GetDevToolsWebContents() const;
brightray::InspectableWebContents* managed_web_contents() const {
return web_contents_.get();
}
NativeWindow* owner_window() const { return owner_window_.get(); }
protected:
// content::WebContentsDelegate:
content::WebContents* OpenURLFromTab(
content::WebContents* source,
const content::OpenURLParams& params) override;
void RequestToLockMouse(content::WebContents* web_contents,
bool user_gesture,
bool last_unlocked_by_target) override;
bool CanOverscrollContent() const override;
content::JavaScriptDialogManager* GetJavaScriptDialogManager(
content::WebContents* source) override;
content::ColorChooser* OpenColorChooser(
content::WebContents* web_contents,
SkColor color,
const std::vector<content::ColorSuggestion>& suggestions) override;
void RunFileChooser(content::WebContents* web_contents,
const content::FileChooserParams& params) override;
void EnumerateDirectory(content::WebContents* web_contents,
int request_id,
const base::FilePath& path) override;
void EnterFullscreenModeForTab(content::WebContents* source,
const GURL& origin) override;
void ExitFullscreenModeForTab(content::WebContents* source) override;
bool IsFullscreenForTabOrPending(
const content::WebContents* source) const override;
// brightray::InspectableWebContentsDelegate:
void DevToolsSaveToFile(const std::string& url,
const std::string& content,
bool save_as) override;
void DevToolsAppendToFile(const std::string& url,
const std::string& content) override;
void DevToolsAddFileSystem() override;
void DevToolsRemoveFileSystem(const std::string& file_system_path) override;
private:
// Callback for when DevToolsSaveToFile has completed.
void OnDevToolsSaveToFile(const std::string& url);
// Callback for when DevToolsAppendToFile has completed.
void OnDevToolsAppendToFile(const std::string& url);
// Set fullscreen mode triggered by html api.
void SetHtmlApiFullscreen(bool enter_fullscreen);
// The window that this WebContents belongs to.
base::WeakPtr<NativeWindow> owner_window_;
// Whether window is fullscreened by HTML5 api.
bool html_fullscreen_;
// Whether window is fullscreened by window api.
bool native_fullscreen_;
scoped_ptr<WebDialogHelper> web_dialog_helper_;
scoped_ptr<AtomJavaScriptDialogManager> dialog_manager_;
// The stored InspectableWebContents object.
// Notice that web_contents_ must be placed after dialog_manager_, so we can
// make sure web_contents_ is destroyed before dialog_manager_, otherwise a
// crash would happen.
scoped_ptr<brightray::InspectableWebContents> web_contents_;
// Maps url to file path, used by the file requests sent from devtools.
typedef std::map<std::string, base::FilePath> PathsMap;
PathsMap saved_files_;
// Maps file system id to file path, used by the file system requests
// sent from devtools.
typedef std::map<std::string, base::FilePath> WorkspaceMap;
WorkspaceMap saved_paths_;
DISALLOW_COPY_AND_ASSIGN(CommonWebContentsDelegate);
};
} // namespace atom
#endif // ATOM_BROWSER_COMMON_WEB_CONTENTS_DELEGATE_H_

View File

@@ -1,10 +1,7 @@
var app = require('app');
var Menu = require('menu');
var MenuItem = require('menu-item');
var BrowserWindow = require('browser-window');
var mainWindow = null;
var menu = null;
// Quit when all windows are closed.
app.on('window-all-closed', function() {
@@ -15,177 +12,9 @@ app.on('ready', function() {
mainWindow = new BrowserWindow({
width: 800,
height: 600,
resizable: false,
'auto-hide-menu-bar': true,
'use-content-size': true,
});
mainWindow.loadUrl('file://' + __dirname + '/index.html');
mainWindow.focus();
if (process.platform == 'darwin') {
var template = [
{
label: 'Electron',
submenu: [
{
label: 'About Electron',
selector: 'orderFrontStandardAboutPanel:'
},
{
type: 'separator'
},
{
label: 'Services',
submenu: []
},
{
type: 'separator'
},
{
label: 'Hide Electron',
accelerator: 'Command+H',
selector: 'hide:'
},
{
label: 'Hide Others',
accelerator: 'Command+Shift+H',
selector: 'hideOtherApplications:'
},
{
label: 'Show All',
selector: 'unhideAllApplications:'
},
{
type: 'separator'
},
{
label: 'Quit',
accelerator: 'Command+Q',
click: function() { app.quit(); }
},
]
},
{
label: 'Edit',
submenu: [
{
label: 'Undo',
accelerator: 'Command+Z',
selector: 'undo:'
},
{
label: 'Redo',
accelerator: 'Shift+Command+Z',
selector: 'redo:'
},
{
type: 'separator'
},
{
label: 'Cut',
accelerator: 'Command+X',
selector: 'cut:'
},
{
label: 'Copy',
accelerator: 'Command+C',
selector: 'copy:'
},
{
label: 'Paste',
accelerator: 'Command+V',
selector: 'paste:'
},
{
label: 'Select All',
accelerator: 'Command+A',
selector: 'selectAll:'
},
]
},
{
label: 'View',
submenu: [
{
label: 'Reload',
accelerator: 'Command+R',
click: function() { mainWindow.restart(); }
},
{
label: 'Enter Fullscreen',
click: function() { mainWindow.setFullScreen(true); }
},
{
label: 'Toggle DevTools',
accelerator: 'Alt+Command+I',
click: function() { mainWindow.toggleDevTools(); }
},
]
},
{
label: 'Window',
submenu: [
{
label: 'Minimize',
accelerator: 'Command+M',
selector: 'performMiniaturize:'
},
{
label: 'Close',
accelerator: 'Command+W',
selector: 'performClose:'
},
{
type: 'separator'
},
{
label: 'Bring All to Front',
selector: 'arrangeInFront:'
},
]
},
];
menu = Menu.buildFromTemplate(template);
Menu.setApplicationMenu(menu);
} else {
var template = [
{
label: '&File',
submenu: [
{
label: '&Open',
accelerator: 'Ctrl+O',
},
{
label: '&Close',
accelerator: 'Ctrl+W',
click: function() { mainWindow.close(); }
},
]
},
{
label: '&View',
submenu: [
{
label: '&Reload',
accelerator: 'Ctrl+R',
click: function() { mainWindow.restart(); }
},
{
label: '&Enter Fullscreen',
click: function() { mainWindow.setFullScreen(true); }
},
{
label: '&Toggle DevTools',
accelerator: 'Alt+Ctrl+I',
click: function() { mainWindow.toggleDevTools(); }
},
]
},
];
menu = Menu.buildFromTemplate(template);
mainWindow.setMenu(menu);
}
});

View File

@@ -2,6 +2,8 @@ var app = require('app');
var dialog = require('dialog');
var fs = require('fs');
var path = require('path');
var Menu = require('menu');
var BrowserWindow = require('browser-window');
// Quit when all windows are closed and no other one is listening to this.
app.on('window-all-closed', function() {
@@ -11,11 +13,14 @@ app.on('window-all-closed', function() {
// Parse command line options.
var argv = process.argv.slice(1);
var option = { file: null, version: null, webdriver: null };
var option = { file: null, help: null, version: null, webdriver: null };
for (var i in argv) {
if (argv[i] == '--version' || argv[i] == '-v') {
option.version = true;
break;
} else if (argv[i] == '--help' || argv[i] == '-h') {
option.help = true;
break;
} else if (argv[i] == '--test-type=webdriver') {
option.webdriver = true;
} else if (argv[i][0] == '-') {
@@ -26,6 +31,249 @@ for (var i in argv) {
}
}
// Create default menu.
app.once('ready', function() {
if (Menu.getApplicationMenu())
return;
var template;
if (process.platform == 'darwin') {
template = [
{
label: 'Electron',
submenu: [
{
label: 'About Electron',
selector: 'orderFrontStandardAboutPanel:'
},
{
type: 'separator'
},
{
label: 'Services',
submenu: []
},
{
type: 'separator'
},
{
label: 'Hide Electron',
accelerator: 'Command+H',
selector: 'hide:'
},
{
label: 'Hide Others',
accelerator: 'Command+Shift+H',
selector: 'hideOtherApplications:'
},
{
label: 'Show All',
selector: 'unhideAllApplications:'
},
{
type: 'separator'
},
{
label: 'Quit',
accelerator: 'Command+Q',
click: function() { app.quit(); }
},
]
},
{
label: 'Edit',
submenu: [
{
label: 'Undo',
accelerator: 'Command+Z',
selector: 'undo:'
},
{
label: 'Redo',
accelerator: 'Shift+Command+Z',
selector: 'redo:'
},
{
type: 'separator'
},
{
label: 'Cut',
accelerator: 'Command+X',
selector: 'cut:'
},
{
label: 'Copy',
accelerator: 'Command+C',
selector: 'copy:'
},
{
label: 'Paste',
accelerator: 'Command+V',
selector: 'paste:'
},
{
label: 'Select All',
accelerator: 'Command+A',
selector: 'selectAll:'
},
]
},
{
label: 'View',
submenu: [
{
label: 'Reload',
accelerator: 'Command+R',
click: function() {
var focusedWindow = BrowserWindow.getFocusedWindow();
if (focusedWindow)
focusedWindow.reload();
}
},
{
label: 'Toggle Full Screen',
accelerator: 'Ctrl+Command+F',
click: function() {
var focusedWindow = BrowserWindow.getFocusedWindow();
if (focusedWindow)
focusedWindow.setFullScreen(!focusedWindow.isFullScreen());
}
},
{
label: 'Toggle Developer Tools',
accelerator: 'Alt+Command+I',
click: function() {
var focusedWindow = BrowserWindow.getFocusedWindow();
if (focusedWindow)
focusedWindow.toggleDevTools();
}
},
]
},
{
label: 'Window',
submenu: [
{
label: 'Minimize',
accelerator: 'Command+M',
selector: 'performMiniaturize:'
},
{
label: 'Close',
accelerator: 'Command+W',
selector: 'performClose:'
},
{
type: 'separator'
},
{
label: 'Bring All to Front',
selector: 'arrangeInFront:'
},
]
},
{
label: 'Help',
submenu: [
{
label: 'Learn More',
click: function() { require('shell').openExternal('http://electron.atom.io') }
},
{
label: 'Documentation',
click: function() { require('shell').openExternal('https://github.com/atom/electron/tree/master/docs#readme') }
},
{
label: 'Community Discussions',
click: function() { require('shell').openExternal('https://discuss.atom.io/c/electron') }
},
{
label: 'Search Issues',
click: function() { require('shell').openExternal('https://github.com/atom/electron/issues') }
}
]
}
];
} else {
template = [
{
label: '&File',
submenu: [
{
label: '&Open',
accelerator: 'Ctrl+O',
},
{
label: '&Close',
accelerator: 'Ctrl+W',
click: function() {
var focusedWindow = BrowserWindow.getFocusedWindow();
if (focusedWindow)
focusedWindow.close();
}
},
]
},
{
label: '&View',
submenu: [
{
label: '&Reload',
accelerator: 'Ctrl+R',
click: function() {
var focusedWindow = BrowserWindow.getFocusedWindow();
if (focusedWindow)
focusedWindow.reload();
}
},
{
label: 'Toggle &Full Screen',
accelerator: 'F11',
click: function() {
var focusedWindow = BrowserWindow.getFocusedWindow();
if (focusedWindow)
focusedWindow.setFullScreen(!focusedWindow.isFullScreen());
}
},
{
label: 'Toggle &Developer Tools',
accelerator: 'Alt+Ctrl+I',
click: function() {
var focusedWindow = BrowserWindow.getFocusedWindow();
if (focusedWindow)
focusedWindow.toggleDevTools();
}
},
]
},
{
label: 'Help',
submenu: [
{
label: 'Learn More',
click: function() { require('shell').openExternal('http://electron.atom.io') }
},
{
label: 'Documentation',
click: function() { require('shell').openExternal('https://github.com/atom/electron/tree/master/docs#readme') }
},
{
label: 'Community Discussions',
click: function() { require('shell').openExternal('https://discuss.atom.io/c/electron') }
},
{
label: 'Search Issues',
click: function() { require('shell').openExternal('https://github.com/atom/electron/issues') }
}
]
}
];
}
var menu = Menu.buildFromTemplate(template);
Menu.setApplicationMenu(menu);
});
// Start the specified app if there is one specified in command line, otherwise
// start the default app.
if (option.file && !option.webdriver) {
@@ -50,7 +298,7 @@ if (option.file && !option.webdriver) {
} catch(e) {
if (e.code == 'MODULE_NOT_FOUND') {
app.focus();
dialog.showErrorBox('Error opening app', 'The app provided is not a valid electron app, please read the docs on how to write one:\nhttps://github.com/atom/electron/tree/master/docs');
dialog.showErrorBox('Error opening app', 'The app provided is not a valid electron app, please read the docs on how to write one:\nhttps://github.com/atom/electron/tree/master/docs\n\n' + e.toString());
process.exit(1);
} else {
console.error('App threw an error when running', e);
@@ -58,7 +306,17 @@ if (option.file && !option.webdriver) {
}
}
} else if (option.version) {
console.log('v' + process.versions['electron']);
console.log('v' + process.versions.electron);
process.exit(0);
} else if (option.help) {
var helpMessage = "Electron v" + process.versions.electron + " - Cross Platform Desktop Application Shell\n\n";
helpMessage += "Usage: electron [options] [path]\n\n";
helpMessage += "A path to an Electron application may be specified. The path must be to \n";
helpMessage += "an index.js file or to a folder containing a package.json or index.js file.\n\n";
helpMessage += "Options:\n";
helpMessage += " -h, --help Print this usage message.\n";
helpMessage += " -v, --version Print the version.";
console.log(helpMessage);
process.exit(0);
} else {
require('./default_app.js');

View File

@@ -4,10 +4,13 @@
#include "atom/browser/javascript_environment.h"
#include "gin/array_buffer.h"
namespace atom {
JavascriptEnvironment::JavascriptEnvironment()
: isolate_(isolate_holder_.isolate()),
: initialized_(Initialize()),
isolate_(isolate_holder_.isolate()),
isolate_scope_(isolate_),
locker_(isolate_),
handle_scope_(isolate_),
@@ -15,4 +18,11 @@ JavascriptEnvironment::JavascriptEnvironment()
context_scope_(v8::Local<v8::Context>::New(isolate_, context_)) {
}
bool JavascriptEnvironment::Initialize() {
gin::IsolateHolder::LoadV8Snapshot();
gin::IsolateHolder::Initialize(gin::IsolateHolder::kNonStrictMode,
gin::ArrayBufferAllocator::SharedInstance());
return true;
}
} // namespace atom

View File

@@ -20,6 +20,9 @@ class JavascriptEnvironment {
}
private:
bool Initialize();
bool initialized_;
gin::IsolateHolder isolate_holder_;
v8::Isolate* isolate_;
v8::Isolate::Scope isolate_scope_;

View File

@@ -10,12 +10,18 @@ supportedWebViewEvents = [
'did-stop-loading'
'did-get-response-details'
'did-get-redirect-request'
'dom-ready'
'console-message'
'new-window'
'close'
'crashed'
'gpu-crashed'
'plugin-crashed'
'destroyed'
'page-title-set'
'page-favicon-updated'
'enter-html-full-screen'
'leave-html-full-screen'
]
nextInstanceId = 0
@@ -32,10 +38,7 @@ createGuest = (embedder, params) ->
webViewManager ?= process.atomBinding 'web_view_manager'
id = getNextInstanceId embedder
guest = webContents.create
isGuest: true
guestInstanceId: id
storagePartitionId: params.storagePartitionId
guest = webContents.create {isGuest: true, embedder}
guestInstances[id] = {guest, embedder}
# Destroy guest when the embedder is gone or navigated.
@@ -52,14 +55,21 @@ createGuest = (embedder, params) ->
delete @attachParams
@viewInstanceId = params.instanceId
min = width: params.minwidth, height: params.minheight
max = width: params.maxwidth, height: params.maxheight
@setAutoSize params.autosize, min, max
@setSize
normal:
width: params.elementWidth, height: params.elementHeight
enableAutoSize: params.autosize
min:
width: params.minwidth, height: params.minheight
max:
width: params.maxwidth, height: params.maxheight
if params.src
if params.httpreferrer
@loadUrl params.src, {httpreferrer: params.httpreferrer}
else
@loadUrl params.src
opts = {}
opts.httpReferrer = params.httpreferrer if params.httpreferrer
opts.userAgent = params.useragent if params.useragent
@loadUrl params.src, opts
if params.allowtransparency?
@setAllowTransparency params.allowtransparency
@@ -115,7 +125,7 @@ destroyGuest = (embedder, id) ->
delete reverseEmbedderElementsMap[id]
delete embedderElementsMap[key]
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_CREATE_GUEST', (event, type, params, requestId) ->
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_CREATE_GUEST', (event, params, requestId) ->
event.sender.send "ATOM_SHELL_RESPONSE_#{requestId}", createGuest(event.sender, params)
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_ATTACH_GUEST', (event, elementInstanceId, guestInstanceId, params) ->
@@ -124,8 +134,8 @@ ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_ATTACH_GUEST', (event, elementInstanceId,
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_DESTROY_GUEST', (event, id) ->
destroyGuest event.sender, id
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_SET_AUTO_SIZE', (event, id, params) ->
guestInstances[id]?.guest.setAutoSize params.enableAutoSize, params.min, params.max
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_SET_SIZE', (event, id, params) ->
guestInstances[id]?.guest.setSize params
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_SET_ALLOW_TRANSPARENCY', (event, id, allowtransparency) ->
guestInstances[id]?.guest.setAllowTransparency allowtransparency

View File

@@ -41,24 +41,21 @@ createGuest = (embedder, url, frameName, options) ->
# Routed window.open messages.
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPEN', (event, args...) ->
[url, frameName, options] = args
event.sender.emit '-new-window', event, url, frameName, 7
event.sender.emit 'new-window', event, url, frameName, 'new-window'
if event.sender.isGuest() or event.defaultPrevented
event.returnValue = null
else
event.returnValue = createGuest event.sender, args...
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_CLOSE', (event, guestId) ->
return unless BrowserWindow.windows.has guestId
BrowserWindow.windows.get(guestId).destroy()
BrowserWindow.fromId(guestId)?.destroy()
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_METHOD', (event, guestId, method, args...) ->
return unless BrowserWindow.windows.has guestId
BrowserWindow.windows.get(guestId)[method] args...
BrowserWindow.fromId(guestId)?[method] args...
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', (event, guestId, message, targetOrigin) ->
return unless BrowserWindow.windows.has guestId
guestContents = BrowserWindow.windows.get(guestId).webContents
if guestContents.getUrl().indexOf(targetOrigin) is 0 or targetOrigin is '*'
guestContents = BrowserWindow.fromId(guestId)?.webContents
if guestContents?.getUrl().indexOf(targetOrigin) is 0 or targetOrigin is '*'
guestContents.send 'ATOM_SHELL_GUEST_WINDOW_POSTMESSAGE', message, targetOrigin
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPENER_POSTMESSAGE', (event, message, targetOrigin) ->
@@ -67,5 +64,4 @@ ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPENER_POSTMESSAGE', (event, mess
embedder.send 'ATOM_SHELL_GUEST_WINDOW_POSTMESSAGE', message, targetOrigin
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', (event, guestId, method, args...) ->
return unless BrowserWindow.windows.has guestId
BrowserWindow.windows.get(guestId).webContents?[method] args...
BrowserWindow.fromId(guestId)?.webContents?[method] args...

View File

@@ -1,15 +1,15 @@
fs = require 'fs'
path = require 'path'
module = require 'module'
util = require 'util'
Module = require 'module'
# We modified the original process.argv to let node.js load the atom.js,
# we need to restore it here.
process.argv.splice 1, 1
# Add browser/api/lib to require's search paths,
# which contains javascript part of Atom's built-in libraries.
globalPaths = module.globalPaths
# Add browser/api/lib to module search paths, which contains javascript part of
# Electron's built-in libraries.
globalPaths = Module.globalPaths
globalPaths.push path.resolve(__dirname, '..', 'api', 'lib')
# Import common settings.
@@ -81,6 +81,9 @@ if packageJson.desktopName?
else
app.setDesktopName "#{app.getName()}.desktop"
# Chrome 42 disables NPAPI plugins by default, reenable them here
app.commandLine.appendSwitch 'enable-npapi'
# Set the user path according to application's name.
app.setPath 'userData', path.join(app.getPath('appData'), app.getName())
app.setPath 'userCache', path.join(app.getPath('cache'), app.getName())
@@ -89,4 +92,4 @@ app.setPath 'userCache', path.join(app.getPath('cache'), app.getName())
require './chrome-extension'
# Finally load app's main.js and transfer control to C++.
module._load path.join(packagePath, packageJson.main), module, true
Module._load path.join(packagePath, packageJson.main), Module, true

View File

@@ -1,5 +1,5 @@
EventEmitter = require('events').EventEmitter
IDWeakMap = require 'id-weak-map'
IDWeakMap = process.atomBinding('id_weak_map').IDWeakMap
v8Util = process.atomBinding 'v8_util'
# Class to reference all objects.

View File

@@ -7,6 +7,7 @@ v8Util = process.atomBinding 'v8_util'
valueToMeta = (sender, value) ->
meta = type: typeof value
meta.type = 'buffer' if Buffer.isBuffer value
meta.type = 'value' if value is null
meta.type = 'array' if Array.isArray value
@@ -26,6 +27,8 @@ valueToMeta = (sender, value) ->
meta.members = []
meta.members.push {name: prop, type: typeof field} for prop, field of value
else if meta.type is 'buffer'
meta.value = Array::slice.call value, 0
else
meta.type = 'value'
meta.value = value
@@ -43,6 +46,7 @@ unwrapArgs = (sender, args) ->
when 'value' then meta.value
when 'remote-object' then objectsRegistry.get meta.id
when 'array' then unwrapArgs sender, meta.value
when 'buffer' then new Buffer(meta.value)
when 'object'
ret = v8Util.createObjectWithName meta.name
for member in meta.members
@@ -107,6 +111,9 @@ ipc.on 'ATOM_BROWSER_CURRENT_WINDOW', (event, guestInstanceId) ->
catch e
event.returnValue = errorToMeta e
ipc.on 'ATOM_BROWSER_CURRENT_WEB_CONTENTS', (event) ->
event.returnValue = valueToMeta event.sender, event.sender
ipc.on 'ATOM_BROWSER_CONSTRUCTOR', (event, id, args) ->
try
args = unwrapArgs event.sender, args

View File

@@ -18,6 +18,4 @@
// CrAppControlProtocol:
- (void)setHandlingSendEvent:(BOOL)handlingSendEvent;
- (IBAction)closeAllWindows:(id)sender;
@end

View File

@@ -36,10 +36,6 @@
andEventID:kAEGetURL];
}
- (IBAction)closeAllWindows:(id)sender {
atom::Browser::Get()->Quit();
}
- (void)handleURLEvent:(NSAppleEventDescriptor*)event
withReplyEvent:(NSAppleEventDescriptor*)replyEvent {
NSString* url = [

View File

@@ -9,10 +9,8 @@
#include <vector>
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/atom_javascript_dialog_manager.h"
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/browser.h"
#include "atom/browser/ui/file_dialog.h"
#include "atom/browser/web_dialog_helper.h"
#include "atom/browser/window_list.h"
#include "atom/common/api/api_messages.h"
#include "atom/common/atom_version.h"
@@ -30,17 +28,9 @@
#include "base/strings/utf_string_conversions.h"
#include "brightray/browser/inspectable_web_contents.h"
#include "brightray/browser/inspectable_web_contents_view.h"
#include "chrome/browser/printing/print_view_manager_basic.h"
#include "chrome/browser/ui/browser_dialogs.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/invalidate_type.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/plugin_service.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/render_widget_host_view.h"
@@ -66,6 +56,8 @@ using content::NavigationEntry;
using content::RenderWidgetHostView;
using content::RenderWidgetHost;
DEFINE_WEB_CONTENTS_USER_DATA_KEY(atom::NativeWindowRelay);
namespace atom {
namespace {
@@ -78,6 +70,7 @@ const char* kWebRuntimeFeatures[] = {
switches::kOverlayScrollbars,
switches::kOverlayFullscreenVideo,
switches::kSharedWorker,
switches::kPageVisibility,
};
std::string RemoveWhitespace(const std::string& str) {
@@ -90,9 +83,10 @@ std::string RemoveWhitespace(const std::string& str) {
} // namespace
NativeWindow::NativeWindow(content::WebContents* web_contents,
const mate::Dictionary& options)
: content::WebContentsObserver(web_contents),
NativeWindow::NativeWindow(
brightray::InspectableWebContents* inspectable_web_contents,
const mate::Dictionary& options)
: content::WebContentsObserver(inspectable_web_contents->GetWebContents()),
has_frame_(true),
transparent_(false),
enable_larger_than_screen_(false),
@@ -100,10 +94,9 @@ NativeWindow::NativeWindow(content::WebContents* web_contents,
node_integration_(true),
has_dialog_attached_(false),
zoom_factor_(1.0),
weak_factory_(this),
inspectable_web_contents_(
brightray::InspectableWebContents::Create(web_contents)) {
printing::PrintViewManagerBasic::CreateForWebContents(web_contents);
inspectable_web_contents_(inspectable_web_contents),
weak_factory_(this) {
inspectable_web_contents->GetView()->SetDelegate(this);
options.Get(switches::kFrame, &has_frame_);
options.Get(switches::kTransparent, &transparent_);
@@ -136,9 +129,6 @@ NativeWindow::NativeWindow(content::WebContents* web_contents,
// Read the zoom factor before any navigation.
options.Get(switches::kZoomFactor, &zoom_factor_);
web_contents->SetDelegate(this);
inspectable_web_contents()->SetDelegate(this);
WindowList::AddWindow(this);
// Override the user agent to contain application and atom-shell's version.
@@ -148,12 +138,8 @@ NativeWindow::NativeWindow(content::WebContents* web_contents,
RemoveWhitespace(browser->GetName()).c_str(),
browser->GetVersion().c_str(),
CHROME_VERSION_STRING);
web_contents->GetMutableRendererPrefs()->user_agent_override =
web_contents()->GetMutableRendererPrefs()->user_agent_override =
content::BuildUserAgentFromProduct(product_name);
// Get notified of title updated message.
registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED,
content::Source<content::WebContents>(web_contents));
}
NativeWindow::~NativeWindow() {
@@ -163,24 +149,13 @@ NativeWindow::~NativeWindow() {
}
// static
NativeWindow* NativeWindow::Create(const mate::Dictionary& options) {
content::WebContents::CreateParams create_params(AtomBrowserContext::Get());
return Create(content::WebContents::Create(create_params), options);
}
// static
NativeWindow* NativeWindow::FromRenderView(int process_id, int routing_id) {
// Stupid iterating.
NativeWindow* NativeWindow::FromWebContents(
content::WebContents* web_contents) {
WindowList& window_list = *WindowList::GetInstance();
for (auto w = window_list.begin(); w != window_list.end(); ++w) {
auto& window = *w;
content::WebContents* web_contents = window->GetWebContents();
int window_process_id = web_contents->GetRenderProcessHost()->GetID();
int window_routing_id = web_contents->GetRoutingID();
if (window_routing_id == routing_id && window_process_id == process_id)
for (NativeWindow* window : window_list) {
if (window->web_contents() == web_contents)
return window;
}
return nullptr;
}
@@ -192,7 +167,7 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) {
int width = -1, height = -1;
options.Get(switches::kWidth, &width);
options.Get(switches::kHeight, &height);
Move(gfx::Rect(x, y, width, height));
SetBounds(gfx::Rect(x, y, width, height));
} else if (options.Get(switches::kCenter, &center) && center) {
Center();
}
@@ -237,6 +212,22 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) {
Show();
}
void NativeWindow::SetSize(const gfx::Size& size) {
SetBounds(gfx::Rect(GetPosition(), size));
}
gfx::Size NativeWindow::GetSize() {
return GetBounds().size();
}
void NativeWindow::SetPosition(const gfx::Point& position) {
SetBounds(gfx::Rect(position, GetSize()));
}
gfx::Point NativeWindow::GetPosition() {
return GetBounds().origin();
}
void NativeWindow::SetRepresentedFilename(const std::string& filename) {
}
@@ -254,11 +245,6 @@ bool NativeWindow::IsDocumentEdited() {
void NativeWindow::SetMenu(ui::MenuModel* menu) {
}
void NativeWindow::Print(bool silent, bool print_background) {
printing::PrintViewManagerBasic::FromWebContents(GetWebContents())->
PrintNow(silent, print_background);
}
void NativeWindow::ShowDefinitionForSelection() {
NOTIMPLEMENTED();
}
@@ -281,45 +267,23 @@ bool NativeWindow::HasModalDialog() {
return has_dialog_attached_;
}
void NativeWindow::OpenDevTools(bool can_dock) {
inspectable_web_contents()->SetCanDock(can_dock);
inspectable_web_contents()->ShowDevTools();
}
void NativeWindow::CloseDevTools() {
inspectable_web_contents()->CloseDevTools();
}
bool NativeWindow::IsDevToolsOpened() {
return inspectable_web_contents()->IsDevToolsViewShowing();
}
void NativeWindow::InspectElement(int x, int y) {
OpenDevTools(true);
scoped_refptr<content::DevToolsAgentHost> agent(
content::DevToolsAgentHost::GetOrCreateFor(GetWebContents()));
agent->InspectElement(x, y);
}
void NativeWindow::FocusOnWebView() {
GetWebContents()->GetRenderViewHost()->Focus();
web_contents()->GetRenderViewHost()->Focus();
}
void NativeWindow::BlurWebView() {
GetWebContents()->GetRenderViewHost()->Blur();
web_contents()->GetRenderViewHost()->Blur();
}
bool NativeWindow::IsWebViewFocused() {
RenderWidgetHostView* host_view =
GetWebContents()->GetRenderViewHost()->GetView();
auto host_view = web_contents()->GetRenderViewHost()->GetView();
return host_view && host_view->HasFocus();
}
void NativeWindow::CapturePage(const gfx::Rect& rect,
const CapturePageCallback& callback) {
content::WebContents* contents = GetWebContents();
RenderWidgetHostView* const view = contents->GetRenderWidgetHostView();
RenderWidgetHost* const host = view ? view->GetRenderWidgetHost() : nullptr;
const auto view = web_contents()->GetRenderWidgetHostView();
const auto host = view ? view->GetRenderWidgetHost() : nullptr;
if (!view || !host) {
callback.Run(SkBitmap());
return;
@@ -349,14 +313,7 @@ void NativeWindow::CapturePage(const gfx::Rect& rect,
kBGRA_8888_SkColorType);
}
void NativeWindow::DestroyWebContents() {
if (!inspectable_web_contents_)
return;
inspectable_web_contents_.reset();
}
void NativeWindow::CloseWebContents() {
void NativeWindow::RequestToClosePage() {
bool prevent_default = false;
FOR_EACH_OBSERVER(NativeWindowObserver,
observers_,
@@ -366,12 +323,6 @@ void NativeWindow::CloseWebContents() {
return;
}
content::WebContents* web_contents(GetWebContents());
if (!web_contents) {
CloseImmediately();
return;
}
// Assume the window is not responding if it doesn't cancel the close and is
// not closed in 5s, in this way we can quickly show the unresponsive
// dialog when the window is busy executing some script withouth waiting for
@@ -379,26 +330,49 @@ void NativeWindow::CloseWebContents() {
if (window_unresposive_closure_.IsCancelled())
ScheduleUnresponsiveEvent(5000);
if (web_contents->NeedToFireBeforeUnload())
web_contents->DispatchBeforeUnload(false);
if (web_contents()->NeedToFireBeforeUnload())
web_contents()->DispatchBeforeUnload(false);
else
web_contents->Close();
web_contents()->Close();
}
content::WebContents* NativeWindow::GetWebContents() const {
void NativeWindow::CloseContents(content::WebContents* source) {
if (!inspectable_web_contents_)
return nullptr;
return inspectable_web_contents()->GetWebContents();
return;
inspectable_web_contents_->GetView()->SetDelegate(nullptr);
inspectable_web_contents_ = nullptr;
Observe(nullptr);
// When the web contents is gone, close the window immediately, but the
// memory will not be freed until you call delete.
// In this way, it would be safe to manage windows via smart pointers. If you
// want to free memory when the window is closed, you can do deleting by
// overriding the OnWindowClosed method in the observer.
CloseImmediately();
// Do not sent "unresponsive" event after window is closed.
window_unresposive_closure_.Cancel();
}
content::WebContents* NativeWindow::GetDevToolsWebContents() const {
if (!inspectable_web_contents_)
return nullptr;
return inspectable_web_contents()->devtools_web_contents();
void NativeWindow::RendererUnresponsive(content::WebContents* source) {
// Schedule the unresponsive shortly later, since we may receive the
// responsive event soon. This could happen after the whole application had
// blocked for a while.
// Also notice that when closing this event would be ignored because we have
// explicity started a close timeout counter. This is on purpose because we
// don't want the unresponsive event to be sent too early when user is closing
// the window.
ScheduleUnresponsiveEvent(50);
}
void NativeWindow::RendererResponsive(content::WebContents* source) {
window_unresposive_closure_.Cancel();
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnRendererResponsive());
}
void NativeWindow::AppendExtraCommandLineSwitches(
base::CommandLine* command_line, int child_process_id) {
base::CommandLine* command_line) {
// Append --node-integration to renderer process.
command_line->AppendSwitchASCII(switches::kNodeIntegration,
node_integration_ ? "true" : "false");
@@ -469,14 +443,10 @@ void NativeWindow::NotifyWindowClosed() {
if (is_closed_)
return;
WindowList::RemoveWindow(this);
is_closed_ = true;
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnWindowClosed());
// Do not receive any notification after window has been closed, there is a
// crash that seems to be caused by this: http://git.io/YqMG5g.
registrar_.RemoveAll();
WindowList::RemoveWindow(this);
}
void NativeWindow::NotifyWindowBlur() {
@@ -503,6 +473,18 @@ void NativeWindow::NotifyWindowRestore() {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnWindowRestore());
}
void NativeWindow::NotifyWindowResize() {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnWindowResize());
}
void NativeWindow::NotifyWindowMove() {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnWindowMove());
}
void NativeWindow::NotifyWindowMoved() {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnWindowMoved());
}
void NativeWindow::NotifyWindowEnterFullScreen() {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_,
OnWindowEnterFullScreen());
@@ -513,69 +495,26 @@ void NativeWindow::NotifyWindowLeaveFullScreen() {
OnWindowLeaveFullScreen());
}
bool NativeWindow::ShouldCreateWebContents(
content::WebContents* web_contents,
int route_id,
int main_frame_route_id,
WindowContainerType window_container_type,
const base::string16& frame_name,
const GURL& target_url,
const std::string& partition_id,
content::SessionStorageNamespace* session_storage_namespace) {
FOR_EACH_OBSERVER(NativeWindowObserver,
observers_,
WillCreatePopupWindow(frame_name,
target_url,
partition_id,
NEW_FOREGROUND_TAB));
return false;
void NativeWindow::NotifyWindowEnterHtmlFullScreen() {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_,
OnWindowEnterHtmlFullScreen());
}
// In atom-shell all reloads and navigations started by renderer process would
// be redirected to this method, so we can have precise control of how we
// would open the url (in our case, is to restart the renderer process). See
// AtomRendererClient::ShouldFork for how this is done.
content::WebContents* NativeWindow::OpenURLFromTab(
content::WebContents* source,
const content::OpenURLParams& params) {
if (params.disposition != CURRENT_TAB) {
FOR_EACH_OBSERVER(NativeWindowObserver,
observers_,
WillCreatePopupWindow(base::string16(),
params.url,
"",
params.disposition));
return nullptr;
}
// Give user a chance to prevent navigation.
bool prevent_default = false;
FOR_EACH_OBSERVER(NativeWindowObserver,
observers_,
WillNavigate(&prevent_default, params.url));
if (prevent_default)
return nullptr;
content::NavigationController::LoadURLParams load_url_params(params.url);
load_url_params.referrer = params.referrer;
load_url_params.transition_type = params.transition;
load_url_params.extra_headers = params.extra_headers;
load_url_params.should_replace_current_entry =
params.should_replace_current_entry;
load_url_params.is_renderer_initiated = params.is_renderer_initiated;
load_url_params.transferred_global_request_id =
params.transferred_global_request_id;
source->GetController().LoadURLWithParams(load_url_params);
return source;
void NativeWindow::NotifyWindowLeaveHtmlFullScreen() {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_,
OnWindowLeaveHtmlFullScreen());
}
content::JavaScriptDialogManager* NativeWindow::GetJavaScriptDialogManager(
content::WebContents* source) {
if (!dialog_manager_)
dialog_manager_.reset(new AtomJavaScriptDialogManager);
void NativeWindow::DevToolsFocused() {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnDevToolsFocus());
}
return dialog_manager_.get();
void NativeWindow::DevToolsOpened() {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnDevToolsOpened());
}
void NativeWindow::DevToolsClosed() {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnDevToolsClosed());
}
void NativeWindow::RenderViewCreated(
@@ -590,104 +529,22 @@ void NativeWindow::RenderViewCreated(
impl->SetBackgroundOpaque(false);
}
void NativeWindow::BeforeUnloadFired(content::WebContents* tab,
bool proceed,
bool* proceed_to_fire_unload) {
*proceed_to_fire_unload = proceed;
void NativeWindow::BeforeUnloadDialogCancelled() {
WindowList::WindowCloseCancelled(this);
if (!proceed) {
WindowList::WindowCloseCancelled(this);
// Cancel unresponsive event when window close is cancelled.
window_unresposive_closure_.Cancel();
}
}
content::ColorChooser* NativeWindow::OpenColorChooser(
content::WebContents* web_contents,
SkColor color,
const std::vector<content::ColorSuggestion>& suggestions) {
return chrome::ShowColorChooser(web_contents, color);
}
void NativeWindow::RunFileChooser(content::WebContents* web_contents,
const content::FileChooserParams& params) {
if (!web_dialog_helper_)
web_dialog_helper_.reset(new WebDialogHelper(this));
web_dialog_helper_->RunFileChooser(web_contents, params);
}
void NativeWindow::EnumerateDirectory(content::WebContents* web_contents,
int request_id,
const base::FilePath& path) {
if (!web_dialog_helper_)
web_dialog_helper_.reset(new WebDialogHelper(this));
web_dialog_helper_->EnumerateDirectory(web_contents, request_id, path);
}
void NativeWindow::RequestToLockMouse(content::WebContents* web_contents,
bool user_gesture,
bool last_unlocked_by_target) {
GetWebContents()->GotResponseToLockMouseRequest(true);
}
bool NativeWindow::CanOverscrollContent() const {
return false;
}
void NativeWindow::ActivateContents(content::WebContents* contents) {
FocusOnWebView();
}
void NativeWindow::DeactivateContents(content::WebContents* contents) {
BlurWebView();
}
void NativeWindow::MoveContents(content::WebContents* source,
const gfx::Rect& pos) {
SetPosition(pos.origin());
SetSize(pos.size());
}
void NativeWindow::CloseContents(content::WebContents* source) {
// Destroy the WebContents before we close the window.
DestroyWebContents();
// When the web contents is gone, close the window immediately, but the
// memory will not be freed until you call delete.
// In this way, it would be safe to manage windows via smart pointers. If you
// want to free memory when the window is closed, you can do deleting by
// overriding the OnWindowClosed method in the observer.
CloseImmediately();
// Do not sent "unresponsive" event after window is closed.
// Cancel unresponsive event when window close is cancelled.
window_unresposive_closure_.Cancel();
}
bool NativeWindow::IsPopupOrPanel(const content::WebContents* source) const {
// Only popup window can use things like window.moveTo.
return true;
}
void NativeWindow::RendererUnresponsive(content::WebContents* source) {
// Schedule the unresponsive shortly later, since we may receive the
// responsive event soon. This could happen after the whole application had
// blocked for a while.
// Also notice that when closing this event would be ignored because we have
// explicity started a close timeout counter. This is on purpose because we
// don't want the unresponsive event to be sent too early when user is closing
// the window.
ScheduleUnresponsiveEvent(50);
}
void NativeWindow::RendererResponsive(content::WebContents* source) {
window_unresposive_closure_.Cancel();
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnRendererResponsive());
}
void NativeWindow::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.
void NativeWindow::TitleWasSet(content::NavigationEntry* entry,
bool explicit_set) {
bool prevent_default = false;
std::string text = base::UTF16ToUTF8(entry->GetTitle());
FOR_EACH_OBSERVER(NativeWindowObserver,
observers_,
OnPageTitleUpdated(&prevent_default, text));
if (!prevent_default)
SetTitle(text);
}
bool NativeWindow::OnMessageReceived(const IPC::Message& message) {
@@ -701,67 +558,6 @@ bool NativeWindow::OnMessageReceived(const IPC::Message& message) {
return handled;
}
void NativeWindow::Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
if (type == content::NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED) {
std::pair<NavigationEntry*, bool>* title =
content::Details<std::pair<NavigationEntry*, bool>>(details).ptr();
if (title->first) {
bool prevent_default = false;
std::string text = base::UTF16ToUTF8(title->first->GetTitle());
FOR_EACH_OBSERVER(NativeWindowObserver,
observers_,
OnPageTitleUpdated(&prevent_default, text));
if (!prevent_default)
SetTitle(text);
}
}
}
void NativeWindow::DevToolsSaveToFile(const std::string& url,
const std::string& content,
bool save_as) {
base::FilePath path;
PathsMap::iterator it = saved_files_.find(url);
if (it != saved_files_.end() && !save_as) {
path = it->second;
} else {
file_dialog::Filters filters;
base::FilePath default_path(base::FilePath::FromUTF8Unsafe(url));
if (!file_dialog::ShowSaveDialog(this, url, default_path, filters, &path)) {
base::StringValue url_value(url);
CallDevToolsFunction("DevToolsAPI.canceledSaveURL", &url_value);
return;
}
}
saved_files_[url] = path;
base::WriteFile(path, content.data(), content.size());
// Notify devtools.
base::StringValue url_value(url);
CallDevToolsFunction("DevToolsAPI.savedURL", &url_value);
}
void NativeWindow::DevToolsAppendToFile(const std::string& url,
const std::string& content) {
PathsMap::iterator it = saved_files_.find(url);
if (it == saved_files_.end())
return;
base::AppendToFile(it->second, content.data(), content.size());
// Notify devtools.
base::StringValue url_value(url);
CallDevToolsFunction("DevToolsAPI.appendedToURL", &url_value);
}
void NativeWindow::DevToolsFocused() {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnDevToolsFocus());
}
void NativeWindow::ScheduleUnresponsiveEvent(int ms) {
if (!window_unresposive_closure_.IsCancelled())
return;
@@ -790,27 +586,4 @@ void NativeWindow::OnCapturePageDone(const CapturePageCallback& callback,
callback.Run(bitmap);
}
void NativeWindow::CallDevToolsFunction(const std::string& function_name,
const base::Value* arg1,
const base::Value* arg2,
const base::Value* arg3) {
std::string params;
if (arg1) {
std::string json;
base::JSONWriter::Write(arg1, &json);
params.append(json);
if (arg2) {
base::JSONWriter::Write(arg2, &json);
params.append(", " + json);
if (arg3) {
base::JSONWriter::Write(arg3, &json);
params.append(", " + json);
}
}
}
base::string16 javascript =
base::UTF8ToUTF16(function_name + "(" + params + ");");
GetDevToolsWebContents()->GetMainFrame()->ExecuteJavaScript(javascript);
}
} // namespace atom

View File

@@ -15,22 +15,24 @@
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "brightray/browser/default_web_contents_delegate.h"
#include "brightray/browser/inspectable_web_contents_delegate.h"
#include "brightray/browser/inspectable_web_contents_impl.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/notification_observer.h"
#include "brightray/browser/inspectable_web_contents_view_delegate.h"
#include "content/public/browser/readback_types.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_user_data.h"
#include "native_mate/persistent_dictionary.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia.h"
namespace base {
class CommandLine;
}
namespace brightray {
class InspectableWebContents;
}
namespace content {
class BrowserContext;
class WebContents;
struct NativeWebKeyboardEvent;
struct WebPreferences;
}
@@ -50,14 +52,10 @@ class MenuModel;
namespace atom {
class AtomJavaScriptDialogManager;
struct DraggableRegion;
class WebDialogHelper;
class NativeWindow : public brightray::DefaultWebContentsDelegate,
public brightray::InspectableWebContentsDelegate,
public content::WebContentsObserver,
public content::NotificationObserver {
class NativeWindow : public content::WebContentsObserver,
public brightray::InspectableWebContentsViewDelegate {
public:
typedef base::Callback<void(const SkBitmap& bitmap)> CapturePageCallback;
@@ -84,21 +82,17 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
// Create window with existing WebContents, the caller is responsible for
// managing the window's live.
static NativeWindow* Create(content::WebContents* web_contents,
const mate::Dictionary& options);
static NativeWindow* Create(
brightray::InspectableWebContents* inspectable_web_contents,
const mate::Dictionary& options);
// Create window with new WebContents, the caller is responsible for
// managing the window's live.
static NativeWindow* Create(const mate::Dictionary& options);
// Find a window from its process id and routing id.
static NativeWindow* FromRenderView(int process_id, int routing_id);
// Find a window from its WebContents
static NativeWindow* FromWebContents(content::WebContents* web_contents);
void InitFromOptions(const mate::Dictionary& options);
virtual void Close() = 0;
virtual void CloseImmediately() = 0;
virtual void Move(const gfx::Rect& pos) = 0;
virtual void Focus(bool focus) = 0;
virtual bool IsFocused() = 0;
virtual void Show() = 0;
@@ -112,9 +106,13 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
virtual void Restore() = 0;
virtual bool IsMinimized() = 0;
virtual void SetFullScreen(bool fullscreen) = 0;
virtual bool IsFullscreen() = 0;
virtual void SetSize(const gfx::Size& size) = 0;
virtual gfx::Size GetSize() = 0;
virtual bool IsFullscreen() const = 0;
virtual void SetBounds(const gfx::Rect& bounds) = 0;
virtual gfx::Rect GetBounds() = 0;
virtual void SetSize(const gfx::Size& size);
virtual gfx::Size GetSize();
virtual void SetPosition(const gfx::Point& position);
virtual gfx::Point GetPosition();
virtual void SetContentSize(const gfx::Size& size) = 0;
virtual gfx::Size GetContentSize() = 0;
virtual void SetMinimumSize(const gfx::Size& size) = 0;
@@ -126,8 +124,6 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
virtual void SetAlwaysOnTop(bool top) = 0;
virtual bool IsAlwaysOnTop() = 0;
virtual void Center() = 0;
virtual void SetPosition(const gfx::Point& position) = 0;
virtual gfx::Point GetPosition() = 0;
virtual void SetTitle(const std::string& title) = 0;
virtual std::string GetTitle() = 0;
virtual void FlashFrame(bool flash) = 0;
@@ -148,10 +144,6 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
virtual bool IsVisibleOnAllWorkspaces() = 0;
virtual bool IsClosed() const { return is_closed_; }
virtual void OpenDevTools(bool can_dock);
virtual void CloseDevTools();
virtual bool IsDevToolsOpened();
virtual void InspectElement(int x, int y);
virtual void FocusOnWebView();
virtual void BlurWebView();
@@ -162,9 +154,6 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
virtual void CapturePage(const gfx::Rect& rect,
const CapturePageCallback& callback);
// Print current page.
virtual void Print(bool silent, bool print_background);
// Show popup dictionary.
virtual void ShowDefinitionForSelection();
@@ -174,24 +163,23 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
virtual void SetMenuBarVisibility(bool visible);
virtual bool IsMenuBarVisible();
// The same with closing a tab in a real browser.
//
// Should be called by platform code when user want to close the window.
virtual void CloseWebContents();
// Destroy the WebContents immediately.
virtual void DestroyWebContents();
base::WeakPtr<NativeWindow> GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
content::WebContents* GetWebContents() const;
content::WebContents* GetDevToolsWebContents() const;
// Requests the WebContents to close, can be cancelled by the page.
virtual void RequestToClosePage();
// Methods called by the WebContents.
virtual void CloseContents(content::WebContents* source);
virtual void RendererUnresponsive(content::WebContents* source);
virtual void RendererResponsive(content::WebContents* source);
virtual void HandleKeyboardEvent(
content::WebContents*,
const content::NativeWebKeyboardEvent& event) {}
// Called when renderer process is going to be started.
void AppendExtraCommandLineSwitches(base::CommandLine* command_line,
int child_process_id);
void AppendExtraCommandLineSwitches(base::CommandLine* command_line);
void OverrideWebkitPrefs(content::WebPreferences* prefs);
// Public API used by platform-dependent delegates and observers to send UI
@@ -203,8 +191,13 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
void NotifyWindowUnmaximize();
void NotifyWindowMinimize();
void NotifyWindowRestore();
void NotifyWindowMove();
void NotifyWindowResize();
void NotifyWindowMoved();
void NotifyWindowEnterFullScreen();
void NotifyWindowLeaveFullScreen();
void NotifyWindowEnterHtmlFullScreen();
void NotifyWindowLeaveHtmlFullScreen();
void AddObserver(NativeWindowObserver* obs) {
observers_.AddObserver(obs);
@@ -214,6 +207,10 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
observers_.RemoveObserver(obs);
}
brightray::InspectableWebContents* inspectable_web_contents() const {
return inspectable_web_contents_;
}
bool has_frame() const { return has_frame_; }
void set_has_dialog_attached(bool has_dialog_attached) {
@@ -221,76 +218,23 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
}
protected:
explicit NativeWindow(content::WebContents* web_contents,
const mate::Dictionary& options);
brightray::InspectableWebContentsImpl* inspectable_web_contents() const {
return static_cast<brightray::InspectableWebContentsImpl*>(
inspectable_web_contents_.get());
}
NativeWindow(brightray::InspectableWebContents* inspectable_web_contents,
const mate::Dictionary& options);
// Called when the window needs to update its draggable region.
virtual void UpdateDraggableRegions(
const std::vector<DraggableRegion>& regions) = 0;
// Implementations of content::WebContentsDelegate.
bool ShouldCreateWebContents(
content::WebContents* web_contents,
int route_id,
int main_frame_route_id,
WindowContainerType window_container_type,
const base::string16& frame_name,
const GURL& target_url,
const std::string& partition_id,
content::SessionStorageNamespace* session_storage_namespace) override;
content::WebContents* OpenURLFromTab(
content::WebContents* source,
const content::OpenURLParams& params) override;
content::JavaScriptDialogManager* GetJavaScriptDialogManager(
content::WebContents* source) override;
void BeforeUnloadFired(content::WebContents* tab,
bool proceed,
bool* proceed_to_fire_unload) override;
content::ColorChooser* OpenColorChooser(
content::WebContents* web_contents,
SkColor color,
const std::vector<content::ColorSuggestion>& suggestions) override;
void RunFileChooser(content::WebContents* web_contents,
const content::FileChooserParams& params) override;
void EnumerateDirectory(content::WebContents* web_contents,
int request_id,
const base::FilePath& path) override;
void RequestToLockMouse(content::WebContents* web_contents,
bool user_gesture,
bool last_unlocked_by_target) override;
bool CanOverscrollContent() const override;
void ActivateContents(content::WebContents* contents) override;
void DeactivateContents(content::WebContents* contents) override;
void MoveContents(content::WebContents* source,
const gfx::Rect& pos) override;
void CloseContents(content::WebContents* source) override;
bool IsPopupOrPanel(
const content::WebContents* source) const override;
void RendererUnresponsive(content::WebContents* source) override;
void RendererResponsive(content::WebContents* source) override;
// Implementations of content::WebContentsObserver.
void RenderViewCreated(content::RenderViewHost* render_view_host) override;
void BeforeUnloadFired(const base::TimeTicks& proceed_time) override;
bool OnMessageReceived(const IPC::Message& message) override;
// Implementations of content::NotificationObserver.
void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) override;
// Implementations of brightray::InspectableWebContentsDelegate.
void DevToolsSaveToFile(const std::string& url,
const std::string& content,
bool save_as) override;
void DevToolsAppendToFile(const std::string& url,
const std::string& content) override;
// brightray::InspectableWebContentsViewDelegate:
void DevToolsFocused() override;
void DevToolsOpened() override;
void DevToolsClosed() override;
// content::WebContentsObserver:
void RenderViewCreated(content::RenderViewHost* render_view_host) override;
void BeforeUnloadDialogCancelled() override;
void TitleWasSet(content::NavigationEntry* entry, bool explicit_set) override;
bool OnMessageReceived(const IPC::Message& message) override;
// Whether window has standard frame.
bool has_frame_;
@@ -304,6 +248,9 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
// Window icon.
gfx::ImageSkia icon_;
// Observers of this window.
ObserverList<NativeWindowObserver> observers_;
private:
// Schedule a notification unresponsive event.
void ScheduleUnresponsiveEvent(int ms);
@@ -311,23 +258,11 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
// Dispatch unresponsive event to observers.
void NotifyWindowUnresponsive();
// Call a function in devtools.
void CallDevToolsFunction(const std::string& function_name,
const base::Value* arg1 = NULL,
const base::Value* arg2 = NULL,
const base::Value* arg3 = NULL);
// Called when CapturePage has done.
void OnCapturePageDone(const CapturePageCallback& callback,
const SkBitmap& bitmap,
content::ReadbackResponse response);
// Notification manager.
content::NotificationRegistrar registrar_;
// Observers of this window.
ObserverList<NativeWindowObserver> observers_;
// The windows has been closed.
bool is_closed_;
@@ -350,23 +285,29 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
// Page's default zoom factor.
double zoom_factor_;
// The page this window is viewing.
brightray::InspectableWebContents* inspectable_web_contents_;
base::WeakPtrFactory<NativeWindow> weak_factory_;
scoped_ptr<WebDialogHelper> web_dialog_helper_;
scoped_ptr<AtomJavaScriptDialogManager> dialog_manager_;
// Notice that inspectable_web_contents_ must be placed after dialog_manager_,
// so we can make sure inspectable_web_contents_ is destroyed before
// dialog_manager_, otherwise a crash would happen.
scoped_ptr<brightray::InspectableWebContents> inspectable_web_contents_;
// Maps url to file path, used by the file requests sent from devtools.
typedef std::map<std::string, base::FilePath> PathsMap;
PathsMap saved_files_;
DISALLOW_COPY_AND_ASSIGN(NativeWindow);
};
// This class provides a hook to get a NativeWindow from a WebContents.
class NativeWindowRelay :
public content::WebContentsUserData<NativeWindowRelay> {
public:
explicit NativeWindowRelay(base::WeakPtr<NativeWindow> window)
: key(UserDataKey()), window(window) {}
void* key;
base::WeakPtr<NativeWindow> window;
private:
friend class content::WebContentsUserData<NativeWindow>;
};
} // namespace atom
#endif // ATOM_BROWSER_NATIVE_WINDOW_H_

View File

@@ -23,14 +23,13 @@ namespace atom {
class NativeWindowMac : public NativeWindow {
public:
explicit NativeWindowMac(content::WebContents* web_contents,
const mate::Dictionary& options);
virtual ~NativeWindowMac();
NativeWindowMac(brightray::InspectableWebContents* inspectable_web_contents,
const mate::Dictionary& options);
~NativeWindowMac() override;
// NativeWindow implementation.
// NativeWindow:
void Close() override;
void CloseImmediately() override;
void Move(const gfx::Rect& pos) override;
void Focus(bool focus) override;
bool IsFocused() override;
void Show() override;
@@ -44,9 +43,9 @@ class NativeWindowMac : public NativeWindow {
void Restore() override;
bool IsMinimized() override;
void SetFullScreen(bool fullscreen) override;
bool IsFullscreen() override;
void SetSize(const gfx::Size& size) override;
gfx::Size GetSize() override;
bool IsFullscreen() const override;
void SetBounds(const gfx::Rect& bounds) override;
gfx::Rect GetBounds() override;
void SetContentSize(const gfx::Size& size) override;
gfx::Size GetContentSize() override;
void SetMinimumSize(const gfx::Size& size) override;
@@ -58,8 +57,6 @@ class NativeWindowMac : public NativeWindow {
void SetAlwaysOnTop(bool top) override;
bool IsAlwaysOnTop() override;
void Center() override;
void SetPosition(const gfx::Point& position) override;
gfx::Point GetPosition() override;
void SetTitle(const std::string& title) override;
std::string GetTitle() override;
void FlashFrame(bool flash) override;
@@ -94,7 +91,7 @@ class NativeWindowMac : public NativeWindow {
void UpdateDraggableRegions(
const std::vector<DraggableRegion>& regions) override;
// Implementations of content::WebContentsDelegate.
// NativeWindow:
void HandleKeyboardEvent(
content::WebContents*,
const content::NativeWebKeyboardEvent&) override;

View File

@@ -11,14 +11,14 @@
#include "atom/common/options_switches.h"
#include "base/mac/mac_util.h"
#include "base/strings/sys_string_conversions.h"
#include "brightray/browser/inspectable_web_contents.h"
#include "brightray/browser/inspectable_web_contents_view.h"
#include "content/public/browser/browser_accessibility_state.h"
#include "content/public/browser/native_web_keyboard_event.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "native_mate/dictionary.h"
#include "vendor/brightray/browser/inspectable_web_contents.h"
#include "vendor/brightray/browser/inspectable_web_contents_view.h"
static const CGFloat kAtomWindowCornerRadius = 4.0;
@@ -54,10 +54,8 @@ static const CGFloat kAtomWindowCornerRadius = 4.0;
@interface AtomNSWindowDelegate : NSObject<NSWindowDelegate> {
@private
atom::NativeWindowMac* shell_;
BOOL acceptsFirstMouse_;
}
- (id)initWithShell:(atom::NativeWindowMac*)shell;
- (void)setAcceptsFirstMouse:(BOOL)accept;
@end
@implementation AtomNSWindowDelegate
@@ -65,17 +63,12 @@ static const CGFloat kAtomWindowCornerRadius = 4.0;
- (id)initWithShell:(atom::NativeWindowMac*)shell {
if ((self = [super init])) {
shell_ = shell;
acceptsFirstMouse_ = NO;
}
return self;
}
- (void)setAcceptsFirstMouse:(BOOL)accept {
acceptsFirstMouse_ = accept;
}
- (void)windowDidBecomeMain:(NSNotification*)notification {
content::WebContents* web_contents = shell_->GetWebContents();
content::WebContents* web_contents = shell_->web_contents();
if (!web_contents)
return;
@@ -89,7 +82,7 @@ static const CGFloat kAtomWindowCornerRadius = 4.0;
}
- (void)windowDidResignMain:(NSNotification*)notification {
content::WebContents* web_contents = shell_->GetWebContents();
content::WebContents* web_contents = shell_->web_contents();
if (!web_contents)
return;
@@ -105,6 +98,15 @@ static const CGFloat kAtomWindowCornerRadius = 4.0;
- (void)windowDidResize:(NSNotification*)notification {
if (!shell_->has_frame())
shell_->ClipWebView();
shell_->NotifyWindowResize();
}
- (void)windowDidMove:(NSNotification*)notification {
// TODO(zcbenz): Remove the alias after figuring out a proper
// way to disptach move.
shell_->NotifyWindowMove();
shell_->NotifyWindowMoved();
}
- (void)windowDidMiniaturize:(NSNotification*)notification {
@@ -147,14 +149,10 @@ static const CGFloat kAtomWindowCornerRadius = 4.0;
// When user tries to close the window by clicking the close button, we do
// not close the window immediately, instead we try to close the web page
// fisrt, and when the web page is closed the window will also be closed.
shell_->CloseWebContents();
shell_->RequestToClosePage();
return NO;
}
- (BOOL)acceptsFirstMouse:(NSEvent*)event {
return acceptsFirstMouse_;
}
@end
@interface AtomNSWindow : EventProcessingWindow {
@@ -162,6 +160,8 @@ static const CGFloat kAtomWindowCornerRadius = 4.0;
atom::NativeWindowMac* shell_;
bool enable_larger_than_screen_;
}
@property BOOL acceptsFirstMouse;
@property BOOL disableAutoHideCursor;
- (void)setShell:(atom::NativeWindowMac*)shell;
- (void)setEnableLargerThanScreen:(bool)enable;
@end
@@ -184,16 +184,6 @@ static const CGFloat kAtomWindowCornerRadius = 4.0;
return [super constrainFrameRect:frameRect toScreen:screen];
}
- (IBAction)reload:(id)sender {
content::WebContents* web_contents = shell_->GetWebContents();
content::NavigationController::LoadURLParams params(web_contents->GetURL());
web_contents->GetController().LoadURLWithParams(params);
}
- (IBAction)showDevTools:(id)sender {
shell_->OpenDevTools(true);
}
- (id)accessibilityAttributeValue:(NSString*)attribute {
if (![attribute isEqualToString:@"AXChildren"])
return [super accessibilityAttributeValue:attribute];
@@ -313,8 +303,9 @@ SkRegion* DraggableRegionsToSkRegion(
} // namespace
NativeWindowMac::NativeWindowMac(content::WebContents* web_contents,
const mate::Dictionary& options)
NativeWindowMac::NativeWindowMac(
brightray::InspectableWebContents* web_contents,
const mate::Dictionary& options)
: NativeWindow(web_contents, options),
is_kiosk_(false),
attention_request_id_(0) {
@@ -329,11 +320,18 @@ NativeWindowMac::NativeWindowMac(content::WebContents* web_contents,
width,
height);
bool useStandardWindow = true;
options.Get(switches::kStandardWindow, &useStandardWindow);
NSUInteger styleMask = NSTitledWindowMask | NSClosableWindowMask |
NSMiniaturizableWindowMask | NSResizableWindowMask;
if (!useStandardWindow || transparent_ || !has_frame_) {
styleMask |= NSTexturedBackgroundWindowMask;
}
window_.reset([[AtomNSWindow alloc]
initWithContentRect:cocoa_bounds
styleMask:NSTitledWindowMask | NSClosableWindowMask |
NSMiniaturizableWindowMask | NSResizableWindowMask |
NSTexturedBackgroundWindowMask
styleMask:styleMask
backing:NSBackingStoreBuffered
defer:YES]);
[window_ setShell:this];
@@ -349,6 +347,10 @@ NativeWindowMac::NativeWindowMac(content::WebContents* web_contents,
[window_ setBackgroundColor:[NSColor clearColor]];
}
// Remove non-transparent corners, see http://git.io/vfonD.
if (!has_frame_)
[window_ setOpaque:NO];
// We will manage window's lifetime ourselves.
[window_ setReleasedWhenClosed:NO];
@@ -361,7 +363,12 @@ NativeWindowMac::NativeWindowMac(content::WebContents* web_contents,
// Enable the NSView to accept first mouse event.
bool acceptsFirstMouse = false;
options.Get(switches::kAcceptFirstMouse, &acceptsFirstMouse);
[window_delegate_ setAcceptsFirstMouse:acceptsFirstMouse];
[window_ setAcceptsFirstMouse:acceptsFirstMouse];
// Disable auto-hiding cursor.
bool disableAutoHideCursor = false;
options.Get(switches::kDisableAutoHideCursor, &disableAutoHideCursor);
[window_ setDisableAutoHideCursor:disableAutoHideCursor];
// Disable fullscreen button when 'fullscreen' is specified to false.
bool fullscreen;
@@ -379,9 +386,7 @@ NativeWindowMac::NativeWindowMac(content::WebContents* web_contents,
}
NativeWindowMac::~NativeWindowMac() {
// Force InspectableWebContents to be destroyed before we destroy window,
// because it may still be observing the window at this time.
DestroyWebContents();
Observe(nullptr);
}
void NativeWindowMac::Close() {
@@ -392,18 +397,6 @@ void NativeWindowMac::CloseImmediately() {
[window_ close];
}
void NativeWindowMac::Move(const gfx::Rect& pos) {
NSRect cocoa_bounds = NSMakeRect(pos.x(), 0,
pos.width(),
pos.height());
// Flip coordinates based on the primary screen.
NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
cocoa_bounds.origin.y =
NSHeight([screen frame]) - pos.height() - pos.y();
[window_ setFrame:cocoa_bounds display:YES];
}
void NativeWindowMac::Focus(bool focus) {
if (!IsVisible())
return;
@@ -476,22 +469,28 @@ void NativeWindowMac::SetFullScreen(bool fullscreen) {
[window_ toggleFullScreen:nil];
}
bool NativeWindowMac::IsFullscreen() {
bool NativeWindowMac::IsFullscreen() const {
return [window_ styleMask] & NSFullScreenWindowMask;
}
void NativeWindowMac::SetSize(const gfx::Size& size) {
NSRect frame = [window_ frame];
frame.origin.y -= size.height() - frame.size.height;
frame.size.width = size.width();
frame.size.height = size.height();
void NativeWindowMac::SetBounds(const gfx::Rect& bounds) {
NSRect cocoa_bounds = NSMakeRect(bounds.x(), 0,
bounds.width(),
bounds.height());
// Flip coordinates based on the primary screen.
NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
cocoa_bounds.origin.y =
NSHeight([screen frame]) - bounds.height() - bounds.y();
[window_ setFrame:frame display:YES];
[window_ setFrame:cocoa_bounds display:YES];
}
gfx::Size NativeWindowMac::GetSize() {
gfx::Rect NativeWindowMac::GetBounds() {
NSRect frame = [window_ frame];
return gfx::Size(frame.size.width, frame.size.height);
gfx::Rect bounds(frame.origin.x, 0, NSWidth(frame), NSHeight(frame));
NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
bounds.set_y(NSHeight([screen frame]) - NSMaxY(frame));
return bounds;
}
void NativeWindowMac::SetContentSize(const gfx::Size& size) {
@@ -564,18 +563,6 @@ void NativeWindowMac::Center() {
[window_ center];
}
void NativeWindowMac::SetPosition(const gfx::Point& position) {
Move(gfx::Rect(position, GetSize()));
}
gfx::Point NativeWindowMac::GetPosition() {
NSRect frame = [window_ frame];
NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
return gfx::Point(frame.origin.x,
NSHeight([screen frame]) - frame.origin.y - frame.size.height);
}
void NativeWindowMac::SetTitle(const std::string& title) {
// We don't want the title to show in transparent window.
if (transparent_)
@@ -690,10 +677,9 @@ void NativeWindowMac::SetOverlayIcon(const gfx::Image& overlay,
}
void NativeWindowMac::ShowDefinitionForSelection() {
content::WebContents* web_contents = GetWebContents();
if (!web_contents)
if (!web_contents())
return;
content::RenderWidgetHostView* rwhv = web_contents->GetRenderWidgetHostView();
auto rwhv = web_contents()->GetRenderWidgetHostView();
if (!rwhv)
return;
rwhv->ShowDefinitionForSelection();
@@ -717,10 +703,9 @@ bool NativeWindowMac::IsVisibleOnAllWorkspaces() {
bool NativeWindowMac::IsWithinDraggableRegion(NSPoint point) const {
if (!draggable_region_)
return false;
content::WebContents* web_contents = GetWebContents();
if (!web_contents)
if (!web_contents())
return false;
NSView* webView = web_contents->GetNativeView();
NSView* webView = web_contents()->GetNativeView();
NSInteger webViewHeight = NSHeight([webView bounds]);
// |draggable_region_| is stored in local platform-indepdent coordiate system
// while |point| is in local Cocoa coordinate system. Do the conversion
@@ -827,16 +812,15 @@ void NativeWindowMac::UninstallView() {
}
void NativeWindowMac::ClipWebView() {
content::WebContents* web_contents = GetWebContents();
if (!web_contents)
if (!web_contents())
return;
NSView* webView = web_contents->GetNativeView();
NSView* webView = web_contents()->GetNativeView();
webView.layer.masksToBounds = YES;
webView.layer.cornerRadius = kAtomWindowCornerRadius;
}
void NativeWindowMac::InstallDraggableRegionView() {
NSView* webView = GetWebContents()->GetNativeView();
NSView* webView = web_contents()->GetNativeView();
base::scoped_nsobject<NSView> controlRegion(
[[ControlRegionView alloc] initWithShellWindow:this]);
[controlRegion setFrame:NSMakeRect(0, 0,
@@ -846,9 +830,10 @@ void NativeWindowMac::InstallDraggableRegionView() {
}
// static
NativeWindow* NativeWindow::Create(content::WebContents* web_contents,
const mate::Dictionary& options) {
return new NativeWindowMac(web_contents, options);
NativeWindow* NativeWindow::Create(
brightray::InspectableWebContents* inspectable_web_contents,
const mate::Dictionary& options) {
return new NativeWindowMac(inspectable_web_contents, options);
}
} // namespace atom

View File

@@ -47,17 +47,27 @@ class NativeWindowObserver {
virtual void OnWindowUnmaximize() {}
virtual void OnWindowMinimize() {}
virtual void OnWindowRestore() {}
virtual void OnWindowResize() {}
virtual void OnWindowMove() {}
virtual void OnWindowMoved() {}
virtual void OnWindowEnterFullScreen() {}
virtual void OnWindowLeaveFullScreen() {}
virtual void OnWindowEnterHtmlFullScreen() {}
virtual void OnWindowLeaveHtmlFullScreen() {}
// Called when devtools window gets focused.
// Redirect devtools events.
virtual void OnDevToolsFocus() {}
virtual void OnDevToolsOpened() {}
virtual void OnDevToolsClosed() {}
// Called when renderer is hung.
virtual void OnRendererUnresponsive() {}
// Called when renderer recovers.
virtual void OnRendererResponsive() {}
// Called on Windows when App Commands arrive (WM_APPCOMMAND)
virtual void OnExecuteWindowsCommand(const std::string& command_name) {}
};
} // namespace atom

View File

@@ -16,7 +16,8 @@
#include "atom/common/draggable_region.h"
#include "atom/common/options_switches.h"
#include "base/strings/utf_string_conversions.h"
#include "browser/inspectable_web_contents_view.h"
#include "brightray/browser/inspectable_web_contents.h"
#include "brightray/browser/inspectable_web_contents_view.h"
#include "content/public/browser/native_web_keyboard_event.h"
#include "native_mate/dictionary.h"
#include "ui/aura/window.h"
@@ -123,6 +124,70 @@ bool IsAltModifier(const content::NativeWebKeyboardEvent& event) {
(modifiers == (Modifiers::AltKey | Modifiers::IsRight));
}
#if defined(OS_WIN)
// Convert Win32 WM_APPCOMMANDS to strings.
const char* AppCommandToString(int command_id) {
switch (command_id) {
case APPCOMMAND_BROWSER_BACKWARD : return "browser-backward";
case APPCOMMAND_BROWSER_FORWARD : return "browser-forward";
case APPCOMMAND_BROWSER_REFRESH : return "browser-refresh";
case APPCOMMAND_BROWSER_STOP : return "browser-stop";
case APPCOMMAND_BROWSER_SEARCH : return "browser-search";
case APPCOMMAND_BROWSER_FAVORITES : return "browser-favorites";
case APPCOMMAND_BROWSER_HOME : return "browser-home";
case APPCOMMAND_VOLUME_MUTE : return "volume-mute";
case APPCOMMAND_VOLUME_DOWN : return "volume-down";
case APPCOMMAND_VOLUME_UP : return "volume-up";
case APPCOMMAND_MEDIA_NEXTTRACK : return "media-nexttrack";
case APPCOMMAND_MEDIA_PREVIOUSTRACK : return "media-previoustrack";
case APPCOMMAND_MEDIA_STOP : return "media-stop";
case APPCOMMAND_MEDIA_PLAY_PAUSE : return "media-play_pause";
case APPCOMMAND_LAUNCH_MAIL : return "launch-mail";
case APPCOMMAND_LAUNCH_MEDIA_SELECT : return "launch-media-select";
case APPCOMMAND_LAUNCH_APP1 : return "launch-app1";
case APPCOMMAND_LAUNCH_APP2 : return "launch-app2";
case APPCOMMAND_BASS_DOWN : return "bass-down";
case APPCOMMAND_BASS_BOOST : return "bass-boost";
case APPCOMMAND_BASS_UP : return "bass-up";
case APPCOMMAND_TREBLE_DOWN : return "treble-down";
case APPCOMMAND_TREBLE_UP : return "treble-up";
case APPCOMMAND_MICROPHONE_VOLUME_MUTE : return "microphone-volume-mute";
case APPCOMMAND_MICROPHONE_VOLUME_DOWN : return "microphone-volume-down";
case APPCOMMAND_MICROPHONE_VOLUME_UP : return "microphone-volume-up";
case APPCOMMAND_HELP : return "help";
case APPCOMMAND_FIND : return "find";
case APPCOMMAND_NEW : return "new";
case APPCOMMAND_OPEN : return "open";
case APPCOMMAND_CLOSE : return "close";
case APPCOMMAND_SAVE : return "save";
case APPCOMMAND_PRINT : return "print";
case APPCOMMAND_UNDO : return "undo";
case APPCOMMAND_REDO : return "redo";
case APPCOMMAND_COPY : return "copy";
case APPCOMMAND_CUT : return "cut";
case APPCOMMAND_PASTE : return "paste";
case APPCOMMAND_REPLY_TO_MAIL : return "reply-to-mail";
case APPCOMMAND_FORWARD_MAIL : return "forward-mail";
case APPCOMMAND_SEND_MAIL : return "send-mail";
case APPCOMMAND_SPELL_CHECK : return "spell-check";
case APPCOMMAND_MIC_ON_OFF_TOGGLE : return "mic-on-off-toggle";
case APPCOMMAND_CORRECTION_LIST : return "correction-list";
case APPCOMMAND_MEDIA_PLAY : return "media-play";
case APPCOMMAND_MEDIA_PAUSE : return "media-pause";
case APPCOMMAND_MEDIA_RECORD : return "media-record";
case APPCOMMAND_MEDIA_FAST_FORWARD : return "media-fast-forward";
case APPCOMMAND_MEDIA_REWIND : return "media-rewind";
case APPCOMMAND_MEDIA_CHANNEL_UP : return "media-channel-up";
case APPCOMMAND_MEDIA_CHANNEL_DOWN : return "media-channel-down";
case APPCOMMAND_DELETE : return "delete";
case APPCOMMAND_DICTATE_OR_COMMAND_CONTROL_TOGGLE:
return "dictate-or-command-control-toggle";
default:
return "unkown";
}
}
#endif
class NativeWindowClientView : public views::ClientView {
public:
NativeWindowClientView(views::Widget* widget,
@@ -132,7 +197,7 @@ class NativeWindowClientView : public views::ClientView {
virtual ~NativeWindowClientView() {}
bool CanClose() override {
static_cast<NativeWindowViews*>(contents_view())->CloseWebContents();
static_cast<NativeWindowViews*>(contents_view())->RequestToClosePage();
return false;
}
@@ -142,8 +207,9 @@ class NativeWindowClientView : public views::ClientView {
} // namespace
NativeWindowViews::NativeWindowViews(content::WebContents* web_contents,
const mate::Dictionary& options)
NativeWindowViews::NativeWindowViews(
brightray::InspectableWebContents* web_contents,
const mate::Dictionary& options)
: NativeWindow(web_contents, options),
window_(new views::Widget),
web_view_(inspectable_web_contents()->GetView()->GetView()),
@@ -176,6 +242,7 @@ NativeWindowViews::NativeWindowViews(content::WebContents* web_contents,
options.Get(switches::kWidth, &width);
options.Get(switches::kHeight, &height);
gfx::Rect bounds(0, 0, width, height);
widget_size_ = bounds.size();
window_->AddObserver(this);
@@ -291,10 +358,6 @@ void NativeWindowViews::CloseImmediately() {
window_->CloseNow();
}
void NativeWindowViews::Move(const gfx::Rect& bounds) {
window_->SetBounds(bounds);
}
void NativeWindowViews::Focus(bool focus) {
if (focus)
window_->Activate();
@@ -369,40 +432,41 @@ void NativeWindowViews::SetFullScreen(bool fullscreen) {
#endif
}
bool NativeWindowViews::IsFullscreen() {
bool NativeWindowViews::IsFullscreen() const {
return window_->IsFullscreen();
}
void NativeWindowViews::SetSize(const gfx::Size& size) {
void NativeWindowViews::SetBounds(const gfx::Rect& bounds) {
#if defined(USE_X11)
// On Linux the minimum and maximum size should be updated with window size
// when window is not resizable.
if (!resizable_) {
SetMaximumSize(size);
SetMinimumSize(size);
SetMaximumSize(bounds.size());
SetMinimumSize(bounds.size());
}
#endif
window_->SetSize(size);
window_->SetBounds(bounds);
}
gfx::Size NativeWindowViews::GetSize() {
gfx::Rect NativeWindowViews::GetBounds() {
#if defined(OS_WIN)
if (IsMinimized())
return window_->GetRestoredBounds().size();
return window_->GetRestoredBounds();
#endif
return window_->GetWindowBoundsInScreen().size();
return window_->GetWindowBoundsInScreen();
}
void NativeWindowViews::SetContentSize(const gfx::Size& size) {
if (!has_frame_) {
SetSize(size);
NativeWindow::SetSize(size);
return;
}
gfx::Rect bounds = window_->GetWindowBoundsInScreen();
SetSize(ContentBoundsToWindowBounds(gfx::Rect(bounds.origin(), size)).size());
bounds.set_size(size);
SetBounds(ContentBoundsToWindowBounds(bounds));
}
gfx::Size NativeWindowViews::GetContentSize() {
@@ -492,19 +556,6 @@ void NativeWindowViews::Center() {
window_->CenterWindow(GetSize());
}
void NativeWindowViews::SetPosition(const gfx::Point& position) {
window_->SetBounds(gfx::Rect(position, GetSize()));
}
gfx::Point NativeWindowViews::GetPosition() {
#if defined(OS_WIN)
if (IsMinimized())
return window_->GetRestoredBounds().origin();
#endif
return window_->GetWindowBoundsInScreen().origin();
}
void NativeWindowViews::SetTitle(const std::string& title) {
title_ = title;
window_->UpdateWindowTitle();
@@ -556,6 +607,19 @@ bool NativeWindowViews::IsKiosk() {
}
void NativeWindowViews::SetMenu(ui::MenuModel* menu_model) {
if (menu_model == nullptr) {
// Remove accelerators
accelerator_table_.clear();
GetFocusManager()->UnregisterAccelerators(this);
// and menu bar.
#if defined(USE_X11)
global_menu_bar_.reset();
#endif
SetMenuBarVisibility(false);
menu_bar_.reset();
return;
}
RegisterAccelerators(menu_model);
#if defined(USE_X11)
@@ -728,14 +792,26 @@ void NativeWindowViews::OnWidgetActivationChanged(
else
NotifyWindowBlur();
if (active && GetWebContents() && !IsDevToolsOpened())
GetWebContents()->Focus();
if (active && inspectable_web_contents() &&
!inspectable_web_contents()->IsDevToolsViewShowing())
web_contents()->Focus();
// Hide menu bar when window is blured.
if (!active && menu_bar_autohide_ && menu_bar_visible_)
SetMenuBarVisibility(false);
}
void NativeWindowViews::OnWidgetBoundsChanged(
views::Widget* widget, const gfx::Rect& bounds) {
if (widget != window_.get())
return;
if (widget_size_ != bounds.size()) {
NotifyWindowResize();
widget_size_ = bounds.size();
}
}
void NativeWindowViews::DeleteDelegate() {
NotifyWindowClosed();
}
@@ -823,6 +899,10 @@ views::NonClientFrameView* NativeWindowViews::CreateNonClientFrameView(
#endif
}
void NativeWindowViews::OnWidgetMove() {
NotifyWindowMove();
}
#if defined(OS_WIN)
bool NativeWindowViews::ExecuteWindowsCommand(int command_id) {
// Windows uses the 4 lower order bits of |command_id| for type-specific
@@ -839,6 +919,11 @@ bool NativeWindowViews::ExecuteWindowsCommand(int command_id) {
is_minimized_ = false;
} else if ((command_id & sc_mask) == SC_MAXIMIZE) {
NotifyWindowMaximize();
} else {
std::string command = AppCommandToString(command_id & sc_mask);
FOR_EACH_OBSERVER(NativeWindowObserver,
observers_,
OnExecuteWindowsCommand(command));
}
return false;
}
@@ -856,12 +941,6 @@ void NativeWindowViews::GetDevToolsWindowWMClass(
}
#endif
void NativeWindowViews::HandleMouseDown() {
// Hide menu bar when web view is clicked.
if (menu_bar_autohide_ && menu_bar_visible_)
SetMenuBarVisibility(false);
}
void NativeWindowViews::HandleKeyboardEvent(
content::WebContents*,
const content::NativeWebKeyboardEvent& event) {
@@ -930,6 +1009,7 @@ void NativeWindowViews::RegisterAccelerators(ui::MenuModel* menu_model) {
gfx::Rect NativeWindowViews::ContentBoundsToWindowBounds(
const gfx::Rect& bounds) {
gfx::Point origin = bounds.origin();
#if defined(OS_WIN)
gfx::Rect dpi_bounds = gfx::win::DIPToScreenRect(bounds);
gfx::Rect window_bounds = gfx::win::ScreenToDIPRect(
@@ -938,6 +1018,9 @@ gfx::Rect NativeWindowViews::ContentBoundsToWindowBounds(
gfx::Rect window_bounds =
window_->non_client_view()->GetWindowBoundsForClientBounds(bounds);
#endif
// The window's position would also be changed, but we only want to change
// the size.
window_bounds.set_origin(origin);
if (menu_bar_ && menu_bar_visible_)
window_bounds.set_height(window_bounds.height() + kMenuBarHeight);
@@ -954,9 +1037,10 @@ ui::WindowShowState NativeWindowViews::GetRestoredState() {
}
// static
NativeWindow* NativeWindow::Create(content::WebContents* web_contents,
const mate::Dictionary& options) {
return new NativeWindowViews(web_contents, options);
NativeWindow* NativeWindow::Create(
brightray::InspectableWebContents* inspectable_web_contents,
const mate::Dictionary& options) {
return new NativeWindowViews(inspectable_web_contents, options);
}
} // namespace atom

View File

@@ -28,14 +28,13 @@ class NativeWindowViews : public NativeWindow,
public views::WidgetDelegateView,
public views::WidgetObserver {
public:
explicit NativeWindowViews(content::WebContents* web_contents,
const mate::Dictionary& options);
virtual ~NativeWindowViews();
NativeWindowViews(brightray::InspectableWebContents* inspectable_web_contents,
const mate::Dictionary& options);
~NativeWindowViews() override;
// NativeWindow:
void Close() override;
void CloseImmediately() override;
void Move(const gfx::Rect& pos) override;
void Focus(bool focus) override;
bool IsFocused() override;
void Show() override;
@@ -49,9 +48,9 @@ class NativeWindowViews : public NativeWindow,
void Restore() override;
bool IsMinimized() override;
void SetFullScreen(bool fullscreen) override;
bool IsFullscreen() override;
void SetSize(const gfx::Size& size) override;
gfx::Size GetSize() override;
bool IsFullscreen() const override;
void SetBounds(const gfx::Rect& bounds) override;
gfx::Rect GetBounds() override;
void SetContentSize(const gfx::Size& size) override;
gfx::Size GetContentSize() override;
void SetMinimumSize(const gfx::Size& size) override;
@@ -63,8 +62,6 @@ class NativeWindowViews : public NativeWindow,
void SetAlwaysOnTop(bool top) override;
bool IsAlwaysOnTop() override;
void Center() override;
void SetPosition(const gfx::Point& position) override;
gfx::Point GetPosition() override;
void SetTitle(const std::string& title) override;
std::string GetTitle() override;
void FlashFrame(bool flash) override;
@@ -96,6 +93,8 @@ class NativeWindowViews : public NativeWindow,
// views::WidgetObserver:
void OnWidgetActivationChanged(
views::Widget* widget, bool active) override;
void OnWidgetBoundsChanged(
views::Widget* widget, const gfx::Rect& bounds) override;
// views::WidgetDelegate:
void DeleteDelegate() override;
@@ -116,19 +115,19 @@ class NativeWindowViews : public NativeWindow,
views::ClientView* CreateClientView(views::Widget* widget) override;
views::NonClientFrameView* CreateNonClientFrameView(
views::Widget* widget) override;
void OnWidgetMove() override;
#if defined(OS_WIN)
bool ExecuteWindowsCommand(int command_id) override;
#endif
// brightray::InspectableWebContentsDelegate:
// brightray::InspectableWebContentsViewDelegate:
gfx::ImageSkia GetDevToolsWindowIcon() override;
#if defined(USE_X11)
void GetDevToolsWindowWMClass(
std::string* name, std::string* class_name) override;
#endif
// content::WebContentsDelegate:
void HandleMouseDown() override;
// NativeWindow:
void HandleKeyboardEvent(
content::WebContents*,
const content::NativeWebKeyboardEvent& event) override;
@@ -176,6 +175,7 @@ class NativeWindowViews : public NativeWindow,
std::string title_;
gfx::Size minimum_size_;
gfx::Size maximum_size_;
gfx::Size widget_size_;
scoped_ptr<SkRegion> draggable_region_;

View File

@@ -4,11 +4,13 @@
#include "atom/browser/net/adapter_request_job.h"
#include "atom/browser/atom_browser_context.h"
#include "base/threading/sequenced_worker_pool.h"
#include "atom/browser/net/url_request_buffer_job.h"
#include "atom/browser/net/url_request_fetch_job.h"
#include "atom/browser/net/url_request_string_job.h"
#include "atom/browser/net/asar/url_request_asar_job.h"
#include "atom/common/asar/asar_util.h"
#include "atom/browser/net/url_request_buffer_job.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/net_errors.h"
#include "net/url_request/url_request_error_job.h"
@@ -66,13 +68,19 @@ bool AdapterRequestJob::GetCharset(std::string* charset) {
return real_job_->GetCharset(charset);
}
void AdapterRequestJob::GetResponseInfo(net::HttpResponseInfo* info) {
real_job_->GetResponseInfo(info);
}
int AdapterRequestJob::GetResponseCode() const {
return real_job_->GetResponseCode();
}
base::WeakPtr<AdapterRequestJob> AdapterRequestJob::GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
void AdapterRequestJob::CreateErrorJobAndStart(int error_code) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
real_job_ = new net::URLRequestErrorJob(
request(), network_delegate(), error_code);
real_job_->Start();
@@ -81,25 +89,21 @@ void AdapterRequestJob::CreateErrorJobAndStart(int error_code) {
void AdapterRequestJob::CreateStringJobAndStart(const std::string& mime_type,
const std::string& charset,
const std::string& data) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
real_job_ = new URLRequestStringJob(
request(), network_delegate(), mime_type, charset, data);
real_job_->Start();
}
void AdapterRequestJob::CreateBufferJobAndStart(const std::string& mime_type,
const std::string& charset,
v8::Local<v8::Object> buffer) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
void AdapterRequestJob::CreateBufferJobAndStart(
const std::string& mime_type,
const std::string& charset,
scoped_refptr<base::RefCountedBytes> data) {
real_job_ = new URLRequestBufferJob(
request(), network_delegate(), mime_type, charset, buffer);
request(), network_delegate(), mime_type, charset, data);
real_job_->Start();
}
void AdapterRequestJob::CreateFileJobAndStart(const base::FilePath& path) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
real_job_ = asar::CreateJobFromPath(
path,
request(),
@@ -110,9 +114,22 @@ void AdapterRequestJob::CreateFileJobAndStart(const base::FilePath& path) {
real_job_->Start();
}
void AdapterRequestJob::CreateHttpJobAndStart(
AtomBrowserContext* browser_context,
const GURL& url,
const std::string& method,
const std::string& referrer) {
if (!url.is_valid()) {
CreateErrorJobAndStart(net::ERR_INVALID_URL);
return;
}
real_job_ = new URLRequestFetchJob(browser_context, request(),
network_delegate(), url, method, referrer);
real_job_->Start();
}
void AdapterRequestJob::CreateJobFromProtocolHandlerAndStart() {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
DCHECK(protocol_handler_);
real_job_ = protocol_handler_->MaybeCreateJob(request(),
network_delegate());
if (!real_job_.get())

View File

@@ -7,7 +7,9 @@
#include <string>
#include "base/memory/ref_counted_memory.h"
#include "base/memory/weak_ptr.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_job.h"
#include "net/url_request/url_request_job_factory.h"
#include "v8/include/v8.h"
@@ -18,6 +20,8 @@ class FilePath;
namespace atom {
class AtomBrowserContext;
// Ask JS which type of job it wants, and then delegate corresponding methods.
class AdapterRequestJob : public net::URLRequestJob {
public:
@@ -39,6 +43,8 @@ class AdapterRequestJob : public net::URLRequestJob {
net::Filter* SetupFilter() const override;
bool GetMimeType(std::string* mime_type) const override;
bool GetCharset(std::string* charset) override;
void GetResponseInfo(net::HttpResponseInfo* info) override;
int GetResponseCode() const override;
base::WeakPtr<AdapterRequestJob> GetWeakPtr();
@@ -53,8 +59,12 @@ class AdapterRequestJob : public net::URLRequestJob {
const std::string& data);
void CreateBufferJobAndStart(const std::string& mime_type,
const std::string& charset,
v8::Local<v8::Object> buffer);
scoped_refptr<base::RefCountedBytes> data);
void CreateFileJobAndStart(const base::FilePath& path);
void CreateHttpJobAndStart(AtomBrowserContext* browser_context,
const GURL& url,
const std::string& method,
const std::string& referrer);
void CreateJobFromProtocolHandlerAndStart();
private:

View File

@@ -0,0 +1,26 @@
// 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/net/http_protocol_handler.h"
#include "net/url_request/url_request_http_job.h"
namespace atom {
HttpProtocolHandler::HttpProtocolHandler(const std::string& scheme)
: scheme_(scheme) {
}
HttpProtocolHandler::~HttpProtocolHandler() {
}
net::URLRequestJob* HttpProtocolHandler::MaybeCreateJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate) const {
return net::URLRequestHttpJob::Factory(request,
network_delegate,
scheme_);
}
} // namespace atom

View File

@@ -0,0 +1,30 @@
// 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_NET_HTTP_PROTOCOL_HANDLER_H_
#define ATOM_BROWSER_NET_HTTP_PROTOCOL_HANDLER_H_
#include <string>
#include "net/url_request/url_request_job_factory.h"
namespace atom {
class HttpProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler {
public:
explicit HttpProtocolHandler(const std::string&);
virtual ~HttpProtocolHandler();
// net::URLRequestJobFactory::ProtocolHandler:
net::URLRequestJob* MaybeCreateJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate) const override;
private:
std::string scheme_;
};
} // namespace atom
#endif // ATOM_BROWSER_NET_HTTP_PROTOCOL_HANDLER_H_

View File

@@ -10,18 +10,16 @@
namespace atom {
URLRequestBufferJob::URLRequestBufferJob(net::URLRequest* request,
net::NetworkDelegate* network_delegate,
const std::string& mime_type,
const std::string& charset,
v8::Local<v8::Object> data)
URLRequestBufferJob::URLRequestBufferJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate,
const std::string& mime_type,
const std::string& charset,
scoped_refptr<base::RefCountedBytes> data)
: net::URLRequestSimpleJob(request, network_delegate),
mime_type_(mime_type),
charset_(charset),
buffer_data_(new base::RefCountedBytes()) {
auto input = reinterpret_cast<const unsigned char*>(node::Buffer::Data(data));
size_t length = node::Buffer::Length(data);
buffer_data_->data().assign(input, input + length);
buffer_data_(data) {
}
int URLRequestBufferJob::GetRefCountedData(

View File

@@ -19,7 +19,7 @@ class URLRequestBufferJob : public net::URLRequestSimpleJob {
net::NetworkDelegate* network_delegate,
const std::string& mime_type,
const std::string& charset,
v8::Local<v8::Object> buffer);
scoped_refptr<base::RefCountedBytes> data);
// URLRequestSimpleJob:
int GetRefCountedData(std::string* mime_type,

View File

@@ -0,0 +1,184 @@
// 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/net/url_request_fetch_job.h"
#include <algorithm>
#include <string>
#include "atom/browser/atom_browser_context.h"
#include "base/strings/string_util.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/http/http_response_headers.h"
#include "net/url_request/url_fetcher.h"
#include "net/url_request/url_fetcher_response_writer.h"
#include "net/url_request/url_request_status.h"
namespace atom {
namespace {
// Convert string to RequestType.
net::URLFetcher::RequestType GetRequestType(const std::string& raw) {
std::string method = StringToUpperASCII(raw);
if (method.empty() || method == "GET")
return net::URLFetcher::GET;
else if (method == "POST")
return net::URLFetcher::POST;
else if (method == "HEAD")
return net::URLFetcher::HEAD;
else if (method == "DELETE")
return net::URLFetcher::DELETE_REQUEST;
else if (method == "PUT")
return net::URLFetcher::PUT;
else if (method == "PATCH")
return net::URLFetcher::PATCH;
else // Use "GET" as fallback.
return net::URLFetcher::GET;
}
// Pipe the response writer back to URLRequestFetchJob.
class ResponsePiper : public net::URLFetcherResponseWriter {
public:
explicit ResponsePiper(URLRequestFetchJob* job)
: first_write_(true), job_(job) {}
// net::URLFetcherResponseWriter:
int Initialize(const net::CompletionCallback& callback) override {
return net::OK;
}
int Write(net::IOBuffer* buffer,
int num_bytes,
const net::CompletionCallback& callback) override {
if (first_write_) {
// The URLFetcherResponseWriter doesn't have an event when headers have
// been read, so we have to emulate by hooking to first write event.
job_->HeadersCompleted();
first_write_ = false;
}
return job_->DataAvailable(buffer, num_bytes);
}
int Finish(const net::CompletionCallback& callback) override {
return net::OK;
}
private:
bool first_write_;
URLRequestFetchJob* job_;
DISALLOW_COPY_AND_ASSIGN(ResponsePiper);
};
} // namespace
URLRequestFetchJob::URLRequestFetchJob(
AtomBrowserContext* browser_context,
net::URLRequest* request,
net::NetworkDelegate* network_delegate,
const GURL& url,
const std::string& method,
const std::string& referrer)
: net::URLRequestJob(request, network_delegate),
pending_buffer_size_(0) {
// Use |request|'s method if |method| is not specified.
net::URLFetcher::RequestType request_type;
if (method.empty())
request_type = GetRequestType(request->method());
else
request_type = GetRequestType(method);
fetcher_.reset(net::URLFetcher::Create(url, request_type, this));
fetcher_->SetRequestContext(browser_context->url_request_context_getter());
fetcher_->SaveResponseWithWriter(make_scoped_ptr(new ResponsePiper(this)));
// Use |request|'s referrer if |referrer| is not specified.
if (referrer.empty()) {
fetcher_->SetReferrer(request->referrer());
} else {
fetcher_->SetReferrer(referrer);
}
// Use |request|'s headers.
net::HttpRequestHeaders headers;
if (request->GetFullRequestHeaders(&headers)) {
fetcher_->SetExtraRequestHeaders(headers.ToString());
}
}
void URLRequestFetchJob::HeadersCompleted() {
response_info_.reset(new net::HttpResponseInfo);
response_info_->headers = fetcher_->GetResponseHeaders();
NotifyHeadersComplete();
}
int URLRequestFetchJob::DataAvailable(net::IOBuffer* buffer, int num_bytes) {
// Clear the IO_PENDING status.
SetStatus(net::URLRequestStatus());
// Do nothing if pending_buffer_ is empty, i.e. there's no ReadRawData()
// operation waiting for IO completion.
if (!pending_buffer_.get())
return net::ERR_IO_PENDING;
// pending_buffer_ is set to the IOBuffer instance provided to ReadRawData()
// by URLRequestJob.
int bytes_read = std::min(num_bytes, pending_buffer_size_);
memcpy(pending_buffer_->data(), buffer->data(), bytes_read);
// Clear the buffers before notifying the read is complete, so that it is
// safe for the observer to read.
pending_buffer_ = nullptr;
pending_buffer_size_ = 0;
NotifyReadComplete(bytes_read);
return bytes_read;
}
void URLRequestFetchJob::Start() {
fetcher_->Start();
}
void URLRequestFetchJob::Kill() {
URLRequestJob::Kill();
fetcher_.reset();
}
bool URLRequestFetchJob::ReadRawData(net::IOBuffer* dest,
int dest_size,
int* bytes_read) {
pending_buffer_ = dest;
pending_buffer_size_ = dest_size;
SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0));
return false;
}
bool URLRequestFetchJob::GetMimeType(std::string* mime_type) const {
if (!response_info_)
return false;
return response_info_->headers->GetMimeType(mime_type);
}
void URLRequestFetchJob::GetResponseInfo(net::HttpResponseInfo* info) {
if (response_info_)
*info = *response_info_;
}
int URLRequestFetchJob::GetResponseCode() const {
if (!response_info_)
return -1;
return response_info_->headers->response_code();
}
void URLRequestFetchJob::OnURLFetchComplete(const net::URLFetcher* source) {
pending_buffer_ = nullptr;
pending_buffer_size_ = 0;
NotifyDone(fetcher_->GetStatus());
if (fetcher_->GetStatus().is_success())
NotifyReadComplete(0);
}
} // namespace atom

View File

@@ -0,0 +1,54 @@
// 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_NET_URL_REQUEST_FETCH_JOB_H_
#define ATOM_BROWSER_NET_URL_REQUEST_FETCH_JOB_H_
#include <string>
#include "net/url_request/url_fetcher_delegate.h"
#include "net/url_request/url_request_job.h"
namespace atom {
class AtomBrowserContext;
class URLRequestFetchJob : public net::URLRequestJob,
public net::URLFetcherDelegate {
public:
URLRequestFetchJob(AtomBrowserContext* browser_context,
net::URLRequest* request,
net::NetworkDelegate* network_delegate,
const GURL& url,
const std::string& method,
const std::string& referrer);
void HeadersCompleted();
int DataAvailable(net::IOBuffer* buffer, int num_bytes);
// net::URLRequestJob:
void Start() override;
void Kill() override;
bool ReadRawData(net::IOBuffer* buf,
int buf_size,
int* bytes_read) override;
bool GetMimeType(std::string* mime_type) const override;
void GetResponseInfo(net::HttpResponseInfo* info) override;
int GetResponseCode() const override;
// net::URLFetcherDelegate:
void OnURLFetchComplete(const net::URLFetcher* source) override;
private:
scoped_ptr<net::URLFetcher> fetcher_;
scoped_refptr<net::IOBuffer> pending_buffer_;
int pending_buffer_size_;
scoped_ptr<net::HttpResponseInfo> response_info_;
DISALLOW_COPY_AND_ASSIGN(URLRequestFetchJob);
};
} // namespace atom
#endif // ATOM_BROWSER_NET_URL_REQUEST_FETCH_JOB_H_

View File

@@ -17,7 +17,7 @@
<key>CFBundleIconFile</key>
<string>atom.icns</string>
<key>CFBundleVersion</key>
<string>0.25.0</string>
<string>0.29.1</string>
<key>LSMinimumSystemVersion</key>
<string>10.8.0</string>
<key>NSMainNibFile</key>
@@ -26,5 +26,7 @@
<string>AtomApplication</string>
<key>NSSupportsAutomaticGraphicsSwitching</key>
<true/>
<key>NSHighResolutionCapable</key>
<true/>
</dict>
</plist>

Some files were not shown because too many files have changed in this diff Show More