Compare commits

..

986 Commits

Author SHA1 Message Date
Cheng Zhao
c0528c5049 Bump v0.33.2 2015-09-25 17:50:53 +08:00
Cheng Zhao
5de1b20935 Merge pull request #2900 from atom/titlebar-drag
Make draggable region work for window with hidden titlebar
2015-09-25 17:12:53 +08:00
Cheng Zhao
7884a2319c osx: Make draggable region work for window with hidden titlebar 2015-09-25 16:38:36 +08:00
Cheng Zhao
6f944ad49b Clean up code 2015-09-25 16:21:08 +08:00
Cheng Zhao
94e5018a47 Merge pull request #2898 from atom/fix-download-item-doc
Fix inconsistent docs: downloadItem.getURL() => downloadItem.getUrl()
2015-09-25 13:33:49 +08:00
Haojian Wu
4a64d1d946 📝 fix a typo
interrputed => interrupted
2015-09-25 13:13:11 +08:00
Cheng Zhao
004d3ced53 Update node to fix building on Windows 2015-09-25 13:04:54 +08:00
Cheng Zhao
109d8352e1 Update node, fixes #2894 2015-09-25 12:52:16 +08:00
Haojian Wu
01f0643142 Fix inconsistent docs: downloadItem.getURL() => downloadItem.getUrl() 2015-09-25 09:34:04 +08:00
Cheng Zhao
a0638fe801 spec: Suppress the setTimeout test on Travis CI
Not sure why it failed there.
2015-09-24 21:06:24 +08:00
Cheng Zhao
ecefd3540b Merge pull request #2840 from atom/download-item
Add more download supports in Electron
2015-09-24 21:04:25 +08:00
Haojian Wu
06cc133959 Some cleanup. 2015-09-24 19:31:09 +08:00
Cheng Zhao
da57a3101f Call WasShown when showing window
Otherwise WebContents would be invisible when window is hidden at first
and then show later.

Refs #2879.
2015-09-24 18:16:41 +08:00
Cheng Zhao
fc422e5d55 spec: Increase timeout for setTimeout test 2015-09-24 18:08:56 +08:00
Cheng Zhao
10731de9d6 Merge pull request #2879 from deepak1556/web_contents_visibility_patch
browser: notify webcontents hidden when window not shown
2015-09-24 18:00:25 +08:00
Cheng Zhao
c73d1ce6c7 Merge pull request #2877 from kostia/utf8-charset-in-quick-start
📝 Include UTF-8 charset in quick start example
2015-09-24 17:49:35 +08:00
Cheng Zhao
83481a369a Merge branch 'master' of https://github.com/preco21/electron into preco21-master 2015-09-24 17:00:06 +08:00
Haojian Wu
1879392c7b Reimplement downloadItem.getFilename API.
Previously, the suggested file name(Always 'empty') returned by
'download_item->GetSuggestedFilename' is not the same with the default one saved
in local disk.

The patch reimplement this API allowing it to return the default file name, which
is more expected from user.
2015-09-24 16:39:02 +08:00
Cheng Zhao
39695cdb85 docs: Set npm_config_runtime when using npm
Refs https://github.com/mapbox/node-pre-gyp/pull/175.
2015-09-24 16:18:02 +08:00
Haojian Wu
0861d5d44b Redefine 'will-download' design. 2015-09-24 16:04:44 +08:00
Cheng Zhao
62604708d1 Merge pull request #2887 from atom/fix-ffi-crash
Fix crash when using ffi
2015-09-24 15:39:16 +08:00
Cheng Zhao
e3fab8b5b3 spec: Run an example of ffi 2015-09-24 15:08:38 +08:00
Cheng Zhao
497732fb6f Revert "spec: ffi is crashing on OS X"
This reverts commit 706deae1b0.
2015-09-24 15:06:06 +08:00
Cheng Zhao
fe2d9ee0f6 Update libchromium to have the V8 patch 2015-09-24 14:16:45 +08:00
Cheng Zhao
5d26bc08ee Merge pull request #2886 from atom/fix-asar-leak
win: Fix leaking of fd when reading file in asar
2015-09-24 14:00:23 +08:00
Robo
5ca5c4fb92 browser: hide webcontents when window not shown 2015-09-24 10:30:18 +05:30
Cheng Zhao
576257470b spec: Remove the will-navigate test
It is unreliable to test in renderer process, remove it for now.
2015-09-24 12:20:29 +08:00
Cheng Zhao
269f70c12a spec: Reading asar file should not leak fd 2015-09-24 12:15:18 +08:00
Cheng Zhao
9e90ea8734 win: Fix leaking of fd when reading file in asar 2015-09-24 12:11:07 +08:00
Cheng Zhao
9b1fa04988 win: Fix building 2015-09-24 12:01:57 +08:00
Plusb Preco
d621755f13 Update as upstream, improve grammar 2015-09-24 12:47:30 +09:00
Cheng Zhao
e3ec705c80 Merge pull request #2882 from atom/no-guids-in-tray
Remove GUID from Shell_NotifyIcon calls
2015-09-24 11:32:15 +08:00
Paul Betts
b0e5039951 Fix initializer 2015-09-23 11:26:57 -07:00
Paul Betts
22e6f15795 Remove GUID from Shell_NotifyIcon calls
https://github.com/atom/electron/issues/2468#issuecomment-142684129 has
the details
2015-09-23 11:20:26 -07:00
Cheng Zhao
1520ebfe1f Update brightray for #2861 2015-09-23 17:31:26 +08:00
Cheng Zhao
142702866d Merge pull request #2861 from deepak1556/ssl_version_config_patch
browser: switch to set minimum version for TLS fallback
2015-09-23 17:30:26 +08:00
Kostiantyn Kahanskyi
334c28d128 📝 Include UTF-8 charset in quick start example
Partially fixes #678
2015-09-23 10:21:03 +02:00
Cheng Zhao
057c77341a Merge pull request #2875 from atom/fix-buffer-gc
Do not rely garbage collection to free memory of Buffer
2015-09-23 15:58:59 +08:00
Cheng Zhao
706deae1b0 spec: ffi is crashing on OS X 2015-09-23 15:44:50 +08:00
Cheng Zhao
f8f8db7e88 spec: Test whether ffi works 2015-09-23 14:16:07 +08:00
Cheng Zhao
6c01cec8d2 Update node to not rely on GC to free memory 2015-09-23 14:16:07 +08:00
Cheng Zhao
d8062ab9e1 docs: win.setMenu is not available on OS X 2015-09-23 11:45:51 +08:00
Robo
748b1387d2 browser: switch to set minimum version for TLS fallback 2015-09-23 09:10:36 +05:30
Cheng Zhao
6c8a9cb072 Merge pull request #2870 from atom/window-open-options
Pass options in "new-window" event
2015-09-23 00:06:50 +08:00
Cheng Zhao
7165aa5467 Merge pull request #2846 from alexsalas/patch-1
err undefined
2015-09-22 23:42:51 +08:00
Cheng Zhao
8bfa3cba63 docs: The options parameter of new-window event 2015-09-22 23:41:08 +08:00
Cheng Zhao
f2fa0e96eb Pass options in "new-window" event 2015-09-22 23:40:16 +08:00
Cheng Zhao
d0d71efb0b Merge pull request #2869 from atom/inherit-window-open
Inherit parent window's options in window.open
2015-09-22 23:15:01 +08:00
Cheng Zhao
486f16fffa spec: Increase timeout for window.open specs 2015-09-22 22:48:52 +08:00
Cheng Zhao
e499bb14de docs: Mention window.open inherits options 2015-09-22 22:46:44 +08:00
Cheng Zhao
4521db459b spec: window.open should inherit options of parent window 2015-09-22 22:36:46 +08:00
Cheng Zhao
de41890196 Inherit parent window's options in window.open 2015-09-22 22:32:10 +08:00
Cheng Zhao
a6b7dd22e8 Merge pull request #2868 from atom/window-open-full
Add allowpopups attribute for webview
2015-09-22 21:52:07 +08:00
Cheng Zhao
f06f8ae73b spec: Add test for allowpopups attribute 2015-09-22 21:18:04 +08:00
Cheng Zhao
9cbdde2eba docs: allowpopups attribute 2015-09-22 20:13:49 +08:00
Cheng Zhao
f07fea1936 Add allowpopups attribute for webview 2015-09-22 20:11:05 +08:00
Cheng Zhao
7c65d05b02 Don't print error when window.open failed 2015-09-22 19:59:32 +08:00
Cheng Zhao
619a397ec9 Bump v0.33.1 2015-09-22 15:13:50 +08:00
Cheng Zhao
889d7c1e02 Merge pull request #2866 from atom/no-expose-setimmediate
No more exposing setImmediate as local variable
2015-09-22 15:10:44 +08:00
Cheng Zhao
4cccce6bfe spec: Suppress beginFrameSubscription for now
Since the callback is called asynchronously there is no way to prevent
the callback from being called twice.
2015-09-22 14:55:35 +08:00
Cheng Zhao
4a91972037 spec: Revert back to original behavior of setImmediate 2015-09-22 14:40:48 +08:00
Cheng Zhao
42515c6f41 No more need of manually setting process as local variable 2015-09-22 14:30:54 +08:00
Cheng Zhao
eccb5e7590 Don't make setImmediate a local variable
It makes more troubles than benefits, and somehow it is slowing message
loop down.
2015-09-22 14:29:21 +08:00
Cheng Zhao
008af00044 Merge pull request #2852 from deepak1556/web_frame_scheme_api_patch
webframe: api to register scheme as privileged
2015-09-22 09:59:24 +08:00
Robo
325feca864 webframe: api to register scheme as privileged 2015-09-21 22:59:59 +05:30
Haojian Wu
5ef9c7e1a1 Add spec for download item. 2015-09-21 21:44:51 +08:00
Haojian Wu
22168bc6d8 Allow emitting 'done' event when user cancel the download saving dialog. 2015-09-21 21:44:18 +08:00
Cheng Zhao
62d64e7528 Merge pull request #2829 from nekuz0r/enhanced-redirect-event
More infos on did-get-redirect-request event
2015-09-21 21:15:13 +08:00
Gohy Leandre
477103191f Add http_response_code, method, referrer, response_headers to did-get-redirect-request event. 2015-09-21 09:51:58 +02:00
Haojian Wu
57bf0cb615 Refractor in completed event in DownloadItem.
* Rename `completed` to `done`, making it align with Chromium's style.
* Add 'state' in `done` event's result. It can check the download item final
status: cancelled, completed, interrupted.
2015-09-21 14:00:38 +08:00
Cheng Zhao
01a3bf5881 Merge pull request #2837 from rhencke/patch-1
Fix small typo in debug message.
2015-09-21 11:49:33 +08:00
Cheng Zhao
a69c9600ce Merge pull request #2836 from Ingramz/patch-1
Fix a typo
2015-09-21 11:46:28 +08:00
Cheng Zhao
a567d7a0b6 spec: Suppress beginFrameSubscription on CI 2015-09-21 11:43:10 +08:00
Cheng Zhao
7807d878d2 spec: Add timeout for beginFrameSubscription 2015-09-21 11:37:35 +08:00
Cheng Zhao
a69121fc24 Merge pull request #2834 from preco21/master
Update as upstream, change name the translation folder
2015-09-21 11:35:37 +08:00
Cheng Zhao
be600fda55 spec: Prevent callback of beginFrameSubscription being called twice 2015-09-21 11:24:05 +08:00
Cheng Zhao
35fc8885de Merge pull request #2847 from atom/add-chromium-license
Add Chromium's licenses to the dist
2015-09-21 11:05:45 +08:00
Cheng Zhao
717e0f9821 Add Chromium's licenses to the dist 2015-09-21 10:18:38 +08:00
Haojian Wu
997ac91fe0 Add donwloadItem.getContentDisposition() API. 2015-09-21 09:38:38 +08:00
Haojian Wu
4391e81dfe Keep compatibility with old APIs. 2015-09-21 09:38:06 +08:00
Haojian Wu
d0ee30101d Fix cpplint warnings. 2015-09-21 09:34:49 +08:00
Haojian Wu
dd38131704 📝 Add DownloadItem doc. 2015-09-21 09:34:42 +08:00
Alexander Salas
40b861bc9c err undefined 2015-09-20 17:58:41 -04:30
Haojian Wu
5ec74451ef Introduce DownloadItem for supporting more downloading features. 2015-09-20 18:56:10 +08:00
Haojian Wu
87b9b0bc31 Implement session.setOpenDownloadDialog() API. 2015-09-20 18:45:34 +08:00
Robert Hencke
76b7cd0908 Fix small typo in debug message. 2015-09-19 17:11:29 -04:00
Indrek Ardel
c626ee6e92 Fix a typo 2015-09-19 21:17:23 +03:00
Plusb Preco
94b6b92e4c Merge remote-tracking branch 'atom/master' 2015-09-19 15:32:20 +09:00
Plusb Preco
6cf6cb9a79 Update as upstream, change name the translation folder
* Update as upstream
* Change name the translation folder (ko to ko-KR)
2015-09-19 15:30:30 +09:00
Cheng Zhao
7bb9595b81 Merge pull request #2827 from atom/fix-2752
Move the BeginFrameSubscription method to WebContents
2015-09-18 19:29:17 +08:00
Cheng Zhao
f716d47e54 spec: Make the will-navigate test run faster 2015-09-18 18:57:48 +08:00
Cheng Zhao
353cdd967a spec: Add test for webContents.beginFrameSubscription 2015-09-18 18:51:49 +08:00
Cheng Zhao
32bff05208 docs: <webview>.sendInputEvent 2015-09-18 18:32:21 +08:00
Cheng Zhao
b8d50f3a3a spec: Add test for sendInputEvent 2015-09-18 18:28:34 +08:00
Cheng Zhao
7b2980434c Fix wrong return values in a few converters 2015-09-18 18:21:51 +08:00
Cheng Zhao
ff0e15bf58 Expose sendInputEvent in webview 2015-09-18 17:55:42 +08:00
Cheng Zhao
1e918480b4 docs: webContents.beginFrameSubscription 2015-09-18 17:53:19 +08:00
Cheng Zhao
573892c112 docs: webContents.sendInputEvent 2015-09-18 17:44:11 +08:00
Cheng Zhao
86f523d3c1 Move BeginFrameSubscription to WebContents 2015-09-18 15:57:43 +08:00
Cheng Zhao
42863e4700 Move SendInputEvent to WebContents 2015-09-18 14:20:31 +08:00
Cheng Zhao
9e7de78231 Fix cpplint warnings 2015-09-18 14:12:48 +08:00
Cheng Zhao
c550546ff1 Do not manually convert Object to WebInputEvent 2015-09-18 14:09:31 +08:00
Cheng Zhao
5a599cb6ff Sequence of definitions should follow the declarations 2015-09-18 13:49:33 +08:00
Cheng Zhao
84ce441fb6 Add converters for WebInputEvent 2015-09-18 13:33:06 +08:00
Cheng Zhao
d7bac5a10b Remove the offscreen-render option
We are going to move the APIs to WebContents
2015-09-18 12:15:13 +08:00
Cheng Zhao
ec90d03d74 Fix compilation error 2015-09-18 12:10:00 +08:00
Cheng Zhao
ee0d48dc5a Merge branch 'master' of https://github.com/MaxWhere/electron into MaxWhere-master 2015-09-18 12:01:33 +08:00
Cheng Zhao
15394b9a3b Merge pull request #2825 from atom/blink-converter
Move the converters for blink structures to another file
2015-09-18 11:27:49 +08:00
Cheng Zhao
5aa7cf7a30 Fix cpplint warning 2015-09-18 11:10:32 +08:00
Cheng Zhao
7dc7ee1c41 Move the converters for blink structures to another file
It makes the api::WebContents smaller.
2015-09-18 11:06:38 +08:00
Cheng Zhao
96d35ec29e Merge pull request #2802 from nekuz0r/device-emulation
Add device emulation
2015-09-18 10:43:17 +08:00
Cheng Zhao
91796e7095 Merge pull request #2819 from IonicaBizauKitchen/hash
Fix the git commit messages hash link
2015-09-18 10:25:31 +08:00
Cheng Zhao
75b0d0cd6c Merge pull request #2818 from IonicaBizauKitchen/require
Fixed the mapNumbers require call
2015-09-18 10:25:10 +08:00
Gohy Leandre
6b875110ed Add device emulation API 2015-09-17 13:50:36 +02:00
Cheng Zhao
1348e18a81 Bump v0.33.0 2015-09-17 18:31:12 +08:00
Cheng Zhao
c700c58793 Merge pull request #2817 from atom/fix-set-immediate
Update to node v4.1.0
2015-09-17 18:27:53 +08:00
Ionică Bizău
a46cb8cebb Fix the git commit messages hash link 2015-09-17 12:34:15 +03:00
Ionică Bizău
01ed2c4222 Fixed the mapNumbers require call
Since mapNumber.js is a file, we should prefix it with "./", otherwise an error is thrown.
2015-09-17 12:24:12 +03:00
Cheng Zhao
d28789b509 Change version to v0.32.4
This makes sure the native modules are built against the headers of
v0.32.4, since Node.js v4.1.0 has bumped the module version.
2015-09-17 16:48:53 +08:00
Cheng Zhao
2be6bdcf4a Update to node v4.1.0 2015-09-17 16:06:35 +08:00
Cheng Zhao
5604655d54 spec: vm.createContext should not crash 2015-09-17 16:06:19 +08:00
Cheng Zhao
93639a080c spec: setImmediate should work in forked scripts 2015-09-17 15:12:15 +08:00
Cheng Zhao
e30dd943db Update brightray for #2808 2015-09-17 15:01:33 +08:00
Cheng Zhao
a386bb4edf Merge pull request #2815 from atom/release-resources
Release the resources of native window immediately when it is closed
2015-09-17 14:56:21 +08:00
Plusb Preco
ce8eb4a32c Merge remote-tracking branch 'atom/master' 2015-09-17 14:35:10 +09:00
Cheng Zhao
e73c655d65 No need to delete window in Destory
The native window is now automatically deleted after it gets closed.
2015-09-17 11:32:19 +08:00
Cheng Zhao
e3c64d7971 Release the native window after window gets closed
Previously we delete the window after the JS object gets garbage
collected, which is too late for releasing some resources.
2015-09-17 11:30:17 +08:00
Cheng Zhao
9fd5a64cd8 Update brightray to unsubscribe from NSNotificationCenter 2015-09-17 11:25:27 +08:00
Cheng Zhao
ec7ea3005d Merge pull request #2800 from seanchas116/app-getlocale
App app.getLocale() API to get application locale
2015-09-16 23:25:25 +08:00
Cheng Zhao
3f881e8617 Merge pull request #2798 from jonatasfreitasv/master
Three api docs translated to pt-BR
2015-09-16 23:18:28 +08:00
Cheng Zhao
cb13d8bdc7 Update brightray for #2790 2015-09-16 19:59:03 +08:00
Cheng Zhao
11ee2c47d0 Merge pull request #2789 from deepak1556/protocol_response_headers_patch
protocol: respect provided mimetype in generated response headers
2015-09-16 19:50:33 +08:00
Ryohei Ikegami
7b75b29265 Add docs for app.getLocale() 2015-09-16 17:17:49 +09:00
Ryohei Ikegami
b9c274929b Add app.getLocale() 2015-09-16 17:16:21 +09:00
Jonatas Freitas
842ec3d11b pt-BR README.md updated. 2015-09-16 00:39:14 -03:00
Jonatas Freitas
244e184b7e api/shell translated to pt-BR 2015-09-16 00:36:43 -03:00
Jonatas Freitas
a3a9bbb979 api/process.md translated to pt-BR 2015-09-16 00:10:35 -03:00
Robo
57c910faef protocol: respect provided mimetype in generated response headers 2015-09-16 08:34:04 +05:30
Heilig Benedek
90064eeddd Returning to original native_mate. 2015-09-16 03:29:23 +02:00
Cheng Zhao
08f5c32306 script: Call Electron binary from Debug build
We usually don't build Release version on the development machine.
2015-09-16 09:21:55 +08:00
Cheng Zhao
69cc3ab5ef docs: Make description of fullscreen more precise
Closes #2793.
2015-09-16 09:20:16 +08:00
Heilig Benedek
5269380b6d Removed duplicate keydown event sending. 2015-09-16 03:12:49 +02:00
Cheng Zhao
d8f77e5134 Merge pull request #2796 from atom/fix-wrong-check-activate-event
Fix a wrong check in emitting 'activate-with-no-open-windows' event.
2015-09-16 09:04:33 +08:00
Heilig Benedek
ceef06b344 Renamed setOffscreenRender to begin/endFrameSubscription because the name was a bit misleading, and replaced the ArrayBuffer creation with a node::Buffer::New call. 2015-09-16 02:59:16 +02:00
Haojian Wu
a3e9ff67b0 Fix a wrong check in emitting 'activate-with-no-open-windows' event. 2015-09-16 08:36:01 +08:00
Cheng Zhao
ae776b523c Merge pull request #2784 from neutrous/patch-1
Update quick-start.md for zh-CN
2015-09-15 21:28:59 +08:00
Cheng Zhao
10b1ea7244 Bump v0.32.3 2015-09-15 15:30:22 +08:00
Cheng Zhao
6615787775 Update node, fixes #2786 2015-09-15 15:19:43 +08:00
Cheng Zhao
cf6008a05e Merge pull request #2787 from atom/test
Fix a few failing specs on the CI machine with OS X 10.10 SDK
2015-09-15 15:02:08 +08:00
Cheng Zhao
f1787d747a The crash-reporter test is not reliable on CI machine 2015-09-15 14:43:11 +08:00
Cheng Zhao
eced01eb9d spec: Delay timeout of window.opener test 2015-09-15 14:37:27 +08:00
Cheng Zhao
357c7af3c0 spec: Check existence of webview before removing it 2015-09-15 13:45:26 +08:00
Cheng Zhao
817363b955 spec: Run tests on OS X CI machine 2015-09-15 13:42:44 +08:00
Cheng Zhao
311a5456ec Make crash-reporter spec more reliable 2015-09-15 13:18:01 +08:00
Cheng Zhao
3cf34fe40f Merge pull request #2785 from atom/fix-devtools-extension
Add BrowserWindow.isDevToolsFocused and fix "devtools-focused" not working
2015-09-15 12:56:36 +08:00
Cheng Zhao
2a3a65f67c Update brightray to use 10.10 SDK 2015-09-15 12:15:15 +08:00
Cheng Zhao
c9ee6b4caf docs: BrowserWindow.isDevToolsFocused 2015-09-15 11:43:45 +08:00
Cheng Zhao
b72a5884f2 Add BrowserWindow.isDevToolsFocused 2015-09-15 11:43:45 +08:00
Cheng Zhao
97857aa152 Update brightray for DevToolsFocused fix 2015-09-15 11:43:45 +08:00
Cheng Zhao
fe2219a635 Merge pull request #2777 from atom/dock-clicked
Implement 'activate' event for app.
2015-09-15 11:17:41 +08:00
Wujg
c99ec368b3 Update quick-start.md for zh-CN
Fixed some typo.
2015-09-15 11:15:11 +08:00
Haojian Wu
9652ed6508 More fixes after code review. 2015-09-14 19:43:21 -07:00
Cheng Zhao
dc59b4fa06 Merge pull request #2783 from atom/fix-devtools-extension
Fix `BrowserWindow.addDevToolsExtension` not working
2015-09-15 10:38:02 +08:00
Cheng Zhao
a1ccfdf777 Merge pull request #2782 from preco21/master
Update as upstream
2015-09-15 09:46:13 +08:00
Haojian Wu
40d93ce55a Deprecate 'activate-with-no-open-windows' event. 2015-09-14 18:36:05 -07:00
Haojian Wu
377e7ee3a7 Implement 'activiate' event instead of 'activate-with-open-windows'. 2015-09-14 18:34:27 -07:00
Cheng Zhao
8a8b11cf10 Do not use did-finish-load to detect whether WebContents is ready
The WebContents JS object can be created way later after the C++ object
gets created.
2015-09-15 09:21:15 +08:00
Cheng Zhao
e656d8428c Make getUrl work for devToolsWebContents 2015-09-15 09:20:56 +08:00
Cheng Zhao
238d4add99 devtools-opened should be emitted after devtools is opened 2015-09-15 09:18:22 +08:00
Cheng Zhao
3bf73bc455 Expose native implementation of WebContent::GetURL 2015-09-15 09:18:14 +08:00
Plusb Preco
9134b9cf43 Update as upstream 2015-09-15 09:50:28 +09:00
Plusb Preco
dd7036035a Merge remote-tracking branch 'atom/master' 2015-09-15 09:50:11 +09:00
Cheng Zhao
6bae0bada0 Merge pull request #2776 from jaanus/osx-window-titlebar
Implements #2734 “New API to configure BrowserWindow title bar on Mac”
2015-09-14 23:07:06 +08:00
Cheng Zhao
f140f35910 Expose experiment APIs 2015-09-14 22:59:49 +08:00
Cheng Zhao
a5dc911a05 Correctly set user agent for devtools 2015-09-14 22:55:29 +08:00
jaanus
5d8f1dd404 Implements #2734 “New API to configure BrowserWindow title bar on Mac”
New API supported on Yosemite 10.10 and newer.
2015-09-14 16:50:00 +02:00
Cheng Zhao
409b0b54e0 spec: Increate timeout for webview tests 2015-09-14 21:13:24 +08:00
Haojian Wu
c006c4efa4 Mention 'activate-with-no-open-windows' on OS X only. 2015-09-14 20:34:45 +08:00
Haojian Wu
3ad5d17612 [OS X] Implement 'activate-with-open-windows' event for app. 2015-09-14 20:32:50 +08:00
Cheng Zhao
4d28fbf561 Update brightray for atom/brightray#140 2015-09-14 19:24:54 +08:00
Cheng Zhao
1533d97e16 Merge pull request #2774 from atom/browser-window-created
Add browser-window-created event for app module
2015-09-14 17:44:50 +08:00
Cheng Zhao
ca8943c4ba spec: browser-window-created event 2015-09-14 17:02:45 +08:00
Cheng Zhao
8534ff4526 docs: browser-window-created event 2015-09-14 17:02:36 +08:00
Cheng Zhao
c346fcb326 Emit browser-window-created when window is created 2015-09-14 17:02:24 +08:00
Cheng Zhao
9e7b67802c Merge pull request #2773 from atom/require-global
Make sure global symbols of Node.js is always available in preload script
2015-09-14 16:45:27 +08:00
Cheng Zhao
9d366e6c5c Make global.setImmediate work in browser process 2015-09-14 16:34:58 +08:00
Cheng Zhao
d2e52fb6bb Set global.setImmediate 2015-09-14 16:25:43 +08:00
Cheng Zhao
baacc939f6 spec: node symbols should always be available in preload script 2015-09-14 16:05:58 +08:00
Cheng Zhao
3bd16a5ecd No more need to override setImmediate
It is now done in Node.js.
2015-09-14 15:47:39 +08:00
Cheng Zhao
7c3d3e4a87 Update node to pass all globals through "require" 2015-09-14 15:46:46 +08:00
Plusb Preco
e388163d33 Update as upstream 2015-09-14 08:07:24 +09:00
Jonatas Freitas
654626305c Documentation api/accelerator translated to pt-BR 2015-09-11 13:28:34 -03:00
Cheng Zhao
989799633d Merge pull request #2762 from GoooIce/master
Add docs-translations\api\ global-shortcut.md and accelerator.md for zh-CN
2015-09-11 21:09:07 +08:00
Cheng Zhao
bf01112acd Merge pull request #2764 from tomashanacek/master
docs: Fix role hideothers, unhide typo
2015-09-11 21:06:26 +08:00
Tomáš Hanáček
af5262630a docs: Fix role hideothers, unhide typo 2015-09-11 14:26:48 +02:00
王雪
a1cd806955 Merge pull request #3 from atom/master
更新一下啊
2015-09-11 18:38:10 +08:00
GoooIce
ff67fae9ef Add api\accelerator.md
Add api\accelerator.md
2015-09-11 17:27:20 +08:00
Cheng Zhao
b80aab3cf2 Merge pull request #2760 from preco21/master
Update as upstream, add new translated docs, fix typos,
2015-09-11 17:06:48 +08:00
Plusb Preco
750d3e979c Add session.md as translated, mark untranslated files in README.md 2015-09-11 13:30:37 +09:00
Plusb Preco
c3664463ab Update as upstream, fix typos 2015-09-11 11:56:36 +09:00
Plusb Preco
c6395c2197 Merge remote-tracking branch 'atom/master' 2015-09-11 11:56:11 +09:00
Jessica Lord
39bd10d1ef Merge pull request #2757 from atom/jl-web-contents-links
Update Documentation Links to web-contents
2015-09-10 14:48:33 -07:00
Jessica Lord
9eca0f82de Merge pull request #2751 from atom/jl-bw-prop
Create Instance Properties Section in BrowserWindow
2015-09-10 14:47:38 -07:00
Jessica Lord
4b8472d3b4 Merge pull request #2756 from GoooIce/master
Add docs-translations\api\shell.md for zh-CN
2015-09-10 12:47:05 -07:00
Jessica Lord
aae2d82c28 Update links to web-contents.md 2015-09-10 12:19:37 -07:00
Jessica Lord
6cfe43a644 Merge branch 'patch-1' of https://github.com/destan/electron into destan-patch-1 2015-09-10 12:13:21 -07:00
Jessica Lord
2ac2392a6b 🔥 extra line 2015-09-10 12:11:40 -07:00
Jessica Lord
7c287d565d Resolve conflicts 2015-09-10 12:09:37 -07:00
Paul Betts
31775aa049 Fix harder 2015-09-10 11:00:43 -07:00
Paul Betts
9ca85a7859 Fix electron-rebuild instructions for Win32 2015-09-10 10:57:08 -07:00
Jessica Lord
b861a174ca Merge pull request #2750 from atom/jl-doc-bits
A Few More Documentation Things
2015-09-10 10:41:42 -07:00
GoooIce
92f7899c60 Add api\global-shortcut.md
Add api\global-shortcut.md
2015-09-10 22:29:22 +08:00
王雪
572199068b Merge pull request #2 from atom/master
更新一下啊
2015-09-10 20:39:22 +08:00
GoooIce
32a66fa94e add api\shell.md
add api\shell.md
2015-09-10 20:27:50 +08:00
Cheng Zhao
60522e0d68 Bump v0.32.2 2015-09-10 16:27:15 +08:00
Cheng Zhao
708526baec Merge pull request #2754 from atom/fix-node-integration
Fix "node-integration" not working in "web-preferences"
2015-09-10 16:26:12 +08:00
Cheng Zhao
ae2f754d10 No need to set menu in spec window 2015-09-10 16:01:04 +08:00
Cheng Zhao
143453b603 Update native-mate to fix the behavior of Dictionary::Get 2015-09-10 15:58:10 +08:00
Cheng Zhao
d4cbf7cadb spec: node-integration should work in web-preferences 2015-09-10 15:57:16 +08:00
GoooIce
3ee854d9a3 Merge branch 'master' of https://github.com/GoooIce/electron 2015-09-10 14:34:11 +08:00
王雪
442b0d5df3 Merge pull request #1 from atom/master
更新一下啊
2015-09-10 14:37:05 +08:00
GoooIce
c8954ff32c Merge remote-tracking branch 'atom/master' 2015-09-10 14:27:16 +08:00
Cheng Zhao
6321a3898c Merge pull request #2748 from etiktin/patch-1
Update README.md
2015-09-10 11:18:24 +08:00
Cheng Zhao
70af2e0bee osx: Don't warn about unkown warning option
We can not make every compiler happy.
2015-09-10 11:15:35 +08:00
Cheng Zhao
626c7d1090 Merge pull request #2747 from nekuz0r/did-fail-event-url
add ValidatedUrl to did-fail-load event
2015-09-10 11:02:01 +08:00
Heilig Benedek
1497e7e2ac Whoops, missed a line last time. 2015-09-10 02:24:08 +02:00
Heilig Benedek
69769f9319 Resetting debug changes 2015-09-10 02:23:12 +02:00
Heilig Benedek
f807a8f1e7 Reset native-mate to the original repo 2015-09-10 02:16:41 +02:00
Heilig Benedek
b2af370249 Changed StringArray options to regular js objects with boolean values for better readability from the js side 2015-09-10 02:10:47 +02:00
Jessica Lord
c29a2e4992 Standardize DevTools 2015-09-09 14:11:06 -07:00
Jessica Lord
279fd0a461 Standardize **Note:** 2015-09-09 14:09:14 -07:00
Jessica Lord
1a35d6bda6 🔥 extra lines 2015-09-09 14:00:37 -07:00
Jessica Lord
5593717d78 Create Instance Properties section 2015-09-09 13:57:35 -07:00
Jessica Lord
6abc4fb255 🔥 odd, stray + 2015-09-09 13:48:04 -07:00
Jessica Lord
e9712e2998 Add section on documentation translations 2015-09-09 13:33:11 -07:00
Jessica Lord
ce49bba2fc Add section links 2015-09-09 13:32:56 -07:00
Eran Tiktin
5089929be8 Update README.md
Capitalized the "Formerly known..." text + rearranged the community section and mention the slack channel.
2015-09-09 21:34:20 +03:00
Gohy Leandre
590be75fa9 add ValidatedUrl to did-fail-load event 2015-09-09 15:56:16 +02:00
Jessica Lord
0046970805 Merge pull request #2713 from etiktin/fix_es_translation_links
Fix es translation links
2015-09-09 06:47:26 -07:00
Cheng Zhao
9dc6cfc1e9 Bump v0.32.1 2015-09-09 19:39:42 +08:00
Cheng Zhao
749a1a3e9a Merge pull request #2746 from atom/no-keep
Fix session not getting persisted on exit
2015-09-09 19:39:20 +08:00
Cheng Zhao
93bbc0bca9 Don't reference RequestContextGetter in JS objects
V8 doesn't guarrentee the C++ class of JS objects will get destroyed, so
this will result in RequestContextGetter never getting freed
2015-09-09 19:27:28 +08:00
Cheng Zhao
9d51da505e Run destruction callbacks before message loop gets destroyed 2015-09-09 19:27:08 +08:00
Destan Sarpkaya
e48f5ea1aa update broken link 2015-09-09 14:06:33 +03:00
Cheng Zhao
e5496d9ac0 Merge pull request #2743 from atom/fix-backward-compatibility
Fix backward compatibility with old BrowserWindow options
2015-09-09 16:25:03 +08:00
Cheng Zhao
c2b2a2072f spec: Set node-integration in window.open should work 2015-09-09 16:11:45 +08:00
Cheng Zhao
446235c8cd Fix backward compatibility with old BrowserWindow options 2015-09-09 15:55:26 +08:00
Cheng Zhao
530b040ade Merge pull request #2732 from John-Lin/master
Add doc translation in zh-TW
2015-09-09 15:41:06 +08:00
Cheng Zhao
375ac3e6ec Update brightray, fixes #2669 2015-09-09 13:35:07 +08:00
John-Lin
a200718944 add doc translation for synopsis 2015-09-08 15:47:29 +08:00
John-Lin
ba02e19fae add doc translation for process 2015-09-08 15:47:11 +08:00
John-Lin
8e1979a6a5 add doc translation for file object 2015-09-08 15:46:48 +08:00
Cheng Zhao
e5386cf8ea Bump v0.32.0 2015-09-08 13:40:10 +08:00
Cheng Zhao
e597229750 Merge pull request #2711 from jonatasfreitasv/master
application-distribution.md translated to pt-BR
2015-09-08 13:36:28 +08:00
Cheng Zhao
8b3ed9067e Merge pull request #2725 from John-Lin/master
Add doc translation in zh-TW
2015-09-08 13:34:14 +08:00
Cheng Zhao
40d4c65866 Merge pull request #2730 from preco21/master
Update as upstream
2015-09-08 13:24:42 +08:00
Cheng Zhao
1ca6534dcd Merge pull request #2712 from etiktin/add_chrome_version_2_gitignore
Fix `create_chrome_version_h` so it will generate chrome_version.h only if needed
2015-09-08 13:24:12 +08:00
Cheng Zhao
830bb54d6a Merge pull request #2731 from deepak1556/cleanup_patch
remove unused code
2015-09-08 13:23:23 +08:00
Robo
785eb9657b remove unused code 2015-09-08 05:24:07 +05:30
Plusb Preco
21bd578935 Update README-ko.md 2015-09-08 08:50:59 +09:00
Plusb Preco
1e0facc103 Update as upstream 2015-09-08 08:42:28 +09:00
Eran Tiktin
db3e27ceaa Fix create_chrome_version_h in bootstrap.py
The code was supposed to compare the content of the existing file with
the new content and only replace the file if the content was different,
but it had a fatal flow. It opened the existing file with 'w+' or 'wb+'
and they both truncate the file, so the compare was always false and we
always overwrote the file.
The updated code compares the file content ignoring line endings and
writes the file only if its different or if it didn't exist.
2015-09-07 21:55:02 +03:00
Eran Tiktin
b521e45ef8 Revert "Remove chrome_version.h from git"
This reverts commit dcbd8316df.
2015-09-07 19:51:37 +03:00
Eran Tiktin
ad6e67fdfa Revert "Add chrome_version.h to gitignore"
This reverts commit 41e1555cf4.
2015-09-07 19:51:28 +03:00
Cheng Zhao
564b74b19c Merge pull request #2726 from atom/fix-stdout
Fix exception when accessing process.stdout
2015-09-07 23:02:56 +08:00
Cheng Zhao
62b1034c6b Suppress the isTTY spec, not reliable on some machines 2015-09-07 22:42:46 +08:00
Cheng Zhao
4412a89270 Explicitly writes debug log to stderr
If we don't do this Chromium will close stdout and stderr for us,
resulting process.stdout not working.
2015-09-07 21:45:43 +08:00
Cheng Zhao
d4aa2308cd Update node to catch exception when accessing process.stdout 2015-09-07 21:45:27 +08:00
Cheng Zhao
8912b404a9 spec: process.stdout should have isTTY defined 2015-09-07 21:37:17 +08:00
Cheng Zhao
d7ec0b99fd spec: process.stdout should not throw exception 2015-09-07 21:37:17 +08:00
Cheng Zhao
87e02f2858 Merge pull request #2723 from atom/cleanup
A few unimportant code cleanups
2015-09-07 17:57:48 +08:00
John-Lin
66f7f2e6f2 add doc translation for power-save-blocker.md 2015-09-07 17:36:33 +08:00
John-Lin
13722e26cd add doc translation for power-monitor.md 2015-09-07 17:36:14 +08:00
Cheng Zhao
e365cb6b1c No longer needs to define node_includes.h at last 2015-09-07 16:41:49 +08:00
Cheng Zhao
46b2b91a27 Don't use Node's internal APIs 2015-09-07 16:41:49 +08:00
Cheng Zhao
24bbe5dabf No need to define WebContentsPreferences::From 2015-09-07 16:16:34 +08:00
Cheng Zhao
3717f5b7f2 Merge pull request #2722 from atom/fix-array-buffer
Support creating externalized ArrayBuffer for node::Buffer
2015-09-07 13:20:19 +08:00
Cheng Zhao
10bc0c20b1 Update libchromiumcontent to have WebArrayBuffer::createExternal API 2015-09-07 11:18:11 +08:00
Cheng Zhao
0a4fb2ec4f Support externalized ArrayBuffer for node::Buffer 2015-09-07 11:12:42 +08:00
Cheng Zhao
8cc1046992 Update to io.js 3.3.0 2015-09-07 11:05:27 +08:00
Plusb Preco
3669113ad2 Merge remote-tracking branch 'atom/master' 2015-09-07 11:47:04 +09:00
Cheng Zhao
aad1f5082f Merge pull request #2719 from Rokt33r/patch-1
fix typo
2015-09-06 16:18:48 +08:00
Jonatas Freitas
f56d715104 Translated application-packaging.md to pt-BR. 2015-09-06 01:27:34 -03:00
Cheng Zhao
cd12dbd47e Merge pull request #2718 from atom/all-in-webcontents
Cleanup code of Session and WebContents
2015-09-06 12:22:20 +08:00
Cheng Zhao
5830532a45 Merge pull request #2704 from preco21/master
Update as upstream
2015-09-06 12:21:14 +08:00
Dick Choi
4537d88a58 fix typo
Code block should be ended ``
2015-09-06 12:36:27 +09:00
Cheng Zhao
342e0c6cf7 Remove dead code 2015-09-06 11:13:41 +08:00
Cheng Zhao
512f89910d docs: No more extra-plugin-dirs 2015-09-06 11:07:38 +08:00
Cheng Zhao
e2bd1abce6 Make sure BrowserContext is destroyed on exit 2015-09-06 10:54:34 +08:00
Cheng Zhao
5eb0bedbbc Parse partition in webContents.create 2015-09-06 10:54:34 +08:00
Cheng Zhao
2454dccde0 docs: preload, node-integration, zoom-factor have been moved 2015-09-06 10:54:34 +08:00
Cheng Zhao
0b1a3f3ef3 Manage the life of BrowserContext in Session 2015-09-06 10:54:34 +08:00
Cheng Zhao
fafb28e41a Move management of browser context to BrowserContext 2015-09-06 10:54:34 +08:00
Cheng Zhao
ba25bed45b Store BrowserContext in ref-counted ptr 2015-09-06 10:54:34 +08:00
Cheng Zhao
3773f81fd5 Pass partition name instead of path to BrowserContext 2015-09-06 10:53:39 +08:00
Cheng Zhao
f2bdca31b3 spec: webview test should avoid affecting each other 2015-09-06 10:53:03 +08:00
Cheng Zhao
9c235509a6 Read guest view's info from WebContentsPreferences 2015-09-06 10:53:03 +08:00
Cheng Zhao
b1afe538ee Add undocumented "preload-url" option for web-preferences 2015-09-06 10:53:03 +08:00
Cheng Zhao
0b97d58a6f Move a few options in NativeWindow to web-preferences 2015-09-06 10:53:03 +08:00
Cheng Zhao
880dce950d Move OverrideWebkitPrefs to WebContentsPreferences 2015-09-06 10:53:03 +08:00
Cheng Zhao
39975378bb Move AppendExtraCommandLineSwitches to WebContentsPreferences 2015-09-06 10:53:03 +08:00
Cheng Zhao
96771c7098 NPAPI has been removed, remove related option 2015-09-06 10:53:03 +08:00
Cheng Zhao
0e92a3e333 Use options['web-preferences'] to create WebContents 2015-09-06 10:53:03 +08:00
Cheng Zhao
dd871812b7 Add WebContentsPrefrences class 2015-09-06 10:53:03 +08:00
Cheng Zhao
81d423c547 Merge pull request #2710 from etiktin/fix_build_failing_on_windows
Fix build failing on windows
2015-09-06 10:52:30 +08:00
Jonatas Freitas
943fe2c22d Change file names to follow styleguide 2015-09-05 23:32:51 -03:00
Plusb Preco
38e948f55b Fix small typo 2015-09-05 09:42:28 +09:00
Plusb Preco
3e4ad4c696 Update README-ko.md 2015-09-05 09:38:36 +09:00
Eran Tiktin
0bc8e7b787 Update README.md
Most of the links in the page were invalid because those docs aren't translated yet, so I changed them to point to the originals written in English. IMO that's a better experience than receiving 404.
2015-09-05 01:40:26 +03:00
Eran Tiktin
a8d56df41e Drop "-es" from file names
When "README.md" is named "README-es.md", github doesn't show it's
preview automatically. So I removed "-es" from all the docs.
2015-09-05 01:29:12 +03:00
Eran Tiktin
41e1555cf4 Add chrome_version.h to gitignore 2015-09-05 01:11:37 +03:00
Eran Tiktin
dcbd8316df Remove chrome_version.h from git
chrome_version.h is dynamically generated by bootstrap.py so it
shouldn't be in git
2015-09-05 01:06:52 +03:00
Jonatas Freitas
1a1b45e088 application-distribution.md translated to pt-BR 2015-09-04 19:01:31 -03:00
Jessica Lord
b980650b6e Use headers so titles are linkable 2015-09-04 14:31:33 -07:00
Jessica Lord
b9da81ee6a Title Case 2015-09-04 13:50:26 -07:00
Jessica Lord
b797804fd9 Use "in" over "on" 2015-09-04 13:44:40 -07:00
Eran Tiktin
0577e911b3 Fix build failing on Windows
build.py would fail on Windows due to a couple of changes made in #2459.

This commit fixes those issues.
2015-09-04 23:24:42 +03:00
Jessica Lord
619c77f409 Merge pull request #2705 from John-Lin/master
Add api/ipc-main-process docs zh-TW translations
2015-09-04 12:02:49 -07:00
Jessica Lord
6c5c202a99 Merge pull request #2709 from jonatasfreitasv/master
Start docs translation to pt-BR
2015-09-04 11:39:26 -07:00
Eran Tiktin
090c817ac9 Merge pull request #2 from atom/master
Update from original
2015-09-04 21:27:32 +03:00
Jonatas Freitas
f91a7e6d04 Fix README links. 2015-09-04 14:25:32 -03:00
Jonatas Freitas
5d6ac2296b Translated styleguide. 2015-09-04 14:19:59 -03:00
Jonatas Freitas
26dea993df Added pt-BR translation in README.md 2015-09-04 11:52:27 -03:00
Jonatas Freitas
eb8ac2b5d8 Translate README.md to pt-BR 2015-09-04 11:42:37 -03:00
Plusb Preco
44528ce60e Merge remote-tracking branch 'atom/master' 2015-09-04 18:18:07 +09:00
Plusb Preco
e72e09719a Update web-view-tag.md
* Update as upstream
2015-09-04 18:05:28 +09:00
Cheng Zhao
6f9d822472 Merge pull request #2459 from deepak1556/web_view_partition_patch
webview: partition attribute
2015-09-04 17:29:37 +09:00
John-Lin
67026cccc8 Add api/shell.md docs zh-TW translations 2015-09-04 16:06:15 +08:00
John-Lin
30c714a27f Fix typos in zh-TW README docs 2015-09-04 15:47:46 +08:00
John-Lin
05031a38e5 Add api docs translations 2015-09-04 15:42:57 +08:00
Plusb Preco
ae8ffae59e Improve grammar, update as upstream 2015-09-04 16:01:43 +09:00
Plusb Preco
587a9f1c5b Merge remote-tracking branch 'atom/master' 2015-09-04 16:01:12 +09:00
Jessica Lord
bd264aa1ba Merge pull request #2700 from lockys/master
Add zh-tw translation of docs-translations/zh-TW/tutorial/online-offline-events.md
2015-09-03 11:59:21 -07:00
Jessica Lord
9557ce523a Merge pull request #2698 from fritx/docs-zh-cn
Add docs-translations for zh-CN
2015-09-03 11:58:58 -07:00
Calvin Jeng
f1e5a99881 zh-tw translation 2015-09-04 00:06:50 +08:00
Robo
03ba9533fb store webviewinfo as web contents userdata 2015-09-03 21:27:50 +05:30
Robo
8f59c0b642 create partitionId with encodedURIcomponent 2015-09-03 20:49:29 +05:30
Robo
da5bac42f3 use embedders' browser context when partition is not specified 2015-09-03 20:49:29 +05:30
Robo
150b540e72 add spec and docs 2015-09-03 20:49:29 +05:30
Robo
5189147021 use embedders' browser context to retrieve webviewmanager 2015-09-03 20:49:29 +05:30
Robo
d180d3b168 webview: fix partition attribute 2015-09-03 20:49:29 +05:30
Fritz Lin
3f546e6bab Add docs-translations for zh-CN
- development/coding-style
- development/atom-shell-vs-node-webkit
2015-09-03 22:27:22 +08:00
Cheng Zhao
c65ccb6857 Merge pull request #2685 from atom/chrome45
Upgrade to Chrome45
2015-09-03 21:17:49 +09:00
Plusb Preco
e3504b2b24 Merge remote-tracking branch 'atom/master' 2015-09-03 21:14:04 +09:00
Cheng Zhao
53b9d61831 Fix building on Windows 2015-09-03 20:07:29 +08:00
Cheng Zhao
2c3751e287 Merge pull request #2696 from John-Lin/master
Add Traditional Chinese documents link in README to navigate
2015-09-03 19:25:26 +09:00
Cheng Zhao
4a81300100 Merge pull request #2695 from takashi/patch-1
Fix jp/quick-start-jp.md
2015-09-03 19:24:58 +09:00
Takashi Nakagawa
73af4c017d remove -jp suffix from quick-start-jp.md 2015-09-03 18:17:51 +09:00
John-Lin
2734d67a38 add Traditional Chinese documents link in README to navigate 2015-09-03 17:10:32 +08:00
Cheng Zhao
c81de98d22 Update brightray to Chrome 45 2015-09-03 17:54:43 +09:00
Cheng Zhao
599e9b90bb Provide task runner for the node mode 2015-09-03 17:50:24 +09:00
Cheng Zhao
c1d7ad9631 Devtools no longer uses iframes 2015-09-03 17:50:24 +09:00
Cheng Zhao
ee0dc0d926 Update clang 2015-09-03 17:50:23 +09:00
Cheng Zhao
4254eb279f Fix API changes on Linux 2015-09-03 17:50:23 +09:00
Cheng Zhao
262b66b93a Feed gin::PerIsolateData with a task runner 2015-09-03 17:50:23 +09:00
Cheng Zhao
45491ca7ab Fix API changes 2015-09-03 17:50:23 +09:00
Cheng Zhao
1db843244d Upgrade to Chrome 45 2015-09-03 17:50:23 +09:00
Cheng Zhao
992aada90f Can only run tests on x64 machine 2015-09-03 17:48:50 +09:00
Cheng Zhao
c01d2fbbcd Suppress running tests on our OS X machine
It gets stuck and I don't know the reason, ignore it for now and work on
more important things, will fix it in future.
2015-09-03 17:46:44 +09:00
Cheng Zhao
f75458f78d Write output directly to stderr 2015-09-03 17:39:06 +09:00
Takashi Nakagawa
d6daea12af fix jp/quick-start-jp.md
this change includes some typo, misspelled things in jp/quick-start-jp.md
2015-09-03 17:19:12 +09:00
Cheng Zhao
28e5258a96 Merge pull request #2692 from John-Lin/master
Add zh-TW documents
2015-09-03 17:13:05 +09:00
Cheng Zhao
f6d6a2a4c3 Merge pull request #2688 from huangruichang/master
* add desktop-environment-integration.md and and online-offline-event…
2015-09-03 17:12:46 +09:00
Cheng Zhao
c56b78f0fa Merge pull request #2690 from preco21/master
Fix mistranslation, update as upstream
2015-09-03 17:12:30 +09:00
John-Lin
27b77a06ed Added zh-TW documents 2015-09-03 12:41:54 +08:00
Jessica Lord
357dea506a Merge pull request #2672 from atom/jl-docs-tuts
Standardize Docs: Tutorials
2015-09-02 19:46:58 -07:00
Jessica Lord
c2dcccf7c7 Merge pull request #2657 from atom/jl-std-docs-9
Standardize Docs: web-frame, web-view-tag, window-open
2015-09-02 18:44:32 -07:00
Jessica Lord
28764b0f77 Merge pull request #2664 from atom/jl-docs-dev
Standardize Docs: Development
2015-09-02 18:44:02 -07:00
Jessica Lord
66a1405d2b Fix conflict 2015-09-02 17:09:37 -07:00
Plusb Preco
b3eb6dc32b Update as upstream 2015-09-03 08:28:12 +09:00
Jessica Lord
3af2540fad Merge pull request #2693 from tcyrus/patch-1
Update browser-window.md
2015-09-02 13:42:06 -07:00
Timothy Cyrus
2f41641139 Update browser-window.md
Fix App Command Web Link
2015-09-02 15:44:51 -04:00
Jessica Lord
131cd9cff6 Merge master 2015-09-02 10:23:37 -07:00
Jessica Lord
bd20104e5a Merge master 2015-09-02 10:19:08 -07:00
Jessica Lord
2e5a539f57 Merge master 2015-09-02 09:57:29 -07:00
Jessica Lord
159b6ca611 Merge pull request #2655 from atom/jl-std-docs-7
Standardize Docs: protocol, remote, screen
2015-09-02 09:46:39 -07:00
Plusb Preco
3914ff2ac5 Fix many typos, update as upstream 2015-09-03 01:12:54 +09:00
Cheng Zhao
f12ccac17e Merge pull request #2686 from astoilkov/patch-4
Clarify Selenium and WebDriver documentation
2015-09-02 20:45:24 +08:00
Cheng Zhao
f8d40a88fb Merge pull request #2678 from vHanda/master
Linux Build Instructions: Add list of packages for fedora
2015-09-02 20:41:45 +08:00
huangruichang
e78db6ae07 * add desktop-environment-integration.md and and online-offline-events.md for zh-CN 2015-09-02 20:12:22 +08:00
Antonio Stoilkov
e71d2bd8e7 Clarify Selenium and WebDriver documentation 2015-09-02 14:18:17 +03:00
Plusb Preco
ba7ddd66a1 Merge remote-tracking branch 'atom/master' 2015-09-02 17:17:42 +09:00
Cheng Zhao
f5f3278ffa Bump v0.31.2 2015-09-02 11:12:01 +08:00
Cheng Zhao
bfa33de792 Merge pull request #2682 from atom/menu-item-role
Add "role" attribute for MenuItem
2015-09-02 10:30:41 +08:00
Jessica Lord
ae3ff4e1e3 Merge pull request #2656 from atom/jl-std-docs-8
Standardize Docs: shell, synopsis, tray
2015-09-01 19:10:10 -07:00
Jessica Lord
0fa0aedd86 Text edits 2015-09-01 19:08:31 -07:00
Jessica Lord
e6265ec405 Merge pull request #2654 from atom/jl-std-docs-6
Standardize Docs: native-image, power-monitor, power-save-blocker, process
2015-09-01 18:44:52 -07:00
Cheng Zhao
6bce5b560b docs: The "role" attribute of MenuItem 2015-09-02 09:44:01 +08:00
Cheng Zhao
009b27f5f1 Unify the menu of default app 2015-09-02 09:42:17 +08:00
Cheng Zhao
7d07f10c25 Assign actions for roles on Windows and Linux 2015-09-02 09:42:17 +08:00
Cheng Zhao
d830badc57 Add role property for MenuItem 2015-09-02 09:42:17 +08:00
Heilig Benedek
dbcd0a4235 Key event sending update. 2015-09-02 02:33:40 +02:00
Jessica Lord
47d103af72 Text edits 2015-09-01 16:21:29 -07:00
Jessica Lord
91c75d73dd Text edits 2015-09-01 15:42:10 -07:00
Jessica Lord
2ead38b03f Text edits on remote 2015-09-01 15:30:08 -07:00
Jessica Lord
dd2ed559cf Merge pull request #2638 from atom/jl-std-docs-5
Standardize Docs: menu, menu-item
2015-09-01 14:26:11 -07:00
Jessica Lord
ab726ec1f5 Merge pull request #2679 from carsonmcdonald/fixaddRecentDocumentlink
Fix link to app.addRecentDocument
2015-09-01 14:24:35 -07:00
Carson McDonald
2c47532702 Fix link to app.addRecentDocument 2015-09-01 17:15:21 -04:00
Jessica Lord
95133af0ee y required if x exists 2015-09-01 14:08:42 -07:00
Vishesh Handa
17cc43152d Linux Build Instructions: Add list of packages for fedora 2015-09-01 16:01:44 +02:00
Cheng Zhao
0cb20c48f6 docs: Small changes to will-download event 2015-09-01 20:16:28 +08:00
Cheng Zhao
4e7f56846f Merge pull request #2650 from deepak1556/webcontents_download_event_patch
app: add will-download event to defaultSession
2015-09-01 20:10:43 +08:00
Robo
4062ca5f68 implement wrapSession 2015-09-01 16:50:42 +05:30
Cheng Zhao
e043ea9c20 Merge pull request #2677 from atom/fix-more-pages-print
Fix print spooler hangs when printing more than 3 pages on Windows.
2015-09-01 19:07:01 +08:00
Haojian Wu
10b53f7f73 Fix print spooler hangs when printing more than 3 pages on Windows. 2015-09-01 17:55:45 +08:00
Cheng Zhao
7acd3c1973 Merge pull request #2675 from atom/improve-node-integration
Fix a few navigation related problems
2015-09-01 16:42:41 +08:00
Jessica Lord
889c982918 Source code structure as tree command 2015-08-31 21:49:05 -07:00
Cheng Zhao
c70513f7ce spec: window.opener.postMessage should set source and origin 2015-09-01 12:15:00 +08:00
Jessica Lord
691d8dd9ab Replace "Mac" with "OS X" 2015-08-31 21:13:05 -07:00
Jessica Lord
316210d6c4 Add $ notation 2015-08-31 21:10:48 -07:00
Cheng Zhao
dddb598818 spec: Node integration should work after POST 2015-09-01 11:51:28 +08:00
Cheng Zhao
50bfe9e335 Set source and origin correctly for window.opener.postMessage 2015-09-01 11:51:10 +08:00
Jessica Lord
a03df3ac5a "the" 2015-08-31 20:17:14 -07:00
Jessica Lord
05d0f17447 Updates from inline comments 2015-08-31 20:05:57 -07:00
Cheng Zhao
f31848563f Merge pull request #2670 from preco21/master
Update as upstream, improve grammar
2015-09-01 10:47:06 +08:00
Jessica Lord
d9c3830df7 Standardize selenium and webdriver 2015-08-31 19:32:25 -07:00
Jessica Lord
cb4558e75b Standardize pepper flash 2015-08-31 19:23:43 -07:00
Jessica Lord
be73388918 Standardize native modules 2015-08-31 19:22:06 -07:00
Jessica Lord
6a2bd80a9a Standardize quick-start 2015-08-31 19:18:46 -07:00
Jessica Lord
52916f70ed Standardize online-offline 2015-08-31 19:17:59 -07:00
Jessica Lord
a5234224a6 Standardize devtools 2015-08-31 19:17:41 -07:00
Jessica Lord
c6269bf77a Standardize desktop env integration 2015-08-31 19:13:27 -07:00
Jessica Lord
0e4ae6f864 Standardize debug main process 2015-08-31 19:12:57 -07:00
Jessica Lord
96bb9b2757 Standardize app packaging 2015-08-31 19:12:33 -07:00
Jessica Lord
e0a57a0a47 Standardize app dist 2015-08-31 19:10:29 -07:00
Cheng Zhao
8cf1bc8457 Merge pull request #2665 from huangruichang/master
* add quick-start.md for zh-CN
2015-09-01 10:08:15 +08:00
Plusb Preco
eb3769f98e Update as upstream, improve grammar 2015-09-01 09:57:43 +09:00
Plusb Preco
afff32dc8d Improve grammar 2015-09-01 08:09:35 +09:00
Jessica Lord
ddee9f3e75 Merge pull request #2604 from atom/jl-std-docs-4
Standardize: global-shortcuts, ipc (main), ipc (render)
2015-08-31 11:01:57 -07:00
Heilig Benedek
3dd3fd9200 Merge branch 'master' of https://github.com/brenca/electron
Conflicts:
	atom/browser/api/atom_api_window.h
	atom/browser/native_window.cc
2015-08-31 18:46:29 +02:00
huangruichang
625ee387f3 * add quick-start.md for zh-CN 2015-09-01 00:34:00 +08:00
Heilig Benedek
c59c0bd5b3 Mouse event handling and keyboard event handling (not totally working yet) 2015-08-31 18:32:33 +02:00
Cheng Zhao
ebedb60684 Insert node integration for all main frames 2015-08-31 21:59:13 +08:00
Cheng Zhao
9ecc4bcb7d Fork renderer process for webview
Previously it was disabled because Chrome doesn't support swapping
renderer process before, it seeems to work fine now, so we enable it to
see how it goes.
2015-08-31 21:38:18 +08:00
Cheng Zhao
b205bd381e Merge pull request #2642 from deepak1556/app_api_patch
process: api to set file descriptor soft limit
2015-08-31 18:40:14 +08:00
Robo
af52eda0eb process: api to set file descriptor soft limit 2015-08-31 13:00:04 +05:30
Robo
aed487ef40 app: add will-download event to defaultSession 2015-08-31 12:57:56 +05:30
Cheng Zhao
50c7985ee2 Merge pull request #2658 from preco21/master
Improve grammar (KR), update as upstream
2015-08-31 14:35:57 +08:00
Cheng Zhao
00136a221f Merge pull request #2649 from fritx/docs-cn
Setting up docs translation in Chinese 👍
2015-08-31 14:30:40 +08:00
Plusb Preco
a6b86e924a Small changes
Improve grammar
2015-08-31 15:13:41 +09:00
Plusb Preco
ed01698444 Update as upstream 2015-08-31 15:11:06 +09:00
Plusb Preco
6459531bef Merge remote-tracking branch 'atom/master' 2015-08-31 14:58:17 +09:00
Cheng Zhao
49b15bd4f3 Merge pull request #2652 from SamyPesse/patch-1
Notes about server-side implementation of auto-updater
2015-08-31 13:50:29 +08:00
Plusb Preco
c67268a74f Improve grammar, update as upstream 2015-08-31 14:48:47 +09:00
Jessica Lord
2c79e9fd41 Standardize dir structure 2015-08-30 22:31:43 -07:00
Jessica Lord
29c865f0e1 Standardize symbol server 2015-08-30 22:31:25 -07:00
Jessica Lord
e0542945ce Standardize code style 2015-08-30 22:31:14 -07:00
Jessica Lord
842ba6aea6 Standardize overview 2015-08-30 22:31:07 -07:00
Jessica Lord
009e228218 Standardize build win 2015-08-30 22:30:36 -07:00
Jessica Lord
d93b6c1cae Standardize build mac 2015-08-30 22:30:23 -07:00
Jessica Lord
2206279846 Standardize build linux 2015-08-30 22:30:12 -07:00
Jessica Lord
1e5b7af490 Standardize atom vs nw 2015-08-30 22:30:01 -07:00
Jessica Lord
cb62afca23 Minor text edits 2015-08-30 21:10:02 -07:00
Jessica Lord
254cdc0e6c Text edits 2015-08-30 20:52:46 -07:00
Jessica Lord
2c6210cf9c Update code example 2015-08-30 20:52:37 -07:00
Fritz Lin
3d4f0dfc44 Move cn to zh-CN for future traditional Chinese translations
ref #2649
2015-08-31 11:02:37 +08:00
Cheng Zhao
874367e2c5 Merge pull request #2643 from etiktin/patch-6
Update web-frame.md phrasing
2015-08-31 09:57:42 +08:00
Cheng Zhao
22652860a2 Merge pull request #2641 from deepak1556/renderer_fork_navigation_patch
renderer: send referrer for all naviagtions
2015-08-31 09:56:04 +08:00
Cheng Zhao
87db1e8802 Merge pull request #2639 from appetizermonster/patch-1
Fix typo
2015-08-31 09:34:26 +08:00
Plusb Preco
8b6f3dc0aa Merge remote-tracking branch 'atom/master' 2015-08-31 09:55:35 +09:00
Plusb Preco
9c46be9d47 Translate styleguide.md 2015-08-31 09:52:28 +09:00
Samy Pessé
9ee063ca14 Add section about server implementations 2015-08-31 00:07:36 +02:00
Fritz Lin
eab88ea09c Setting up docs translation in Chinese 👍 2015-08-30 22:53:40 +08:00
Eran Tiktin
cfc5ecb05d Update web-frame.md phrasing 2015-08-29 20:05:15 +03:00
Robo
8757da6c47 renderer: send referrer for all naviagtions 2015-08-29 19:20:09 +05:30
appetizermonster
39e3506add Fix typo 2015-08-29 18:04:30 +09:00
Cheng Zhao
0f2ef3feb2 Merge pull request #2637 from RIAEvangelist/master
Update documentation to clarify bundled node/io.js version
2015-08-29 16:12:47 +08:00
Cheng Zhao
82d801ab9e Merge pull request #2635 from fscherwi/master
⬆️ asar@0.8.x
2015-08-29 15:57:49 +08:00
Jessica Lord
955ae78e33 Standardize window-open 2015-08-28 23:21:09 -07:00
Jessica Lord
8d40714f78 Standardize web-view-tag 2015-08-28 23:20:59 -07:00
Jessica Lord
2c3ed90ff3 Standardize web-frame 2015-08-28 23:20:49 -07:00
Jessica Lord
b1fc18f405 Standardize tray 2015-08-28 22:46:39 -07:00
Jessica Lord
e8a04981bb Standardize synopsis 2015-08-28 22:46:31 -07:00
Jessica Lord
a2cc936a3b Standardize shell 2015-08-28 22:28:30 -07:00
Jessica Lord
e6e09a8a7c Standardize screen 2015-08-28 22:24:54 -07:00
Jessica Lord
50736296a7 Standardize remote 2015-08-28 22:17:35 -07:00
Jessica Lord
b759999272 Standardize protocol 2015-08-28 22:03:39 -07:00
Jessica Lord
a5969fd076 Standardize process 2015-08-28 21:47:31 -07:00
Jessica Lord
91150839be Standardize power-save-blocker 2015-08-28 21:44:13 -07:00
Jessica Lord
83aa9df1ee Standardize power-monitor 2015-08-28 21:37:07 -07:00
Jessica Lord
a38d34d368 Standardize native-image 2015-08-28 21:33:45 -07:00
Jessica Lord
e8461b6f90 Capital Ms 2015-08-28 16:35:22 -07:00
Jessica Lord
33a19f9071 Edits and standardization 2015-08-28 16:19:28 -07:00
gellert
58081ca9e9 setOffscreenRender and api docs added 2015-08-29 00:45:00 +02:00
Jessica Lord
8ee91bce44 message → arg 2015-08-28 14:57:14 -07:00
Jessica Lord
dbc1855b42 Small edits 2015-08-28 14:21:37 -07:00
Brandon Nozaki Miller
dd28a2ef14 Update documentation to clarify bundled node/io.js version 2015-08-28 14:16:05 -07:00
Jessica Lord
609961a1de Merge pull request #2585 from atom/jl-std-docs-2
Standardize: clipboard, content-tracing, crash-reporter
2015-08-28 13:51:16 -07:00
fscherwi
852d982057 ⬆️ asar@0.8.x 2015-08-28 22:04:42 +02:00
Jessica Lord
6277a65bb7 Merge pull request #2535 from atom/jl-br-win
Updating Browser Window Documentation
2015-08-28 11:31:08 -07:00
Jessica Lord
26f7f2ab21 Merge pull request #2602 from atom/jl-std-docs-3
Standardize Docs: dialog, file-object, frameless-window
2015-08-28 11:30:18 -07:00
Jessica Lord
aa03fddb62 contentTracing → tracing → content-tracing 2015-08-28 10:57:20 -07:00
Jessica Lord
bbf2cbb6f6 Small edits 2015-08-28 10:50:30 -07:00
Jessica Lord
221eff7fec ⬇️ list level 2015-08-28 10:50:02 -07:00
Jessica Lord
c2073a3c45 Consolidate note on experimental APIs 2015-08-28 10:34:48 -07:00
Cheng Zhao
71d257b190 Merge pull request #2619 from etiktin/ignore_native_modules_in_debug_tests_windows
Skip native modules in debug tests on Windows
2015-08-28 10:43:32 +08:00
Cheng Zhao
0684d9da6d Merge pull request #2614 from timruffles/patch-3
[docs] improve advice on callbacks passed from renderer to main
2015-08-28 10:19:35 +08:00
Eran Tiktin
5337d8c23f Ignore native module tests on Windows debug build
This resolves #2558. There are no more errors when running test.py on
the debug build in Windows. When running the release build the tests
will be executed as usual.
2015-08-27 23:05:06 +03:00
Eran Tiktin
b7d80e792d Merge pull request #1 from atom/master
Update from original
2015-08-27 20:31:20 +03:00
Jessica Lord
d02ced87b8 message → arg, 80-col 2015-08-27 10:13:25 -07:00
Tim Ruffles
4bc9bf7654 improve advice on callbacks passed from renderer to main
Remote is a great feature, it's a shame to put people off unnecessarily. I think the original warnings given are too extreme

The potential bugs that stem from not cleaning up event handlers (or any reference) are present in any Javascript code. We don't avoid using event-handlers in the DOM because we might forget to clean them up!

I've added an example of the behaviour of return values from synchronously called callbacks from renderer, and have changed the advice from 'you shouldn't do this' to 'be careful when you do this'.
2015-08-27 17:10:02 +01:00
Jessica Lord
f74d7d71e6 Edits per inline comments 2015-08-27 08:11:51 -07:00
Cheng Zhao
195be931a4 Merge pull request #2613 from atom/fix-geolocation
Opt into location services
2015-08-27 23:01:22 +08:00
Cheng Zhao
4a7d5fa769 Merge pull request #2612 from atom/disable-pinch
Add webFrame.setZoomLevelLimits API
2015-08-27 22:52:10 +08:00
Cheng Zhao
16a0185ab5 Opt into location services 2015-08-27 22:50:40 +08:00
Cheng Zhao
8a09cf5369 Add webFrame.setZoomLevelLimits API 2015-08-27 22:08:25 +08:00
Cheng Zhao
c91ab5ec7c Merge pull request #2611 from atom/pod-optimize
Optimize memory usage when using remote module
2015-08-27 20:51:02 +08:00
Cheng Zhao
37244c3b08 Remove extra output 2015-08-27 20:35:04 +08:00
Cheng Zhao
7889e2750f Suppress the heap snapshot test
It is failing in Travis CI but not in GitHub CI or my own machine,
ignore it for now.
2015-08-27 20:21:05 +08:00
Cheng Zhao
63eb4b72e2 IDWeakMap is not used anly more in JS 2015-08-27 19:55:16 +08:00
Cheng Zhao
64e8ce0c07 Don't rely on IDWeakMap for bookkeeping remote objects
It frees us from using C++ to track JS objects, thus improves the
performance of collecting memory.
2015-08-27 19:01:34 +08:00
Heilig Benedek
e4c01f3187 Offscreen render support base 2015-08-27 11:22:39 +02:00
Cheng Zhao
bd64f5ced2 Use V8's new SetWeak method 2015-08-27 16:41:51 +08:00
Cheng Zhao
f7c75d36ba Do not create remote object for simple return values of APIs 2015-08-27 16:14:53 +08:00
Cheng Zhao
e99b8c3a2b Fix leak of handle when emitting events 2015-08-27 15:22:02 +08:00
Cheng Zhao
0ddf90815b Merge pull request #2608 from atom/fix-debugger
Fix debugger not working for main process
2015-08-27 14:28:30 +08:00
Cheng Zhao
e432638b7d Update node: Remove unneeded exports 2015-08-27 13:51:46 +08:00
Cheng Zhao
134ccb550c Use libuv to wake up main thread 2015-08-27 13:30:04 +08:00
Cheng Zhao
573c959a75 Use our debugger implementation in Node 2015-08-27 13:16:19 +08:00
Cheng Zhao
e7791a5486 Import the TCPListenSocket removed by Chromium 2015-08-27 12:59:54 +08:00
Cheng Zhao
a1a6ea6fe1 Revert "Remove our own debugger implementation"
This reverts commit 1d148fe2fb.
2015-08-27 12:25:28 +08:00
Cheng Zhao
04d8f3218f Merge pull request #2607 from atom/fix-quit
win: Delay quitting until next tick of message loop
2015-08-27 11:56:58 +08:00
Cheng Zhao
ab859067aa win: Delay quitting until next tick of message loop
This fixes app.quit() not working when it is called before the message
loop starts to run.
2015-08-27 11:42:06 +08:00
Cheng Zhao
9cdefb6069 Merge pull request #2606 from atom/win-manifest
win: Add compatibility information in manifest file
2015-08-27 10:58:06 +08:00
Cheng Zhao
a6c21666f4 win: Add compatibility information in manifest 2015-08-27 10:45:39 +08:00
Cheng Zhao
3dad645619 Merge pull request #2596 from deepak1556/value_converter_patch
nativemate: increase recursion depth
2015-08-27 10:35:31 +08:00
Jessica Lord
292ffffa14 Merge pull request #2603 from preco21/master
Fix important typo and update as upstream
2015-08-26 18:23:58 -07:00
Jessica Lord
a1f17069ec First run t ipc-r 2015-08-26 17:56:10 -07:00
Jessica Lord
71f46c0287 arg → message 2015-08-26 17:52:45 -07:00
Jessica Lord
a34a16653e Standardize global-shortcut 2015-08-26 17:32:47 -07:00
Jessica Lord
f96c76584f First run at ipc-m-p edits 2015-08-26 17:27:17 -07:00
Plusb Preco
ade5b142f8 Update as upstream 2015-08-27 09:19:24 +09:00
Plusb Preco
ed8f143427 Fix IMPORTANT Typos and update as upstream 2015-08-27 09:06:12 +09:00
Jessica Lord
586b407103 Small edits and line wrap 2015-08-26 16:41:25 -07:00
Jessica Lord
715a88026e Small edits 2015-08-26 16:28:44 -07:00
Jessica Lord
3001ef7980 General text edits to content-tracing 2015-08-26 14:56:00 -07:00
Jessica Lord
0a4144e67a Merge branch 'master' into jl-std-docs-2 2015-08-26 14:26:36 -07:00
Jessica Lord
71fa87e4ed Note about platform specific apis 2015-08-26 14:14:59 -07:00
Jessica Lord
4e781eb042 Add platform labels 2015-08-26 14:05:47 -07:00
Jessica Lord
5f1897713c Edits, grammar, punctuation and merge conflicts 2015-08-26 13:57:42 -07:00
Jessica Lord
38b519ceb5 Add (optional) notation 2015-08-26 10:45:57 -07:00
Jessica Lord
71f74f4042 Add platform label where applicable 2015-08-26 10:45:57 -07:00
Jessica Lord
c282d4c0ff Line wrap 80-col 2015-08-26 10:45:57 -07:00
Jessica Lord
00de81771c Text edits per commit comments 2015-08-26 10:45:16 -07:00
Jessica Lord
bc909ddf5e Add new files to readme 2015-08-26 10:45:15 -07:00
Jessica Lord
840095b444 Break out methods, standardize 2015-08-26 10:45:15 -07:00
Robo
be18a114e2 nativemate: increase recursion depth 2015-08-26 15:52:28 +05:30
Cheng Zhao
3e5449561f Merge pull request #2595 from atom/mac-tray-quick-click
mac: make tray's behavior more official when getting clicked quickly multiple times.
2015-08-26 17:18:51 +08:00
Cheng Zhao
7f67cfb6a0 Merge pull request #2594 from atom/fix-rounded-corner
mac: Do not set rounded corner by adding layer
2015-08-26 16:36:50 +08:00
Haojian Wu
2b051e3884 mac: make tray's behavior more official when getting clicked quickly
multiple times.
2015-08-26 16:28:22 +08:00
Cheng Zhao
290b221d79 mac: Do not set rounded corner by adding layer 2015-08-26 15:58:44 +08:00
Cheng Zhao
c441dd1436 Merge pull request #2571 from atom/index-entry-startup
Support index.js module resolution at startup of Electron.
2015-08-26 12:35:24 +08:00
Cheng Zhao
fcecd091da Merge pull request #2589 from etiktin/patch-5
Update build-instructions-windows
2015-08-26 12:22:10 +08:00
Jessica Lord
ac84f56e36 Merge pull request #2533 from atom/jl-snd-docs
Standardize Docs: app, auto-updater, styleguide
2015-08-25 14:37:48 -07:00
Eran Tiktin
5a8f60fe32 Update build-instructions-windows
The build instructions mistakenly said that you can find `atom.exe` under `out\D` instead of `electron.exe`. I fixed that and mentioned that the release build will be to `out\R`.
2015-08-25 23:28:41 +03:00
Jessica Lord
aeb37941bb Replace platform notes with one general note 2015-08-25 10:12:21 -07:00
Jessica Lord
28a4069520 Mac → OS X 2015-08-25 10:05:48 -07:00
Plusb Preco
1aab23ece7 Merge remote-tracking branch 'atom/master' 2015-08-25 22:46:41 +09:00
Plusb Preco
eea04e513d Update as upstream 2015-08-25 22:46:28 +09:00
Cheng Zhao
73c9241a17 Merge pull request #2577 from preco21/master
Add more translations and fixes, remove outdated comments
2015-08-25 21:43:01 +08:00
Plusb Preco
fcf2be78cb Reset and remove unrelated files 2015-08-25 22:28:27 +09:00
Plusb Preco
ecb1625756 Revert "Rename xx-ko.md to xx.md"
This reverts commit 638bb9b0b1.
2015-08-25 22:17:24 +09:00
Plusb Preco
2592d2cfcd Revert "Revert "Rename xx-ko.md to xx.md""
This reverts commit aef4acb2e6.
2015-08-25 22:17:01 +09:00
Plusb Preco
50cbb5744b Revert "Fix link target in README.md"
This reverts commit c9965f0ffd.
2015-08-25 22:15:43 +09:00
Plusb Preco
aef4acb2e6 Revert "Rename xx-ko.md to xx.md"
This reverts commit 638bb9b0b1.
2015-08-25 22:14:33 +09:00
Jessica Lord
f4783772c5 Merge branch 'master' into jl-std-docs-2 2015-08-25 06:10:04 -07:00
Jessica Lord
ba9c47eb7e Merge branch 'master' into jl-std-docs-3 2015-08-25 06:09:45 -07:00
Jessica Lord
76416d5e47 Standardize frameless-window 2015-08-25 05:56:38 -07:00
Plusb Preco
1065374db4 Merge remote-tracking branch 'atom/master' 2015-08-25 21:56:37 +09:00
Cheng Zhao
65046b05af Update brightray and node
* brightray: fix building on OS X
* node: remove a not used patch
2015-08-25 20:56:26 +08:00
Plusb Preco
638bb9b0b1 Rename xx-ko.md to xx.md 2015-08-25 21:54:20 +09:00
Jessica Lord
864c8df639 Standardize file-object 2015-08-25 05:48:24 -07:00
Jessica Lord
81ed608b9c Standardize dialog 2015-08-25 05:46:06 -07:00
Cheng Zhao
474f92e41b Merge pull request #2578 from christian-bromann/patch-1
minor wording fix, updated example
2015-08-25 20:40:35 +08:00
Cheng Zhao
6a7113e3ce Update brightray 2015-08-25 20:30:50 +08:00
Jessica Lord
d2288815f8 List punctuation in crash-reporter 2015-08-25 05:18:02 -07:00
Jessica Lord
2c7ccffe1a Line wrap at 80-col 2015-08-25 05:16:20 -07:00
Jessica Lord
a67767dbea Standardize crash-reporter 2015-08-25 05:01:57 -07:00
Jessica Lord
703ced32db Standardize content-tracing 2015-08-25 04:49:48 -07:00
Plusb Preco
c9965f0ffd Fix link target in README.md 2015-08-25 17:06:16 +09:00
Christian Bromann
291a60444a minor wording fix, updated example 2015-08-24 23:15:59 -07:00
Cheng Zhao
a1ef09a243 Merge pull request #2559 from etiktin/fix_test.py_errors_on_windows
Fix path comparison in api-ipc-spec
2015-08-25 14:12:11 +08:00
Cheng Zhao
da10df3a9a Merge pull request #2556 from etiktin/fix_msg_box_no_close_btn
Fix message box missing a close button on Windows
2015-08-25 13:57:24 +08:00
Plusb Preco
5dc5f52f32 Fix typos and improve grammer, translate more files
Translate content-tracing-ko.md file.
Fix typos, improve grammer in tutorials and update as upstream.
2015-08-25 14:43:37 +09:00
Cheng Zhao
ce0509a665 Merge pull request #2554 from etiktin/patch-4
Update coding-style with info about Chromium's types
2015-08-25 13:41:54 +08:00
Cheng Zhao
1c9088ce7d Merge pull request #2550 from LeMoussel/patch-1
Update using-selenium-and-webdriver.md
2015-08-25 13:32:06 +08:00
Cheng Zhao
a14739bde9 Merge pull request #2553 from etiktin/patch-3
Update dialog.md with info about filter extensions
2015-08-25 12:49:13 +08:00
Cheng Zhao
b479aa3d45 Merge pull request #2547 from atom/dialog-asterisk-extension
Make dialog works on "*" file extension.
2015-08-25 12:46:36 +08:00
Cheng Zhao
102d3966af Merge pull request #2521 from deepak1556/webcontents_fullscreen_patch
webContents: exit tabbed fullscreen when esc key is pressed
2015-08-25 12:39:14 +08:00
Robo
1518ff6d22 webContents: exit tabbed fullscreen when esc key is pressed 2015-08-25 10:05:03 +05:30
Plusb Preco
5a37f96434 Remove comments about remote buffer
Remove comments about remote buffer in browser-window.md, because remote
buffer now supports in remote module.
2015-08-25 10:14:52 +09:00
Plusb Preco
dddfe902a3 Merge branch 'master' of https://github.com/preco21/electron 2015-08-25 09:44:04 +09:00
Plusb Preco
3740161caa Remove remain sentences 2015-08-25 09:39:45 +09:00
Plusb Preco
7a158773f3 Remove remain sentences 2015-08-25 08:04:07 +09:00
Jessica Lord
7f72207e66 Add platform label where applicable 2015-08-24 15:33:07 -07:00
Jessica Lord
f74ce9cc1c Add items to style guide list 2015-08-24 15:18:40 -07:00
Jessica Lord
5018fe1e17 Revert "Add links to docs translations"
This reverts commit d7fda9c8cc.
2015-08-24 15:14:13 -07:00
Jessica Lord
90392e9231 Standardize clipboard 2015-08-24 14:35:43 -07:00
Haojian Wu
7a23add23b Support index.js module resolution at startup of Electron. 2015-08-24 21:16:19 +08:00
Jessica Lord
d87c8a8291 Add optional notation 2015-08-24 14:56:19 +02:00
Jessica Lord
9b84dc4e1a Line wrap 80 2015-08-24 14:38:29 +02:00
Cheng Zhao
37044f6fd4 Merge pull request #2568 from atom/first-crashed
Make sure guest view is destroyed immediately when embeder is closed
2015-08-24 16:35:57 +08:00
Cheng Zhao
33737498ec Make sure guest view is destroyed immediately when embeder is closed 2015-08-24 16:17:15 +08:00
Cheng Zhao
a0fea28632 asar@0.7.x 2015-08-24 15:50:19 +08:00
Cheng Zhao
23d1a80c04 Merge pull request #2557 from atom/jl-mv-translations
Organize Documentation Translations
2015-08-24 13:49:10 +08:00
Jessica Lord
29c39a3245 Add documentation translation links 2015-08-23 17:19:37 +02:00
Jessica Lord
d7fda9c8cc Add links to docs translations 2015-08-23 11:17:19 +02:00
Eran Tiktin
f05ee4205d Fix path comparison in api-ipc-spec
One of the tests failed because in one of the paths the drive letter was
upper case `C` and in the other it was lower case `c`.
Paths in Windows are case insensitive, so this shouldn't fail. The fix
was to lower case the paths before comparison (only on Windows).
2015-08-22 19:50:54 +03:00
Jessica Lord
1964bb2acc Move files to ES translation docs 2015-08-22 14:24:43 +02:00
Jessica Lord
04967de2ed Move file to JP translation docs 2015-08-22 14:24:35 +02:00
Jessica Lord
6c984fac7c Add file to KO translation docs 2015-08-22 14:23:57 +02:00
Jessica Lord
3f52a91312 Create directory for KO translations 2015-08-22 14:21:01 +02:00
Jessica Lord
acc0c616c4 Spec out doc styleguide 2015-08-22 14:07:45 +02:00
Eran Tiktin
c686fc4d6b Made sure that lines are not longer than 80 characters 2015-08-22 05:09:37 +03:00
Eran Tiktin
9232620023 Fixed comment spacing 2015-08-22 04:26:09 +03:00
Eran Tiktin
b1406fbad9 Fix no close button in message box on Windows
This resolves #2293.
2015-08-22 04:20:52 +03:00
Eran Tiktin
79c602c3cc Update coding-style with info about Chromium's types
When I first tried to add something to the C++ code, I was a bit overwhelmed by all the special types and abstractions.
The info added will hopefully make it a bit easier to start, by directing users to the right place.
2015-08-21 22:23:49 +03:00
Eran Tiktin
db2f0a68e8 Update dialog.md with info about filter extensions
There was some confusion about the correct way to add an `All Files` filter (see #2525), so I added it to the example.
Also added a short note about the extension syntax.

This is related to PR #2547.
2015-08-21 21:18:37 +03:00
Cheng Zhao
d7cf460918 docs: callback => completion in some places 2015-08-21 20:16:56 +08:00
Cheng Zhao
68a98d5dc2 Bump v0.31.0 2015-08-21 19:51:56 +08:00
Cheng Zhao
7c32378a73 Merge pull request #2474 from atom/chrome44
Upgrade to Chrome 44
2015-08-21 19:49:00 +08:00
Cheng Zhao
9212a1db8e Merge branch 'master' into chrome44 2015-08-21 19:29:34 +08:00
LeMoussel
a839f70a99 Update using-selenium-and-webdriver.md
Add an example of how to use webdriverio with electron
2015-08-21 12:09:31 +02:00
Cheng Zhao
d931a49e89 Warn about removed protocol APIs 2015-08-21 18:02:58 +08:00
Cheng Zhao
61b7a3afe3 No need to ship ffmpeg in dist 2015-08-21 16:27:29 +08:00
Cheng Zhao
cf6a904f95 win: Fix release build 2015-08-21 16:21:20 +08:00
Cheng Zhao
00e5290dc8 win: Update libchromium to fix .pdb missing errors 2015-08-21 16:19:19 +08:00
Cheng Zhao
627fe75a6a Update brightray to fix building on Linux 2015-08-21 16:14:47 +08:00
Cheng Zhao
bc5ebb9911 Update to io.js v3.1.0 2015-08-21 14:28:37 +08:00
Cheng Zhao
1bd8a9869a Run build script on arm and ia32 Linux 2015-08-21 14:18:04 +08:00
Cheng Zhao
0ee6e5334a Now working at 0.31.0 2015-08-21 13:58:49 +08:00
Cheng Zhao
c18ec7f5bc runas@3.x 2015-08-21 13:52:05 +08:00
Haojian Wu
5f663dbf0a mac: make * extension filter works. 2015-08-21 12:15:20 +08:00
Haojian Wu
c566ba575f Linux: make * extension filter works. 2015-08-21 12:13:33 +08:00
Cheng Zhao
e016100860 Bump v0.30.5 2015-08-21 12:08:32 +08:00
Cheng Zhao
82fc98848a win: Move the ICO reading code into a separate function 2015-08-21 12:06:38 +08:00
Cheng Zhao
ec18c2f354 Merge pull request #2453 from etiktin/nativeimage_ico_support_windows
Add support for using .ico icon files on Windows
2015-08-21 11:45:12 +08:00
Cheng Zhao
b4da15bba8 Merge pull request #2545 from mmastrac/master
Fix for issue 1968: use uv_backend_timeout to determine timeout to match other platforms
2015-08-21 11:33:43 +08:00
Cheng Zhao
993a5fda41 Merge branch 'preco21-master' 2015-08-21 11:31:42 +08:00
Cheng Zhao
01921ee6fa Merge branch 'master' of https://github.com/preco21/electron into preco21-master
Conflicts:
	docs/api/browser-window-ko.md
2015-08-21 11:30:47 +08:00
Plusb Preco
ad24c11f32 Merge remote-tracking branch 'atom/master' 2015-08-21 11:41:07 +09:00
Plusb Preco
351dc4ed6b Translate more files, fix outdated remote.md section
Translate content-tracing(50%), remote docs.
Fix `Remote buffer` section as outdated.
2015-08-21 11:33:02 +09:00
Matt Mastracci
e628c7b37d Fix for issue 1968: use uv_backend_timeout to determine timeout to match other platforms 2015-08-20 20:13:04 -06:00
Cheng Zhao
8cc602ff94 Merge pull request #2515 from atom/fix-no-print-background
Fix a typing error in option checking: printBackgrounds => printBackground
2015-08-21 09:02:08 +08:00
Cheng Zhao
715fdc8614 Merge pull request #2454 from etiktin/fix_asar_testing
Fix asar testing (it would fail on Windows due to line endings)
2015-08-21 09:00:36 +08:00
Cheng Zhao
b1ffd1b02a Merge pull request #2503 from teleclimber/master
Clarify that MSVS 2015 will not work in Windows build docs.
2015-08-21 08:57:32 +08:00
Cheng Zhao
cf6415bf84 Merge pull request #2520 from etiktin/patch-2
Update browser-window.md
2015-08-21 08:57:14 +08:00
Eran Tiktin
f386342a7c Fix memory leak and confirming to style guide
Fixed according to @hokein 's suggestions.
2015-08-20 19:26:20 +03:00
Eran Tiktin
2bc087b5d5 Merge branch 'master' into nativeimage_ico_support_windows 2015-08-20 17:11:52 +03:00
Plusb Preco
172cc22d90 Fix some typos, update as upstream 2015-08-20 07:50:07 +09:00
Jessica Lord
454413f69a Standardize auto-updater.md 2015-08-19 18:55:11 +02:00
Jessica Lord
714745cdd7 Add 'returns' and change h2 descriptions 2015-08-19 18:51:36 +02:00
Jessica Lord
624b6b9762 Standardize app.md 2015-08-19 18:28:48 +02:00
Jessica Lord
12672cf50b Merge pull request #2511 from petrfelzmann/doc-github-link
Fix absolute url to github
2015-08-19 13:33:54 +02:00
Haojian Wu
4e6dc49646 📝 Fix a typing error: printBackgrounds => printBackground 2015-08-19 09:44:33 +08:00
Eran Tiktin
129d92b30a Update browser-window.md
Update the `beforeunload` example to use `e.returnValue = false` instead of `return false`, since `e.returnValue` always works while the `return` works only in certain conditions. See #2481 for details.
2015-08-18 19:34:14 +03:00
Haojian Wu
69e1e3c0bd Fix a typing error in option checking: printBackgrounds => printBackground 2015-08-18 09:28:02 +08:00
Paul Betts
0efdb448b6 Merge pull request #2509 from atom/fix-win-tray
Correct generation of GUID on Windows.
2015-08-17 09:02:21 -07:00
Petr Felzmann
7842a90c5e Fix absolute url to github 2015-08-17 15:03:04 +02:00
Thomas Johansen
7c62cfba33 Merge pull request #2510 from petrfelzmann/doc-formatting
Fix formatting of print and printToPDF methods
2015-08-17 12:28:13 +02:00
Petr Felzmann
acffc713e0 Fix formatting of print and printToPDF methods 2015-08-17 10:52:10 +02:00
Thomas Johansen
d3db178182 Merge pull request #2508 from etiktin/fix_typo_in_init
Fix typo
2015-08-17 10:03:54 +02:00
Haojian Wu
763dcc545d Correct generation of GUID on Windows. 2015-08-17 13:20:36 +08:00
Eran Tiktin
6f25996fa1 Fixed typo 2015-08-16 23:20:09 +03:00
Olivier Forget
e296f6daa2 Merge pull request #1 from teleclimber/teleclimber-win-build
Clarify that MSVS 2015 will not work in Windows build docs.
2015-08-14 10:28:26 -07:00
Olivier Forget
092f9d2c46 Clarify that MSVS 2015 will not work in Windows build docs. 2015-08-14 10:25:18 -07:00
Cheng Zhao
7d97bb6fe0 docs: Rewrite docs for new protocol API 2015-08-14 13:44:18 +08:00
Cheng Zhao
86eb0a5eaa Create both Uint8Array and ArrayBuffer from blink 2015-08-14 12:40:03 +08:00
Cheng Zhao
62d5c89f62 spec: Rewrite tests for new protocol API 2015-08-13 22:39:11 +08:00
Cheng Zhao
a88f951b2f Always set headers for response
When intercepting HTTP protocols Chromium will assume there is always headers
set, so we have to provide headers for all the responses to avoid the
crash.
2015-08-13 22:26:27 +08:00
Cheng Zhao
467ba6b7a9 Rename protocol.isHandledProtocol to protocol.isProtocolHandled 2015-08-13 21:29:23 +08:00
Cheng Zhao
02714d466c Fix crash when requesting invalid url 2015-08-13 21:21:23 +08:00
Cheng Zhao
741c8f3d98 Implement protocol.uninterceptProtocol 2015-08-13 20:19:02 +08:00
Cheng Zhao
773e932e98 Implement protocol.interceptProtocol 2015-08-13 20:10:05 +08:00
Cheng Zhao
374d83ed9c Implement protocol.isHandledProtocol 2015-08-13 19:33:53 +08:00
Cheng Zhao
05fd81ebdc Implement protocol.unregisterProtocol 2015-08-13 19:26:18 +08:00
Cheng Zhao
777f99193f Update native_mate to fix VS compilation error 2015-08-13 13:44:37 +08:00
Cheng Zhao
d0ef43bd12 Completion callback is called on IO thread 2015-08-12 23:16:17 +08:00
Cheng Zhao
78171e2072 Don't use C++11 to not crash VS 2015-08-12 23:14:20 +08:00
Cheng Zhao
94c1fb32a7 Try work around VS's bug 2015-08-12 23:07:15 +08:00
Cheng Zhao
d9b845fcdf Make session parameter work with null value 2015-08-12 22:57:25 +08:00
Cheng Zhao
225321b580 Make the completion callback optional 2015-08-12 21:32:52 +08:00
Cheng Zhao
f493eb34ae Implement protocol.registerHttpProtocol 2015-08-12 21:09:44 +08:00
Cheng Zhao
1f2d7d1cd8 Implement protocol.registerBufferProtocol 2015-08-12 20:37:52 +08:00
Cheng Zhao
ebb1ddc0df Support converting Buffer to Value 2015-08-12 15:39:33 +08:00
Cheng Zhao
d2681d2ba1 Implement protocol.registerFileProtocol 2015-08-12 15:22:19 +08:00
Cheng Zhao
337460cdc2 Enable return error for arbitray request job 2015-08-12 13:50:31 +08:00
Cheng Zhao
ee51e37db7 Guard against callback being called twice 2015-08-12 13:43:27 +08:00
Cheng Zhao
96d53d279e Initial implementation of new protocol API 2015-08-12 13:30:19 +08:00
Kevin Sawicki
1a5269e51b Merge pull request #2476 from atom/ks-contributor-covenant
Switch to Contributor Covenant from Open Code of Conduct
2015-08-11 09:49:25 -07:00
Kevin Sawicki
8f32f9f5cb Open Code of Conduct -> Contributor Covenant 2015-08-11 09:45:45 -07:00
Cheng Zhao
1e9eaba423 win: Fix compiler warning 2015-08-11 23:41:43 +08:00
Cheng Zhao
a8681b0072 Fix emitting did-attach event 2015-08-11 15:59:16 +08:00
Cheng Zhao
e6a2b0a479 Fix finding the WebContents of a pending renderer process
Apparently after Chrome 44 a renderer process can be started before the
corresponding render view is created, though it can be patched but from
the source code Chromium is enforcing this everywhere now, so fixing it
on our side seems the only reliable solution.

This fix is very similar to what we did, but instead of blindly setting
swapped process, we now remember which process the pending process is
going to replace, so we should not have those race conditions.
2015-08-11 15:39:17 +08:00
Cheng Zhao
0f990d40cc Use blink's allocator in Node's Buffer 2015-08-11 12:31:41 +08:00
Cheng Zhao
2dc533c4b9 Fix search path of ffmpeg
It is somehow set to @load_path by Chromium.
2015-08-11 10:55:27 +08:00
Cheng Zhao
bc06195409 Link with a few more static libraries on Linux and OS X 2015-08-11 10:45:40 +08:00
Cheng Zhao
e43c63ae08 Update chrome_version.h 2015-08-11 10:40:41 +08:00
Cheng Zhao
cc34bc844d Tell compiler we want to ignore result of SetPrototype 2015-08-11 10:10:07 +08:00
Cheng Zhao
7423c89968 Fix compilation warnings caused by chrome44 update 2015-08-11 10:08:34 +08:00
Cheng Zhao
4337c07425 Define node_byteorder and node_release_urlbase 2015-08-11 10:02:46 +08:00
Cheng Zhao
5c57f92ba5 Update io.js to v3.0.0 2015-08-11 09:58:36 +08:00
Cheng Zhao
c5e540823b Update to Chrome 44 2015-08-11 09:50:19 +08:00
Haojian Wu
28093a4d2d Fix a crash issue in GetProcessOwner if no renderer view host is found. 2015-08-11 09:48:55 +08:00
Haojian Wu
4e3187fbbd No need to specify ffmpeg library as it's a normal built library in libchromiumcontent. 2015-08-11 09:48:55 +08:00
Haojian Wu
f9fee9174a net::URLFetcher::Create now returns object with scoped_ptr. 2015-08-11 09:48:55 +08:00
Haojian Wu
0e8a585157 Fix content::BrowserPluginDelegate::DidResizeElement API changes.
Chromium has removed old_size in DidResizeElement interface as the 'old_size'
is internal.
2015-08-11 09:48:55 +08:00
Haojian Wu
11ffb9dfb6 Fix node::Buffer API changes. 2015-08-11 09:48:29 +08:00
Haojian Wu
46c7ba734b Fix WillAttach API changes in content::BrowserPluginGuestDelegate. 2015-08-11 09:48:29 +08:00
Haojian Wu
fc4031ec26 Now the value in ScopedPtrHashMap is required to be scoped_ptr. 2015-08-11 09:48:29 +08:00
Haojian Wu
d003b1bb57 LoadV8Snapshot has been moved from gin::IsolateHolder to gin::V8Initializer. 2015-08-11 09:48:29 +08:00
Haojian Wu
8fda175264 Update base::Value::CreateNullValue API changes. 2015-08-11 09:48:29 +08:00
Haojian Wu
d08392a0c4 No need base/float_util.h since VS2013 supports well enough. 2015-08-11 09:48:29 +08:00
Haojian Wu
48ccb0f2ab No gfx::SingletonHwnd::Observer any more.
Using gfx::SingletonHwndObserver instead.
2015-08-11 09:48:29 +08:00
Cheng Zhao
b4e836bf2e Bump v0.30.4 2015-08-10 16:50:48 +08:00
Cheng Zhao
a296b4ef33 Merge pull request #2465 from atom/fix-incept-scheme
Force request context to initialize beforing incepting protocol
2015-08-10 15:47:12 +08:00
Cheng Zhao
140ba2858a Fix cpplint warnings 2015-08-10 15:37:03 +08:00
Cheng Zhao
3379641fe2 Force request context to initialize beforing incepting protocol 2015-08-10 15:31:29 +08:00
Cheng Zhao
0644129fbe Pass net::URLRequestContextGetter in scoped_refptr 2015-08-10 15:28:18 +08:00
Cheng Zhao
c295979270 BrowserContext::GetRequestContext can only be called on UI thread 2015-08-10 15:02:16 +08:00
Cheng Zhao
e4a7352b62 Merge pull request #2462 from atom/tray-event
More fixes of Tray
2015-08-10 13:45:35 +08:00
Cheng Zhao
33eadad139 popContextMenu => popUpContextMenu 2015-08-10 13:00:15 +08:00
Cheng Zhao
225140bd64 win: Don't emit right-clicked event when there is menu attached 2015-08-10 12:52:55 +08:00
Cheng Zhao
58dee04d5c mac: Redraw icon when menu is closed 2015-08-10 12:52:35 +08:00
Cheng Zhao
4b9ff309ec Add our own MenuModel class 2015-08-10 12:39:05 +08:00
Cheng Zhao
a3f3a35fd1 mac: Don't emit "clicked" event if there is menu attached 2015-08-10 12:18:00 +08:00
Cheng Zhao
aa03eb5b6c Merge pull request #2461 from atom/fix-webview-crash
Delay the call of element resize callback to next tick
2015-08-10 12:07:58 +08:00
Cheng Zhao
ebe70435ef Merge pull request #2460 from atom/iojs-new-headers
Upload node headers with new filenames
2015-08-10 12:00:17 +08:00
Cheng Zhao
0a49dcc623 Delay the call of element resize callback to next tick 2015-08-10 11:56:42 +08:00
Cheng Zhao
52d07eb30f Update checksums for new filenames 2015-08-10 11:42:14 +08:00
Cheng Zhao
70be04a2d3 Upload headers with new filenames 2015-08-10 11:28:43 +08:00
Cheng Zhao
eaaf52483e Merge pull request #2443 from ialexryan/patch-1
Fixed typo
2015-08-10 11:22:06 +08:00
Cheng Zhao
ebfd03570f Merge pull request #2456 from etiktin/update_build_md
Add a comment to build instructions about cpplint
2015-08-10 11:21:51 +08:00
Plusb Preco
40c7e6e179 Update as upstream, translate 2 files, fix some typos 2015-08-10 03:33:32 +09:00
Eran Tiktin
de441916d6 Add a comment to build instructions about cpplint
I added a mention of `cpplint.py` in the build instructions.
The reason, is because it's easy to miss it's existence. Even if you
noticed it's mentioned in `coding-style.md` you might mistakenly think
that `test.py` runs it).
2015-08-08 23:25:27 +03:00
Eran Tiktin
850edd546c Added support for reading .ico from asar
If the file path is to an asar archive, we extract the file to temp, so
LoadImage can load it
2015-08-08 21:57:29 +03:00
Eran Tiktin
b67070f0ae Made the tests ignore the line ending
I had 4 asar tests fail because, the testing assumed that the file
content ends with UNIX line endings (\n), while it was using Windows
line endings (git probably changed them when I cloned the project on
Windows).
Since the line ending is not what matters in the tests, I trimmed them
and now all the tests pass as expected.
2015-08-08 20:03:34 +03:00
Eran Tiktin
c495088390 Updated native-image.md
Add a mention of the support for .ico files on Windows
2015-08-08 19:08:09 +03:00
Eran Tiktin
ab1b4c46b2 Converted tabs to spaces 2015-08-08 18:31:12 +03:00
Eran Tiktin
bec7a399cb Add support for using .ico icon files on Windows
NativeImage::CreateFromPath now supports loading .ico icon files on
Windows.
2015-08-08 17:58:05 +03:00
Cheng Zhao
0bf5effe58 Bump v0.30.3 2015-08-07 22:04:59 +08:00
Cheng Zhao
b65e089028 Merge pull request #2447 from atom/fix-microtask-checkpoint
Make sure microtask checkpoint is performed after Node.js calls
2015-08-07 22:03:51 +08:00
Cheng Zhao
c51f349dfa Run microtask before handling pending process.nextTick tasks
This follows the behavior of Node.js.
2015-08-07 21:26:24 +08:00
Cheng Zhao
1bb0dde360 Use WebScopedRunV8Script in converted C++ functions 2015-08-07 19:37:17 +08:00
Cheng Zhao
5c18d89453 Reimplement callback.h with C++11 2015-08-07 19:35:35 +08:00
Cheng Zhao
2ff104d012 Move callback converter from native mate to electron 2015-08-07 19:35:35 +08:00
Cheng Zhao
3402871741 spec: Check the time when Promise's callback is called 2015-08-07 19:35:35 +08:00
Cheng Zhao
74fa2c809d Make every JS function call is wrapped with V8RecursionScope 2015-08-07 19:35:35 +08:00
Cheng Zhao
ab44edd294 Perform microtask checkpoint after diving into libuv 2015-08-07 19:35:35 +08:00
Cheng Zhao
5d3445cebb Style fix 2015-08-07 19:35:35 +08:00
Cheng Zhao
24ba712aa5 Update libchromiumcontent to have WebScopedRunV8Script 2015-08-07 19:35:34 +08:00
Alex Ryan
fb60f7946f Fixed typo 2015-08-06 22:15:59 -07:00
Cheng Zhao
744059b8bd Check button size 2015-08-06 15:22:17 +08:00
Cheng Zhao
8864498065 Merge pull request #2431 from atom/clean-up-native-window-2
Clean up NativeWindow code, phase 2
2015-08-06 13:25:35 +08:00
Cheng Zhao
454085eb95 Fix cpplint warning 2015-08-06 13:07:39 +08:00
Cheng Zhao
6e75af5c0f Move SetOverlayIcon to TaskbarHost 2015-08-06 13:07:00 +08:00
Cheng Zhao
8da7803f3e Save the taskbar object 2015-08-06 12:58:40 +08:00
Cheng Zhao
2d6f8350cb Move SetProgressBar to TaskbarHost 2015-08-06 12:54:00 +08:00
Cheng Zhao
958658513c Refactor code in taskbarHost 2015-08-06 12:44:07 +08:00
Cheng Zhao
a28f70e85c Decouple TaskbarHost from NativeWindow 2015-08-06 11:10:34 +08:00
Cheng Zhao
8f8c3aef87 ThumbarHost => TaskbarHost 2015-08-06 10:30:22 +08:00
Cheng Zhao
39af10cc8d Move thumbar_host_ from TreeHost to NativeWindow 2015-08-06 10:25:50 +08:00
Cheng Zhao
d175a68586 Add MessageHandlerDelegate 2015-08-06 10:15:27 +08:00
Cheng Zhao
f740684f41 Merge pull request #2400 from atom/thumbar_button
Implement API for supporting thumbnail toolbars
2015-08-06 09:55:26 +08:00
Cheng Zhao
20a8e7838f Merge pull request #2424 from deepak1556/web_contents_patch
webcontents: minor patches
2015-08-06 09:52:16 +08:00
Haojian Wu
2f1cb8b52a Expose NativeWindow.setThumbarButtons API to all platforms. 2015-08-05 22:30:05 +08:00
Robo
0a7a4c0d0a webview: adding load-commit event 2015-08-05 19:22:30 +05:30
Robo
6b8d4a43a3 override: intialise BrowserWindowProxy.closed 2015-08-05 19:22:30 +05:30
Haojian Wu
78eac4116c Polish thumbar code.
* Fix a memory leak in thumbar initialization.
* Check the number of thumbar buttons, should be <= 7.
* Correct to check thumbar button click event.
2015-08-05 19:38:12 +08:00
Cheng Zhao
5a2f94f415 Merge pull request #2423 from atom/fix-release-leak
Fix memory leak when creating NativeImage
2015-08-05 15:55:52 +08:00
Cheng Zhao
2f04f76e69 ImageSkiaRep doesn't release memory 2015-08-05 15:49:37 +08:00
Cheng Zhao
b8d364f11e Merge pull request #2422 from atom/resizable-resize
mac: Disable resizing window when changing style mask
2015-08-05 14:44:31 +08:00
Cheng Zhao
5871428c83 spec: BrowserWindow.setResizable should not change window size 2015-08-05 14:25:53 +08:00
Cheng Zhao
1505dc207b mac: Disable resizing window when changing style mask 2015-08-05 14:12:55 +08:00
Haojian Wu
dfd076a3e5 Move atom_desktop_window_tree_host_win to atom/browser/ui/win directory. 2015-08-05 13:55:06 +08:00
Haojian Wu
ad01a1731a 📝 say more about thumbnail toolbar. 2015-08-05 13:55:04 +08:00
Haojian Wu
97ab780305 📝 BrowserWindow.setThumbarButton API. 2015-08-05 13:55:04 +08:00
Haojian Wu
54af048f04 win: Add BrowserWindow.setThumbarButtons API. 2015-08-05 13:55:02 +08:00
Cheng Zhao
488a69d461 Merge pull request #2419 from atom/clean-native-window
Clean up NativeWindow code
2015-08-05 13:28:09 +08:00
Cheng Zhao
bbd6c927b1 Remove a few unused headers 2015-08-05 13:18:41 +08:00
Cheng Zhao
adbb909b39 Move ShouldUseGlobalMenuBar to x_window_utils 2015-08-05 13:16:03 +08:00
Cheng Zhao
58b1172025 Avoid exposing data members to subclass 2015-08-05 12:46:32 +08:00
Cheng Zhao
438a5acc0f Use ranged for loop 2015-08-05 12:34:45 +08:00
Cheng Zhao
58c0486236 Remove duplicate UpdateDraggableRegions 2015-08-05 12:32:22 +08:00
Cheng Zhao
1c4f50b2df Merge pull request #2418 from deepak1556/content_tracing_api_patch
tracing: fix api and docs
2015-08-05 10:42:18 +08:00
Cheng Zhao
dc60bfa885 Merge pull request #2410 from atom/pop_context_menu_issue
Check context menu when calling popContextMenu API.
2015-08-05 10:04:26 +08:00
Robo
3b05b135a5 tracing: fix api and docs 2015-08-05 02:29:55 +05:30
Cheng Zhao
6b65a66119 Update brightray for #2263 2015-08-04 22:53:03 +08:00
Cheng Zhao
97c15c463e Merge pull request #2412 from atom/dialog-title
win: Use app name as default title of message box
2015-08-04 22:52:20 +08:00
Cheng Zhao
50f226e34e win: Use app name as default title of message box
TaskDialogIndirect doesn't allow empty name, if we set empty title
it will show "electron.exe" in title.
2015-08-04 21:57:00 +08:00
Cheng Zhao
2d18f91e57 Merge pull request #2411 from atom/fix-crash-reporter
Fix crash reporter process not exiting if there is another one running
2015-08-04 21:22:18 +08:00
Machisté N. Quintana
7910fe7785 Only build pushes on Travis for master branch [ci skip] 2015-08-04 08:27:17 -04:00
Haojian Wu
613e5c77ea Check context menu when calling popContextMenu API. 2015-08-04 19:45:44 +08:00
Cheng Zhao
c872b1a770 Use different name for window class name 2015-08-04 19:35:46 +08:00
Cheng Zhao
db58048077 Use different name for wait events for different apps 2015-08-04 19:30:35 +08:00
Cheng Zhao
14803e4cf8 Close handle when waiting is end 2015-08-04 19:18:12 +08:00
Cheng Zhao
1347c61c8e Set AppUserModelID for all renderer processes 2015-08-04 17:13:05 +08:00
Cheng Zhao
69b20d25ee Update brightray for #2294 2015-08-04 16:48:10 +08:00
Cheng Zhao
9642cd286e Merge pull request #2408 from atom/window-opener
Only set window.opener for windows opened by window.open
2015-08-04 16:13:09 +08:00
Cheng Zhao
2a30520799 Only set window.opener for windows opened by window.open 2015-08-04 15:47:12 +08:00
Cheng Zhao
039d4aaecb spec: Test window.opener 2015-08-04 15:46:59 +08:00
Cheng Zhao
9e922dd0c7 spec: Don't set window to fullscreen unless under travis 2015-08-04 15:40:31 +08:00
Cheng Zhao
4ac59e2674 Merge pull request #2391 from seanchas116/support-remote-promise
Support Promise over remote objects
2015-08-03 15:22:36 +08:00
Cheng Zhao
7c5d443284 Merge pull request #2394 from DerNivel/fix-typos
Fix typos
2015-08-03 15:04:13 +08:00
Cheng Zhao
666a2233a7 Merge pull request #2389 from atom/resize-mask-flag
Fix a bug calling setResizable multiple times will take no effect on OS X.
2015-08-03 14:52:40 +08:00
Cheng Zhao
7c75329b18 Merge pull request #2375 from deepak1556/web_frame_api_patch
webFrame: api to make scheme bypass CSP
2015-08-03 14:46:40 +08:00
Cheng Zhao
e135bcb5b7 docs: userGesture is optional 2015-08-03 14:43:01 +08:00
Cheng Zhao
d455232eb1 Merge pull request #2383 from deepak1556/render_script_execution_patch
render: executejavascript with option to create usergesture context
2015-08-03 14:37:29 +08:00
Ryohei Ikegami
c8a794ac34 Use constructor name to check if Promise 2015-08-01 12:20:16 +09:00
Jonathan
c0ce8723d4 Fix typo 2015-07-31 20:16:26 +02:00
Jonathan
9dab6e02ca Fix typo 2015-07-31 20:14:50 +02:00
Robo
9fb03d584c add spec and fix docs 2015-07-31 12:30:17 +05:30
Ryohei Ikegami
428ad20807 Change spec to test Promise in both side 2015-07-31 14:52:48 +09:00
Ryohei Ikegami
92af275f98 Support remote Promise in browser 2015-07-31 14:52:48 +09:00
Ryohei Ikegami
c7d1f4f6b2 Add spec for remote Promise 2015-07-31 14:52:48 +09:00
Ryohei Ikegami
ddf2cfd48d Support remote Promise in renderer 2015-07-31 14:52:37 +09:00
Haojian Wu
c69002b0dd Fix: browser window will be resiable when calling window.setResizable(false) twice. 2015-07-31 09:57:08 +08:00
Robo
92ea533aee webFrame: api to make scheme bypass CSP 2015-07-30 22:36:02 +05:30
Robo
239d535cac render: executejavascript with option to simulate usergesture 2015-07-30 15:38:46 +05:30
Cheng Zhao
2eaaad610d Merge pull request #2382 from jiaz/patch-3
Add missing dependency for ubuntu build
2015-07-30 16:53:57 +08:00
Jiaji Zhou
e0a117414b Add missing dependency for ubuntu build
I tried to follow the document to build electron on a fresh clean built Ubuntu 15.04.
I encountered the following error message when trying to run ./script/bootstrap.py -v

Package nss was not found in the pkg-config search path. 
Perhaps you should add the directory containing `nss.pc' 
to the PKG_CONFIG_PATH environment variable 
No package 'nss' found 

After installing libnss3-dev, the build can pass.
2015-07-30 01:21:17 -07:00
Cheng Zhao
2ab079dc7d Bump v0.30.2 2015-07-30 14:17:43 +08:00
Cheng Zhao
03e03a5daa Merge pull request #2381 from atom/my-status-item
mac: Make the tray icon behave more like the official one
2015-07-30 14:17:26 +08:00
Cheng Zhao
be24d3e78c mac: Make the tray icon behave more like the official one 2015-07-30 13:58:53 +08:00
Cheng Zhao
0e779e20c3 Fix compilation error caused by #2340 2015-07-30 10:38:04 +08:00
Cheng Zhao
2d5c0ac9ee Coffeescript declares variable before assigning it 2015-07-30 10:31:49 +08:00
Cheng Zhao
8d09f13bad Fix running callback when global.global is deleted
Close #2366.
2015-07-30 10:28:24 +08:00
Cheng Zhao
b68356b9b9 Merge pull request #2377 from CtrlVP/master
Replaced 'browser' with 'main'
2015-07-30 09:39:53 +08:00
Cheng Zhao
764a6e1d76 Merge pull request #2376 from timruffles/patch-2
more accuracy around why to use ASAR
2015-07-30 09:39:36 +08:00
Cheng Zhao
bbce2c7e2f Merge pull request #2372 from atom/allow-insecure-content
Add allowing-insecure-content option
2015-07-30 09:38:27 +08:00
Plusb Preco
0f648f4468 Update as upstream 2015-07-30 10:27:56 +09:00
Plusb Preco
05def654c3 Translate web-view-tag-tag-ko.md, improve grammer 2015-07-30 09:56:27 +09:00
Vivek Patel
2ded7497b6 Merge pull request #1 from CtrlVP/CtrlVP-patch-1
Replaced 'browser' with 'main'
2015-07-29 15:09:34 +02:00
Vivek Patel
90bd32c680 Replaced 'browser' with 'main'
"A JavaScript error occured in the browser process" is confusing. Replacing it with 'main', just like everywhere else.
2015-07-29 15:04:34 +02:00
Tim Ruffles
f9d5915542 more accuracy around why to use ASAR
'protect' implies a lot more security than ASAR provides (none). I asked around #2374 to get some understanding of what ASAR does do for you.
2015-07-29 13:45:30 +01:00
Cheng Zhao
643ed27fd4 Check whether entry is null
This fixes the crash in #7877.
2015-07-29 18:26:20 +08:00
Haojian Wu
f154da38e6 Make 'allow-displaying-insecure-content' and
'allow-running-insecure-content' higher priority than `web-security`.
2015-07-29 18:08:44 +08:00
Cheng Zhao
046a8e8a08 Merge pull request #2368 from dataich/master
do not overwrite `node-integration` option
2015-07-29 17:25:30 +08:00
Cheng Zhao
80f45f6226 Merge pull request #2370 from atom/osx-tray
Use NSImageView to draw tray icon.
2015-07-29 17:22:47 +08:00
Cheng Zhao
898a838ad7 Merge pull request #2340 from atom/set_download_path_api
Implement setDownloadPath API.
2015-07-29 17:19:02 +08:00
Cheng Zhao
b311969f0e Update brightray for #2327 2015-07-29 17:16:23 +08:00
Cheng Zhao
d719244d1e Merge pull request #2327 from deepak1556/devtools_api_patch
webContents: api to add/remove path from devtools workspace
2015-07-29 17:16:02 +08:00
Haojian Wu
1d0568dd5b 📝 allow-running-insecure-content and
`allow-displaying-insecure-content`.
2015-07-29 16:17:14 +08:00
Haojian Wu
77a8a3d33c Add allow-running-insecure-content, allow-display-insecure-content
in BrowserWindow option.
2015-07-29 16:15:03 +08:00
Cheng Zhao
d5893d8c9f Merge pull request #2369 from atom/better-modifiers
Fix a few things of Tray
2015-07-29 15:22:27 +08:00
Cheng Zhao
409c6155c2 Merge pull request #2363 from atom/mime-check
Fix a missing the specified mime type check in <input> accept attribute.
2015-07-29 14:52:20 +08:00
Cheng Zhao
b786772819 Update brightray for #2324 2015-07-29 14:50:56 +08:00
Cheng Zhao
b2f03fc2d8 Add metaKey 2015-07-29 14:44:08 +08:00
Cheng Zhao
3e1a5b229c docs: modifiers removed 2015-07-29 14:27:32 +08:00
Cheng Zhao
8d22eeb3be Use DOM's way of telling modifiers 2015-07-29 14:25:12 +08:00
Cheng Zhao
625143426a Enable using custom events when emitting 2015-07-29 14:24:45 +08:00
Haojian Wu
f40155645c 📝 say more about setDownloadPath API. 2015-07-29 14:13:28 +08:00
Haojian Wu
877830e4a1 No need for default_download_path_ member. 2015-07-29 14:04:14 +08:00
Haojian Wu
45f5a10d5d Use NSImageView to draw tray icon.
* Fixes Tempate image doesn't show correctly in dark mode.
* Fixes the tray icon is stretched showing in menubar.
* Fixes title color will not reversed in dark mode.
2015-07-29 13:45:01 +08:00
Cheng Zhao
d42fd6fc7e win: Pass modifers in 'clicked' events 2015-07-29 13:10:51 +08:00
Cheng Zhao
74248253f5 win: Set GUID when getting icon's bounds 2015-07-29 12:55:44 +08:00
Cheng Zhao
15273c1f7a docs: Don't say things that are expected 2015-07-29 12:41:40 +08:00
Taichiro Yoshida
fc92ceb0b6 do not overwrite node-integration option
If `node-integration` option pass to window.open, do not overwrite by current window's one
2015-07-29 13:41:11 +09:00
Cheng Zhao
9afa94f4b8 win: Implement double-clicked event 2015-07-29 12:36:01 +08:00
Cheng Zhao
edde653d60 Merge branch 'feature/modifiers-click-tray' of https://github.com/nishanths/electron into nishanths-feature/modifiers-click-tray 2015-07-29 12:19:17 +08:00
Robo
66553eea1a webContents: api to add/remove path from devtools workspace 2015-07-29 09:29:38 +05:30
Cheng Zhao
2c97cd64cf Minor style fix for #2352 2015-07-29 11:48:40 +08:00
Cheng Zhao
ff6b9d0907 Merge pull request #2352 from nishanths/feature/native-image-is-template
Add NativeImage.isTemplateImage method
2015-07-29 11:47:00 +08:00
Cheng Zhao
c500c9b289 Merge pull request #2349 from atom/mq-run-your-app
Reorganize the Run Your App section
2015-07-29 11:46:02 +08:00
Cheng Zhao
9afb973498 Merge pull request #2347 from deepak1556/fetch_job_headers_patch
protocol: fix request headers in urlRequestFetchJob
2015-07-29 11:44:47 +08:00
Cheng Zhao
1bc49487ad Merge pull request #2314 from UsabilityEtc/update-api-docs
Update api docs
2015-07-29 11:35:14 +08:00
Cheng Zhao
f485a9894c Merge pull request #2318 from craigshoemaker/patch-1
📝 Windows/Linux compatibility changes
2015-07-29 11:34:46 +08:00
Cheng Zhao
c140077d53 Merge pull request #2338 from atom/page_size_option
Add 'pageSize' option in printToPDF API.
2015-07-29 11:32:49 +08:00
Cheng Zhao
42ce91323c docs: Small style fix for #2337 2015-07-29 11:28:20 +08:00
Cheng Zhao
0ca9dfbc12 Merge pull request #2337 from nishanths/feature/bounds-tray-dblclick
Send bounding Rect on tray double click events
2015-07-29 11:27:04 +08:00
Cheng Zhao
b08af89473 Style fix for #2328 2015-07-29 11:22:12 +08:00
Cheng Zhao
b9cf0f2126 Merge pull request #2328 from atom/tray-settings-propagate
Propagate User App Model ID to Tray Icon
2015-07-29 11:08:35 +08:00
Plusb Preco
11589a7bde Update as upstream 2015-07-29 02:21:32 +09:00
Jeffrey Morgan
b10560a5b0 Fix typo in auto-updater.md 2015-07-28 16:51:41 +01:00
Cheng Zhao
f4d8e32c9f Merge pull request #2350 from matiasinsaurralde/master
Basic Spanish docs
2015-07-28 16:22:11 +08:00
Haojian Wu
617bff8ec8 Fix a missing the specified mime type check in <input> accept attribute. 2015-07-28 10:32:13 +08:00
Nishanth Shanmugham
a44f14d76e Fix code formatting issues 2015-07-27 03:33:15 -07:00
Nishanth Shanmugham
74b4522195 Add keyboard modifiers payload to tray click events
* Add keyboard and mouse button bitsum to Tray click events payload
* Move getBoundsFromRect: to common event_util file
* Update documentation
2015-07-27 03:15:51 -07:00
Nishanth Shanmugham
99a8f29de9 Move event type functions to a common event_util file 2015-07-27 00:41:20 -07:00
Nishanth Shanmugham
51111430b3 Add NativeImage docs for IsTemplateImage 2015-07-26 21:59:43 -07:00
Nishanth Shanmugham
9211109088 Add NativeImage.IsTemplateImage method
* Rename internal function that determines template image filename patterns
* Add the new IsTemplateMethod
2015-07-26 21:58:48 -07:00
Matias Insaurralde
ad7e4a77db custom dom texts 2015-07-26 22:59:19 -04:00
Matias Insaurralde
faf10183d8 first docs 2015-07-26 22:57:43 -04:00
Haojian Wu
59c3efd44b Correct the override comment. 2015-07-27 09:09:32 +08:00
Machisté N. Quintana
f2b2c58758 📝 🎨 Grammar fix 2015-07-26 20:31:01 -04:00
Machisté N. Quintana
b6f6bf9778 📝 Reorganize the Run Your App section 2015-07-26 20:26:10 -04:00
Robo
b0e73532de protocol: fix request headers in urlRequestFetchJob 2015-07-27 02:51:41 +05:30
Haojian Wu
7f0cb0ce1b 📝 session.setDownloadPath API. 2015-07-26 16:52:02 +08:00
Haojian Wu
fef53d18c4 Add session.setDownloadPath API. 2015-07-26 16:51:27 +08:00
Haojian Wu
2aa17debc8 prefs' key needs to be registered before using. 2015-07-26 16:17:55 +08:00
Haojian Wu
0700f08d6d Copy pref_names files from Chromium. 2015-07-26 16:08:29 +08:00
Nishanth Shanmugham
1a074bb148 Update tray double-click docs
* Mention bounds payload
2015-07-25 21:16:15 -07:00
Haojian Wu
74f2e9f102 📝 pageSize option. 2015-07-26 11:57:53 +08:00
Nishanth Shanmugham
f53995d555 Send bounding Rect on tray double click events 2015-07-25 20:56:35 -07:00
Haojian Wu
9eeebedf5f Add pageSize option in printToPDF API. 2015-07-26 11:55:52 +08:00
Paul Betts
5e61974c24 Set NIF_GUID if we have a GUID 2015-07-24 08:05:36 -07:00
Craig Shoemaker
d485cfbca3 Fixed typo 2015-07-24 06:53:55 -07:00
Paul Betts
70feb08f84 Fix linting issues 2015-07-24 03:30:23 -07:00
Paul Betts
75b08f510e Fix up namespaces 2015-07-24 03:27:15 -07:00
Paul Betts
08383a69ce Propagate User App Model ID to Tray Icon
This PR prevents dozens of items showing up in the notification area
preferences when using Squirrel for Windows, by ensuring that
notification tray items are tied to the User App Model ID.
2015-07-24 03:10:03 -07:00
Cheng Zhao
7ceca9f426 Bump v0.30.1 2015-07-24 16:59:18 +08:00
Cheng Zhao
720dc92efe Merge pull request #2325 from atom/linux-min-max
linux: Fix min/max size not working
2015-07-24 16:57:59 +08:00
Cheng Zhao
73ded9d378 linux: Fix min/max size not working 2015-07-24 16:21:44 +08:00
Cheng Zhao
48975d04e0 Merge pull request #2323 from atom/better-spec
Fix a few flaky tests
2015-07-24 16:21:16 +08:00
Cheng Zhao
417e97eef0 spec: Don't reuse port in session spec 2015-07-24 15:49:19 +08:00
Cheng Zhao
b52c07f650 spec: Make dom-ready spec stronger 2015-07-24 15:48:13 +08:00
Cheng Zhao
1a93b1db52 spec: Make the basic-auth spec stronger 2015-07-24 15:33:07 +08:00
Cheng Zhao
b547772c68 Merge pull request #2321 from atom/web-contents-focus
Focus on WebContents when we load url in BrowserWindow for the first time
2015-07-24 14:24:14 +08:00
Jeffrey Morgan
4de4ef1ccc Remove change to "mapped onto" in accelerator.md
Remove the change to “mapped onto” in `accelerator.md` after feedback
from @OlsonDev.
2015-07-24 07:19:43 +01:00
Cheng Zhao
d822e0d720 Merge pull request #2320 from atom/appcomands
Fix app-command event always return 'unknown'.
2015-07-24 13:28:30 +08:00
Cheng Zhao
29c574cf0f Focus WebContents when we first load url in BrowserWindow 2015-07-24 13:08:19 +08:00
Haojian Wu
3840a10da6 Fix app-command event always return 'unknown'. 2015-07-24 13:02:11 +08:00
Cheng Zhao
9bb87af66b Add webContents.focus 2015-07-24 12:58:28 +08:00
Cheng Zhao
9ec60cd585 Merge pull request #2316 from tengyifei/master
Only allow extensions explicitly specified by the user. Fixes #2296
2015-07-24 11:11:56 +08:00
Craig Shoemaker
959f5d61b7 Windows/Linux compatibility changes
- Updated accelerator to cross platform values
- Added a warning to non-Mac users regarding the selector option
2015-07-23 15:04:43 -07:00
Jeffrey Morgan
d9ee8519e9 Correct error in chrome-command-line-switches.md
Replace “to” with “in” to correct the error identified in
`chrome-command-line-switches.md` by @OlsonDev.
2015-07-23 20:45:08 +01:00
Yifei Teng
8960aa956c Only allow extensions explicitly specified by the user. Fixes #2296 2015-07-23 12:30:07 -07:00
Plusb Preco
63258f9f53 Update as upstream, Fix typos 2015-07-24 02:39:55 +09:00
Jeffrey Morgan
8b4815fd95 Improve grammar and punctuation of crash-reporter.md
Improve the grammar, sentence structure, punctuation and formatting of
`crash-reporter.md`.
2015-07-23 18:02:45 +01:00
Jeffrey Morgan
32b84bd3f9 Improve grammar and punctuation of clipboard.md
Improve the grammar, sentence structure, punctuation and formatting of
`clipboard.md`.
2015-07-23 18:01:00 +01:00
Jeffrey Morgan
adab769700 Improve grammar and punctuation of chrome-command-line-switches.md
Improve the grammar, sentence structure, punctuation and formatting of
`chrome-command-line-switches.md`
2015-07-23 17:59:51 +01:00
Jeffrey Morgan
d138c2970c Improve grammar and punctuation of auto-updater.md
Improve the grammar, sentence structure, punctuation and formatting of
`auto-updater.md`.
2015-07-23 17:57:42 +01:00
Jeffrey Morgan
452619990e Improve grammar and punctuation of accelerator.md
Improve the grammar, sentence structure, punctuation and formatting of
`accelerator.md`.
2015-07-23 17:55:57 +01:00
Cheng Zhao
de17894fce Merge pull request #2307 from atom/dialog-options
Add "noLink" option for showMessageBox
2015-07-23 17:59:09 +08:00
Cheng Zhao
6c44553456 Show all buttons as custom buttons when noLink is specified 2015-07-23 17:34:35 +08:00
Cheng Zhao
cc2a9f617d Add noLink option for showMessageBox 2015-07-23 17:25:37 +08:00
Cheng Zhao
1578d2fda9 Allow the C++ JS binding function to accept arbitrary long arguments 2015-07-23 15:00:42 +08:00
Cheng Zhao
da724d65d7 Add |options| for ShowMessageBox 2015-07-23 14:16:43 +08:00
Cheng Zhao
eb92e9cdd8 Use node::MakeCallback to emit events in C++
Fix #2165
2015-07-23 13:48:34 +08:00
Cheng Zhao
5a980497e8 Merge pull request #2298 from deepak1556/default_protocol_handler_patch
protocol: fix adapter request job for default handlers
2015-07-23 12:15:54 +08:00
Cheng Zhao
72eb87a631 Make the extraSize of BrowserWindow.setAspectRatio optional 2015-07-23 10:14:02 +08:00
Cheng Zhao
df35700b94 Style fixes
* Use under_score for variable names in C++
* Use const& when possible
* Line length <= 80
2015-07-23 10:07:58 +08:00
Cheng Zhao
ea1b89c699 Merge pull request #2250 from EyeSee360/master
Maintain an aspect ratio for content within a window
2015-07-23 09:45:42 +08:00
Cheng Zhao
a8658b7dca Merge pull request #2302 from etiktin/patch-1
Update dialog.md
2015-07-23 09:42:03 +08:00
Brendon Gonzalez
e64fbe3529 Merge pull request #4 from EyeSee360/msb/electron-pr-update
changes requested for pull request #2250 into electron master
2015-07-22 13:48:51 -04:00
Robo
97c90d31d3 get jsprotocolhandler in IO thread 2015-07-22 21:54:12 +05:30
Robo
a1ec07e07e read post-filtered data when filters are present 2015-07-22 21:45:08 +05:30
Eran Tiktin
d701e1aa40 Update dialog.md
Added a comment about the fact that on Windows, the "question" message box uses the same icon as the "info" message box (Electron uses the task dialog API instead of the message box API). This is because Microsoft's API doesn't supply a default question icon (see `pszIcon` in https://msdn.microsoft.com/en-us/library/windows/desktop/bb760540(v=vs.85).aspx).
2015-07-22 18:13:50 +03:00
Michael S. Barthelemy
6d25c81bd1 changes requested for pull request #2250 into electron master 2015-07-22 10:23:31 -04:00
Robo
58f1907579 protocol: copy headers from original request for custom request job 2015-07-22 13:54:39 +05:30
Cheng Zhao
3250764e72 Merge pull request #2297 from atom/get-user-agent
Implement getUserAgent API.
2015-07-22 15:38:35 +08:00
Haojian Wu
462e6e0a82 Implement getUserAgent API. 2015-07-22 12:25:10 +08:00
Cheng Zhao
59269a70a0 docs: Mention libappindicator1 is required, close #1347 2015-07-21 11:27:43 +08:00
Cheng Zhao
8df8b5731e Merge pull request #2287 from atom/fix-mac-content-size
mac: Always call SetSize for frameless window
2015-07-21 10:53:17 +08:00
Cheng Zhao
dbab889fcc Merge pull request #2232 from atom/status_item_view
Introduce custom status item view on OS X.
2015-07-21 10:36:19 +08:00
Cheng Zhao
891d107a51 mac: Always use GetSize for frameless window 2015-07-21 10:34:37 +08:00
Cheng Zhao
3ea878941b mac: Always call SetSize for framless window 2015-07-21 10:29:05 +08:00
Cheng Zhao
f25cf7481f spec: Test setContentSize for frameless window 2015-07-21 10:17:38 +08:00
Haojian Wu
d342c9a6df Implement 'drop-files' tray event on OS X. 2015-07-20 20:06:15 +08:00
Cheng Zhao
a1f0c24bf4 Merge pull request #2270 from UsabilityEtc/patch-1
Improve grammar and sentence structure of app.md
2015-07-20 18:40:09 +08:00
Cheng Zhao
a11d8ea558 Merge pull request #2246 from deepak1556/session_proxy_api
session: api to set proxy
2015-07-20 18:29:53 +08:00
Cheng Zhao
f6263f8c6b Update brightray for #2238 2015-07-20 18:27:49 +08:00
Robo
d3055a5ca0 session: api to set proxy 2015-07-20 15:21:47 +05:30
Matias Insaurralde
73790fcef5 preparing README-es 2015-07-19 17:39:59 -04:00
Jeffrey Morgan
5010c15ffc Improve grammar and sentence structure of app.md
Improve the grammar and sentence structure of app.md. Replace references to Mac with OS X for consistency with other docs and use the OS X nomenclature of notification rather than message.
2015-07-18 15:40:01 +01:00
Michael S. Barthelemy
6656afd57f fix bug with computing the case where we should constrain via height 2015-07-17 10:25:30 -04:00
Plusb Preco
0b7a1a1eef Fix typos, Improve grammer 2015-07-17 13:28:13 +09:00
Plusb Preco
72d332dfa0 Translate little files into korean 2015-07-17 09:18:16 +09:00
Cheng Zhao
8cf9df2d8d docs: Mention null session of RequestHttpJob 2015-07-16 15:17:45 -07:00
Cheng Zhao
3145c78b61 Merge pull request #2207 from deepak1556/fetch_job_patch
protocol: create separate request context for fetch job
2015-07-16 15:14:45 -07:00
Robo
de3ccc4b98 use current session when not defined 2015-07-17 02:00:43 +05:30
Michael S. Barthelemy
d0c6176640 wrap lines to meet Travis CI build requirements 2015-07-16 14:45:27 -04:00
Michael S. Barthelemy
7cdfa44438 shorten names 2015-07-16 14:31:01 -04:00
Michael S. Barthelemy
10faf314d4 fix line length issue 2015-07-16 14:26:48 -04:00
mbarthelemy
378e81ffaa Merge pull request #1 from EyeSee360/msb/aspect-ratio
add function maintainAspectRatioOfInteriorContent to BrowserWindow
2015-07-16 14:01:55 -04:00
Michael S. Barthelemy
423ea00263 Merge branch 'master' into msb/aspect-ratio 2015-07-16 13:57:38 -04:00
Michael S. Barthelemy
666aca7803 add function maintainAspectRatioOfInteriorContent to BrowserWindow in order to enforce an aspect ratio for an electron window 2015-07-16 13:54:51 -04:00
Robo
57244e4718 use request context from session if provided 2015-07-16 20:18:33 +05:30
Robo
8eb87c5d2b protocol: create separate request context for fetch job 2015-07-16 20:18:33 +05:30
Haojian Wu
2cd6ad1a97 More code style fixing. 2015-07-16 18:42:20 +08:00
Haojian Wu
17628b3e40 📝 tray.popContextMenu API. 2015-07-16 11:53:13 +08:00
Haojian Wu
736fe0c1db Fix OS X build error. 2015-07-16 11:43:42 +08:00
Haojian Wu
ed4c69343f Add 'tray.popContextMenu()' Windows implementation. 2015-07-16 11:42:43 +08:00
Haojian Wu
4421fbf9f3 Implement 'tray.popContextMenu' API on OS X. 2015-07-16 10:50:53 +08:00
Haojian Wu
002eb1a326 Simplify code logic and fix object-c code style. 2015-07-16 10:49:55 +08:00
Haojian Wu
38c33d69ae 📝 'right-clicked' doc. 2015-07-15 20:13:59 +08:00
Haojian Wu
5ad3fff6a0 Implement 'right-clicked' tray event on Windows. 2015-07-15 20:03:05 +08:00
Haojian Wu
cca4f4abd5 Implement 'right-clicked' tray event on OS X. 2015-07-15 19:32:00 +08:00
Haojian Wu
e54fda6b34 Introduce Electron custom statusItem view.
Reimplement tray functions on OS X by using custom statusItem view.
2015-07-15 18:26:39 +08:00
Plusb Preco
b524914008 Update as upstream 2015-07-15 08:30:02 +09:00
Plusb Preco
26163e5812 Prepare update forked repo 2015-07-15 08:09:07 +09:00
Plusb Preco
0dfcc7a9b3 Update changes as upstream 2015-07-15 08:09:05 +09:00
Plusb Preco
e510384375 Revert "Revert "Update APIs, check grammars""
This reverts commit 5e083473e7b4d3a6014d35e68618594765151afe.
2015-07-15 08:09:03 +09:00
Plusb Preco
eb81810a52 Revert "Update APIs, check grammars"
This reverts commit d1eb971263f72deae84541d12b3bdd6d5972365a.
2015-07-15 08:09:01 +09:00
Plusb Preco
3b2f3c3152 Update APIs, check grammars 2015-07-15 08:08:59 +09:00
Plusb Preco
de5bc32d0b Fix typos, update some files 2015-07-15 08:08:57 +09:00
440 changed files with 17937 additions and 9789 deletions

View File

@@ -22,3 +22,7 @@ matrix:
- env: TARGET_ARCH=ia32
script: './script/cibuild'
branches:
only:
- master

View File

@@ -2,8 +2,8 @@
:+1::tada: First off, thanks for taking the time to contribute! :tada::+1:
This project adheres to the [Open Code of Conduct][code-of-conduct]. By participating, you are expected to uphold this code.
[code-of-conduct]: http://todogroup.org/opencodeofconduct/#Electron/opensource@github.com
This project adheres to the [Contributor Covenant 1.2](http://contributor-covenant.org/version/1/2/0).
By participating, you are expected to uphold this code. Please report unacceptable behavior to atom@github.com.
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
@@ -29,7 +29,8 @@ possible with your report. If you can, please include:
* 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).
See the [Documentation Styleguide](/docs/styleguide.md).
* Use short, present tense commit messages. See [Commit Message Styleguide](#git-commit-messages).
## Styleguides

View File

@@ -1,29 +1,31 @@
[![Electron Logo](http://electron.atom.io/images/electron-logo.svg)](http://electron.atom.io/)
[![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/)
### [Electron](https://github.com/atom/electron/) 한국어 참조문서
:zap: *전까지 Atom Shell로 알려져 있었습니다* :zap:
:zap: *프레임워크 이름이 Atom Shell에서 Electron으로 변경되었습니다* :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은 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)를 팔로우 하세요.
Electron에 대한 중요한 알림을 받으려면 Twitter에서 [@ElectronJS](https://twitter.com/electronjs)를 Follow하세요.
이 프로젝트는 기여자 규약 1.2를 준수합니다. 이 프로젝트에 참여할 때 코드를 유지해야 합니다. 받아들일 수 없는 행동은 atom@github.com로 보고 하십시오.
## 다운로드
Linux, Windows, Mac용으로 미리 빌드된 Electron 바이너리와 디버그 심볼이 준비되어 있습니다. [releases](https://github.com/atom/electron/releases) 페이지에서 받아 볼 수 있습니다.
또한 [`npm`](https://docs.npmjs.com/)을 이용하여 미리 빌드된 Electron 바이너리를 받을 수 있습니다:
또한 [`npm`](https://docs.npmjs.com/)을 통해 미리 빌드된 Electron 바이너리를 받을 수 있습니다:
```sh
# $PATH에 `electron` 등록하고 전역에 설치합니다.
# $PATH에 `electron` 커맨드를 등록하고 전역에 설치합니다.
npm install electron-prebuilt -g
# 개발용 dependency로 설치합니다.
# 개발 의존성 모듈 형태로 설치합니다.
npm install electron-prebuilt --save-dev
```
@@ -31,13 +33,26 @@ npm install electron-prebuilt --save-dev
- [China](https://npm.taobao.org/mirrors/electron)
## 참조문서
## 참조 문서
[docs](https://github.com/atom/electron/tree/master/docs/README-ko.md) 프레임워크 사용 가이드와 API 레퍼런스가 있습니다.
추가적으로 Electron을 빌드 하는 방법과 프로젝트에 기여하는 방법도 문서에 포함되어 있으니 참고하기 바랍니다.
[Docs](https://github.com/atom/electron/tree/master/docs/README.md)에 개발 가이드와 API 레퍼런스가 있습니다.
Electron을 빌드 하는 방법과 프로젝트에 기여하는 방법도 문서에 포함되어 있으니 참고하기 바랍니다.
## 참조 문서 (번역)
- [브라질 포르투칼어](https://github.com/atom/electron/tree/master/docs-translations/pt-BR)
- [한국어](https://github.com/atom/electron/tree/master/docs-translations/ko-KR)
- [일본어](https://github.com/atom/electron/tree/master/docs-translations/jp)
- [스페인어](https://github.com/atom/electron/tree/master/docs-translations/es)
- [중국어 간체](https://github.com/atom/electron/tree/master/docs-translations/zh-CN)
- [중국어 번체](https://github.com/atom/electron/tree/master/docs-translations/zh-TW)
## 커뮤니티
[Atom 포럼내의 `electron` 카테고리](http://discuss.atom.io/category/electron) 와 Freenode `#atom-shell` 채팅채널이 있습니다.
다음 링크를 통해 커뮤니티에 질문을 올리거나 토론을 나누실 수 있습니다:
[awesome-electron](https://github.com/sindresorhus/awesome-electron) 에 커뮤니티가 운영중인 유용한 예제 앱과 툴, 리소스가 있으니 한번 탐색해 보시기 바랍니다.
- Atom 포럼의 [`electron`](http://discuss.atom.io/category/electron) 카테고리
- Freenode 채팅의 `#atom-shell` 채널
- Slack의 [`Atom`](http://atom-slack.herokuapp.com/) 채널
[awesome-electron](https://github.com/sindresorhus/awesome-electron) 프로젝트엔 커뮤니티가 운영중인 유용한 예제 어플리케이션과 도구, 리소스가 있으니 한번 참고해 보시기 바랍니다.

View File

@@ -4,7 +4,7 @@
[![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:
:zap: *Formerly known as Atom Shell* :zap:
The Electron framework lets you write cross-platform desktop applications
using JavaScript, HTML and CSS. It is based on [io.js](http://iojs.org) and
@@ -14,8 +14,9 @@ editor](https://github.com/atom/atom).
Follow [@ElectronJS](https://twitter.com/electronjs) on Twitter for important
announcements.
This project adheres to the [Open Code of Conduct][code-of-conduct]. By participating, you are expected to uphold this code.
[code-of-conduct]: http://todogroup.org/opencodeofconduct/#Electron/opensource@github.com
This project adheres to the [Contributor Covenant 1.2](http://contributor-covenant.org/version/1/2/0).
By participating, you are expected to uphold this code. Please report
unacceptable behavior to atom@github.com.
## Downloads
@@ -43,9 +44,23 @@ Guides and the API reference are located in the
[docs](https://github.com/atom/electron/tree/master/docs) directory. It also
contains documents describing how to build and contribute to Electron.
## Documentation Translations
- [Brazilian Portuguese](https://github.com/atom/electron/tree/master/docs-translations/pt-BR)
- [Korean](https://github.com/atom/electron/tree/master/docs-translations/ko-KR)
- [Japanese](https://github.com/atom/electron/tree/master/docs-translations/jp)
- [Spanish](https://github.com/atom/electron/tree/master/docs-translations/es)
- [Simplified Chinese](https://github.com/atom/electron/tree/master/docs-translations/zh-CN)
- [Traditional Chinese](https://github.com/atom/electron/tree/master/docs-translations/zh-TW)
## Community
There is an [`electron` category on the Atom forums](http://discuss.atom.io/category/electron)
as well as an `#atom-shell` channel on Freenode.
You can ask questions and interact with the community in the following
locations:
- [`electron`](http://discuss.atom.io/category/electron) category on the Atom
forums
- `#atom-shell` channel on Freenode
- [`Atom`](http://atom-slack.herokuapp.com/) channel on Slack
Check out [awesome-electron](https://github.com/sindresorhus/awesome-electron) for a community maintained list of useful example apps, tools and resources.
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,7 +4,7 @@
'product_name%': 'Electron',
'company_name%': 'GitHub, Inc',
'company_abbr%': 'github',
'version%': '0.30.0',
'version%': '0.33.2',
},
'includes': [
'filenames.gypi',
@@ -144,7 +144,6 @@
'destination': '<(PRODUCT_DIR)',
'files': [
'<@(copied_libraries)',
'<(libchromiumcontent_dir)/ffmpegsumo.dll',
'<(libchromiumcontent_dir)/libEGL.dll',
'<(libchromiumcontent_dir)/libGLESv2.dll',
'<(libchromiumcontent_dir)/icudtl.dat',
@@ -193,7 +192,6 @@
'destination': '<(PRODUCT_DIR)',
'files': [
'<@(copied_libraries)',
'<(libchromiumcontent_dir)/libffmpegsumo.so',
'<(libchromiumcontent_dir)/icudtl.dat',
'<(libchromiumcontent_dir)/content_shell.pak',
'<(libchromiumcontent_dir)/natives_blob.bin',
@@ -226,8 +224,6 @@
# Defined in Chromium but not exposed in its gyp file.
'V8_USE_EXTERNAL_STARTUP_DATA',
'ENABLE_PLUGINS',
# Needed by Node.
'NODE_WANT_INTERNALS=1',
],
'sources': [
'<@(lib_sources)',
@@ -441,7 +437,6 @@
'destination': '<(PRODUCT_DIR)/<(product_name) Framework.framework/Versions/A/Libraries',
'files': [
'<@(copied_libraries)',
'<(libchromiumcontent_dir)/ffmpegsumo.so',
],
},
{
@@ -462,6 +457,16 @@
'${BUILT_PRODUCTS_DIR}/<(product_name) Framework.framework/Versions/A/<(product_name) Framework',
],
},
{
'postbuild_name': 'Fix path of ffmpeg',
'action': [
'install_name_tool',
'-change',
'@loader_path/libffmpeg.dylib',
'@rpath/libffmpeg.dylib',
'${BUILT_PRODUCTS_DIR}/<(product_name) Framework.framework/Versions/A/<(product_name) Framework',
],
},
{
'postbuild_name': 'Add symlinks for framework subdirectories',
'action': [

View File

@@ -7,6 +7,7 @@
#include <string>
#include <vector>
#include "atom/common/atom_version.h"
#include "atom/common/chrome_version.h"
#include "atom/common/options_switches.h"
#include "base/command_line.h"
@@ -14,6 +15,7 @@
#include "base/strings/string_util.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/pepper_plugin_info.h"
#include "content/public/common/user_agent.h"
#include "ppapi/shared_impl/ppapi_permissions.h"
namespace atom {
@@ -72,6 +74,12 @@ std::string AtomContentClient::GetProduct() const {
return "Chrome/" CHROME_VERSION_STRING;
}
std::string AtomContentClient::GetUserAgent() const {
return content::BuildUserAgentFromProduct(
"Chrome/" CHROME_VERSION_STRING " "
ATOM_PRODUCT_NAME "/" ATOM_VERSION_STRING);
}
void AtomContentClient::AddAdditionalSchemes(
std::vector<std::string>* standard_schemes,
std::vector<std::string>* savable_schemes) {

View File

@@ -20,6 +20,7 @@ class AtomContentClient : public brightray::ContentClient {
protected:
// content::ContentClient:
std::string GetProduct() const override;
std::string GetUserAgent() const override;
void AddAdditionalSchemes(
std::vector<std::string>* standard_schemes,
std::vector<std::string>* savable_schemes) override;

View File

@@ -33,6 +33,7 @@
#include "atom/app/node_main.h"
#include "atom/common/atom_command_line.h"
#include "base/at_exit.h"
#include "base/i18n/icu_util.h"
#if defined(OS_WIN)
@@ -134,6 +135,7 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
if (env->GetVar("ATOM_SHELL_INTERNAL_RUN_AS_NODE", &node_indicator) &&
node_indicator == "1") {
// Now that argv conversion is done, we can finally start.
base::AtExitManager atexit_manager;
base::i18n::InitializeICU();
return atom::NodeMain(argc, argv);
} else if (env->GetVar("ATOM_SHELL_INTERNAL_CRASH_SERVICE",
@@ -165,6 +167,7 @@ int main(int argc, const char* argv[]) {
char* node_indicator = getenv("ATOM_SHELL_INTERNAL_RUN_AS_NODE");
if (node_indicator != NULL && strcmp(node_indicator, "1") == 0) {
base::i18n::InitializeICU();
base::AtExitManager atexit_manager;
return atom::NodeMain(argc, const_cast<char**>(argv));
}

View File

@@ -38,7 +38,9 @@ bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
#else
settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
#endif // defined(DEBUG)
#endif // defined(OS_WIN)
#else // defined(OS_WIN)
settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
#endif // !defined(OS_WIN)
logging::InitLogging(settings);
// Logging with pid and timestamp.

View File

@@ -4,14 +4,21 @@
#include "atom/app/node_main.h"
#include "atom/app/uv_task_runner.h"
#include "atom/browser/javascript_environment.h"
#include "atom/browser/node_debugger.h"
#include "atom/common/node_includes.h"
#include "base/command_line.h"
#include "base/thread_task_runner_handle.h"
#include "gin/array_buffer.h"
#include "gin/public/isolate_holder.h"
#include "gin/v8_initializer.h"
namespace atom {
int NodeMain(int argc, char *argv[]) {
base::CommandLine::Init(argc, argv);
argv = uv_setup_args(argc, argv);
int exec_argc;
const char** exec_argv;
@@ -19,27 +26,29 @@ int NodeMain(int argc, char *argv[]) {
int exit_code = 1;
{
gin::IsolateHolder::LoadV8Snapshot();
// Feed gin::PerIsolateData with a task runner.
uv_loop_t* loop = uv_default_loop();
scoped_refptr<UvTaskRunner> uv_task_runner(new UvTaskRunner(loop));
base::ThreadTaskRunnerHandle handle(uv_task_runner);
gin::V8Initializer::LoadV8Snapshot();
gin::V8Initializer::LoadV8Natives();
gin::IsolateHolder::Initialize(
gin::IsolateHolder::kNonStrictMode,
gin::ArrayBufferAllocator::SharedInstance());
JavascriptEnvironment gin_env;
node::Environment* env = node::CreateEnvironment(
gin_env.isolate(), uv_default_loop(), gin_env.context(), argc, argv,
gin_env.isolate(), loop, gin_env.context(), argc, argv,
exec_argc, exec_argv);
// Start debugger.
node::node_isolate = gin_env.isolate();
if (node::use_debug_agent)
node::StartDebug(env, node::debug_wait_connect);
// Start our custom debugger implementation.
NodeDebugger node_debugger(gin_env.isolate());
if (node_debugger.IsRunning())
env->AssignToContext(v8::Debug::GetDebugContext());
node::LoadEnvironment(env);
// Enable debugger.
if (node::use_debug_agent)
node::EnableDebug(env);
bool more;
do {
more = uv_run(env->event_loop(), UV_RUN_ONCE);

View File

@@ -0,0 +1,55 @@
// 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/app/uv_task_runner.h"
#include "base/stl_util.h"
namespace atom {
UvTaskRunner::UvTaskRunner(uv_loop_t* loop) : loop_(loop) {
}
UvTaskRunner::~UvTaskRunner() {
for (auto& iter : tasks_) {
uv_unref(reinterpret_cast<uv_handle_t*>(iter.first));
delete iter.first;
}
}
bool UvTaskRunner::PostDelayedTask(const tracked_objects::Location& from_here,
const base::Closure& task,
base::TimeDelta delay) {
uv_timer_t* timer = new uv_timer_t;
timer->data = this;
uv_timer_init(loop_, timer);
uv_timer_start(timer, UvTaskRunner::OnTimeout, delay.InMilliseconds(), 0);
tasks_[timer] = task;
return true;
}
bool UvTaskRunner::RunsTasksOnCurrentThread() const {
return true;
}
bool UvTaskRunner::PostNonNestableDelayedTask(
const tracked_objects::Location& from_here,
const base::Closure& task,
base::TimeDelta delay) {
return PostDelayedTask(from_here, task, delay);;
}
// static
void UvTaskRunner::OnTimeout(uv_timer_t* timer) {
UvTaskRunner* self = static_cast<UvTaskRunner*>(timer->data);
if (!ContainsKey(self->tasks_, timer))
return;
self->tasks_[timer].Run();
self->tasks_.erase(timer);
uv_unref(reinterpret_cast<uv_handle_t*>(timer));
delete timer;
}
} // namespace atom

44
atom/app/uv_task_runner.h Normal file
View File

@@ -0,0 +1,44 @@
// 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_APP_UV_TASK_RUNNER_H_
#define ATOM_APP_UV_TASK_RUNNER_H_
#include <map>
#include "base/callback.h"
#include "base/single_thread_task_runner.h"
#include "vendor/node/deps/uv/include/uv.h"
namespace atom {
// TaskRunner implementation that posts tasks into libuv's default loop.
class UvTaskRunner : public base::SingleThreadTaskRunner {
public:
explicit UvTaskRunner(uv_loop_t* loop);
~UvTaskRunner() override;
// base::SingleThreadTaskRunner:
bool PostDelayedTask(const tracked_objects::Location& from_here,
const base::Closure& task,
base::TimeDelta delay) override;
bool RunsTasksOnCurrentThread() const override;
bool PostNonNestableDelayedTask(
const tracked_objects::Location& from_here,
const base::Closure& task,
base::TimeDelta delay) override;
private:
static void OnTimeout(uv_timer_t* timer);
uv_loop_t* loop_;
std::map<uv_timer_t*, base::Closure> tasks_;
DISALLOW_COPY_AND_ASSIGN(UvTaskRunner);
};
} // namespace atom
#endif // ATOM_APP_UV_TASK_RUNNER_H_

View File

@@ -17,7 +17,9 @@
#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/callback.h"
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "atom/common/node_includes.h"
#include "base/command_line.h"
#include "base/environment.h"
#include "base/files/file_path.h"
@@ -25,17 +27,15 @@
#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/ssl/ssl_cert_request_info.h"
#include "ui/base/l10n/l10n_util.h"
#if defined(OS_WIN)
#include "base/strings/utf_string_conversions.h"
#endif
#include "atom/common/node_includes.h"
using atom::Browser;
namespace mate {
@@ -168,8 +168,8 @@ void App::OnOpenURL(const std::string& url) {
Emit("open-url", url);
}
void App::OnActivateWithNoOpenWindows() {
Emit("activate-with-no-open-windows");
void App::OnActivate(bool has_visible_windows) {
Emit("activate", has_visible_windows);
}
void App::OnWillFinishLaunching() {
@@ -249,6 +249,10 @@ void App::SetAppUserModelId(const std::string& app_id) {
#endif
}
std::string App::GetLocale() {
return l10n_util::GetApplicationLocale("");
}
v8::Local<v8::Value> App::DefaultSession(v8::Isolate* isolate) {
if (default_session_.IsEmpty())
return v8::Null(isolate);
@@ -279,6 +283,7 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder(
.SetMethod("getPath", &App::GetPath)
.SetMethod("setDesktopName", &App::SetDesktopName)
.SetMethod("setAppUserModelId", &App::SetAppUserModelId)
.SetMethod("getLocale", &App::GetLocale)
.SetProperty("defaultSession", &App::DefaultSession);
}

View File

@@ -41,7 +41,7 @@ class App : public mate::EventEmitter,
void OnQuit() override;
void OnOpenFile(bool* prevent_default, const std::string& file_path) override;
void OnOpenURL(const std::string& url) override;
void OnActivateWithNoOpenWindows() override;
void OnActivate(bool has_visible_windows) override;
void OnWillFinishLaunching() override;
void OnFinishLaunching() override;
void OnSelectCertificate(
@@ -65,6 +65,7 @@ class App : public mate::EventEmitter,
void SetDesktopName(const std::string& desktop_name);
void SetAppUserModelId(const std::string& app_id);
std::string GetLocale();
v8::Local<v8::Value> DefaultSession(v8::Isolate* isolate);
v8::Global<v8::Value> default_session_;

View File

@@ -7,11 +7,10 @@
#include "base/time/time.h"
#include "atom/browser/auto_updater.h"
#include "atom/browser/browser.h"
#include "atom/common/node_includes.h"
#include "native_mate/dictionary.h"
#include "native_mate/object_template_builder.h"
#include "atom/common/node_includes.h"
namespace atom {
namespace api {

View File

@@ -5,40 +5,32 @@
#include <set>
#include <string>
#include "atom/common/native_mate_converters/callback.h"
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "base/bind.h"
#include "content/public/browser/tracing_controller.h"
#include "native_mate/callback.h"
#include "native_mate/dictionary.h"
#include "atom/common/node_includes.h"
#include "base/bind.h"
#include "base/files/file_util.h"
#include "content/public/browser/tracing_controller.h"
#include "native_mate/dictionary.h"
using content::TracingController;
namespace mate {
template<>
struct Converter<base::trace_event::CategoryFilter> {
struct Converter<base::trace_event::TraceConfig> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
base::trace_event::CategoryFilter* out) {
std::string filter;
if (!ConvertFromV8(isolate, val, &filter))
return false;
*out = base::trace_event::CategoryFilter(filter);
return true;
}
};
template<>
struct Converter<base::trace_event::TraceOptions> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
base::trace_event::TraceOptions* out) {
std::string options;
base::trace_event::TraceConfig* out) {
Dictionary options;
if (!ConvertFromV8(isolate, val, &options))
return false;
return out->SetFromString(options);
std::string category_filter, trace_options;
if (!options.Get("categoryFilter", &category_filter) ||
!options.Get("traceOptions", &trace_options))
return false;
*out = base::trace_event::TraceConfig(category_filter, trace_options);
return true;
}
};
@@ -46,6 +38,31 @@ struct Converter<base::trace_event::TraceOptions> {
namespace {
using CompletionCallback = base::Callback<void(const base::FilePath&)>;
scoped_refptr<TracingController::TraceDataSink> GetTraceDataSink(
const base::FilePath& path, const CompletionCallback& callback) {
base::FilePath result_file_path = path;
if (result_file_path.empty() && !base::CreateTemporaryFile(&result_file_path))
LOG(ERROR) << "Creating temporary file failed";
return TracingController::CreateFileSink(result_file_path,
base::Bind(callback,
result_file_path));
}
void StopRecording(const base::FilePath& path,
const CompletionCallback& callback) {
TracingController::GetInstance()->DisableRecording(
GetTraceDataSink(path, callback));
}
void CaptureMonitoringSnapshot(const base::FilePath& path,
const CompletionCallback& callback) {
TracingController::GetInstance()->CaptureMonitoringSnapshot(
GetTraceDataSink(path, callback));
}
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());
@@ -54,14 +71,12 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
&TracingController::GetCategories, controller));
dict.SetMethod("startRecording", base::Bind(
&TracingController::EnableRecording, controller));
dict.SetMethod("stopRecording", base::Bind(
&TracingController::DisableRecording, controller, nullptr));
dict.SetMethod("stopRecording", &StopRecording);
dict.SetMethod("startMonitoring", base::Bind(
&TracingController::EnableMonitoring, controller));
dict.SetMethod("stopMonitoring", base::Bind(
&TracingController::DisableMonitoring, controller));
dict.SetMethod("captureMonitoringSnapshot", base::Bind(
&TracingController::CaptureMonitoringSnapshot, controller, nullptr));
dict.SetMethod("captureMonitoringSnapshot", &CaptureMonitoringSnapshot);
dict.SetMethod("getTraceBufferUsage", base::Bind(
&TracingController::GetTraceBufferUsage, controller));
dict.SetMethod("setWatchEvent", base::Bind(

View File

@@ -4,13 +4,14 @@
#include "atom/browser/api/atom_api_cookies.h"
#include "atom/common/native_mate_converters/callback.h"
#include "atom/common/native_mate_converters/gurl_converter.h"
#include "atom/common/native_mate_converters/value_converter.h"
#include "base/bind.h"
#include "base/time/time.h"
#include "base/values.h"
#include "content/public/browser/browser_context.h"
#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"
@@ -19,8 +20,6 @@
#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;
@@ -179,8 +178,8 @@ namespace atom {
namespace api {
Cookies::Cookies(content::BrowserContext* browser_context) :
browser_context_(browser_context) {
Cookies::Cookies(content::BrowserContext* browser_context)
: request_context_getter_(browser_context->GetRequestContext()) {
}
Cookies::~Cookies() {
@@ -198,11 +197,9 @@ void Cookies::Get(const base::DictionaryValue& options,
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,
if (!GetCookieListFromStore(GetCookieStore(), url,
base::Bind(&Cookies::OnGetCookies, base::Unretained(this),
Passed(&filter), callback))) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
@@ -245,9 +242,7 @@ void Cookies::Remove(const mate::Dictionary& details,
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,
GetCookieStore()->DeleteCookieAsync(url, name,
base::Bind(&Cookies::OnRemoveCookies, base::Unretained(this), callback));
}
@@ -286,8 +281,6 @@ 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;
@@ -308,7 +301,7 @@ void Cookies::SetCookiesOnIOThread(scoped_ptr<base::DictionaryValue> details,
base::Time::FromDoubleT(expiration_date);
}
cookie_store->GetCookieMonster()->SetCookieWithDetailsAsync(
GetCookieStore()->GetCookieMonster()->SetCookieWithDetailsAsync(
url,
name,
value,
@@ -337,6 +330,10 @@ mate::ObjectTemplateBuilder Cookies::GetObjectTemplateBuilder(
.SetMethod("set", &Cookies::Set);
}
net::CookieStore* Cookies::GetCookieStore() {
return request_context_getter_->GetURLRequestContext()->cookie_store();
}
// static
mate::Handle<Cookies> Cookies::Create(
v8::Isolate* isolate,

View File

@@ -8,17 +8,27 @@
#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 base {
class DictionaryValue;
}
namespace content {
class BrowserContext;
}
namespace mate {
class Dictionary;
}
namespace net {
class CookieStore;
class URLRequestContextGetter;
}
namespace atom {
namespace api {
@@ -60,13 +70,15 @@ class Cookies : public mate::Wrappable {
void OnSetCookies(const CookiesCallback& callback,
bool set_success);
// mate::Wrappable implementations:
// mate::Wrappable:
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) override;
private:
content::BrowserContext* browser_context_;
// Must be called on IO thread.
net::CookieStore* GetCookieStore();
net::URLRequestContextGetter* request_context_getter_;
DISALLOW_COPY_AND_ASSIGN(Cookies);
};

View File

@@ -10,9 +10,9 @@
#include "atom/browser/native_window.h"
#include "atom/browser/ui/file_dialog.h"
#include "atom/browser/ui/message_box.h"
#include "atom/common/native_mate_converters/callback.h"
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "atom/common/native_mate_converters/image_converter.h"
#include "native_mate/callback.h"
#include "native_mate/dictionary.h"
#include "atom/common/node_includes.h"
@@ -42,28 +42,24 @@ namespace {
void ShowMessageBox(int type,
const std::vector<std::string>& buttons,
int cancel_id,
const std::vector<std::string>& texts,
int options,
const std::string& title,
const std::string& message,
const std::string& detail,
const gfx::ImageSkia& icon,
atom::NativeWindow* window,
mate::Arguments* args) {
// FIXME We are exceeding the parameters limit of base::Bind here, so we have
// to pass some parameters in an array. We should remove this once we have
// variadic template support in base::Bind.
const std::string& title = texts[0];
const std::string& message = texts[1];
const std::string& detail = texts[2];
v8::Local<v8::Value> peek = args->PeekNext();
atom::MessageBoxCallback callback;
if (mate::Converter<atom::MessageBoxCallback>::FromV8(args->isolate(),
peek,
&callback)) {
atom::ShowMessageBox(window, (atom::MessageBoxType)type, buttons, cancel_id,
title, message, detail, icon, callback);
options, title, message, detail, icon, callback);
} else {
int chosen = atom::ShowMessageBox(window, (atom::MessageBoxType)type,
buttons, cancel_id, title, message,
detail, icon);
buttons, cancel_id, options, title,
message, detail, icon);
args->Return(chosen);
}
}

View File

@@ -0,0 +1,201 @@
// 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_download_item.h"
#include <map>
#include "atom/common/native_mate_converters/callback.h"
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "atom/common/native_mate_converters/gurl_converter.h"
#include "atom/common/node_includes.h"
#include "base/memory/linked_ptr.h"
#include "base/strings/utf_string_conversions.h"
#include "native_mate/dictionary.h"
#include "net/base/filename_util.h"
namespace mate {
template<>
struct Converter<content::DownloadItem::DownloadState> {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
content::DownloadItem::DownloadState state) {
std::string download_state;
switch (state) {
case content::DownloadItem::COMPLETE:
download_state = "completed";
break;
case content::DownloadItem::CANCELLED:
download_state = "cancelled";
break;
case content::DownloadItem::INTERRUPTED:
download_state = "interrupted";
break;
default:
break;
}
return ConvertToV8(isolate, download_state);
}
};
} // namespace mate
namespace atom {
namespace api {
namespace {
// The wrapDownloadItem funtion which is implemented in JavaScript
using WrapDownloadItemCallback = base::Callback<void(v8::Local<v8::Value>)>;
WrapDownloadItemCallback g_wrap_download_item;
char kDownloadItemSavePathKey[] = "DownloadItemSavePathKey";
std::map<uint32, linked_ptr<v8::Global<v8::Value>>> g_download_item_objects;
} // namespace
DownloadItem::SavePathData::SavePathData(const base::FilePath& path) :
path_(path) {
}
const base::FilePath& DownloadItem::SavePathData::path() {
return path_;
}
DownloadItem::DownloadItem(content::DownloadItem* download_item) :
download_item_(download_item) {
download_item_->AddObserver(this);
}
DownloadItem::~DownloadItem() {
Destroy();
}
void DownloadItem::Destroy() {
if (download_item_) {
download_item_->RemoveObserver(this);
auto iter = g_download_item_objects.find(download_item_->GetId());
if (iter != g_download_item_objects.end())
g_download_item_objects.erase(iter);
download_item_ = nullptr;
}
}
bool DownloadItem::IsDestroyed() const {
return download_item_ == nullptr;
}
void DownloadItem::OnDownloadUpdated(content::DownloadItem* item) {
download_item_->IsDone() ? Emit("done", item->GetState()) : Emit("updated");
}
void DownloadItem::OnDownloadDestroyed(content::DownloadItem* download) {
Destroy();
}
int64 DownloadItem::GetReceivedBytes() {
return download_item_->GetReceivedBytes();
}
int64 DownloadItem::GetTotalBytes() {
return download_item_->GetTotalBytes();
}
const GURL& DownloadItem::GetUrl() {
return download_item_->GetURL();
}
std::string DownloadItem::GetMimeType() {
return download_item_->GetMimeType();
}
bool DownloadItem::HasUserGesture() {
return download_item_->HasUserGesture();
}
std::string DownloadItem::GetFilename() {
return base::UTF16ToUTF8(net::GenerateFileName(GetUrl(),
GetContentDisposition(),
std::string(),
download_item_->GetSuggestedFilename(),
GetMimeType(),
std::string()).LossyDisplayName());
}
std::string DownloadItem::GetContentDisposition() {
return download_item_->GetContentDisposition();
}
void DownloadItem::SetSavePath(const base::FilePath& path) {
download_item_->SetUserData(UserDataKey(), new SavePathData(path));
}
void DownloadItem::Pause() {
download_item_->Pause();
}
void DownloadItem::Resume() {
download_item_->Resume();
}
void DownloadItem::Cancel() {
download_item_->Cancel(true);
}
mate::ObjectTemplateBuilder DownloadItem::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
return mate::ObjectTemplateBuilder(isolate)
.SetMethod("pause", &DownloadItem::Pause)
.SetMethod("resume", &DownloadItem::Resume)
.SetMethod("cancel", &DownloadItem::Cancel)
.SetMethod("getReceivedBytes", &DownloadItem::GetReceivedBytes)
.SetMethod("getTotalBytes", &DownloadItem::GetTotalBytes)
.SetMethod("getUrl", &DownloadItem::GetUrl)
.SetMethod("getMimeType", &DownloadItem::GetMimeType)
.SetMethod("hasUserGesture", &DownloadItem::HasUserGesture)
.SetMethod("getFilename", &DownloadItem::GetFilename)
.SetMethod("getContentDisposition", &DownloadItem::GetContentDisposition)
.SetMethod("setSavePath", &DownloadItem::SetSavePath);
}
void SetWrapDownloadItem(const WrapDownloadItemCallback& callback) {
g_wrap_download_item = callback;
}
void ClearWrapDownloadItem() {
g_wrap_download_item.Reset();
}
// static
mate::Handle<DownloadItem> DownloadItem::Create(
v8::Isolate* isolate, content::DownloadItem* item) {
auto handle = mate::CreateHandle(isolate, new DownloadItem(item));
g_wrap_download_item.Run(handle.ToV8());
g_download_item_objects[item->GetId()] = make_linked_ptr(
new v8::Global<v8::Value>(isolate, handle.ToV8()));
return handle;
}
// static
void* DownloadItem::UserDataKey() {
return &kDownloadItemSavePathKey;
}
} // namespace api
} // namespace atom
namespace {
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
v8::Local<v8::Context> context, void* priv) {
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary dict(isolate, exports);
dict.SetMethod("_setWrapDownloadItem", &atom::api::SetWrapDownloadItem);
dict.SetMethod("_clearWrapDownloadItem", &atom::api::ClearWrapDownloadItem);
}
} // namespace
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_download_item, Initialize);

View File

@@ -0,0 +1,72 @@
// 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_DOWNLOAD_ITEM_H_
#define ATOM_BROWSER_API_ATOM_API_DOWNLOAD_ITEM_H_
#include <string>
#include "atom/browser/api/trackable_object.h"
#include "base/files/file_path.h"
#include "content/public/browser/download_item.h"
#include "native_mate/handle.h"
#include "url/gurl.h"
namespace atom {
namespace api {
class DownloadItem : public mate::EventEmitter,
public content::DownloadItem::Observer {
public:
class SavePathData : public base::SupportsUserData::Data {
public:
explicit SavePathData(const base::FilePath& path);
const base::FilePath& path();
private:
base::FilePath path_;
};
static mate::Handle<DownloadItem> Create(v8::Isolate* isolate,
content::DownloadItem* item);
static void* UserDataKey();
protected:
explicit DownloadItem(content::DownloadItem* download_item);
~DownloadItem();
// Override content::DownloadItem::Observer methods
void OnDownloadUpdated(content::DownloadItem* download) override;
void OnDownloadDestroyed(content::DownloadItem* download) override;
void Pause();
void Resume();
void Cancel();
int64 GetReceivedBytes();
int64 GetTotalBytes();
std::string GetMimeType();
bool HasUserGesture();
std::string GetFilename();
std::string GetContentDisposition();
const GURL& GetUrl();
void SetSavePath(const base::FilePath& path);
private:
// mate::Wrappable:
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) override;
bool IsDestroyed() const override;
void Destroy();
content::DownloadItem* download_item_;
DISALLOW_COPY_AND_ASSIGN(DownloadItem);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_DOWNLOAD_ITEM_H_

View File

@@ -7,8 +7,8 @@
#include <string>
#include "atom/common/native_mate_converters/accelerator_converter.h"
#include "atom/common/native_mate_converters/callback.h"
#include "base/stl_util.h"
#include "native_mate/callback.h"
#include "native_mate/dictionary.h"
#include "atom/common/node_includes.h"

View File

@@ -6,9 +6,9 @@
#include "atom/browser/native_window.h"
#include "atom/common/native_mate_converters/accelerator_converter.h"
#include "atom/common/native_mate_converters/callback.h"
#include "atom/common/native_mate_converters/image_converter.h"
#include "atom/common/native_mate_converters/string16_converter.h"
#include "native_mate/callback.h"
#include "native_mate/constructor.h"
#include "native_mate/dictionary.h"
#include "native_mate/object_template_builder.h"
@@ -20,7 +20,7 @@ namespace atom {
namespace api {
Menu::Menu()
: model_(new ui::SimpleMenuModel(this)),
: model_(new AtomMenuModel(this)),
parent_(NULL) {
}
@@ -107,6 +107,10 @@ void Menu::SetSublabel(int index, const base::string16& sublabel) {
model_->SetSublabel(index, sublabel);
}
void Menu::SetRole(int index, const base::string16& role) {
model_->SetRole(index, role);
}
void Menu::Clear() {
model_->Clear();
}
@@ -154,6 +158,7 @@ void Menu::BuildPrototype(v8::Isolate* isolate,
.SetMethod("insertSubMenu", &Menu::InsertSubMenuAt)
.SetMethod("setIcon", &Menu::SetIcon)
.SetMethod("setSublabel", &Menu::SetSublabel)
.SetMethod("setRole", &Menu::SetRole)
.SetMethod("clear", &Menu::Clear)
.SetMethod("getIndexOfCommandId", &Menu::GetIndexOfCommandId)
.SetMethod("getItemCount", &Menu::GetItemCount)

View File

@@ -8,9 +8,9 @@
#include <string>
#include "atom/browser/api/atom_api_window.h"
#include "atom/browser/ui/atom_menu_model.h"
#include "base/callback.h"
#include "base/memory/scoped_ptr.h"
#include "ui/base/models/simple_menu_model.h"
#include "native_mate/wrappable.h"
namespace atom {
@@ -18,7 +18,7 @@ namespace atom {
namespace api {
class Menu : public mate::Wrappable,
public ui::SimpleMenuModel::Delegate {
public AtomMenuModel::Delegate {
public:
static mate::Wrappable* Create();
@@ -33,7 +33,7 @@ class Menu : public mate::Wrappable,
static void SendActionToFirstResponder(const std::string& action);
#endif
ui::SimpleMenuModel* model() const { return model_.get(); }
AtomMenuModel* model() const { return model_.get(); }
protected:
Menu();
@@ -42,7 +42,7 @@ class Menu : public mate::Wrappable,
// mate::Wrappable:
void AfterInit(v8::Isolate* isolate) override;
// ui::SimpleMenuModel::Delegate implementations:
// ui::SimpleMenuModel::Delegate:
bool IsCommandIdChecked(int command_id) const override;
bool IsCommandIdEnabled(int command_id) const override;
bool IsCommandIdVisible(int command_id) const override;
@@ -54,7 +54,7 @@ class Menu : public mate::Wrappable,
virtual void Popup(Window* window) = 0;
virtual void PopupAt(Window* window, int x, int y) = 0;
scoped_ptr<ui::SimpleMenuModel> model_;
scoped_ptr<AtomMenuModel> model_;
Menu* parent_;
private:
@@ -73,6 +73,7 @@ class Menu : public mate::Wrappable,
Menu* menu);
void SetIcon(int index, const gfx::Image& image);
void SetSublabel(int index, const base::string16& sublabel);
void SetRole(int index, const base::string16& role);
void Clear();
int GetIndexOfCommandId(int command_id);
int GetItemCount() const;
@@ -102,9 +103,9 @@ class Menu : public mate::Wrappable,
namespace mate {
template<>
struct Converter<ui::SimpleMenuModel*> {
struct Converter<atom::AtomMenuModel*> {
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
ui::SimpleMenuModel** out) {
atom::AtomMenuModel** out) {
// null would be tranfered to NULL.
if (val->IsNull()) {
*out = nullptr;

View File

@@ -5,12 +5,11 @@
#include "atom/browser/api/atom_api_power_monitor.h"
#include "atom/browser/browser.h"
#include "atom/common/node_includes.h"
#include "base/power_monitor/power_monitor.h"
#include "base/power_monitor/power_monitor_device_source.h"
#include "native_mate/dictionary.h"
#include "atom/common/node_includes.h"
namespace atom {
namespace api {
@@ -41,9 +40,9 @@ void PowerMonitor::OnResume() {
// static
v8::Local<v8::Value> PowerMonitor::Create(v8::Isolate* isolate) {
if (!Browser::Get()->is_ready()) {
node::ThrowError(
isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
isolate,
"Cannot initialize \"power-monitor\" module before app is ready");
"Cannot initialize \"power-monitor\" module before app is ready")));
return v8::Null(isolate);
}

View File

@@ -6,9 +6,9 @@
#include <string>
#include "atom/common/node_includes.h"
#include "content/public/browser/power_save_blocker.h"
#include "native_mate/dictionary.h"
#include "atom/common/node_includes.h"
namespace mate {

View File

@@ -7,16 +7,13 @@
#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"
#include "net/url_request/url_request_context.h"
#include "atom/browser/net/url_request_async_asar_job.h"
#include "atom/browser/net/url_request_buffer_job.h"
#include "atom/browser/net/url_request_fetch_job.h"
#include "atom/browser/net/url_request_string_job.h"
#include "atom/common/native_mate_converters/callback.h"
#include "atom/common/node_includes.h"
#include "native_mate/dictionary.h"
using content::BrowserThread;
@@ -40,211 +37,35 @@ namespace atom {
namespace api {
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,
ProtocolHandler* protocol_handler,
net::URLRequest* request,
net::NetworkDelegate* network_delegate)
: AdapterRequestJob(protocol_handler, request, network_delegate),
registry_(registry) {
}
// AdapterRequestJob:
void GetJobTypeInUI() override {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
v8::Locker locker(registry_->isolate());
v8::HandleScope handle_scope(registry_->isolate());
// Call the JS handler.
Protocol::JsProtocolHandler callback =
registry_->GetProtocolHandler(request()->url().scheme());
v8::Local<v8::Value> result = callback.Run(request());
// Determine the type of the job we are going to create.
if (result->IsString()) {
std::string data = mate::V8ToString(result);
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&AdapterRequestJob::CreateStringJobAndStart,
GetWeakPtr(), "text/plain", "UTF-8", data));
return;
} else if (result->IsObject()) {
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;
dict.Get("mimeType", &mime_type);
dict.Get("charset", &charset);
dict.Get("data", &data);
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&AdapterRequestJob::CreateStringJobAndStart,
GetWeakPtr(), mime_type, charset, data));
return;
} else if (name == "RequestBufferJob") {
std::string mime_type, encoding;
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,
BufferToRefCountedBytes(buffer)));
return;
} else if (name == "RequestFileJob") {
base::FilePath path;
dict.Get("path", &path);
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
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;
}
}
// Try the default protocol handler if we have.
if (default_protocol_handler()) {
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&AdapterRequestJob::CreateJobFromProtocolHandlerAndStart,
GetWeakPtr()));
return;
}
// Fallback to the not implemented error.
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&AdapterRequestJob::CreateErrorJobAndStart,
GetWeakPtr(), net::ERR_NOT_IMPLEMENTED));
}
private:
Protocol* registry_; // Weak, the Protocol class is expected to live forever.
};
// Always return the same CustomProtocolRequestJob for all requests, because
// the content API needs the ProtocolHandler to return a job immediately, and
// getting the real job from the JS requires asynchronous calls, so we have
// to create an adapter job first.
// Users can also pass an extra ProtocolHandler as the fallback one when
// registered handler doesn't want to deal with the request.
class CustomProtocolHandler : public ProtocolHandler {
public:
CustomProtocolHandler(api::Protocol* registry,
ProtocolHandler* protocol_handler = NULL)
: registry_(registry), protocol_handler_(protocol_handler) {
}
net::URLRequestJob* MaybeCreateJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate) const override {
return new CustomProtocolRequestJob(registry_, protocol_handler_.get(),
request, network_delegate);
}
ProtocolHandler* ReleaseDefaultProtocolHandler() {
return protocol_handler_.release();
}
ProtocolHandler* original_handler() { return protocol_handler_.get(); }
private:
Protocol* registry_; // Weak, the Protocol class is expected to live forever.
scoped_ptr<ProtocolHandler> protocol_handler_;
DISALLOW_COPY_AND_ASSIGN(CustomProtocolHandler);
};
std::string ConvertErrorCode(int error_code) {
switch (error_code) {
case Protocol::ERR_SCHEME_REGISTERED:
return "The Scheme is already registered";
case Protocol::ERR_SCHEME_UNREGISTERED:
return "The Scheme has not been registered";
case Protocol::ERR_SCHEME_INTERCEPTED:
return "There is no protocol handler to intercept";
case Protocol::ERR_SCHEME_UNINTERCEPTED:
return "The protocol is not intercepted";
case Protocol::ERR_NO_SCHEME:
return "The Scheme does not exist.";
case Protocol::ERR_SCHEME:
return "Cannot intercept custom protocols";
default:
NOTREACHED();
return std::string();
}
}
} // namespace
Protocol::Protocol(AtomBrowserContext* browser_context)
: browser_context_(browser_context),
: request_context_getter_(browser_context->GetRequestContext()),
job_factory_(browser_context->job_factory()) {
CHECK(job_factory_);
}
Protocol::JsProtocolHandler Protocol::GetProtocolHandler(
const std::string& scheme) {
return protocol_handlers_[scheme];
}
void Protocol::OnIOActionCompleted(const JsCompletionCallback& callback,
int error) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
if (error) {
callback.Run(v8::Exception::Error(
mate::StringToV8(isolate(), ConvertErrorCode(error))));
return;
}
callback.Run(v8::Null(isolate()));
}
mate::ObjectTemplateBuilder Protocol::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
return mate::ObjectTemplateBuilder(isolate)
.SetMethod("registerStandardSchemes", &Protocol::RegisterStandardSchemes)
.SetMethod("isHandledProtocol", &Protocol::IsHandledProtocol)
.SetMethod("_registerProtocol", &Protocol::RegisterProtocol)
.SetMethod("_unregisterProtocol", &Protocol::UnregisterProtocol)
.SetMethod("_interceptProtocol", &Protocol::InterceptProtocol)
.SetMethod("_uninterceptProtocol", &Protocol::UninterceptProtocol);
.SetMethod("registerStringProtocol",
&Protocol::RegisterProtocol<URLRequestStringJob>)
.SetMethod("registerBufferProtocol",
&Protocol::RegisterProtocol<URLRequestBufferJob>)
.SetMethod("registerFileProtocol",
&Protocol::RegisterProtocol<UrlRequestAsyncAsarJob>)
.SetMethod("registerHttpProtocol",
&Protocol::RegisterProtocol<URLRequestFetchJob>)
.SetMethod("unregisterProtocol", &Protocol::UnregisterProtocol)
.SetMethod("isProtocolHandled", &Protocol::IsProtocolHandled)
.SetMethod("interceptStringProtocol",
&Protocol::InterceptProtocol<URLRequestStringJob>)
.SetMethod("interceptBufferProtocol",
&Protocol::InterceptProtocol<URLRequestBufferJob>)
.SetMethod("interceptFileProtocol",
&Protocol::InterceptProtocol<UrlRequestAsyncAsarJob>)
.SetMethod("interceptHttpProtocol",
&Protocol::InterceptProtocol<URLRequestFetchJob>)
.SetMethod("uninterceptProtocol", &Protocol::UninterceptProtocol);
}
void Protocol::RegisterStandardSchemes(
@@ -252,127 +73,86 @@ void Protocol::RegisterStandardSchemes(
atom::AtomBrowserClient::SetCustomSchemes(schemes);
}
void Protocol::IsHandledProtocol(const std::string& scheme,
const net::CompletionCallback& callback) {
BrowserThread::PostTaskAndReplyWithResult(BrowserThread::IO, FROM_HERE,
base::Bind(&AtomURLRequestJobFactory::IsHandledProtocol,
base::Unretained(job_factory_), scheme),
void Protocol::UnregisterProtocol(
const std::string& scheme, mate::Arguments* args) {
CompletionCallback callback;
args->GetNext(&callback);
content::BrowserThread::PostTaskAndReplyWithResult(
content::BrowserThread::IO, FROM_HERE,
base::Bind(&Protocol::UnregisterProtocolInIO,
base::Unretained(this), scheme),
base::Bind(&Protocol::OnIOCompleted,
base::Unretained(this), callback));
}
Protocol::ProtocolError Protocol::UnregisterProtocolInIO(
const std::string& scheme) {
if (!job_factory_->HasProtocolHandler(scheme))
return PROTOCOL_NOT_REGISTERED;
job_factory_->SetProtocolHandler(scheme, nullptr);
return PROTOCOL_OK;
}
void Protocol::IsProtocolHandled(const std::string& scheme,
const BooleanCallback& callback) {
content::BrowserThread::PostTaskAndReplyWithResult(
content::BrowserThread::IO, FROM_HERE,
base::Bind(&Protocol::IsProtocolHandledInIO,
base::Unretained(this), scheme),
callback);
}
void Protocol::RegisterProtocol(v8::Isolate* isolate,
const std::string& scheme,
const JsProtocolHandler& handler,
const JsCompletionCallback& callback) {
BrowserThread::PostTaskAndReplyWithResult(BrowserThread::IO, FROM_HERE,
base::Bind(&Protocol::RegisterProtocolInIO,
base::Unretained(this), scheme, handler),
base::Bind(&Protocol::OnIOActionCompleted,
base::Unretained(this), callback));
bool Protocol::IsProtocolHandledInIO(const std::string& scheme) {
return job_factory_->IsHandledProtocol(scheme);
}
void Protocol::UnregisterProtocol(v8::Isolate* isolate,
const std::string& scheme,
const JsCompletionCallback& callback) {
BrowserThread::PostTaskAndReplyWithResult(BrowserThread::IO, FROM_HERE,
base::Bind(&Protocol::UnregisterProtocolInIO,
base::Unretained(this), scheme),
base::Bind(&Protocol::OnIOActionCompleted,
base::Unretained(this), callback));
}
void Protocol::InterceptProtocol(v8::Isolate* isolate,
const std::string& scheme,
const JsProtocolHandler& handler,
const JsCompletionCallback& callback) {
BrowserThread::PostTaskAndReplyWithResult(BrowserThread::IO, FROM_HERE,
base::Bind(&Protocol::InterceptProtocolInIO,
base::Unretained(this), scheme, handler),
base::Bind(&Protocol::OnIOActionCompleted,
base::Unretained(this), callback));
}
void Protocol::UninterceptProtocol(v8::Isolate* isolate,
const std::string& scheme,
const JsCompletionCallback& callback) {
BrowserThread::PostTaskAndReplyWithResult(BrowserThread::IO, FROM_HERE,
void Protocol::UninterceptProtocol(
const std::string& scheme, mate::Arguments* args) {
CompletionCallback callback;
args->GetNext(&callback);
content::BrowserThread::PostTaskAndReplyWithResult(
content::BrowserThread::IO, FROM_HERE,
base::Bind(&Protocol::UninterceptProtocolInIO,
base::Unretained(this), scheme),
base::Bind(&Protocol::OnIOActionCompleted,
base::Bind(&Protocol::OnIOCompleted,
base::Unretained(this), callback));
}
int Protocol::RegisterProtocolInIO(const std::string& scheme,
const JsProtocolHandler& handler) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (ContainsKey(protocol_handlers_, scheme) ||
job_factory_->IsHandledProtocol(scheme)) {
return ERR_SCHEME_REGISTERED;
}
protocol_handlers_[scheme] = handler;
job_factory_->SetProtocolHandler(scheme, new CustomProtocolHandler(this));
return OK;
Protocol::ProtocolError Protocol::UninterceptProtocolInIO(
const std::string& scheme) {
if (!original_protocols_.contains(scheme))
return PROTOCOL_NOT_INTERCEPTED;
job_factory_->ReplaceProtocol(scheme,
original_protocols_.take_and_erase(scheme));
return PROTOCOL_OK;
}
int Protocol::UnregisterProtocolInIO(const std::string& scheme) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
void Protocol::OnIOCompleted(
const CompletionCallback& callback, ProtocolError error) {
// The completion callback is optional.
if (callback.is_null())
return;
ProtocolHandlersMap::iterator it(protocol_handlers_.find(scheme));
if (it == protocol_handlers_.end()) {
return ERR_SCHEME_UNREGISTERED;
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
if (error == PROTOCOL_OK) {
callback.Run(v8::Null(isolate()));
} else {
std::string str = ErrorCodeToString(error);
callback.Run(v8::Exception::Error(mate::StringToV8(isolate(), str)));
}
protocol_handlers_.erase(it);
job_factory_->SetProtocolHandler(scheme, NULL);
return OK;
}
int Protocol::InterceptProtocolInIO(const std::string& scheme,
const JsProtocolHandler& handler) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!job_factory_->HasProtocolHandler(scheme))
return ERR_NO_SCHEME;
if (ContainsKey(protocol_handlers_, scheme))
return ERR_SCHEME;
protocol_handlers_[scheme] = handler;
ProtocolHandler* original_handler = job_factory_->GetProtocolHandler(scheme);
if (original_handler == nullptr) {
return ERR_SCHEME_INTERCEPTED;
std::string Protocol::ErrorCodeToString(ProtocolError error) {
switch (error) {
case PROTOCOL_FAIL: return "Failed to manipulate protocol factory";
case PROTOCOL_REGISTERED: return "The scheme has been registred";
case PROTOCOL_NOT_REGISTERED: return "The scheme has not been registred";
case PROTOCOL_INTERCEPTED: return "The scheme has been intercepted";
case PROTOCOL_NOT_INTERCEPTED: return "The scheme has not been intercepted";
default: return "Unexpected error";
}
job_factory_->ReplaceProtocol(
scheme, new CustomProtocolHandler(this, original_handler));
return OK;
}
int Protocol::UninterceptProtocolInIO(const std::string& scheme) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
ProtocolHandlersMap::iterator it(protocol_handlers_.find(scheme));
if (it == protocol_handlers_.end())
return ERR_SCHEME_UNREGISTERED;
protocol_handlers_.erase(it);
CustomProtocolHandler* handler = static_cast<CustomProtocolHandler*>(
job_factory_->GetProtocolHandler(scheme));
if (handler->original_handler() == nullptr) {
return ERR_SCHEME_UNINTERCEPTED;
}
// Reset the protocol handler to the orignal one and delete current protocol
// handler.
ProtocolHandler* original_handler = handler->ReleaseDefaultProtocolHandler();
delete job_factory_->ReplaceProtocol(scheme, original_handler);
return OK;
}
// static

View File

@@ -9,13 +9,18 @@
#include <map>
#include <vector>
#include "atom/browser/api/event_emitter.h"
#include "atom/browser/net/atom_url_request_job_factory.h"
#include "base/callback.h"
#include "base/containers/scoped_ptr_hash_map.h"
#include "content/public/browser/browser_thread.h"
#include "native_mate/arguments.h"
#include "native_mate/dictionary.h"
#include "native_mate/handle.h"
#include "net/base/completion_callback.h"
#include "native_mate/wrappable.h"
namespace net {
class URLRequest;
class URLRequestContextGetter;
}
namespace atom {
@@ -25,29 +30,16 @@ class AtomURLRequestJobFactory;
namespace api {
class Protocol : public mate::EventEmitter {
class Protocol : public mate::Wrappable {
public:
using JsProtocolHandler =
base::Callback<v8::Local<v8::Value>(const net::URLRequest*)>;
using JsCompletionCallback = base::Callback<void(v8::Local<v8::Value>)>;
enum {
OK = 0,
ERR_SCHEME_REGISTERED,
ERR_SCHEME_UNREGISTERED,
ERR_SCHEME_INTERCEPTED,
ERR_SCHEME_UNINTERCEPTED,
ERR_NO_SCHEME,
ERR_SCHEME
};
using Handler =
base::Callback<void(const net::URLRequest*, v8::Local<v8::Value>)>;
using CompletionCallback = base::Callback<void(v8::Local<v8::Value>)>;
using BooleanCallback = base::Callback<void(bool)>;
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:
explicit Protocol(AtomBrowserContext* browser_context);
@@ -56,47 +48,139 @@ class Protocol : public mate::EventEmitter {
v8::Isolate* isolate);
private:
typedef std::map<std::string, JsProtocolHandler> ProtocolHandlersMap;
// Possible errors.
enum ProtocolError {
PROTOCOL_OK, // no error
PROTOCOL_FAIL, // operation failed, should never occur
PROTOCOL_REGISTERED,
PROTOCOL_NOT_REGISTERED,
PROTOCOL_INTERCEPTED,
PROTOCOL_NOT_INTERCEPTED,
};
// Callback called after performing action on IO thread.
void OnIOActionCompleted(const JsCompletionCallback& callback,
int error);
// The protocol handler that will create a protocol handler for certain
// request job.
template<typename RequestJob>
class CustomProtocolHandler
: public net::URLRequestJobFactory::ProtocolHandler {
public:
CustomProtocolHandler(
v8::Isolate* isolate,
net::URLRequestContextGetter* request_context,
const Handler& handler)
: isolate_(isolate),
request_context_(request_context),
handler_(handler) {}
~CustomProtocolHandler() override {}
net::URLRequestJob* MaybeCreateJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate) const override {
RequestJob* request_job = new RequestJob(request, network_delegate);
request_job->SetHandlerInfo(isolate_, request_context_, handler_);
return request_job;
}
private:
v8::Isolate* isolate_;
net::URLRequestContextGetter* request_context_;
Protocol::Handler handler_;
DISALLOW_COPY_AND_ASSIGN(CustomProtocolHandler);
};
// Register schemes to standard scheme list.
void RegisterStandardSchemes(const std::vector<std::string>& schemes);
// Returns whether a scheme has been registered.
void IsHandledProtocol(const std::string& scheme,
const net::CompletionCallback& callback);
// Register the protocol with certain request job.
template<typename RequestJob>
void RegisterProtocol(const std::string& scheme,
const Handler& handler,
mate::Arguments* args) {
CompletionCallback callback;
args->GetNext(&callback);
content::BrowserThread::PostTaskAndReplyWithResult(
content::BrowserThread::IO, FROM_HERE,
base::Bind(&Protocol::RegisterProtocolInIO<RequestJob>,
base::Unretained(this), scheme, handler),
base::Bind(&Protocol::OnIOCompleted,
base::Unretained(this), callback));
}
template<typename RequestJob>
ProtocolError RegisterProtocolInIO(const std::string& scheme,
const Handler& handler) {
if (job_factory_->IsHandledProtocol(scheme))
return PROTOCOL_REGISTERED;
scoped_ptr<CustomProtocolHandler<RequestJob>> protocol_handler(
new CustomProtocolHandler<RequestJob>(
isolate(), request_context_getter_, handler));
if (job_factory_->SetProtocolHandler(scheme, protocol_handler.Pass()))
return PROTOCOL_OK;
else
return PROTOCOL_FAIL;
}
// Register/unregister an networking |scheme| which would be handled by
// |callback|.
void RegisterProtocol(v8::Isolate* isolate,
const std::string& scheme,
const JsProtocolHandler& handler,
const JsCompletionCallback& callback);
void UnregisterProtocol(v8::Isolate* isolate, const std::string& scheme,
const JsCompletionCallback& callback);
// Unregister the protocol handler that handles |scheme|.
void UnregisterProtocol(const std::string& scheme, mate::Arguments* args);
ProtocolError UnregisterProtocolInIO(const std::string& scheme);
// Intercept/unintercept an existing protocol handler.
void InterceptProtocol(v8::Isolate* isolate,
const std::string& scheme,
const JsProtocolHandler& handler,
const JsCompletionCallback& callback);
void UninterceptProtocol(v8::Isolate* isolate, const std::string& scheme,
const JsCompletionCallback& callback);
// Whether the protocol has handler registered.
void IsProtocolHandled(const std::string& scheme,
const BooleanCallback& callback);
bool IsProtocolHandledInIO(const std::string& scheme);
// The networking related operations have to be done in IO thread.
int RegisterProtocolInIO(const std::string& scheme,
const JsProtocolHandler& handler);
int UnregisterProtocolInIO(const std::string& scheme);
int InterceptProtocolInIO(const std::string& scheme,
const JsProtocolHandler& handler);
int UninterceptProtocolInIO(const std::string& scheme);
// Replace the protocol handler with a new one.
template<typename RequestJob>
void InterceptProtocol(const std::string& scheme,
const Handler& handler,
mate::Arguments* args) {
CompletionCallback callback;
args->GetNext(&callback);
content::BrowserThread::PostTaskAndReplyWithResult(
content::BrowserThread::IO, FROM_HERE,
base::Bind(&Protocol::InterceptProtocolInIO<RequestJob>,
base::Unretained(this), scheme, handler),
base::Bind(&Protocol::OnIOCompleted,
base::Unretained(this), callback));
}
template<typename RequestJob>
ProtocolError InterceptProtocolInIO(const std::string& scheme,
const Handler& handler) {
if (!job_factory_->IsHandledProtocol(scheme))
return PROTOCOL_NOT_REGISTERED;
// It is possible a protocol is handled but can not be intercepted.
if (!job_factory_->HasProtocolHandler(scheme))
return PROTOCOL_FAIL;
if (ContainsKey(original_protocols_, scheme))
return PROTOCOL_INTERCEPTED;
scoped_ptr<CustomProtocolHandler<RequestJob>> protocol_handler(
new CustomProtocolHandler<RequestJob>(
isolate(), request_context_getter_, handler));
original_protocols_.set(
scheme,
job_factory_->ReplaceProtocol(scheme, protocol_handler.Pass()));
return PROTOCOL_OK;
}
AtomBrowserContext* browser_context_;
AtomURLRequestJobFactory* job_factory_;
ProtocolHandlersMap protocol_handlers_;
// Restore the |scheme| to its original protocol handler.
void UninterceptProtocol(const std::string& scheme, mate::Arguments* args);
ProtocolError UninterceptProtocolInIO(const std::string& scheme);
// Convert error code to JS exception and call the callback.
void OnIOCompleted(const CompletionCallback& callback, ProtocolError error);
// Convert error code to string.
std::string ErrorCodeToString(ProtocolError error);
net::URLRequestContextGetter* request_context_getter_;
// Map that stores the original protocols of schemes.
using OriginalProtocolsMap = base::ScopedPtrHashMap<
std::string,
scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>>;
OriginalProtocolsMap original_protocols_;
AtomURLRequestJobFactory* job_factory_; // weak ref
DISALLOW_COPY_AND_ASSIGN(Protocol);
};

View File

@@ -113,14 +113,16 @@ mate::ObjectTemplateBuilder Screen::GetObjectTemplateBuilder(
// static
v8::Local<v8::Value> Screen::Create(v8::Isolate* isolate) {
if (!Browser::Get()->is_ready()) {
node::ThrowError(isolate,
"Cannot initialize \"screen\" module before app is ready");
isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
isolate,
"Cannot initialize \"screen\" module before app is ready")));
return v8::Null(isolate);
}
gfx::Screen* screen = gfx::Screen::GetNativeScreen();
if (!screen) {
node::ThrowError(isolate, "Failed to get screen information");
isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
isolate, "Failed to get screen information")));
return v8::Null(isolate);
}

View File

@@ -8,22 +8,29 @@
#include <vector>
#include "atom/browser/api/atom_api_cookies.h"
#include "atom/browser/api/atom_api_download_item.h"
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/api/atom_api_web_contents.h"
#include "atom/common/native_mate_converters/callback.h"
#include "atom/common/native_mate_converters/gurl_converter.h"
#include "base/thread_task_runner_handle.h"
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "atom/common/node_includes.h"
#include "base/files/file_path.h"
#include "base/prefs/pref_service.h"
#include "base/strings/string_util.h"
#include "base/thread_task_runner_handle.h"
#include "chrome/common/pref_names.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/storage_partition.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/disk_cache/disk_cache.h"
#include "net/proxy/proxy_service.h"
#include "net/proxy/proxy_config_service_fixed.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 content::BrowserThread;
using content::StoragePartition;
@@ -103,6 +110,10 @@ namespace api {
namespace {
// The wrapSession funtion which is implemented in JavaScript
using WrapSessionCallback = base::Callback<void(v8::Local<v8::Value>)>;
WrapSessionCallback g_wrap_session;
class ResolveProxyHelper {
public:
ResolveProxyHelper(AtomBrowserContext* browser_context,
@@ -157,9 +168,10 @@ class ResolveProxyHelper {
};
// Runs the callback in UI thread.
void RunCallbackInUI(const net::CompletionCallback& callback, int result) {
template <typename ...T>
void RunCallbackInUI(const base::Callback<void(T...)>& callback, T... result) {
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE, base::Bind(callback, result));
BrowserThread::UI, FROM_HERE, base::Bind(callback, result...));
}
// Callback of HttpCache::GetBackend.
@@ -169,19 +181,19 @@ void OnGetBackend(disk_cache::Backend** backend_ptr,
if (result != net::OK) {
RunCallbackInUI(callback, result);
} else if (backend_ptr && *backend_ptr) {
(*backend_ptr)->DoomAllEntries(base::Bind(&RunCallbackInUI, callback));
(*backend_ptr)->DoomAllEntries(base::Bind(&RunCallbackInUI<int>, callback));
} else {
RunCallbackInUI(callback, net::ERR_FAILED);
RunCallbackInUI<int>(callback, net::ERR_FAILED);
}
}
void ClearHttpCacheInIO(content::BrowserContext* browser_context,
const net::CompletionCallback& callback) {
auto request_context =
browser_context->GetRequestContext()->GetURLRequestContext();
void ClearHttpCacheInIO(
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
const net::CompletionCallback& callback) {
auto request_context = context_getter->GetURLRequestContext();
auto http_cache = request_context->http_transaction_factory()->GetCache();
if (!http_cache)
RunCallbackInUI(callback, net::ERR_FAILED);
RunCallbackInUI<int>(callback, net::ERR_FAILED);
// Call GetBackend and make the backend's ptr accessable in OnGetBackend.
using BackendPtr = disk_cache::Backend*;
@@ -193,24 +205,62 @@ void ClearHttpCacheInIO(content::BrowserContext* browser_context,
on_get_backend.Run(net::OK);
}
void SetProxyInIO(net::URLRequestContextGetter* getter,
const std::string& proxy,
const base::Closure& callback) {
net::ProxyConfig config;
config.proxy_rules().ParseFromString(proxy);
auto proxy_service = getter->GetURLRequestContext()->proxy_service();
proxy_service->ResetConfigService(new net::ProxyConfigServiceFixed(config));
RunCallbackInUI(callback);
}
} // namespace
Session::Session(AtomBrowserContext* browser_context)
: browser_context_(browser_context) {
AttachAsUserData(browser_context);
// Observe DownloadManger to get download notifications.
content::BrowserContext::GetDownloadManager(browser_context)->
AddObserver(this);
}
Session::~Session() {
content::BrowserContext::GetDownloadManager(browser_context())->
RemoveObserver(this);
Destroy();
}
void Session::OnDownloadCreated(content::DownloadManager* manager,
content::DownloadItem* item) {
auto web_contents = item->GetWebContents();
bool prevent_default = Emit(
"will-download",
DownloadItem::Create(isolate(), item),
api::WebContents::CreateFrom(isolate(), web_contents));
if (prevent_default) {
item->Cancel(true);
item->Remove();
}
}
bool Session::IsDestroyed() const {
return !browser_context_;
}
void Session::Destroy() {
browser_context_ = nullptr;
}
void Session::ResolveProxy(const GURL& url, ResolveProxyCallback callback) {
new ResolveProxyHelper(browser_context_, url, callback);
new ResolveProxyHelper(browser_context(), url, callback);
}
void Session::ClearCache(const net::CompletionCallback& callback) {
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&ClearHttpCacheInIO,
base::Unretained(browser_context_),
make_scoped_refptr(browser_context_->GetRequestContext()),
callback));
}
@@ -225,16 +275,28 @@ void Session::ClearStorageData(mate::Arguments* args) {
}
auto storage_partition =
content::BrowserContext::GetStoragePartition(browser_context_, nullptr);
content::BrowserContext::GetStoragePartition(browser_context(), nullptr);
storage_partition->ClearData(
options.storage_types, options.quota_types, options.origin,
content::StoragePartition::OriginMatcherFunction(),
base::Time(), base::Time::Max(), callback);
}
void Session::SetProxy(const std::string& proxy,
const base::Closure& callback) {
auto getter = browser_context_->GetRequestContext();
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&SetProxyInIO, base::Unretained(getter), proxy, callback));
}
void Session::SetDownloadPath(const base::FilePath& path) {
browser_context_->prefs()->SetFilePath(
prefs::kDownloadDefaultDirectory, path);
}
v8::Local<v8::Value> Session::Cookies(v8::Isolate* isolate) {
if (cookies_.IsEmpty()) {
auto handle = atom::api::Cookies::Create(isolate, browser_context_);
auto handle = atom::api::Cookies::Create(isolate, browser_context());
cookies_.Reset(isolate, handle.ToV8());
}
return v8::Local<v8::Value>::New(isolate, cookies_);
@@ -246,20 +308,54 @@ mate::ObjectTemplateBuilder Session::GetObjectTemplateBuilder(
.SetMethod("resolveProxy", &Session::ResolveProxy)
.SetMethod("clearCache", &Session::ClearCache)
.SetMethod("clearStorageData", &Session::ClearStorageData)
.SetMethod("setProxy", &Session::SetProxy)
.SetMethod("setDownloadPath", &Session::SetDownloadPath)
.SetProperty("cookies", &Session::Cookies);
}
// static
mate::Handle<Session> Session::CreateFrom(
v8::Isolate* isolate,
AtomBrowserContext* browser_context) {
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));
auto handle = mate::CreateHandle(isolate, new Session(browser_context));
g_wrap_session.Run(handle.ToV8());
return handle;
}
// static
mate::Handle<Session> Session::FromPartition(
v8::Isolate* isolate, const std::string& partition, bool in_memory) {
auto browser_context = brightray::BrowserContext::From(partition, in_memory);
return CreateFrom(isolate,
static_cast<AtomBrowserContext*>(browser_context.get()));
}
void SetWrapSession(const WrapSessionCallback& callback) {
g_wrap_session = callback;
}
void ClearWrapSession() {
g_wrap_session.Reset();
}
} // namespace api
} // namespace atom
namespace {
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
v8::Local<v8::Context> context, void* priv) {
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary dict(isolate, exports);
dict.SetMethod("fromPartition", &atom::api::Session::FromPartition);
dict.SetMethod("_setWrapSession", &atom::api::SetWrapSession);
dict.SetMethod("_clearWrapSession", &atom::api::ClearWrapSession);
}
} // namespace
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_session, Initialize)

View File

@@ -8,11 +8,16 @@
#include <string>
#include "atom/browser/api/trackable_object.h"
#include "content/public/browser/download_manager.h"
#include "native_mate/handle.h"
#include "net/base/completion_callback.h"
class GURL;
namespace base {
class FilePath;
}
namespace mate {
class Arguments;
}
@@ -23,7 +28,8 @@ class AtomBrowserContext;
namespace api {
class Session: public mate::TrackableObject<Session> {
class Session: public mate::TrackableObject<Session>,
public content::DownloadManager::Observer {
public:
using ResolveProxyCallback = base::Callback<void(std::string)>;
@@ -31,23 +37,40 @@ class Session: public mate::TrackableObject<Session> {
static mate::Handle<Session> CreateFrom(
v8::Isolate* isolate, AtomBrowserContext* browser_context);
// Gets the Session of |partition| and |in_memory|.
static mate::Handle<Session> FromPartition(
v8::Isolate* isolate, const std::string& partition, bool in_memory);
AtomBrowserContext* browser_context() const { return browser_context_.get(); }
protected:
explicit Session(AtomBrowserContext* browser_context);
~Session();
// mate::Wrappable implementations:
// content::DownloadManager::Observer:
void OnDownloadCreated(content::DownloadManager* manager,
content::DownloadItem* item) override;
// mate::Wrappable:
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) override;
bool IsDestroyed() const override;
private:
// mate::TrackableObject:
void Destroy() override;
void ResolveProxy(const GURL& url, ResolveProxyCallback callback);
void ClearCache(const net::CompletionCallback& callback);
void ClearStorageData(mate::Arguments* args);
void SetProxy(const std::string& proxy, const base::Closure& callback);
void SetDownloadPath(const base::FilePath& path);
v8::Local<v8::Value> Cookies(v8::Isolate* isolate);
// Cached object for cookies API.
v8::Global<v8::Value> cookies_;
AtomBrowserContext* browser_context_; // weak ref
scoped_refptr<AtomBrowserContext> browser_context_;
DISALLOW_COPY_AND_ASSIGN(Session);
};

View File

@@ -12,12 +12,12 @@
#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 "atom/common/node_includes.h"
#include "native_mate/constructor.h"
#include "native_mate/dictionary.h"
#include "ui/events/event_constants.h"
#include "ui/gfx/image/image.h"
#include "atom/common/node_includes.h"
namespace atom {
namespace api {
@@ -34,18 +34,32 @@ Tray::~Tray() {
// static
mate::Wrappable* Tray::New(v8::Isolate* isolate, const gfx::Image& image) {
if (!Browser::Get()->is_ready()) {
node::ThrowError(isolate, "Cannot create Tray before app is ready");
isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
isolate, "Cannot create Tray before app is ready")));
return nullptr;
}
return new Tray(image);
}
void Tray::OnClicked(const gfx::Rect& bounds) {
Emit("clicked", bounds);
void Tray::OnClicked(const gfx::Rect& bounds, int modifiers) {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
EmitCustomEvent("clicked",
ModifiersToObject(isolate(), modifiers), bounds);
}
void Tray::OnDoubleClicked() {
Emit("double-clicked");
void Tray::OnDoubleClicked(const gfx::Rect& bounds, int modifiers) {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
EmitCustomEvent("double-clicked",
ModifiersToObject(isolate(), modifiers), bounds);
}
void Tray::OnRightClicked(const gfx::Rect& bounds, int modifiers) {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
EmitCustomEvent("right-clicked",
ModifiersToObject(isolate(), modifiers), bounds);
}
void Tray::OnBalloonShow() {
@@ -60,6 +74,10 @@ void Tray::OnBalloonClosed() {
Emit("balloon-closed");
}
void Tray::OnDropFiles(const std::vector<std::string>& files) {
Emit("drop-files", files);
}
bool Tray::IsDestroyed() const {
return !tray_icon_;
}
@@ -102,10 +120,26 @@ void Tray::DisplayBalloon(mate::Arguments* args,
tray_icon_->DisplayBalloon(icon, title, content);
}
void Tray::PopUpContextMenu(mate::Arguments* args) {
gfx::Point pos;
args->GetNext(&pos);
tray_icon_->PopUpContextMenu(pos);
}
void Tray::SetContextMenu(mate::Arguments* args, Menu* menu) {
tray_icon_->SetContextMenu(menu->model());
}
v8::Local<v8::Object> Tray::ModifiersToObject(v8::Isolate* isolate,
int modifiers) {
mate::Dictionary obj(isolate, v8::Object::New(isolate));
obj.Set("shiftKey", static_cast<bool>(modifiers & ui::EF_SHIFT_DOWN));
obj.Set("ctrlKey", static_cast<bool>(modifiers & ui::EF_CONTROL_DOWN));
obj.Set("altKey", static_cast<bool>(modifiers & ui::EF_ALT_DOWN));
obj.Set("metaKey", static_cast<bool>(modifiers & ui::EF_COMMAND_DOWN));
return obj.GetHandle();
}
// static
void Tray::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::ObjectTemplate> prototype) {
@@ -117,6 +151,7 @@ void Tray::BuildPrototype(v8::Isolate* isolate,
.SetMethod("setTitle", &Tray::SetTitle)
.SetMethod("setHighlightMode", &Tray::SetHighlightMode)
.SetMethod("displayBalloon", &Tray::DisplayBalloon)
.SetMethod("popUpContextMenu", &Tray::PopUpContextMenu)
.SetMethod("_setContextMenu", &Tray::SetContextMenu);
}

View File

@@ -6,6 +6,7 @@
#define ATOM_BROWSER_API_ATOM_API_TRAY_H_
#include <string>
#include <vector>
#include "atom/browser/api/event_emitter.h"
#include "atom/browser/ui/tray_icon_observer.h"
@@ -41,11 +42,13 @@ class Tray : public mate::EventEmitter,
virtual ~Tray();
// TrayIconObserver:
void OnClicked(const gfx::Rect&) override;
void OnDoubleClicked() override;
void OnClicked(const gfx::Rect& bounds, int modifiers) override;
void OnDoubleClicked(const gfx::Rect& bounds, int modifiers) override;
void OnRightClicked(const gfx::Rect& bounds, int modifiers) override;
void OnBalloonShow() override;
void OnBalloonClicked() override;
void OnBalloonClosed() override;
void OnDropFiles(const std::vector<std::string>& files) override;
// mate::Wrappable:
bool IsDestroyed() const override;
@@ -57,9 +60,12 @@ class Tray : public mate::EventEmitter,
void SetTitle(mate::Arguments* args, const std::string& title);
void SetHighlightMode(mate::Arguments* args, bool highlight);
void DisplayBalloon(mate::Arguments* args, const mate::Dictionary& options);
void PopUpContextMenu(mate::Arguments* args);
void SetContextMenu(mate::Arguments* args, Menu* menu);
private:
v8::Local<v8::Object> ModifiersToObject(v8::Isolate* isolate, int modifiers);
scoped_ptr<TrayIcon> tray_icon_;
DISALLOW_COPY_AND_ASSIGN(Tray);

View File

@@ -11,9 +11,13 @@
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/native_window.h"
#include "atom/browser/web_contents_preferences.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/api/event_emitter_caller.h"
#include "atom/common/native_mate_converters/blink_converter.h"
#include "atom/common/native_mate_converters/callback.h"
#include "atom/common/native_mate_converters/file_path_converter.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"
@@ -24,24 +28,27 @@
#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/common/view_messages.h"
#include "content/public/browser/favicon_status.h"
#include "content/public/browser/native_web_keyboard_event.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 "net/http/http_response_headers.h"
#include "net/url_request/static_http_user_agent_settings.h"
#include "net/url_request/url_request_context.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
#include "atom/common/node_includes.h"
@@ -113,6 +120,33 @@ struct Converter<WindowOpenDisposition> {
}
};
template<>
struct Converter<net::HttpResponseHeaders*> {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
net::HttpResponseHeaders* headers) {
base::DictionaryValue response_headers;
if (headers) {
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());
}
}
}
return ConvertToV8(isolate, response_headers);
}
};
} // namespace mate
@@ -124,7 +158,7 @@ namespace {
v8::Persistent<v8::ObjectTemplate> template_;
// The wrapWebContents funtion which is implemented in JavaScript
// The wrapWebContents function which is implemented in JavaScript
using WrapWebContentsCallback = base::Callback<void(v8::Local<v8::Value>)>;
WrapWebContentsCallback g_wrap_web_contents;
@@ -152,23 +186,41 @@ WebContents::WebContents(content::WebContents* web_contents)
web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent());
}
WebContents::WebContents(const mate::Dictionary& options) {
WebContents::WebContents(v8::Isolate* isolate,
const mate::Dictionary& options) {
// Whether it is a guest WebContents.
bool is_guest = false;
options.Get("isGuest", &is_guest);
type_ = is_guest ? WEB_VIEW : BROWSER_WINDOW;
auto browser_context = AtomBrowserMainParts::Get()->browser_context();
// Obtain the session.
std::string partition;
mate::Handle<api::Session> session;
if (options.Get("session", &session)) {
} else if (options.Get("partition", &partition) && !partition.empty()) {
bool in_memory = true;
if (base::StartsWith(partition, "persist:", base::CompareCase::SENSITIVE)) {
in_memory = false;
partition = partition.substr(8);
}
session = Session::FromPartition(isolate, partition, in_memory);
} else {
// Use the default session if not specified.
session = Session::FromPartition(isolate, "", false);
}
session_.Reset(isolate, session.ToV8());
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);
session->browser_context(), GURL("chrome-guest://fake-host"));
content::WebContents::CreateParams params(
session->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);
content::WebContents::CreateParams params(session->browser_context());
web_contents = content::WebContents::Create(params);
}
@@ -176,6 +228,11 @@ WebContents::WebContents(const mate::Dictionary& options) {
AttachAsUserData(web_contents);
InitWithWebContents(web_contents);
// Save the preferences in C++.
base::DictionaryValue web_preferences;
mate::ConvertFromV8(isolate, options.GetHandle(), &web_preferences);
new WebContentsPreferences(web_contents, &web_preferences);
web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent());
if (is_guest) {
@@ -216,7 +273,7 @@ bool WebContents::ShouldCreateWebContents(
int route_id,
int main_frame_route_id,
WindowContainerType window_container_type,
const base::string16& frame_name,
const std::string& frame_name,
const GURL& target_url,
const std::string& partition_id,
content::SessionStorageNamespace* session_storage_namespace) {
@@ -276,7 +333,10 @@ bool WebContents::IsPopupOrPanel(const content::WebContents* source) const {
void WebContents::HandleKeyboardEvent(
content::WebContents* source,
const content::NativeWebKeyboardEvent& event) {
if (type_ == BROWSER_WINDOW) {
if (event.windowsKeyCode == ui::VKEY_ESCAPE && is_html_fullscreen()) {
// Escape exits tabbed fullscreen mode.
ExitFullscreenModeForTab(source);
} else 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.
@@ -358,15 +418,17 @@ void WebContents::DidFailProvisionalLoad(
content::RenderFrameHost* render_frame_host,
const GURL& validated_url,
int error_code,
const base::string16& error_description) {
Emit("did-fail-load", error_code, error_description);
const base::string16& error_description,
bool was_ignored_by_handler) {
Emit("did-fail-load", error_code, error_description, validated_url);
}
void WebContents::DidFailLoad(content::RenderFrameHost* render_frame_host,
const GURL& validated_url,
int error_code,
const base::string16& error_description) {
Emit("did-fail-load", error_code, error_description);
const base::string16& error_description,
bool was_ignored_by_handler) {
Emit("did-fail-load", error_code, error_description, validated_url);
}
void WebContents::DidStartLoading() {
@@ -379,30 +441,6 @@ void WebContents::DidStopLoading() {
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,
@@ -410,7 +448,7 @@ void WebContents::DidGetResourceResponseStart(
details.http_response_code,
details.method,
details.referrer,
response_headers);
details.headers.get());
}
void WebContents::DidGetRedirectForResourceRequest(
@@ -419,7 +457,11 @@ void WebContents::DidGetRedirectForResourceRequest(
Emit("did-get-redirect-request",
details.url,
details.new_url,
(details.resource_type == content::RESOURCE_TYPE_MAIN_FRAME));
(details.resource_type == content::RESOURCE_TYPE_MAIN_FRAME),
details.http_response_code,
details.method,
details.referrer,
details.headers.get());
}
void WebContents::DidNavigateMainFrame(
@@ -475,6 +517,7 @@ void WebContents::NavigationEntryCommitted(
}
void WebContents::Destroy() {
session_.Reset();
if (type_ == WEB_VIEW && managed_web_contents()) {
// When force destroying the "destroyed" event is not emitted.
WebContentsDestroyed();
@@ -516,6 +559,10 @@ void WebContents::LoadURL(const GURL& url, const mate::Dictionary& options) {
web_contents()->GetController().LoadURLWithParams(params);
}
GURL WebContents::GetURL() const {
return web_contents()->GetURL();
}
base::string16 WebContents::GetTitle() const {
return web_contents()->GetTitle();
}
@@ -563,12 +610,17 @@ void WebContents::SetUserAgent(const std::string& user_agent) {
base::Bind(&SetUserAgentInIO, getter, user_agent));
}
std::string WebContents::GetUserAgent() {
return web_contents()->GetUserAgentOverride();
}
void WebContents::InsertCSS(const std::string& css) {
web_contents()->InsertCSS(css);
}
void WebContents::ExecuteJavaScript(const base::string16& code) {
web_contents()->GetMainFrame()->ExecuteJavaScript(code);
void WebContents::ExecuteJavaScript(const base::string16& code,
bool has_user_gesture) {
Send(new AtomViewMsg_ExecuteJavaScript(routing_id(), code, has_user_gesture));
}
void WebContents::OpenDevTools(mate::Arguments* args) {
@@ -600,6 +652,21 @@ bool WebContents::IsDevToolsOpened() {
return managed_web_contents()->IsDevToolsViewShowing();
}
void WebContents::EnableDeviceEmulation(
const blink::WebDeviceEmulationParams& params) {
if (type_ == REMOTE)
return;
Send(new ViewMsg_EnableDeviceEmulation(routing_id(), params));
}
void WebContents::DisableDeviceEmulation() {
if (type_ == REMOTE)
return;
Send(new ViewMsg_DisableDeviceEmulation(routing_id()));
}
void WebContents::ToggleDevTools() {
if (IsDevToolsOpened())
CloseDevTools();
@@ -632,10 +699,6 @@ void WebContents::InspectServiceWorker() {
}
v8::Local<v8::Value> WebContents::Session(v8::Isolate* isolate) {
if (session_.IsEmpty()) {
auto handle = Session::CreateFrom(isolate, GetBrowserContext());
session_.Reset(isolate, handle.ToV8());
}
return v8::Local<v8::Value>::New(isolate, session_);
}
@@ -685,6 +748,24 @@ void WebContents::PrintToPDF(const base::DictionaryValue& setting,
PrintToPDF(setting, callback);
}
void WebContents::AddWorkSpace(mate::Arguments* args,
const base::FilePath& path) {
if (path.empty()) {
args->ThrowError("path cannot be empty");
return;
}
DevToolsAddFileSystem(path);
}
void WebContents::RemoveWorkSpace(mate::Arguments* args,
const base::FilePath& path) {
if (path.empty()) {
args->ThrowError("path cannot be empty");
return;
}
DevToolsRemoveFileSystem(path);
}
void WebContents::Undo() {
web_contents()->Undo();
}
@@ -729,11 +810,69 @@ void WebContents::ReplaceMisspelling(const base::string16& word) {
web_contents()->ReplaceMisspelling(word);
}
void WebContents::Focus() {
web_contents()->Focus();
}
void WebContents::TabTraverse(bool reverse) {
web_contents()->FocusThroughTabTraversal(reverse);
}
bool WebContents::SendIPCMessage(const base::string16& channel,
const base::ListValue& args) {
return Send(new AtomViewMsg_Message(routing_id(), channel, args));
}
void WebContents::SendInputEvent(v8::Isolate* isolate,
v8::Local<v8::Value> input_event) {
const auto view = web_contents()->GetRenderWidgetHostView();
if (!view)
return;
const auto host = view->GetRenderWidgetHost();
if (!host)
return;
int type = mate::GetWebInputEventType(isolate, input_event);
if (blink::WebInputEvent::isMouseEventType(type)) {
blink::WebMouseEvent mouse_event;
if (mate::ConvertFromV8(isolate, input_event, &mouse_event)) {
host->ForwardMouseEvent(mouse_event);
return;
}
} else if (blink::WebInputEvent::isKeyboardEventType(type)) {
content::NativeWebKeyboardEvent keyboard_event;;
if (mate::ConvertFromV8(isolate, input_event, &keyboard_event)) {
host->ForwardKeyboardEvent(keyboard_event);
return;
}
} else if (type == blink::WebInputEvent::MouseWheel) {
blink::WebMouseWheelEvent mouse_wheel_event;
if (mate::ConvertFromV8(isolate, input_event, &mouse_wheel_event)) {
host->ForwardWheelEvent(mouse_wheel_event);
return;
}
}
isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
isolate, "Invalid event object")));
}
void WebContents::BeginFrameSubscription(
const FrameSubscriber::FrameCaptureCallback& callback) {
const auto view = web_contents()->GetRenderWidgetHostView();
if (view) {
scoped_ptr<FrameSubscriber> frame_subscriber(new FrameSubscriber(
isolate(), view->GetVisibleViewportSize(), callback));
view->BeginFrameSubscription(frame_subscriber.Pass());
}
}
void WebContents::EndFrameSubscription() {
const auto view = web_contents()->GetRenderWidgetHostView();
if (view)
view->EndFrameSubscription();
}
void WebContents::SetSize(const SetSizeParams& params) {
if (guest_delegate_)
guest_delegate_->SetSize(params);
@@ -748,6 +887,12 @@ bool WebContents::IsGuest() const {
return type_ == WEB_VIEW;
}
v8::Local<v8::Value> WebContents::GetWebPreferences(v8::Isolate* isolate) {
WebContentsPreferences* web_preferences =
WebContentsPreferences::FromWebContents(web_contents());
return mate::ConvertToV8(isolate, *web_preferences->web_preferences());
}
mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
if (template_.IsEmpty())
@@ -757,6 +902,7 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder(
.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)
@@ -767,11 +913,16 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder(
.SetMethod("_goToOffset", &WebContents::GoToOffset)
.SetMethod("isCrashed", &WebContents::IsCrashed)
.SetMethod("setUserAgent", &WebContents::SetUserAgent)
.SetMethod("getUserAgent", &WebContents::GetUserAgent)
.SetMethod("insertCSS", &WebContents::InsertCSS)
.SetMethod("_executeJavaScript", &WebContents::ExecuteJavaScript)
.SetMethod("openDevTools", &WebContents::OpenDevTools)
.SetMethod("closeDevTools", &WebContents::CloseDevTools)
.SetMethod("isDevToolsOpened", &WebContents::IsDevToolsOpened)
.SetMethod("enableDeviceEmulation",
&WebContents::EnableDeviceEmulation)
.SetMethod("disableDeviceEmulation",
&WebContents::DisableDeviceEmulation)
.SetMethod("toggleDevTools", &WebContents::ToggleDevTools)
.SetMethod("inspectElement", &WebContents::InspectElement)
.SetMethod("setAudioMuted", &WebContents::SetAudioMuted)
@@ -787,16 +938,25 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder(
.SetMethod("unselect", &WebContents::Unselect)
.SetMethod("replace", &WebContents::Replace)
.SetMethod("replaceMisspelling", &WebContents::ReplaceMisspelling)
.SetMethod("focus", &WebContents::Focus)
.SetMethod("tabTraverse", &WebContents::TabTraverse)
.SetMethod("_send", &WebContents::SendIPCMessage, true)
.SetMethod("sendInputEvent", &WebContents::SendInputEvent)
.SetMethod("beginFrameSubscription",
&WebContents::BeginFrameSubscription)
.SetMethod("endFrameSubscription", &WebContents::EndFrameSubscription)
.SetMethod("setSize", &WebContents::SetSize)
.SetMethod("setAllowTransparency", &WebContents::SetAllowTransparency)
.SetMethod("isGuest", &WebContents::IsGuest)
.SetMethod("getWebPreferences", &WebContents::GetWebPreferences)
.SetMethod("hasServiceWorker", &WebContents::HasServiceWorker)
.SetMethod("unregisterServiceWorker",
&WebContents::UnregisterServiceWorker)
.SetMethod("inspectServiceWorker", &WebContents::InspectServiceWorker)
.SetMethod("print", &WebContents::Print)
.SetMethod("_printToPDF", &WebContents::PrintToPDF)
.SetMethod("addWorkSpace", &WebContents::AddWorkSpace)
.SetMethod("removeWorkSpace", &WebContents::RemoveWorkSpace)
.SetProperty("session", &WebContents::Session)
.Build());
@@ -842,7 +1002,7 @@ mate::Handle<WebContents> WebContents::CreateFrom(
// static
mate::Handle<WebContents> WebContents::Create(
v8::Isolate* isolate, const mate::Dictionary& options) {
auto handle = mate::CreateHandle(isolate, new WebContents(options));
auto handle = mate::CreateHandle(isolate, new WebContents(isolate, options));
g_wrap_web_contents.Run(handle.ToV8());
return handle;
}

View File

@@ -8,13 +8,18 @@
#include <string>
#include <vector>
#include "atom/browser/api/frame_subscriber.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 "content/public/common/favicon_url.h"
#include "native_mate/handle.h"
#include "ui/gfx/image/image.h"
namespace blink {
struct WebDeviceEmulationParams;
}
namespace brightray {
class InspectableWebContents;
}
@@ -37,8 +42,8 @@ class WebContents : public mate::TrackableObject<WebContents>,
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;
using PrintToPDFCallback =
base::Callback<void(v8::Local<v8::Value>, v8::Local<v8::Value>)>;
// Create from an existing WebContents.
static mate::Handle<WebContents> CreateFrom(
@@ -48,11 +53,14 @@ class WebContents : public mate::TrackableObject<WebContents>,
static mate::Handle<WebContents> Create(
v8::Isolate* isolate, const mate::Dictionary& options);
void Destroy();
// mate::TrackableObject:
void Destroy() override;
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;
@@ -63,12 +71,16 @@ class WebContents : public mate::TrackableObject<WebContents>,
void GoToOffset(int offset);
bool IsCrashed() const;
void SetUserAgent(const std::string& user_agent);
std::string GetUserAgent();
void InsertCSS(const std::string& css);
void ExecuteJavaScript(const base::string16& code);
void ExecuteJavaScript(const base::string16& code,
bool has_user_gesture);
void OpenDevTools(mate::Arguments* args);
void CloseDevTools();
bool IsDevToolsOpened();
void ToggleDevTools();
void EnableDeviceEmulation(const blink::WebDeviceEmulationParams& params);
void DisableDeviceEmulation();
void InspectElement(int x, int y);
void InspectServiceWorker();
v8::Local<v8::Value> Session(v8::Isolate* isolate);
@@ -82,6 +94,10 @@ class WebContents : public mate::TrackableObject<WebContents>,
void PrintToPDF(const base::DictionaryValue& setting,
const PrintToPDFCallback& callback);
// DevTools workspace api.
void AddWorkSpace(mate::Arguments* args, const base::FilePath& path);
void RemoveWorkSpace(mate::Arguments* args, const base::FilePath& path);
// Editing commands.
void Undo();
void Redo();
@@ -95,18 +111,33 @@ class WebContents : public mate::TrackableObject<WebContents>,
void Replace(const base::string16& word);
void ReplaceMisspelling(const base::string16& word);
// Sending messages to browser.
// Focus.
void Focus();
void TabTraverse(bool reverse);
// Send messages to browser.
bool SendIPCMessage(const base::string16& channel,
const base::ListValue& args);
// Send WebInputEvent to the page.
void SendInputEvent(v8::Isolate* isolate, v8::Local<v8::Value> input_event);
// Subscribe to the frame updates.
void BeginFrameSubscription(
const FrameSubscriber::FrameCaptureCallback& callback);
void EndFrameSubscription();
// Methods for creating <webview>.
void SetSize(const SetSizeParams& params);
void SetAllowTransparency(bool allow);
bool IsGuest() const;
// Returns the web preferences of current WebContents.
v8::Local<v8::Value> GetWebPreferences(v8::Isolate* isolate);
protected:
explicit WebContents(content::WebContents* web_contents);
explicit WebContents(const mate::Dictionary& options);
WebContents(v8::Isolate* isolate, const mate::Dictionary& options);
~WebContents();
// mate::Wrappable:
@@ -125,7 +156,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
int route_id,
int main_frame_route_id,
WindowContainerType window_container_type,
const base::string16& frame_name,
const std::string& frame_name,
const GURL& target_url,
const std::string& partition_id,
content::SessionStorageNamespace* session_storage_namespace) override;
@@ -160,11 +191,13 @@ class WebContents : public mate::TrackableObject<WebContents>,
void DidFailLoad(content::RenderFrameHost* render_frame_host,
const GURL& validated_url,
int error_code,
const base::string16& error_description) override;
const base::string16& error_description,
bool was_ignored_by_handler) override;
void DidFailProvisionalLoad(content::RenderFrameHost* render_frame_host,
const GURL& validated_url,
int error_code,
const base::string16& error_description) override;
const base::string16& error_description,
bool was_ignored_by_handler) override;
void DidStartLoading() override;
void DidStopLoading() override;
void DidGetResourceResponseStart(

View File

@@ -3,13 +3,14 @@
// found in the LICENSE file.
#include "atom/browser/api/atom_api_web_contents.h"
#include "atom/browser/web_contents_preferences.h"
#include "atom/browser/web_view_manager.h"
#include "atom/common/native_mate_converters/gurl_converter.h"
#include "atom/common/native_mate_converters/value_converter.h"
#include "atom/common/node_includes.h"
#include "content/public/browser/browser_context.h"
#include "native_mate/dictionary.h"
#include "net/base/filename_util.h"
#include "atom/common/node_includes.h"
using atom::WebContentsPreferences;
namespace mate {
@@ -25,28 +26,6 @@ struct Converter<content::WebContents*> {
}
};
template<>
struct Converter<atom::WebViewManager::WebViewInfo> {
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
atom::WebViewManager::WebViewInfo* out) {
Dictionary options;
if (!ConvertFromV8(isolate, val, &options))
return false;
GURL preload_url;
if (!options.Get("preloadUrl", &preload_url))
return false;
if (!preload_url.is_empty() &&
!net::FileURLToFilePath(preload_url, &(out->preload_script)))
return false;
return options.Get("nodeIntegration", &(out->node_integration)) &&
options.Get("plugins", &(out->plugins)) &&
options.Get("disableWebSecurity", &(out->disable_web_security));
}
};
} // namespace mate
namespace {
@@ -65,14 +44,13 @@ void AddGuest(int guest_instance_id,
int element_instance_id,
content::WebContents* embedder,
content::WebContents* guest_web_contents,
atom::WebViewManager::WebViewInfo info) {
const base::DictionaryValue& options) {
auto manager = GetWebViewManager(embedder);
if (manager) {
info.guest_instance_id = guest_instance_id;
info.embedder = embedder;
if (manager)
manager->AddGuest(guest_instance_id, element_instance_id, embedder,
guest_web_contents, info);
}
guest_web_contents);
WebContentsPreferences::FromWebContents(guest_web_contents)->Merge(options);
}
void RemoveGuest(content::WebContents* embedder, int guest_instance_id) {

View File

@@ -8,17 +8,42 @@
#include "atom/browser/api/atom_api_web_contents.h"
#include "atom/browser/browser.h"
#include "atom/browser/native_window.h"
#include "atom/common/native_mate_converters/callback.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/node_includes.h"
#include "atom/common/options_switches.h"
#include "content/public/browser/render_process_host.h"
#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"
#if defined(OS_WIN)
#include "atom/browser/native_window_views.h"
#include "atom/browser/ui/win/taskbar_host.h"
#endif
#if defined(OS_WIN)
namespace mate {
template<>
struct Converter<atom::TaskbarHost::ThumbarButton> {
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
atom::TaskbarHost::ThumbarButton* out) {
mate::Dictionary dict;
if (!ConvertFromV8(isolate, val, &dict))
return false;
dict.Get("click", &(out->clicked_callback));
dict.Get("tooltip", &(out->tooltip));
dict.Get("flags", &out->flags);
return dict.Get("icon", &(out->icon));
}
};
} // namespace mate
#endif
namespace atom {
@@ -39,12 +64,28 @@ void OnCapturePageDone(
Window::Window(v8::Isolate* isolate, const mate::Dictionary& options) {
// Use options['web-preferences'] to create WebContents.
mate::Dictionary web_preferences = mate::Dictionary::CreateEmpty(isolate);
options.Get(switches::kWebPreferences, &web_preferences);
// Be compatible with old options which are now in web_preferences.
v8::Local<v8::Value> value;
if (options.Get(switches::kNodeIntegration, &value))
web_preferences.Set(switches::kNodeIntegration, value);
if (options.Get(switches::kPreloadScript, &value))
web_preferences.Set(switches::kPreloadScript, value);
if (options.Get(switches::kZoomFactor, &value))
web_preferences.Set(switches::kZoomFactor, value);
// 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);
auto web_contents = WebContents::Create(isolate, web_preferences);
web_contents_.Reset(isolate, web_contents.ToV8());
api_web_contents_ = web_contents.get();
// Keep a copy of the options for later use.
mate::Dictionary(isolate, web_contents->GetWrapper(isolate)).Set(
"browserWindowOptions", options);
// Creates BrowserWindow.
window_.reset(NativeWindow::Create(web_contents->managed_web_contents(),
options));
@@ -78,6 +119,9 @@ void Window::OnWindowClosed() {
window_->RemoveObserver(this);
Emit("closed");
// Clean up the resources after window has been closed.
base::MessageLoop::current()->DeleteSoon(FROM_HERE, window_.release());
}
void Window::OnWindowBlur() {
@@ -145,21 +189,21 @@ void Window::OnDevToolsFocus() {
}
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());
Emit("devtools-opened");
}
void Window::OnDevToolsClosed() {
Emit("devtools-closed");
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
devtools_web_contents_.Reset();
Emit("devtools-closed");
}
void Window::OnExecuteWindowsCommand(const std::string& command_name) {
@@ -170,8 +214,8 @@ void Window::OnExecuteWindowsCommand(const std::string& command_name) {
mate::Wrappable* Window::New(v8::Isolate* isolate,
const mate::Dictionary& options) {
if (!Browser::Get()->is_ready()) {
node::ThrowError(isolate,
"Cannot create BrowserWindow before app is ready");
isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
isolate, "Cannot create BrowserWindow before app is ready")));
return nullptr;
}
return new Window(isolate, options);
@@ -182,7 +226,8 @@ bool Window::IsDestroyed() const {
}
void Window::Destroy() {
window_->CloseContents(nullptr);
if (window_)
window_->CloseContents(nullptr);
}
void Window::Close() {
@@ -373,6 +418,10 @@ bool Window::IsWebViewFocused() {
return window_->IsWebViewFocused();
}
bool Window::IsDevToolsFocused() {
return window_->IsDevToolsFocused();
}
void Window::SetRepresentedFilename(const std::string& filename) {
window_->SetRepresentedFilename(filename);
}
@@ -413,6 +462,21 @@ void Window::SetOverlayIcon(const gfx::Image& overlay,
window_->SetOverlayIcon(overlay, description);
}
bool Window::SetThumbarButtons(mate::Arguments* args) {
#if defined(OS_WIN)
std::vector<TaskbarHost::ThumbarButton> buttons;
if (!args->GetNext(&buttons)) {
args->ThrowError();
return false;
}
auto window = static_cast<NativeWindowViews*>(window_.get());
return window->taskbar_host().SetThumbarButtons(
window->GetAcceleratedWidget(), buttons);
#else
return false;
#endif
}
void Window::SetMenu(v8::Isolate* isolate, v8::Local<v8::Value> value) {
mate::Handle<Menu> menu;
if (value->IsObject() &&
@@ -451,6 +515,12 @@ void Window::ShowDefinitionForSelection() {
}
#endif
void Window::SetAspectRatio(double aspect_ratio, mate::Arguments* args) {
gfx::Size extra_size;
args->GetNext(&extra_size);
window_->SetAspectRatio(aspect_ratio, extra_size);
}
void Window::SetVisibleOnAllWorkspaces(bool visible) {
return window_->SetVisibleOnAllWorkspaces(visible);
}
@@ -498,6 +568,7 @@ void Window::BuildPrototype(v8::Isolate* isolate,
.SetMethod("isMinimized", &Window::IsMinimized)
.SetMethod("setFullScreen", &Window::SetFullScreen)
.SetMethod("isFullScreen", &Window::IsFullscreen)
.SetMethod("setAspectRatio", &Window::SetAspectRatio)
.SetMethod("getBounds", &Window::GetBounds)
.SetMethod("setBounds", &Window::SetBounds)
.SetMethod("getSize", &Window::GetSize)
@@ -528,9 +599,11 @@ void Window::BuildPrototype(v8::Isolate* isolate,
.SetMethod("focusOnWebView", &Window::FocusOnWebView)
.SetMethod("blurWebView", &Window::BlurWebView)
.SetMethod("isWebViewFocused", &Window::IsWebViewFocused)
.SetMethod("isDevToolsFocused", &Window::IsDevToolsFocused)
.SetMethod("capturePage", &Window::CapturePage)
.SetMethod("setProgressBar", &Window::SetProgressBar)
.SetMethod("setOverlayIcon", &Window::SetOverlayIcon)
.SetMethod("setThumbarButtons", &Window::SetThumbarButtons)
.SetMethod("setMenu", &Window::SetMenu)
.SetMethod("setAutoHideMenuBar", &Window::SetAutoHideMenuBar)
.SetMethod("isMenuBarAutoHide", &Window::IsMenuBarAutoHide)

View File

@@ -11,6 +11,7 @@
#include "base/memory/scoped_ptr.h"
#include "ui/gfx/image/image.h"
#include "atom/browser/api/trackable_object.h"
#include "atom/browser/native_window.h"
#include "atom/browser/native_window_observer.h"
#include "native_mate/handle.h"
@@ -77,8 +78,10 @@ class Window : public mate::TrackableObject<Window>,
bool IsDestroyed() const override;
private:
// mate::TrackableObject:
void Destroy() override;
// APIs for NativeWindow.
void Destroy();
void Close();
bool IsClosed();
void Focus();
@@ -121,6 +124,7 @@ class Window : public mate::TrackableObject<Window>,
void FocusOnWebView();
void BlurWebView();
bool IsWebViewFocused();
bool IsDevToolsFocused();
void SetRepresentedFilename(const std::string& filename);
std::string GetRepresentedFilename();
void SetDocumentEdited(bool edited);
@@ -129,11 +133,13 @@ class Window : public mate::TrackableObject<Window>,
void SetProgressBar(double progress);
void SetOverlayIcon(const gfx::Image& overlay,
const std::string& description);
bool SetThumbarButtons(mate::Arguments* args);
void SetMenu(v8::Isolate* isolate, v8::Local<v8::Value> menu);
void SetAutoHideMenuBar(bool auto_hide);
bool IsMenuBarAutoHide();
void SetMenuBarVisibility(bool visible);
bool IsMenuBarVisible();
void SetAspectRatio(double aspect_ratio, mate::Arguments* args);
#if defined(OS_MACOSX)
void ShowDefinitionForSelection();

View File

@@ -37,9 +37,8 @@ v8::Local<v8::Object> CreateEventObject(v8::Isolate* isolate) {
EventEmitter::EventEmitter() {
}
v8::Local<v8::Object> EventEmitter::CreateJSEvent(v8::Isolate* isolate,
content::WebContents* sender,
IPC::Message* message) {
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;
@@ -54,4 +53,12 @@ v8::Local<v8::Object> EventEmitter::CreateJSEvent(v8::Isolate* isolate,
return event;
}
v8::Local<v8::Object> EventEmitter::CreateCustomEvent(
v8::Isolate* isolate, v8::Local<v8::Object> custom_event) {
v8::Local<v8::Object> event = CreateEventObject(isolate);
(void)event->SetPrototype(custom_event->CreationContext(), custom_event);
mate::Dictionary(isolate, event).Set("sender", GetWrapper(isolate));
return event;
}
} // namespace mate

View File

@@ -7,7 +7,7 @@
#include <vector>
#include "atom/common/event_emitter_caller.h"
#include "atom/common/api/event_emitter_caller.h"
#include "native_mate/wrappable.h"
namespace content {
@@ -25,6 +25,14 @@ class EventEmitter : public Wrappable {
public:
typedef std::vector<v8::Local<v8::Value>> ValueArray;
// this.emit(name, event, args...);
template<typename... Args>
bool EmitCustomEvent(const base::StringPiece& name,
v8::Local<v8::Object> event,
const Args&... args) {
return EmitWithEvent(name, CreateCustomEvent(isolate(), event), args...);
}
// this.emit(name, new Event(), args...);
template<typename... Args>
bool Emit(const base::StringPiece& name, const Args&... args) {
@@ -40,18 +48,30 @@ class EventEmitter : public Wrappable {
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();
return EmitWithEvent(name, event, args...);
}
protected:
EventEmitter();
private:
// this.emit(name, event, args...);
template<typename... Args>
bool EmitWithEvent(const base::StringPiece& name,
v8::Local<v8::Object> event,
const Args&... args) {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
EmitEvent(isolate(), GetWrapper(isolate()), name, event, args...);
return event->Get(
StringToV8(isolate(), "defaultPrevented"))->BooleanValue();
}
v8::Local<v8::Object> CreateJSEvent(v8::Isolate* isolate,
content::WebContents* sender,
IPC::Message* message);
v8::Local<v8::Object> CreateCustomEvent(
v8::Isolate* isolate, v8::Local<v8::Object> event);
DISALLOW_COPY_AND_ASSIGN(EventEmitter);
};

View File

@@ -0,0 +1,66 @@
// 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/frame_subscriber.h"
#include "atom/common/node_includes.h"
#include "base/bind.h"
#include "media/base/video_frame.h"
#include "media/base/yuv_convert.h"
namespace atom {
namespace api {
FrameSubscriber::FrameSubscriber(v8::Isolate* isolate,
const gfx::Size& size,
const FrameCaptureCallback& callback)
: isolate_(isolate), size_(size), callback_(callback) {
}
bool FrameSubscriber::ShouldCaptureFrame(
const gfx::Rect& damage_rect,
base::TimeTicks present_time,
scoped_refptr<media::VideoFrame>* storage,
DeliverFrameCallback* callback) {
*storage = media::VideoFrame::CreateFrame(media::VideoFrame::YV12, size_,
gfx::Rect(size_), size_,
base::TimeDelta());
*callback = base::Bind(&FrameSubscriber::OnFrameDelivered,
base::Unretained(this),
*storage);
return true;
}
void FrameSubscriber::OnFrameDelivered(
scoped_refptr<media::VideoFrame> frame, base::TimeTicks, bool result) {
if (!result)
return;
gfx::Rect rect = frame->visible_rect();
size_t rgb_arr_size = rect.width() * rect.height() * 4;
v8::MaybeLocal<v8::Object> buffer = node::Buffer::New(isolate_, rgb_arr_size);
if (buffer.IsEmpty())
return;
// Convert a frame of YUV to 32 bit ARGB.
media::ConvertYUVToRGB32(frame->data(media::VideoFrame::kYPlane),
frame->data(media::VideoFrame::kUPlane),
frame->data(media::VideoFrame::kVPlane),
reinterpret_cast<uint8*>(
node::Buffer::Data(buffer.ToLocalChecked())),
rect.width(), rect.height(),
frame->stride(media::VideoFrame::kYPlane),
frame->stride(media::VideoFrame::kUVPlane),
rect.width() * 4,
media::YV12);
v8::Locker locker(isolate_);
v8::HandleScope handle_scope(isolate_);
callback_.Run(buffer.ToLocalChecked());
}
} // namespace api
} // namespace atom

View File

@@ -0,0 +1,45 @@
// 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_FRAME_SUBSCRIBER_H_
#define ATOM_BROWSER_API_FRAME_SUBSCRIBER_H_
#include "base/callback.h"
#include "content/public/browser/render_widget_host_view_frame_subscriber.h"
#include "ui/gfx/geometry/size.h"
#include "v8/include/v8.h"
namespace atom {
namespace api {
class FrameSubscriber : public content::RenderWidgetHostViewFrameSubscriber {
public:
using FrameCaptureCallback = base::Callback<void(v8::Local<v8::Value>)>;
FrameSubscriber(v8::Isolate* isolate,
const gfx::Size& size,
const FrameCaptureCallback& callback);
bool ShouldCaptureFrame(const gfx::Rect& damage_rect,
base::TimeTicks present_time,
scoped_refptr<media::VideoFrame>* storage,
DeliverFrameCallback* callback) override;
private:
void OnFrameDelivered(
scoped_refptr<media::VideoFrame> frame, base::TimeTicks, bool);
v8::Isolate* isolate_;
gfx::Size size_;
FrameCaptureCallback callback_;
DISALLOW_COPY_AND_ASSIGN(FrameSubscriber);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_FRAME_SUBSCRIBER_H_

View File

@@ -1,10 +1,25 @@
EventEmitter = require('events').EventEmitter
bindings = process.atomBinding 'app'
sessionBindings = process.atomBinding 'session'
downloadItemBindings = process.atomBinding 'download_item'
app = bindings.app
app.__proto__ = EventEmitter.prototype
wrapSession = (session) ->
# session is an Event Emitter.
session.__proto__ = EventEmitter.prototype
wrapDownloadItem = (download_item) ->
# download_item is an Event Emitter.
download_item.__proto__ = EventEmitter.prototype
# Be compatible with old APIs.
download_item.url = download_item.getUrl()
download_item.filename = download_item.getFilename()
download_item.mimeType = download_item.getMimeType()
download_item.hasUserGesture = download_item.hasUserGesture()
app.setApplicationMenu = (menu) ->
require('menu').setApplicationMenu menu
@@ -40,6 +55,14 @@ app.getHomeDir = -> @getPath 'home'
app.getDataPath = -> @getPath 'userData'
app.setDataPath = (path) -> @setPath 'userData', path
app.resolveProxy = -> @defaultSession.resolveProxy.apply @defaultSession, arguments
app.on 'activate', (event, hasVisibleWindows) -> @emit 'activate-with-no-open-windows' if not hasVisibleWindows
# Session wrapper.
sessionBindings._setWrapSession wrapSession
process.once 'exit', sessionBindings._clearWrapSession
downloadItemBindings._setWrapDownloadItem wrapDownloadItem
process.once 'exit', downloadItemBindings._clearWrapDownloadItem
# Only one App object pemitted.
module.exports = app

View File

@@ -30,12 +30,24 @@ BrowserWindow::_init = ->
@webContents.on 'crashed', =>
@emit 'crashed'
# Sometimes the webContents doesn't get focus when window is shown, so we have
# to force focusing on webContents in this case. The safest way is to focus it
# when we first start to load URL, if we do it earlier it won't have effect,
# if we do it later we might move focus in the page.
# Though this hack is only needed on OS X when the app is launched from
# Finder, we still do it on all platforms in case of other bugs we don't know.
@webContents.once 'load-url', ->
@focus()
# Redirect focus/blur event to app instance too.
@on 'blur', (event) =>
app.emit 'browser-window-blur', event, this
@on 'focus', (event) =>
app.emit 'browser-window-focus', event, this
# Notify the creation of the window.
app.emit 'browser-window-created', {}, this
BrowserWindow.getFocusedWindow = ->
windows = BrowserWindow.getAllWindows()
return window for window in windows when window.isFocused()
@@ -53,6 +65,12 @@ BrowserWindow::loadUrl = -> @webContents.loadUrl.apply @webContents, arguments
BrowserWindow::send = -> @webContents.send.apply @webContents, arguments
# Be compatible with old API.
BrowserWindow::undo = -> @webContents.undo()
BrowserWindow::redo = -> @webContents.redo()
BrowserWindow::cut = -> @webContents.cut()
BrowserWindow::copy = -> @webContents.copy()
BrowserWindow::paste = -> @webContents.paste()
BrowserWindow::selectAll = -> @webContents.selectAll()
BrowserWindow::restart = -> @webContents.reload()
BrowserWindow::getUrl = -> @webContents.getUrl()
BrowserWindow::reload = -> @webContents.reload.apply @webContents, arguments

View File

@@ -1,7 +1 @@
module.exports = process.atomBinding 'content_tracing'
# Mirrored from content::TracingController::Options
module.exports.DEFAULT_OPTIONS = 0
module.exports.ENABLE_SYSTRACE = 1 << 0
module.exports.ENABLE_SAMPLING = 1 << 1
module.exports.RECORD_CONTINUOUSLY = 1 << 2

View File

@@ -11,6 +11,9 @@ fileDialogProperties =
messageBoxTypes = ['none', 'info', 'warning', 'error', 'question']
messageBoxOptions =
noLink: 1 << 0
parseArgs = (window, options, callback) ->
unless window is null or window?.constructor is BrowserWindow
# Shift.
@@ -101,10 +104,15 @@ module.exports =
options.cancelId = i
break
flags = if options.noLink then messageBoxOptions.noLink else 0
binding.showMessageBox messageBoxType,
options.buttons,
options.cancelId,
[options.title, options.message, options.detail],
flags,
options.title,
options.message,
options.detail,
options.icon,
window,
callback

View File

@@ -3,18 +3,30 @@ v8Util = process.atomBinding 'v8_util'
nextCommandId = 0
# Maps role to methods of webContents
rolesMap =
undo: 'undo'
redo: 'redo'
cut: 'cut'
copy: 'copy'
paste: 'paste'
selectall: 'selectAll'
minimize: 'minimize'
close: 'close'
class MenuItem
@types = ['normal', 'separator', 'submenu', 'checkbox', 'radio']
constructor: (options) ->
Menu = require 'menu'
{click, @selector, @type, @label, @sublabel, @accelerator, @icon, @enabled, @visible, @checked, @submenu} = options
{click, @selector, @type, @role, @label, @sublabel, @accelerator, @icon, @enabled, @visible, @checked, @submenu} = options
@type = 'submenu' if not @type? and @submenu?
throw new Error('Invalid submenu') if @type is 'submenu' and @submenu?.constructor isnt Menu
@overrideReadOnlyProperty 'type', 'normal'
@overrideReadOnlyProperty 'role'
@overrideReadOnlyProperty 'accelerator'
@overrideReadOnlyProperty 'icon'
@overrideReadOnlyProperty 'submenu'
@@ -27,12 +39,14 @@ class MenuItem
throw new Error("Unknown menu type #{@type}") if MenuItem.types.indexOf(@type) is -1
@commandId = ++nextCommandId
@click = =>
@click = (focusedWindow) =>
# Manually flip the checked flags when clicked.
@checked = !@checked if @type in ['checkbox', 'radio']
if typeof click is 'function'
click this, BrowserWindow.getFocusedWindow()
if @role and rolesMap[@role] and process.platform isnt 'darwin'
focusedWindow?[rolesMap[@role]]()
else if typeof click is 'function'
click this, focusedWindow
else if typeof @selector is 'string'
Menu.sendActionToFirstResponder @selector

View File

@@ -67,7 +67,8 @@ Menu::_init = ->
isCommandIdVisible: (commandId) => @commandsMap[commandId]?.visible
getAcceleratorForCommandId: (commandId) => @commandsMap[commandId]?.accelerator
getIconForCommandId: (commandId) => @commandsMap[commandId]?.icon
executeCommand: (commandId) => @commandsMap[commandId]?.click()
executeCommand: (commandId) =>
@commandsMap[commandId]?.click BrowserWindow.getFocusedWindow()
menuWillShow: =>
# Make sure radio groups have at least one menu item seleted.
for id, group of @groupsMap
@@ -115,6 +116,7 @@ Menu::insert = (pos, item) ->
@setSublabel pos, item.sublabel if item.sublabel?
@setIcon pos, item.icon if item.icon?
@setRole pos, item.role if item.role?
# Make menu accessable to items.
item.overrideReadOnlyProperty 'menu', this

View File

@@ -16,6 +16,11 @@ class NavigationController
constructor: (@webContents) ->
@clearHistory()
# webContents may have already navigated to a page.
if @webContents._getUrl()
@currentIndex++
@history.push @webContents._getUrl()
@webContents.on 'navigation-entry-commited', (event, url, inPage, replaceEntry) =>
if @inPageIndex > -1 and not inPage
# Navigated to a new page, clear in-page mark.
@@ -40,6 +45,7 @@ class NavigationController
loadUrl: (url, options={}) ->
@pendingIndex = -1
@webContents._loadUrl url, options
@webContents.emit 'load-url', url, options
getUrl: ->
if @currentIndex is -1

View File

@@ -2,63 +2,23 @@ app = require 'app'
throw new Error('Can not initialize protocol module before app is ready') unless app.isReady()
protocol = process.atomBinding('protocol').protocol
EventEmitter = require('events').EventEmitter
protocol.__proto__ = EventEmitter.prototype
GetWrappedCallback = (scheme, callback, notification) ->
wrappedCallback = (error) ->
if not callback?
if error
throw error
else
protocol.emit notification, scheme
else
callback error, scheme
# Compatibility with old api.
# Warn about removed APIs.
logAndThrow = (callback, message) ->
console.error message
if callback then callback(new Error(message)) else throw new Error(message)
protocol.registerProtocol = (scheme, handler, callback) ->
protocol._registerProtocol scheme, handler, GetWrappedCallback(scheme, callback, 'registered')
protocol.unregisterProtocol = (scheme, callback) ->
protocol._unregisterProtocol scheme, GetWrappedCallback(scheme, callback, 'unregistered')
logAndThrow callback,
'registerProtocol API has been replaced by the
register[File/Http/Buffer/String]Protocol API family, please
switch to the new APIs.'
protocol.isHandledProtocol = (scheme, callback) ->
logAndThrow callback,
'isHandledProtocol API has been replaced by isProtocolHandled.'
protocol.interceptProtocol = (scheme, handler, callback) ->
protocol._interceptProtocol scheme, handler, GetWrappedCallback(scheme, callback, 'intercepted')
protocol.uninterceptProtocol = (scheme, callback) ->
protocol._uninterceptProtocol scheme, GetWrappedCallback(scheme, callback, 'unintercepted')
protocol.RequestStringJob =
class RequestStringJob
constructor: ({mimeType, charset, data}) ->
if typeof data isnt 'string' and not data instanceof Buffer
throw new TypeError('Data should be string or Buffer')
@mimeType = mimeType ? 'text/plain'
@charset = charset ? 'UTF-8'
@data = String data
protocol.RequestBufferJob =
class RequestBufferJob
constructor: ({mimeType, encoding, data}) ->
if not data instanceof Buffer
throw new TypeError('Data should be Buffer')
@mimeType = mimeType ? 'application/octet-stream'
@encoding = encoding ? 'utf8'
@data = new Buffer(data)
protocol.RequestFileJob =
class RequestFileJob
constructor: (@path) ->
protocol.RequestErrorJob =
class RequestErrorJob
constructor: (@error) ->
protocol.RequestHttpJob =
class RequestHttpJob
constructor: ({@url, @method, @referrer}) ->
logAndThrow callback,
'interceptProtocol API has been replaced by the
intercept[File/Http/Buffer/String]Protocol API family, please
switch to the new APIs.'
module.exports = protocol

View File

@@ -3,8 +3,12 @@ bindings = process.atomBinding 'tray'
Tray = bindings.Tray
Tray::__proto__ = EventEmitter.prototype
Tray::setContextMenu = (menu) ->
@_setContextMenu menu
@menu = menu # Keep a strong reference of menu.
# Keep compatibility with old APIs.
Tray::popContextMenu = Tray::popUpContextMenu
module.exports = Tray

View File

@@ -6,6 +6,34 @@ ipc = require 'ipc'
nextId = 0
getNextId = -> ++nextId
PDFPageSize =
A4:
custom_display_name: "A4"
height_microns: 297000
name: "ISO_A4"
is_default: "true"
width_microns: 210000
A3:
custom_display_name: "A3"
height_microns: 420000
name: "ISO_A3"
width_microns: 297000
Legal:
custom_display_name: "Legal"
height_microns: 355600
name: "NA_LEGAL"
width_microns: 215900
Letter:
custom_display_name: "Letter"
height_microns: 279400
name: "NA_LETTER"
width_microns: 215900
Tabloid:
height_microns: 431800
name: "NA_LEDGER"
width_microns: 279400
custom_display_name: "Tabloid"
wrapWebContents = (webContents) ->
# webContents is an EventEmitter.
webContents.__proto__ = EventEmitter.prototype
@@ -16,13 +44,11 @@ wrapWebContents = (webContents) ->
# Make sure webContents.executeJavaScript would run the code only when the
# web contents has been loaded.
webContents.loaded = false
webContents.once 'did-finish-load', -> @loaded = true
webContents.executeJavaScript = (code) ->
if @loaded
@_executeJavaScript code
webContents.executeJavaScript = (code, hasUserGesture=false) ->
if @getUrl() and not @isLoading()
@_executeJavaScript code, hasUserGesture
else
webContents.once 'did-finish-load', @_executeJavaScript.bind(this, code)
webContents.once 'did-finish-load', @_executeJavaScript.bind(this, code, hasUserGesture)
# The navigation controller.
controller = new NavigationController(webContents)
@@ -41,32 +67,27 @@ wrapWebContents = (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
pageRage: []
mediaSize: {}
landscape: false
color: 2
headerFooterEnabled: false
marginsType: 0
isFirstRequest: false
requestID: getNextId()
previewModifiable: true
printToPDF: true
printWithCloudPrint: false
printWithPrivet: false
printWithExtension: false
deviceName: "Save as PDF"
generateDraftData: true
fitToPageEnabled: false
duplex: 0
copies: 1
collate: true
shouldPrintBackgrounds: false
shouldPrintSelectionOnly: false
if options.landscape
printingSetting.landscape = options.landscape
@@ -74,9 +95,14 @@ wrapWebContents = (webContents) ->
printingSetting.marginsType = options.marginsType
if options.printSelectionOnly
printingSetting.shouldPrintSelectionOnly = options.printSelectionOnly
if options.printBackgrounds
if options.printBackground
printingSetting.shouldPrintBackgrounds = options.printBackground
if options.pageSize and PDFPageSize[options.pageSize]
printingSetting.mediaSize = PDFPageSize[options.pageSize]
else
printingSetting.mediaSize = PDFPageSize['A4']
@_printToPDF printingSetting, callback
binding._setWrapWebContents wrapWebContents

View File

@@ -29,7 +29,9 @@ class IDUserData : public base::SupportsUserData::Data {
} // namespace
TrackableObjectBase::TrackableObjectBase()
: weak_map_id_(0), wrapped_(nullptr) {
: weak_map_id_(0), wrapped_(nullptr), weak_factory_(this) {
RegisterDestructionCallback(
base::Bind(&TrackableObjectBase::Destroy, weak_factory_.GetWeakPtr()));
}
TrackableObjectBase::~TrackableObjectBase() {
@@ -61,8 +63,9 @@ int32_t TrackableObjectBase::GetIDFromWrappedClass(base::SupportsUserData* w) {
}
// static
void TrackableObjectBase::RegisterDestructionCallback(void (*c)()) {
atom::AtomBrowserMainParts::Get()->RegisterDestructionCallback(base::Bind(c));
void TrackableObjectBase::RegisterDestructionCallback(
const base::Closure& closure) {
atom::AtomBrowserMainParts::Get()->RegisterDestructionCallback(closure);
}
} // namespace mate

View File

@@ -9,7 +9,9 @@
#include "atom/browser/api/event_emitter.h"
#include "atom/common/id_weak_map.h"
#include "base/bind.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
namespace base {
class SupportsUserData;
@@ -28,6 +30,9 @@ class TrackableObjectBase : public mate::EventEmitter {
// Wrap TrackableObject into a class that SupportsUserData.
void AttachAsUserData(base::SupportsUserData* wrapped);
// Subclasses should implement this to destroy their native types.
virtual void Destroy() = 0;
protected:
~TrackableObjectBase() override;
@@ -39,12 +44,14 @@ class TrackableObjectBase : public mate::EventEmitter {
// Register a callback that should be destroyed before JavaScript environment
// gets destroyed.
static void RegisterDestructionCallback(void (*callback)());
static void RegisterDestructionCallback(const base::Closure& closure);
int32_t weak_map_id_;
base::SupportsUserData* wrapped_;
private:
base::WeakPtrFactory<TrackableObjectBase> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(TrackableObjectBase);
};
@@ -85,7 +92,8 @@ class TrackableObject : public TrackableObjectBase {
}
TrackableObject() {
RegisterDestructionCallback(&TrackableObject<T>::ReleaseAllWeakReferences);
RegisterDestructionCallback(
base::Bind(&TrackableObject<T>::ReleaseAllWeakReferences));
}
// Removes this instance from the weak map.

View File

@@ -9,6 +9,7 @@
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/common/google_api_key.h"
#include "content/public/browser/geolocation_provider.h"
namespace atom {
@@ -24,6 +25,7 @@ const char* kGeolocationProviderUrl =
} // namespace
AtomAccessTokenStore::AtomAccessTokenStore() {
content::GeolocationProvider::GetInstance()->UserDidOptIntoLocationServices();
}
AtomAccessTokenStore::~AtomAccessTokenStore() {

View File

@@ -4,6 +4,10 @@
#include "atom/browser/atom_browser_client.h"
#if defined(OS_WIN)
#include <shlobj.h>
#endif
#include "atom/browser/atom_access_token_store.h"
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/atom_browser_main_parts.h"
@@ -11,11 +15,12 @@
#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/web_contents_preferences.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/stl_util.h"
#include "base/strings/string_util.h"
#include "base/strings/string_number_conversions.h"
#include "chrome/browser/printing/printing_message_filter.h"
@@ -32,6 +37,7 @@
#include "net/ssl/ssl_cert_request_info.h"
#include "ppapi/host/ppapi_host.h"
#include "ui/base/l10n/l10n_util.h"
#include "v8/include/v8.h"
namespace atom {
@@ -48,34 +54,6 @@ bool g_suppress_renderer_process_restart = false;
// Custom schemes to be registered to standard.
std::string g_custom_schemes = "";
// 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())
@@ -151,15 +129,7 @@ void AtomBrowserClient::OverrideWebkitPrefs(
// Custom preferences of guest page.
auto web_contents = content::WebContents::FromRenderViewHost(host);
WebViewManager::WebViewInfo info;
if (WebViewManager::GetInfoForWebContents(web_contents, &info)) {
prefs->web_security_enabled = !info.disable_web_security;
return;
}
NativeWindow* window = NativeWindow::FromWebContents(web_contents);
if (window)
window->OverrideWebkitPrefs(prefs);
WebContentsPreferences::OverrideWebkitPrefs(web_contents, prefs);
}
std::string AtomBrowserClient::GetApplicationLocale() {
@@ -181,6 +151,13 @@ void AtomBrowserClient::OverrideSiteInstanceForNavigation(
return;
*new_instance = content::SiteInstance::CreateForURL(browser_context, url);
// Remember the original renderer process of the pending renderer process.
auto current_process = current_instance->GetProcess();
auto pending_process = (*new_instance)->GetProcess();
pending_processes_[pending_process->GetID()] = current_process->GetID();
// Clear the entry in map when process ends.
current_process->AddObserver(this);
}
void AtomBrowserClient::AppendExtraCommandLineSwitches(
@@ -190,27 +167,32 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches(
if (process_type != "renderer")
return;
// The registered standard schemes.
if (!g_custom_schemes.empty())
command_line->AppendSwitchASCII(switches::kRegisterStandardSchemes,
g_custom_schemes);
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);
#if defined(OS_WIN)
// Append --app-user-model-id.
PWSTR current_app_id;
if (SUCCEEDED(GetCurrentProcessExplicitAppUserModelID(&current_app_id))) {
command_line->AppendSwitchNative(switches::kAppUserModelId, current_app_id);
CoTaskMemFree(current_app_id);
}
#endif
// If the process is a pending process, we should use the old one.
if (ContainsKey(pending_processes_, process_id))
process_id = pending_processes_[process_id];
// Get the WebContents of the render process.
content::WebContents* web_contents = content::WebContents::FromRenderViewHost(
content::RenderViewHost::FromID(process_id, kDefaultRoutingID));
if (!web_contents)
return;
WebContentsPreferences::AppendExtraCommandLineSwitches(
web_contents, command_line);
}
void AtomBrowserClient::DidCreatePpapiPlugin(
@@ -250,4 +232,15 @@ brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts(
return new AtomBrowserMainParts;
}
void AtomBrowserClient::RenderProcessHostDestroyed(
content::RenderProcessHost* host) {
int process_id = host->GetID();
for (const auto& entry : pending_processes_) {
if (entry.first == process_id || entry.second == process_id) {
pending_processes_.erase(entry.first);
break;
}
}
}
} // namespace atom

View File

@@ -5,10 +5,12 @@
#ifndef ATOM_BROWSER_ATOM_BROWSER_CLIENT_H_
#define ATOM_BROWSER_ATOM_BROWSER_CLIENT_H_
#include <map>
#include <string>
#include <vector>
#include "brightray/browser/browser_client.h"
#include "content/public/browser/render_process_host_observer.h"
namespace content {
class QuotaPermissionContext;
@@ -21,7 +23,8 @@ class SSLCertRequestInfo;
namespace atom {
class AtomBrowserClient : public brightray::BrowserClient {
class AtomBrowserClient : public brightray::BrowserClient,
public content::RenderProcessHostObserver {
public:
AtomBrowserClient();
virtual ~AtomBrowserClient();
@@ -54,10 +57,17 @@ class AtomBrowserClient : public brightray::BrowserClient {
net::SSLCertRequestInfo* cert_request_info,
scoped_ptr<content::ClientCertificateDelegate> delegate) override;
private:
// brightray::BrowserClient:
brightray::BrowserMainParts* OverrideCreateBrowserMainParts(
const content::MainFunctionParams&) override;
// content::RenderProcessHostObserver:
void RenderProcessHostDestroyed(content::RenderProcessHost* host) override;
private:
// pending_render_process => current_render_process.
std::map<int, int> pending_processes_;
DISALLOW_COPY_AND_ASSIGN(AtomBrowserClient);
};

View File

@@ -6,6 +6,7 @@
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/atom_download_manager_delegate.h"
#include "atom/browser/atom_ssl_config_service.h"
#include "atom/browser/browser.h"
#include "atom/browser/net/atom_url_request_job_factory.h"
#include "atom/browser/net/asar/asar_protocol_handler.h"
@@ -15,10 +16,13 @@
#include "atom/common/chrome_version.h"
#include "atom/common/options_switches.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/prefs/pref_registry_simple.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/threading/sequenced_worker_pool.h"
#include "base/threading/worker_pool.h"
#include "chrome/common/pref_names.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/user_agent.h"
@@ -53,8 +57,10 @@ std::string RemoveWhitespace(const std::string& str) {
} // namespace
AtomBrowserContext::AtomBrowserContext()
: job_factory_(new AtomURLRequestJobFactory) {
AtomBrowserContext::AtomBrowserContext(const std::string& partition,
bool in_memory)
: brightray::BrowserContext(partition, in_memory),
job_factory_(new AtomURLRequestJobFactory) {
}
AtomBrowserContext::~AtomBrowserContext() {
@@ -82,32 +88,37 @@ net::URLRequestJobFactory* AtomBrowserContext::CreateURLRequestJobFactory(
content::URLRequestInterceptorScopedVector* interceptors) {
scoped_ptr<AtomURLRequestJobFactory> job_factory(job_factory_);
for (content::ProtocolHandlerMap::iterator it = handlers->begin();
it != handlers->end(); ++it)
job_factory->SetProtocolHandler(it->first, it->second.release());
for (auto& it : *handlers) {
job_factory->SetProtocolHandler(it.first,
make_scoped_ptr(it.second.release()));
}
handlers->clear();
job_factory->SetProtocolHandler(
url::kDataScheme, new net::DataProtocolHandler);
url::kDataScheme, make_scoped_ptr(new net::DataProtocolHandler));
job_factory->SetProtocolHandler(
url::kFileScheme, new asar::AsarProtocolHandler(
url::kFileScheme, make_scoped_ptr(new asar::AsarProtocolHandler(
BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)));
base::SequencedWorkerPool::SKIP_ON_SHUTDOWN))));
job_factory->SetProtocolHandler(
url::kHttpScheme, new HttpProtocolHandler(url::kHttpScheme));
url::kHttpScheme,
make_scoped_ptr(new HttpProtocolHandler(url::kHttpScheme)));
job_factory->SetProtocolHandler(
url::kHttpsScheme, new HttpProtocolHandler(url::kHttpsScheme));
url::kHttpsScheme,
make_scoped_ptr(new HttpProtocolHandler(url::kHttpsScheme)));
job_factory->SetProtocolHandler(
url::kWsScheme, new HttpProtocolHandler(url::kWsScheme));
url::kWsScheme,
make_scoped_ptr(new HttpProtocolHandler(url::kWsScheme)));
job_factory->SetProtocolHandler(
url::kWssScheme, new HttpProtocolHandler(url::kWssScheme));
url::kWssScheme,
make_scoped_ptr(new HttpProtocolHandler(url::kWssScheme)));
auto host_resolver = url_request_context_getter()
->GetURLRequestContext()
->host_resolver();
auto host_resolver =
url_request_context_getter()->GetURLRequestContext()->host_resolver();
job_factory->SetProtocolHandler(
url::kFtpScheme, new net::FtpProtocolHandler(
new net::FtpNetworkLayer(host_resolver)));
url::kFtpScheme,
make_scoped_ptr(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();
@@ -142,8 +153,29 @@ AtomBrowserContext::GetDownloadManagerDelegate() {
content::BrowserPluginGuestManager* AtomBrowserContext::GetGuestManager() {
if (!guest_manager_)
guest_manager_.reset(new WebViewManager(this));
guest_manager_.reset(new WebViewManager);
return guest_manager_.get();
}
net::SSLConfigService* AtomBrowserContext::CreateSSLConfigService() {
return new AtomSSLConfigService;
}
void AtomBrowserContext::RegisterPrefs(PrefRegistrySimple* pref_registry) {
pref_registry->RegisterFilePathPref(prefs::kSelectFileLastDirectory,
base::FilePath());
pref_registry->RegisterFilePathPref(prefs::kDownloadDefaultDirectory,
base::FilePath());
}
} // namespace atom
namespace brightray {
// static
scoped_refptr<BrowserContext> BrowserContext::Create(
const std::string& partition, bool in_memory) {
return make_scoped_refptr(new atom::AtomBrowserContext(partition, in_memory));
}
} // namespace brightray

View File

@@ -17,8 +17,8 @@ class WebViewManager;
class AtomBrowserContext : public brightray::BrowserContext {
public:
AtomBrowserContext();
virtual ~AtomBrowserContext();
AtomBrowserContext(const std::string& partition, bool in_memory);
~AtomBrowserContext() override;
// brightray::URLRequestContextGetter::Delegate:
std::string GetUserAgent() override;
@@ -27,18 +27,23 @@ class AtomBrowserContext : public brightray::BrowserContext {
content::URLRequestInterceptorScopedVector* interceptors) override;
net::HttpCache::BackendFactory* CreateHttpCacheBackendFactory(
const base::FilePath& base_path) override;
net::SSLConfigService* CreateSSLConfigService() override;
// content::BrowserContext:
content::DownloadManagerDelegate* GetDownloadManagerDelegate() override;
content::BrowserPluginGuestManager* GetGuestManager() override;
// brightray::BrowserContext:
void RegisterPrefs(PrefRegistrySimple* pref_registry) override;
AtomURLRequestJobFactory* job_factory() const { return job_factory_; }
private:
scoped_ptr<AtomDownloadManagerDelegate> download_manager_delegate_;
scoped_ptr<WebViewManager> guest_manager_;
AtomURLRequestJobFactory* job_factory_; // Weak reference.
// Managed by brightray::BrowserContext.
AtomURLRequestJobFactory* job_factory_;
DISALLOW_COPY_AND_ASSIGN(AtomBrowserContext);
};

View File

@@ -7,11 +7,15 @@
#include "atom/browser/api/trackable_object.h"
#include "atom/browser/atom_browser_client.h"
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/bridge_task_runner.h"
#include "atom/browser/browser.h"
#include "atom/browser/javascript_environment.h"
#include "atom/browser/node_debugger.h"
#include "atom/common/api/atom_bindings.h"
#include "atom/common/node_bindings.h"
#include "atom/common/node_includes.h"
#include "base/command_line.h"
#include "base/thread_task_runner_handle.h"
#include "chrome/browser/browser_process.h"
#include "v8/include/v8-debug.h"
@@ -19,8 +23,6 @@
#include "chrome/browser/ui/libgtk2ui/gtk2_util.h"
#endif
#include "atom/common/node_includes.h"
namespace atom {
// static
@@ -37,8 +39,6 @@ AtomBrowserMainParts::AtomBrowserMainParts()
}
AtomBrowserMainParts::~AtomBrowserMainParts() {
for (const auto& callback : destruction_callbacks_)
callback.Run();
}
// static
@@ -52,10 +52,6 @@ void AtomBrowserMainParts::RegisterDestructionCallback(
destruction_callbacks_.push_back(callback);
}
brightray::BrowserContext* AtomBrowserMainParts::CreateBrowserContext() {
return new AtomBrowserContext();
}
void AtomBrowserMainParts::PostEarlyInitialization() {
brightray::BrowserMainParts::PostEarlyInitialization();
@@ -63,15 +59,30 @@ void AtomBrowserMainParts::PostEarlyInitialization() {
SetDPIFromGSettings();
#endif
// The ProxyResolverV8 has setup a complete V8 environment, in order to avoid
// conflicts we only initialize our V8 environment after that.
js_env_.reset(new JavascriptEnvironment);
{
// Temporary set the bridge_task_runner_ as current thread's task runner,
// so we can fool gin::PerIsolateData to use it as its task runner, instead
// of getting current message loop's task runner, which is null for now.
bridge_task_runner_ = new BridgeTaskRunner;
base::ThreadTaskRunnerHandle handle(bridge_task_runner_);
// The ProxyResolverV8 has setup a complete V8 environment, in order to
// avoid conflicts we only initialize our V8 environment after that.
js_env_.reset(new JavascriptEnvironment);
}
node_bindings_->Initialize();
// Support the "--debug" switch.
node_debugger_.reset(new NodeDebugger(js_env_->isolate()));
// Create the global environment.
global_env = node_bindings_->CreateEnvironment(js_env_->context());
// Make sure node can get correct environment when debugging.
if (node_debugger_->IsRunning())
global_env->AssignToContext(v8::Debug::GetDebugContext());
// Add atom-shell extended APIs.
atom_bindings_->BindTo(js_env_->isolate(), global_env->process_object());
@@ -105,4 +116,14 @@ void AtomBrowserMainParts::PreMainMessageLoopRun() {
#endif
}
void AtomBrowserMainParts::PostMainMessageLoopRun() {
brightray::BrowserMainParts::PostMainMessageLoopRun();
// Make sure destruction callbacks are called before message loop is
// destroyed, otherwise some objects that need to be deleted on IO thread
// won't be freed.
for (const auto& callback : destruction_callbacks_)
callback.Run();
}
} // namespace atom

View File

@@ -6,10 +6,12 @@
#define ATOM_BROWSER_ATOM_BROWSER_MAIN_PARTS_H_
#include <list>
#include <string>
#include "base/callback.h"
#include "base/timer/timer.h"
#include "brightray/browser/browser_main_parts.h"
#include "content/public/browser/browser_context.h"
class BrowserProcess;
@@ -19,6 +21,8 @@ class AtomBindings;
class Browser;
class JavascriptEnvironment;
class NodeBindings;
class NodeDebugger;
class BridgeTaskRunner;
class AtomBrowserMainParts : public brightray::BrowserMainParts {
public:
@@ -34,12 +38,10 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
Browser* browser() { return browser_.get(); }
protected:
// Implementations of brightray::BrowserMainParts.
brightray::BrowserContext* CreateBrowserContext() override;
// Implementations of content::BrowserMainParts.
// content::BrowserMainParts:
void PostEarlyInitialization() override;
void PreMainMessageLoopRun() override;
void PostMainMessageLoopRun() override;
#if defined(OS_MACOSX)
void PreMainMessageLoopStart() override;
void PostDestroyThreads() override;
@@ -53,10 +55,15 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
// A fake BrowserProcess object that used to feed the source code from chrome.
scoped_ptr<BrowserProcess> fake_browser_process_;
// The gin::PerIsolateData requires a task runner to create, so we feed it
// with a task runner that will post all work to main loop.
scoped_refptr<BridgeTaskRunner> bridge_task_runner_;
scoped_ptr<Browser> browser_;
scoped_ptr<JavascriptEnvironment> js_env_;
scoped_ptr<NodeBindings> node_bindings_;
scoped_ptr<AtomBindings> atom_bindings_;
scoped_ptr<NodeDebugger> node_debugger_;
base::Timer gc_timer_;

View File

@@ -6,10 +6,14 @@
#include <string>
#include "atom/browser/api/atom_api_download_item.h"
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/native_window.h"
#include "atom/browser/ui/file_dialog.h"
#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/prefs/pref_service.h"
#include "chrome/common/pref_names.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/download_manager.h"
@@ -70,13 +74,19 @@ void AtomDownloadManagerDelegate::OnDownloadPathGenerated(
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;
if (file_dialog::ShowSaveDialog(window, item->GetURL().spec(), default_path,
file_dialog::Filters(), &path)) {
// Remember the last selected download directory.
AtomBrowserContext* browser_context = static_cast<AtomBrowserContext*>(
download_manager_->GetBrowserContext());
browser_context->prefs()->SetFilePath(prefs::kDownloadDefaultDirectory,
path.DirName());
}
// Running the DownloadTargetCallback with an empty FilePath signals that the
// download should be cancelled.
// If user cancels the file save dialog, run the callback with empty FilePath.
callback.Run(path,
content::DownloadItem::TARGET_DISPOSITION_PROMPT,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, path);
@@ -92,11 +102,6 @@ bool AtomDownloadManagerDelegate::DetermineDownloadTarget(
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,
@@ -104,6 +109,27 @@ bool AtomDownloadManagerDelegate::DetermineDownloadTarget(
download->GetForcedFilePath());
return true;
}
base::SupportsUserData::Data* save_path = download->GetUserData(
atom::api::DownloadItem::UserDataKey());
if (save_path) {
const base::FilePath& default_download_path =
static_cast<api::DownloadItem::SavePathData*>(save_path)->path();
callback.Run(default_download_path,
content::DownloadItem::TARGET_DISPOSITION_OVERWRITE,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
default_download_path);
return true;
}
AtomBrowserContext* browser_context = static_cast<AtomBrowserContext*>(
download_manager_->GetBrowserContext());
base::FilePath default_download_path = browser_context->prefs()->GetFilePath(
prefs::kDownloadDefaultDirectory);
// If users didn't set download path, use 'Downloads' directory by default.
if (default_download_path.empty()) {
auto path = download_manager_->GetBrowserContext()->GetPath();
default_download_path = path.Append(FILE_PATH_LITERAL("Downloads"));
}
CreateDownloadPathCallback download_path_callback =
base::Bind(&AtomDownloadManagerDelegate::OnDownloadPathGenerated,
@@ -118,7 +144,7 @@ bool AtomDownloadManagerDelegate::DetermineDownloadTarget(
download->GetContentDisposition(),
download->GetSuggestedFilename(),
download->GetMimeType(),
default_download_path_,
default_download_path,
download_path_callback));
return true;
}

View File

@@ -47,7 +47,6 @@ class AtomDownloadManagerDelegate : public content::DownloadManagerDelegate {
private:
content::DownloadManager* download_manager_;
base::FilePath default_download_path_;
base::WeakPtrFactory<AtomDownloadManagerDelegate> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(AtomDownloadManagerDelegate);

View File

@@ -0,0 +1,47 @@
// 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_ssl_config_service.h"
#include <string>
#include "base/command_line.h"
#include "atom/common/options_switches.h"
#include "content/public/browser/browser_thread.h"
#include "net/socket/ssl_client_socket.h"
namespace atom {
namespace {
uint16 GetSSLProtocolVersion(const std::string& version_string) {
uint16 version = 0; // Invalid
if (version_string == "tls1")
version = net::SSL_PROTOCOL_VERSION_TLS1;
else if (version_string == "tls1.1")
version = net::SSL_PROTOCOL_VERSION_TLS1_1;
else if (version_string == "tls1.2")
version = net::SSL_PROTOCOL_VERSION_TLS1_2;
return version;
}
} // namespace
AtomSSLConfigService::AtomSSLConfigService() {
auto cmd_line = base::CommandLine::ForCurrentProcess();
if (cmd_line->HasSwitch(switches::kSSLVersionFallbackMin)) {
auto version_string =
cmd_line->GetSwitchValueASCII(switches::kSSLVersionFallbackMin);
config_.version_fallback_min = GetSSLProtocolVersion(version_string);
}
}
AtomSSLConfigService::~AtomSSLConfigService() {
}
void AtomSSLConfigService::GetSSLConfig(net::SSLConfig* config) {
*config = config_;
}
} // namespace atom

View File

@@ -0,0 +1,28 @@
// 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_SSL_CONFIG_SERVICE_H_
#define ATOM_BROWSER_ATOM_SSL_CONFIG_SERVICE_H_
#include "net/ssl/ssl_config_service.h"
namespace atom {
class AtomSSLConfigService : public net::SSLConfigService {
public:
AtomSSLConfigService();
~AtomSSLConfigService() override;
// net::SSLConfigService:
void GetSSLConfig(net::SSLConfig* config) override;
private:
net::SSLConfig config_;
DISALLOW_COPY_AND_ASSIGN(AtomSSLConfigService);
};
} // namespace atom
#endif // ATOM_BROWSER_ATOM_SSL_CONFIG_SERVICE_H_

View File

@@ -0,0 +1,42 @@
// 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/bridge_task_runner.h"
#include "base/message_loop/message_loop.h"
namespace atom {
bool BridgeTaskRunner::PostDelayedTask(
const tracked_objects::Location& from_here,
const base::Closure& task,
base::TimeDelta delay) {
auto message_loop = base::MessageLoop::current();
if (!message_loop)
return false;
return message_loop->task_runner()->PostDelayedTask(from_here, task, delay);
}
bool BridgeTaskRunner::RunsTasksOnCurrentThread() const {
auto message_loop = base::MessageLoop::current();
if (!message_loop)
return false;
return message_loop->task_runner()->RunsTasksOnCurrentThread();
}
bool BridgeTaskRunner::PostNonNestableDelayedTask(
const tracked_objects::Location& from_here,
const base::Closure& task,
base::TimeDelta delay) {
auto message_loop = base::MessageLoop::current();
if (!message_loop)
return false;
return message_loop->task_runner()->PostNonNestableDelayedTask(
from_here, task, delay);
}
} // namespace atom

View File

@@ -0,0 +1,35 @@
// 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_BRIDGE_TASK_RUNNER_H_
#define ATOM_BROWSER_BRIDGE_TASK_RUNNER_H_
#include "base/single_thread_task_runner.h"
namespace atom {
// Post all tasks to the current message loop's task runner if available,
// otherwise fail silently.
class BridgeTaskRunner : public base::SingleThreadTaskRunner {
public:
BridgeTaskRunner() {}
~BridgeTaskRunner() override {}
// base::SingleThreadTaskRunner:
bool PostDelayedTask(const tracked_objects::Location& from_here,
const base::Closure& task,
base::TimeDelta delay) override;
bool RunsTasksOnCurrentThread() const override;
bool PostNonNestableDelayedTask(
const tracked_objects::Location& from_here,
const base::Closure& task,
base::TimeDelta delay) override;
private:
DISALLOW_COPY_AND_ASSIGN(BridgeTaskRunner);
};
} // namespace atom
#endif // ATOM_BROWSER_BRIDGE_TASK_RUNNER_H_

View File

@@ -45,7 +45,8 @@ void Browser::Shutdown() {
FOR_EACH_OBSERVER(BrowserObserver, observers_, OnQuit());
is_quiting_ = true;
base::MessageLoop::current()->Quit();
base::MessageLoop::current()->PostTask(
FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
}
std::string Browser::GetVersion() const {
@@ -93,8 +94,10 @@ void Browser::OpenURL(const std::string& url) {
FOR_EACH_OBSERVER(BrowserObserver, observers_, OnOpenURL(url));
}
void Browser::ActivateWithNoOpenWindows() {
FOR_EACH_OBSERVER(BrowserObserver, observers_, OnActivateWithNoOpenWindows());
void Browser::Activate(bool has_visible_windows) {
FOR_EACH_OBSERVER(BrowserObserver,
observers_,
OnActivate(has_visible_windows));
}
void Browser::WillFinishLaunching() {

View File

@@ -108,8 +108,9 @@ class Browser : public WindowListObserver {
// Tell the application to open a url.
void OpenURL(const std::string& url);
// Tell the application that application is activated with no open windows.
void ActivateWithNoOpenWindows();
// Tell the application that application is activated with visible/invisible
// windows.
void Activate(bool has_visible_windows);
// Tell the application the loading has been done.
void WillFinishLaunching();
@@ -153,7 +154,7 @@ class Browser : public WindowListObserver {
void OnWindowAllClosed() override;
// Observers of the browser.
ObserverList<BrowserObserver> observers_;
base::ObserverList<BrowserObserver> observers_;
// Whether "ready" event has been emitted.
bool is_ready_;

View File

@@ -43,9 +43,9 @@ class BrowserObserver {
// Browser is used to open a url.
virtual void OnOpenURL(const std::string& url) {}
// The browser is activated with no open windows (usually by clicking on the
// dock icon).
virtual void OnActivateWithNoOpenWindows() {}
// The browser is activated with visible/invisible windows (usually by
// clicking on the dock icon).
virtual void OnActivate(bool has_visible_windows) {}
// The browser has finished loading.
virtual void OnWillFinishLaunching() {}

View File

@@ -274,16 +274,21 @@ void CommonWebContentsDelegate::DevToolsAppendToFile(
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;
void CommonWebContentsDelegate::DevToolsAddFileSystem(
const base::FilePath& file_system_path) {
base::FilePath path = file_system_path;
if (path.empty()) {
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;
path = paths[0];
}
base::FilePath path = paths[0];
std::string registered_name;
std::string file_system_id = RegisterFileSystem(GetDevToolsWebContents(),
path,
@@ -313,20 +318,20 @@ void CommonWebContentsDelegate::DevToolsAddFileSystem() {
}
void CommonWebContentsDelegate::DevToolsRemoveFileSystem(
const std::string& file_system_path) {
const base::FilePath& file_system_path) {
if (!web_contents_)
return;
base::FilePath path = base::FilePath::FromUTF8Unsafe(file_system_path);
storage::IsolatedContext::GetInstance()->RevokeFileSystemByPath(path);
storage::IsolatedContext::GetInstance()->
RevokeFileSystemByPath(file_system_path);
for (auto it = saved_paths_.begin(); it != saved_paths_.end(); ++it)
if (it->second == path) {
if (it->second == file_system_path) {
saved_paths_.erase(it);
break;
}
base::StringValue file_system_path_value(file_system_path);
base::StringValue file_system_path_value(file_system_path.AsUTF8Unsafe());
web_contents_->CallClientFunction(
"DevToolsAPI.fileSystemRemoved",
&file_system_path_value,

View File

@@ -48,6 +48,8 @@ class CommonWebContentsDelegate
NativeWindow* owner_window() const { return owner_window_.get(); }
bool is_html_fullscreen() const { return html_fullscreen_; }
protected:
// content::WebContentsDelegate:
content::WebContents* OpenURLFromTab(
@@ -80,8 +82,9 @@ class CommonWebContentsDelegate
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;
void DevToolsAddFileSystem(const base::FilePath& path) override;
void DevToolsRemoveFileSystem(
const base::FilePath& file_system_path) override;
private:
// Callback for when DevToolsSaveToFile has completed.

View File

@@ -36,238 +36,176 @@ app.once('ready', function() {
if (Menu.getApplicationMenu())
return;
var template;
var template = [
{
label: 'Edit',
submenu: [
{
label: 'Undo',
accelerator: 'CmdOrCtrl+Z',
role: 'undo'
},
{
label: 'Redo',
accelerator: 'Shift+CmdOrCtrl+Z',
role: 'redo'
},
{
type: 'separator'
},
{
label: 'Cut',
accelerator: 'CmdOrCtrl+X',
role: 'cut'
},
{
label: 'Copy',
accelerator: 'CmdOrCtrl+C',
role: 'copy'
},
{
label: 'Paste',
accelerator: 'CmdOrCtrl+V',
role: 'paste'
},
{
label: 'Select All',
accelerator: 'CmdOrCtrl+A',
role: 'selectall'
},
]
},
{
label: 'View',
submenu: [
{
label: 'Reload',
accelerator: 'CmdOrCtrl+R',
click: function(item, focusedWindow) {
if (focusedWindow)
focusedWindow.reload();
}
},
{
label: 'Toggle Full Screen',
accelerator: (function() {
if (process.platform == 'darwin')
return 'Ctrl+Command+F';
else
return 'F11';
})(),
click: function(item, focusedWindow) {
if (focusedWindow)
focusedWindow.setFullScreen(!focusedWindow.isFullScreen());
}
},
{
label: 'Toggle Developer Tools',
accelerator: (function() {
if (process.platform == 'darwin')
return 'Alt+Command+I';
else
return 'Ctrl+Shift+I';
})(),
click: function(item, focusedWindow) {
if (focusedWindow)
focusedWindow.toggleDevTools();
}
},
]
},
{
label: 'Window',
role: 'window',
submenu: [
{
label: 'Minimize',
accelerator: 'CmdOrCtrl+M',
role: 'minimize'
},
{
label: 'Close',
accelerator: 'CmdOrCtrl+W',
role: 'close'
},
]
},
{
label: 'Help',
role: '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') }
}
]
},
];
if (process.platform == 'darwin') {
template = [
template.unshift({
label: 'Electron',
submenu: [
{
label: 'About Electron',
role: 'about'
},
{
type: 'separator'
},
{
label: 'Services',
role: 'services',
submenu: []
},
{
type: 'separator'
},
{
label: 'Hide Electron',
accelerator: 'Command+H',
role: 'hide'
},
{
label: 'Hide Others',
accelerator: 'Command+Shift+H',
role: 'hideothers:'
},
{
label: 'Show All',
role: 'unhide:'
},
{
type: 'separator'
},
{
label: 'Quit',
accelerator: 'Command+Q',
click: function() { app.quit(); }
},
]
});
template[3].submenu.push(
{
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(); }
},
]
type: 'separator'
},
{
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') }
}
]
label: 'Bring All to Front',
role: 'front'
}
];
} 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: 'Shift+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);

View File

@@ -5,6 +5,7 @@
#include "atom/browser/javascript_environment.h"
#include "gin/array_buffer.h"
#include "gin/v8_initializer.h"
namespace atom {
@@ -19,7 +20,7 @@ JavascriptEnvironment::JavascriptEnvironment()
}
bool JavascriptEnvironment::Initialize() {
gin::IsolateHolder::LoadV8Snapshot();
gin::V8Initializer::LoadV8Snapshot();
gin::IsolateHolder::Initialize(gin::IsolateHolder::kNonStrictMode,
gin::ArrayBufferAllocator::SharedInstance());
return true;

View File

@@ -32,6 +32,7 @@ getExtensionInfoFromPath = (srcDirectory) ->
startPage: page
name: manifest.name
srcDirectory: srcDirectory
exposeExperimentalAPIs: true
extensionInfoMap[manifest.name]
# The loaded extensions cache and its persistent path.
@@ -64,14 +65,16 @@ app.once 'ready', ->
catch e
# The chrome-extension: can map a extension URL request to real file path.
protocol.registerProtocol 'chrome-extension', (request) ->
chromeExtensionHandler = (request, callback) ->
parsed = url.parse request.url
return unless parsed.hostname and parsed.path?
return unless /extension-\d+/.test parsed.hostname
return callback() unless parsed.hostname and parsed.path?
return callback() unless /extension-\d+/.test parsed.hostname
directory = getPathForHost parsed.hostname
return unless directory?
return new protocol.RequestFileJob(path.join(directory, parsed.path))
return callback() unless directory?
callback path.join(directory, parsed.path)
protocol.registerFileProtocol 'chrome-extension', chromeExtensionHandler, (error) ->
console.error 'Unable to register chrome-extension protocol' if error
BrowserWindow::_loadDevToolsExtensions = (extensionInfoArray) ->
@devToolsWebContents?.executeJavaScript "DevToolsAPI.addExtensions(#{JSON.stringify(extensionInfoArray)});"

View File

@@ -3,6 +3,7 @@ webContents = require 'web-contents'
webViewManager = null # Doesn't exist in early initialization.
supportedWebViewEvents = [
'load-commit'
'did-finish-load'
'did-fail-load'
'did-frame-finish-load'
@@ -29,6 +30,10 @@ guestInstances = {}
embedderElementsMap = {}
reverseEmbedderElementsMap = {}
# Moves the last element of array to the first one.
moveLastToFirst = (list) ->
list.unshift list.pop()
# Generate guestInstanceId.
getNextInstanceId = (webContents) ->
++nextInstanceId
@@ -38,14 +43,20 @@ createGuest = (embedder, params) ->
webViewManager ?= process.atomBinding 'web_view_manager'
id = getNextInstanceId embedder
guest = webContents.create {isGuest: true, embedder}
guest = webContents.create {isGuest: true, partition: params.partition, embedder}
guestInstances[id] = {guest, embedder}
# Destroy guest when the embedder is gone or navigated.
destroyEvents = ['destroyed', 'crashed', 'did-navigate-to-different-page']
destroy = ->
destroyGuest embedder, id if guestInstances[id]?
embedder.once event, destroy for event in destroyEvents
for event in destroyEvents
embedder.once event, destroy
# Users might also listen to the crashed event, so We must ensure the guest
# is destroyed before users' listener gets called. It is done by moving our
# listener to the first one in queue.
listeners = embedder._events[event]
moveLastToFirst listeners if Array.isArray listeners
guest.once 'destroyed', ->
embedder.removeListener event, destroy for event in destroyEvents
@@ -73,6 +84,8 @@ createGuest = (embedder, params) ->
if params.allowtransparency?
@setAllowTransparency params.allowtransparency
guest.allowPopups = params.allowpopups
# Dispatch events to embedder.
for event in supportedWebViewEvents
do (event) ->
@@ -104,11 +117,13 @@ attachGuest = (embedder, elementInstanceId, guestInstanceId, params) ->
return unless guestInstances[oldGuestInstanceId]?
destroyGuest embedder, oldGuestInstanceId
webViewManager.addGuest guestInstanceId, elementInstanceId, embedder, guest,
nodeIntegration: params.nodeintegration
plugins: params.plugins
disableWebSecurity: params.disablewebsecurity
preloadUrl: params.preload ? ''
webPreferences =
'guest-instance-id': guestInstanceId
'node-integration': params.nodeintegration ? false
'plugins': params.plugins
'web-security': !params.disablewebsecurity
webPreferences['preload-url'] = params.preload if params.preload
webViewManager.addGuest guestInstanceId, elementInstanceId, embedder, guest, webPreferences
guest.attachParams = params
embedderElementsMap[key] = guestInstanceId

View File

@@ -4,6 +4,17 @@ BrowserWindow = require 'browser-window'
frameToGuest = {}
# Merge |options| with the |embedder|'s window's options.
mergeBrowserWindowOptions = (embedder, options) ->
if embedder.browserWindowOptions?
# Inherit the original options if it is a BrowserWindow.
options.__proto__ = embedder.browserWindowOptions
else
# Or only inherit web-preferences if it is a webview.
options['web-preferences'] ?= {}
options['web-preferences'].__proto__ = embedder.getWebPreferences()
options
# Create a new guest created by |embedder| with |options|.
createGuest = (embedder, url, frameName, options) ->
guest = frameToGuest[frameName]
@@ -40,11 +51,12 @@ 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, 'new-window'
if event.sender.isGuest() or event.defaultPrevented
options = mergeBrowserWindowOptions event.sender, options
event.sender.emit 'new-window', event, url, frameName, 'new-window', options
if (event.sender.isGuest() and not event.sender.allowPopups) or event.defaultPrevented
event.returnValue = null
else
event.returnValue = createGuest event.sender, args...
event.returnValue = createGuest event.sender, url, frameName, options
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_CLOSE', (event, guestId) ->
BrowserWindow.fromId(guestId)?.destroy()
@@ -57,10 +69,19 @@ ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', (event, guestId, me
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) ->
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPENER_POSTMESSAGE', (event, guestId, message, targetOrigin, sourceOrigin) ->
embedder = v8Util.getHiddenValue event.sender, 'embedder'
if embedder?.getUrl().indexOf(targetOrigin) is 0 or targetOrigin is '*'
embedder.send 'ATOM_SHELL_GUEST_WINDOW_POSTMESSAGE', message, targetOrigin
embedder.send 'ATOM_SHELL_GUEST_WINDOW_POSTMESSAGE', guestId, message, sourceOrigin
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', (event, guestId, method, args...) ->
BrowserWindow.fromId(guestId)?.webContents?[method] args...
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_GET_GUEST_ID', (event) ->
embedder = v8Util.getHiddenValue event.sender, 'embedder'
if embedder?
guest = BrowserWindow.fromWebContents event.sender
if guest?
event.returnValue = guest.id
return
event.returnValue = null

View File

@@ -38,7 +38,7 @@ process.on 'uncaughtException', (error) ->
# Show error in GUI.
stack = error.stack ? "#{error.name}: #{error.message}"
message = "Uncaught Exception:\n#{stack}"
require('dialog').showErrorBox 'A JavaScript error occured in the browser process', message
require('dialog').showErrorBox 'A JavaScript error occurred in the main process', message
# Emit 'exit' event on quit.
app = require 'app'
@@ -92,5 +92,8 @@ app.setAppPath packagePath
# Load the chrome extension support.
require './chrome-extension'
# Set main startup script of the app.
mainStartupScript = packageJson.main or 'index.js'
# 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, mainStartupScript), Module, true

View File

@@ -1,82 +1,65 @@
EventEmitter = require('events').EventEmitter
IDWeakMap = process.atomBinding('id_weak_map').IDWeakMap
v8Util = process.atomBinding 'v8_util'
# Class to reference all objects.
class ObjectsStore
@stores = {}
constructor: ->
@nextId = 0
@objects = []
getNextId: ->
++@nextId
add: (obj) ->
id = @getNextId()
@objects[id] = obj
id
has: (id) ->
@objects[id]?
remove: (id) ->
throw new Error("Invalid key #{id} for ObjectsStore") unless @has id
delete @objects[id]
get: (id) ->
throw new Error("Invalid key #{id} for ObjectsStore") unless @has id
@objects[id]
@forRenderView: (key) ->
@stores[key] = new ObjectsStore unless @stores[key]?
@stores[key]
@releaseForRenderView: (key) ->
delete @stores[key]
class ObjectsRegistry extends EventEmitter
constructor: ->
@setMaxListeners Number.MAX_VALUE
@nextId = 0
# Objects in weak map will be not referenced (so we won't leak memory), and
# every object created in browser will have a unique id in weak map.
@objectsWeakMap = new IDWeakMap
@objectsWeakMap.add = (obj) ->
id = IDWeakMap::add.call this, obj
v8Util.setHiddenValue obj, 'atomId', id
id
# Stores all objects by ref-counting.
# (id) => {object, count}
@storage = {}
# Stores the IDs of objects referenced by WebContents.
# (webContentsId) => {(id) => (count)}
@owners = {}
# Register a new object, the object would be kept referenced until you release
# it explicitly.
add: (key, obj) ->
# Some native objects may already been added to objectsWeakMap, be care not
# to add it twice.
@objectsWeakMap.add obj unless v8Util.getHiddenValue obj, 'atomId'
id = v8Util.getHiddenValue obj, 'atomId'
add: (webContentsId, obj) ->
id = @saveToStorage obj
# Remember the owner.
@owners[webContentsId] ?= {}
@owners[webContentsId][id] ?= 0
@owners[webContentsId][id]++
# Returns object's id
id
# Store and reference the object, then return the storeId which points to
# where the object is stored. The caller can later dereference the object
# with the storeId.
# We use a difference key because the same object can be referenced for
# multiple times by the same renderer view.
store = ObjectsStore.forRenderView key
storeId = store.add obj
[id, storeId]
# Get an object according to its id.
# Get an object according to its ID.
get: (id) ->
@objectsWeakMap.get id
@storage[id]?.object
# Remove an object according to its storeId.
remove: (key, storeId) ->
ObjectsStore.forRenderView(key).remove storeId
# Dereference an object according to its ID.
remove: (webContentsId, id) ->
@dereference id, 1
# Also reduce the count in owner.
pointer = @owners[webContentsId]
--pointer[id]
delete pointer[id] if pointer[id] is 0
# Clear all references to objects from renderer view.
clear: (key) ->
@emit "clear-#{key}"
ObjectsStore.releaseForRenderView key
# Clear all references to objects refrenced by the WebContents.
clear: (webContentsId) ->
@emit "clear-#{webContentsId}"
return unless @owners[webContentsId]?
@dereference id, count for id, count of @owners[webContentsId]
delete @owners[webContentsId]
# Private: Saves the object into storage and assigns an ID for it.
saveToStorage: (object) ->
id = v8Util.getHiddenValue object, 'atomId'
unless id
id = ++@nextId
@storage[id] = {count: 0, object}
v8Util.setHiddenValue object, 'atomId', id
++@storage[id].count
id
# Private: Dereference the object from store.
dereference: (id, count) ->
pointer = @storage[id]
pointer.count -= count
if pointer.count is 0
v8Util.deleteHiddenValue pointer.object, 'atomId'
delete @storage[id]
module.exports = new ObjectsRegistry

View File

@@ -4,12 +4,17 @@ objectsRegistry = require './objects-registry.js'
v8Util = process.atomBinding 'v8_util'
# Convert a real value into meta data.
valueToMeta = (sender, value) ->
valueToMeta = (sender, value, optimizeSimpleObject=false) ->
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
meta.type = 'promise' if value? and value.constructor.name is 'Promise'
# Treat simple objects as value.
if optimizeSimpleObject and meta.type is 'object' and v8Util.getHiddenValue value, 'simple'
meta.type = 'value'
# Treat the arguments object as array.
meta.type = 'array' if meta.type is 'object' and value.callee? and value.length?
@@ -23,12 +28,14 @@ valueToMeta = (sender, value) ->
# Reference the original value if it's an object, because when it's
# passed to renderer we would assume the renderer keeps a reference of
# it.
[meta.id, meta.storeId] = objectsRegistry.add sender.getId(), value
meta.id = objectsRegistry.add sender.getId(), 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 if meta.type is 'promise'
meta.then = valueToMeta(sender, value.then.bind(value))
else
meta.type = 'value'
meta.value = value
@@ -47,6 +54,7 @@ unwrapArgs = (sender, args) ->
when 'remote-object' then objectsRegistry.get meta.id
when 'array' then unwrapArgs sender, meta.value
when 'buffer' then new Buffer(meta.value)
when 'promise' then Promise.resolve(then: metaToValue(meta.then))
when 'object'
ret = v8Util.createObjectWithName meta.name
for member in meta.members
@@ -76,11 +84,11 @@ unwrapArgs = (sender, args) ->
callFunction = (event, func, caller, args) ->
if v8Util.getHiddenValue(func, 'asynchronous') and typeof args[args.length - 1] isnt 'function'
args.push (ret) ->
event.returnValue = valueToMeta event.sender, ret
event.returnValue = valueToMeta event.sender, ret, true
func.apply caller, args
else
ret = func.apply caller, args
event.returnValue = valueToMeta event.sender, ret
event.returnValue = valueToMeta event.sender, ret, true
# Send by BrowserWindow when its render view is deleted.
process.on 'ATOM_BROWSER_RELEASE_RENDER_VIEW', (id) ->
@@ -166,8 +174,8 @@ ipc.on 'ATOM_BROWSER_MEMBER_GET', (event, id, name) ->
catch e
event.returnValue = errorToMeta e
ipc.on 'ATOM_BROWSER_DEREFERENCE', (event, storeId) ->
objectsRegistry.remove event.sender.getId(), storeId
ipc.on 'ATOM_BROWSER_DEREFERENCE', (event, id) ->
objectsRegistry.remove event.sender.getId(), id
ipc.on 'ATOM_BROWSER_GUEST_WEB_CONTENTS', (event, guestInstanceId) ->
try

View File

@@ -52,12 +52,8 @@
- (BOOL)applicationShouldHandleReopen:(NSApplication*)theApplication
hasVisibleWindows:(BOOL)flag {
atom::Browser* browser = atom::Browser::Get();
if (flag) {
return YES;
} else {
browser->ActivateWithNoOpenWindows();
return NO;
}
browser->Activate(static_cast<bool>(flag));
return flag;
}
@end

View File

@@ -8,10 +8,6 @@
#include <utility>
#include <vector>
#if defined(OS_WIN)
#include <shlobj.h>
#endif
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/window_list.h"
@@ -19,12 +15,10 @@
#include "atom/common/native_mate_converters/image_converter.h"
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "atom/common/options_switches.h"
#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/json/json_writer.h"
#include "base/prefs/pref_service.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "brightray/browser/inspectable_web_contents.h"
#include "brightray/browser/inspectable_web_contents_view.h"
@@ -35,8 +29,6 @@
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/renderer_preferences.h"
#include "content/public/common/web_preferences.h"
#include "ipc/ipc_message_macros.h"
#include "native_mate/dictionary.h"
#include "ui/gfx/codec/png_codec.h"
@@ -47,30 +39,27 @@
#include "ui/gfx/screen.h"
#include "ui/gl/gpu_switching_manager.h"
#if defined(OS_WIN)
#include "ui/gfx/switches.h"
#endif
using content::NavigationEntry;
using content::RenderWidgetHostView;
using content::RenderWidgetHost;
DEFINE_WEB_CONTENTS_USER_DATA_KEY(atom::NativeWindowRelay);
namespace atom {
namespace {
// Array of available web runtime features.
const char* kWebRuntimeFeatures[] = {
switches::kExperimentalFeatures,
switches::kExperimentalCanvasFeatures,
switches::kSubpixelFontScaling,
switches::kOverlayScrollbars,
switches::kOverlayFullscreenVideo,
switches::kSharedWorker,
switches::kPageVisibility,
};
// Convert draggable regions in raw format to SkRegion format. Caller is
// responsible for deleting the returned SkRegion instance.
scoped_ptr<SkRegion> DraggableRegionsToSkRegion(
const std::vector<DraggableRegion>& regions) {
scoped_ptr<SkRegion> sk_region(new SkRegion);
for (const DraggableRegion& region : regions) {
sk_region->op(
region.bounds.x(),
region.bounds.y(),
region.bounds.right(),
region.bounds.bottom(),
region.draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op);
}
return sk_region.Pass();
}
} // namespace
@@ -79,12 +68,12 @@ NativeWindow::NativeWindow(
const mate::Dictionary& options)
: content::WebContentsObserver(inspectable_web_contents->GetWebContents()),
has_frame_(true),
force_using_draggable_region_(false),
transparent_(false),
enable_larger_than_screen_(false),
is_closed_(false),
node_integration_(true),
has_dialog_attached_(false),
zoom_factor_(1.0),
aspect_ratio_(0.0),
inspectable_web_contents_(inspectable_web_contents),
weak_factory_(this) {
inspectable_web_contents->GetView()->SetDelegate(this);
@@ -92,7 +81,6 @@ NativeWindow::NativeWindow(
options.Get(switches::kFrame, &has_frame_);
options.Get(switches::kTransparent, &transparent_);
options.Get(switches::kEnableLargerThanScreen, &enable_larger_than_screen_);
options.Get(switches::kNodeIntegration, &node_integration_);
// Tell the content module to initialize renderer widget with transparent
// mode.
@@ -101,25 +89,6 @@ NativeWindow::NativeWindow(
// Read icon before window is created.
options.Get(switches::kIcon, &icon_);
// The "preload" option must be absolute path.
if (options.Get(switches::kPreloadScript, &preload_script_) &&
!preload_script_.IsAbsolute()) {
LOG(ERROR) << "Path of \"preload\" script must be absolute.";
preload_script_.clear();
}
// Be compatible with old API of "node-integration" option.
std::string old_string_token;
if (options.Get(switches::kNodeIntegration, &old_string_token) &&
old_string_token != "disable")
node_integration_ = true;
// Read the web preferences.
options.Get(switches::kWebPreferences, &web_preferences_);
// Read the zoom factor before any navigation.
options.Get(switches::kZoomFactor, &zoom_factor_);
WindowList::AddWindow(this);
}
@@ -191,8 +160,13 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) {
// Then show it.
bool show = true;
options.Get(switches::kShow, &show);
if (show)
if (show) {
Show();
} else {
// When RenderView is created it sets to visible, this is to prevent
// breaking the visibility API.
web_contents()->WasHidden();
}
}
void NativeWindow::SetSize(const gfx::Size& size) {
@@ -228,24 +202,6 @@ bool NativeWindow::IsDocumentEdited() {
void NativeWindow::SetMenu(ui::MenuModel* menu) {
}
void NativeWindow::ShowDefinitionForSelection() {
NOTIMPLEMENTED();
}
void NativeWindow::SetAutoHideMenuBar(bool auto_hide) {
}
bool NativeWindow::IsMenuBarAutoHide() {
return false;
}
void NativeWindow::SetMenuBarVisibility(bool visible) {
}
bool NativeWindow::IsMenuBarVisible() {
return true;
}
bool NativeWindow::HasModalDialog() {
return has_dialog_attached_;
}
@@ -263,6 +219,10 @@ bool NativeWindow::IsWebViewFocused() {
return host_view && host_view->HasFocus();
}
bool NativeWindow::IsDevToolsFocused() {
return inspectable_web_contents_->GetView()->IsDevToolsViewFocused();
}
void NativeWindow::CapturePage(const gfx::Rect& rect,
const CapturePageCallback& callback) {
const auto view = web_contents()->GetRenderWidgetHostView();
@@ -296,6 +256,38 @@ void NativeWindow::CapturePage(const gfx::Rect& rect,
kBGRA_8888_SkColorType);
}
void NativeWindow::ShowDefinitionForSelection() {
NOTIMPLEMENTED();
}
void NativeWindow::SetAutoHideMenuBar(bool auto_hide) {
}
bool NativeWindow::IsMenuBarAutoHide() {
return false;
}
void NativeWindow::SetMenuBarVisibility(bool visible) {
}
bool NativeWindow::IsMenuBarVisible() {
return true;
}
double NativeWindow::GetAspectRatio() {
return aspect_ratio_;
}
gfx::Size NativeWindow::GetAspectRatioExtraSize() {
return aspect_ratio_extraSize_;
}
void NativeWindow::SetAspectRatio(double aspect_ratio,
const gfx::Size& extra_size) {
aspect_ratio_ = aspect_ratio;
aspect_ratio_extraSize_ = extra_size;
}
void NativeWindow::RequestToClosePage() {
bool prevent_default = false;
FOR_EACH_OBSERVER(NativeWindowObserver,
@@ -354,86 +346,6 @@ void NativeWindow::RendererResponsive(content::WebContents* source) {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnRendererResponsive());
}
void NativeWindow::AppendExtraCommandLineSwitches(
base::CommandLine* command_line) {
// Append --node-integration to renderer process.
command_line->AppendSwitchASCII(switches::kNodeIntegration,
node_integration_ ? "true" : "false");
// Append --preload.
if (!preload_script_.empty())
command_line->AppendSwitchPath(switches::kPreloadScript, preload_script_);
// Append --zoom-factor.
if (zoom_factor_ != 1.0)
command_line->AppendSwitchASCII(switches::kZoomFactor,
base::DoubleToString(zoom_factor_));
#if defined(OS_WIN)
// Append --app-user-model-id.
PWSTR current_app_id;
if (SUCCEEDED(GetCurrentProcessExplicitAppUserModelID(&current_app_id))) {
command_line->AppendSwitchNative(switches::kAppUserModelId, current_app_id);
CoTaskMemFree(current_app_id);
}
#endif
if (web_preferences_.IsEmpty())
return;
bool b;
#if defined(OS_WIN)
// Check if DirectWrite is disabled.
if (web_preferences_.Get(switches::kDirectWrite, &b) && !b)
command_line->AppendSwitch(::switches::kDisableDirectWrite);
#endif
// Check if plugins are enabled.
if (web_preferences_.Get("plugins", &b) && b)
command_line->AppendSwitch(switches::kEnablePlugins);
// This set of options are not availabe in WebPreferences, so we have to pass
// them via command line and enable them in renderer procss.
for (size_t i = 0; i < arraysize(kWebRuntimeFeatures); ++i) {
const char* feature = kWebRuntimeFeatures[i];
if (web_preferences_.Get(feature, &b))
command_line->AppendSwitchASCII(feature, b ? "true" : "false");
}
}
void NativeWindow::OverrideWebkitPrefs(content::WebPreferences* prefs) {
if (web_preferences_.IsEmpty())
return;
bool b;
std::vector<base::FilePath> list;
if (web_preferences_.Get("javascript", &b))
prefs->javascript_enabled = b;
if (web_preferences_.Get("images", &b))
prefs->images_enabled = b;
if (web_preferences_.Get("java", &b))
prefs->java_enabled = b;
if (web_preferences_.Get("text-areas-are-resizable", &b))
prefs->text_areas_are_resizable = b;
if (web_preferences_.Get("webgl", &b))
prefs->experimental_webgl_enabled = b;
if (web_preferences_.Get("webaudio", &b))
prefs->webaudio_enabled = b;
if (web_preferences_.Get("web-security", &b)) {
prefs->web_security_enabled = b;
prefs->allow_displaying_insecure_content = !b;
prefs->allow_running_insecure_content = !b;
}
if (web_preferences_.Get("extra-plugin-dirs", &list)) {
if (content::PluginService::GetInstance()->NPAPIPluginsSupported()) {
for (size_t i = 0; i < list.size(); ++i)
content::PluginService::GetInstance()->AddExtraPluginDir(list[i]);
} else {
LOG(WARNING) << "NPAPI plugins not supported on this platform";
}
}
}
void NativeWindow::NotifyWindowClosed() {
if (is_closed_)
return;
@@ -500,6 +412,12 @@ void NativeWindow::NotifyWindowLeaveHtmlFullScreen() {
OnWindowLeaveHtmlFullScreen());
}
void NativeWindow::NotifyWindowExecuteWindowsCommand(
const std::string& command) {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_,
OnExecuteWindowsCommand(command));
}
void NativeWindow::DevToolsFocused() {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnDevToolsFocus());
}
@@ -534,7 +452,7 @@ void NativeWindow::BeforeUnloadDialogCancelled() {
void NativeWindow::TitleWasSet(content::NavigationEntry* entry,
bool explicit_set) {
bool prevent_default = false;
std::string text = base::UTF16ToUTF8(entry->GetTitle());
std::string text = entry ? base::UTF16ToUTF8(entry->GetTitle()) : "";
FOR_EACH_OBSERVER(NativeWindowObserver,
observers_,
OnPageTitleUpdated(&prevent_default, text));
@@ -553,6 +471,14 @@ bool NativeWindow::OnMessageReceived(const IPC::Message& message) {
return handled;
}
void NativeWindow::UpdateDraggableRegions(
const std::vector<DraggableRegion>& regions) {
// Draggable region is not supported for non-frameless window.
if (has_frame_ && !force_using_draggable_region_)
return;
draggable_region_ = DraggableRegionsToSkRegion(regions);
}
void NativeWindow::ScheduleUnresponsiveEvent(int ms) {
if (!window_unresposive_closure_.IsCancelled())
return;

View File

@@ -19,13 +19,10 @@
#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;
}
class SkRegion;
namespace brightray {
class InspectableWebContents;
@@ -33,7 +30,6 @@ class InspectableWebContents;
namespace content {
struct NativeWebKeyboardEvent;
struct WebPreferences;
}
namespace gfx {
@@ -57,7 +53,7 @@ struct DraggableRegion;
class NativeWindow : public content::WebContentsObserver,
public brightray::InspectableWebContentsViewDelegate {
public:
typedef base::Callback<void(const SkBitmap& bitmap)> CapturePageCallback;
using CapturePageCallback = base::Callback<void(const SkBitmap& bitmap)>;
class DialogScope {
public:
@@ -93,6 +89,7 @@ class NativeWindow : public content::WebContentsObserver,
virtual void Close() = 0;
virtual void CloseImmediately() = 0;
virtual bool IsClosed() const { return is_closed_; }
virtual void Focus(bool focus) = 0;
virtual bool IsFocused() = 0;
virtual void Show() = 0;
@@ -137,17 +134,21 @@ class NativeWindow : public content::WebContentsObserver,
virtual void SetMenu(ui::MenuModel* menu);
virtual bool HasModalDialog();
virtual gfx::NativeWindow GetNativeWindow() = 0;
// Taskbar/Dock APIs.
virtual void SetProgressBar(double progress) = 0;
virtual void SetOverlayIcon(const gfx::Image& overlay,
const std::string& description) = 0;
// Workspace APIs.
virtual void SetVisibleOnAllWorkspaces(bool visible) = 0;
virtual bool IsVisibleOnAllWorkspaces() = 0;
virtual bool IsClosed() const { return is_closed_; }
// Webview APIs.
virtual void FocusOnWebView();
virtual void BlurWebView();
virtual bool IsWebViewFocused();
virtual bool IsDevToolsFocused();
// Captures the page with |rect|, |callback| would be called when capturing is
// done.
@@ -163,6 +164,11 @@ class NativeWindow : public content::WebContentsObserver,
virtual void SetMenuBarVisibility(bool visible);
virtual bool IsMenuBarVisible();
// Set the aspect ratio when resizing window.
double GetAspectRatio();
gfx::Size GetAspectRatioExtraSize();
void SetAspectRatio(double aspect_ratio, const gfx::Size& extra_size);
base::WeakPtr<NativeWindow> GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
@@ -178,10 +184,6 @@ class NativeWindow : public content::WebContentsObserver,
content::WebContents*,
const content::NativeWebKeyboardEvent& event) {}
// Called when renderer process is going to be started.
void AppendExtraCommandLineSwitches(base::CommandLine* command_line);
void OverrideWebkitPrefs(content::WebPreferences* prefs);
// Public API used by platform-dependent delegates and observers to send UI
// related notifications.
void NotifyWindowClosed();
@@ -198,11 +200,11 @@ class NativeWindow : public content::WebContentsObserver,
void NotifyWindowLeaveFullScreen();
void NotifyWindowEnterHtmlFullScreen();
void NotifyWindowLeaveHtmlFullScreen();
void NotifyWindowExecuteWindowsCommand(const std::string& command);
void AddObserver(NativeWindowObserver* obs) {
observers_.AddObserver(obs);
}
void RemoveObserver(NativeWindowObserver* obs) {
observers_.RemoveObserver(obs);
}
@@ -212,6 +214,17 @@ class NativeWindow : public content::WebContentsObserver,
}
bool has_frame() const { return has_frame_; }
bool transparent() const { return transparent_; }
SkRegion* draggable_region() const { return draggable_region_.get(); }
bool enable_larger_than_screen() const { return enable_larger_than_screen_; }
gfx::ImageSkia icon() const { return icon_; }
bool force_using_draggable_region() const {
return force_using_draggable_region_;
}
void set_force_using_draggable_region(bool force) {
force_using_draggable_region_ = true;
}
void set_has_dialog_attached(bool has_dialog_attached) {
has_dialog_attached_ = has_dialog_attached;
@@ -221,10 +234,6 @@ class NativeWindow : public content::WebContentsObserver,
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;
// brightray::InspectableWebContentsViewDelegate:
void DevToolsFocused() override;
void DevToolsOpened() override;
@@ -236,22 +245,11 @@ class NativeWindow : public content::WebContentsObserver,
void TitleWasSet(content::NavigationEntry* entry, bool explicit_set) override;
bool OnMessageReceived(const IPC::Message& message) override;
// Whether window has standard frame.
bool has_frame_;
// Whether window is transparent.
bool transparent_;
// Whether window can be resized larger than screen.
bool enable_larger_than_screen_;
// Window icon.
gfx::ImageSkia icon_;
// Observers of this window.
ObserverList<NativeWindowObserver> observers_;
private:
// Called when the window needs to update its draggable region.
void UpdateDraggableRegions(
const std::vector<DraggableRegion>& regions);
// Schedule a notification unresponsive event.
void ScheduleUnresponsiveEvent(int ms);
@@ -263,12 +261,28 @@ class NativeWindow : public content::WebContentsObserver,
const SkBitmap& bitmap,
content::ReadbackResponse response);
// Whether window has standard frame.
bool has_frame_;
// Force the window to be aware of draggable regions.
bool force_using_draggable_region_;
// Whether window is transparent.
bool transparent_;
// For custom drag, the whole window is non-draggable and the draggable region
// has to been explicitly provided.
scoped_ptr<SkRegion> draggable_region_; // used in custom drag.
// Whether window can be resized larger than screen.
bool enable_larger_than_screen_;
// Window icon.
gfx::ImageSkia icon_;
// The windows has been closed.
bool is_closed_;
// Whether node integration is enabled.
bool node_integration_;
// There is a dialog that has been attached to window.
bool has_dialog_attached_;
@@ -276,24 +290,22 @@ class NativeWindow : public content::WebContentsObserver,
// it should be cancelled when we can prove that the window is responsive.
base::CancelableClosure window_unresposive_closure_;
// Web preferences.
mate::PersistentDictionary web_preferences_;
// The script to load before page's JavaScript starts to run.
base::FilePath preload_script_;
// Page's default zoom factor.
double zoom_factor_;
// Used to maintain the aspect ratio of a view which is inside of the
// content view.
double aspect_ratio_;
gfx::Size aspect_ratio_extraSize_;
// The page this window is viewing.
brightray::InspectableWebContents* inspectable_web_contents_;
// Observers of this window.
base::ObserverList<NativeWindowObserver> observers_;
base::WeakPtrFactory<NativeWindow> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(NativeWindow);
};
// This class provides a hook to get a NativeWindow from a WebContents.
class NativeWindowRelay :
public content::WebContentsUserData<NativeWindowRelay> {

View File

@@ -11,13 +11,11 @@
#include <vector>
#include "base/mac/scoped_nsobject.h"
#include "base/memory/scoped_ptr.h"
#include "atom/browser/native_window.h"
@class AtomNSWindow;
@class AtomNSWindowDelegate;
@class FullSizeContentView;
class SkRegion;
namespace atom {
@@ -84,13 +82,7 @@ class NativeWindowMac : public NativeWindow {
// Called to handle a mouse event.
void HandleMouseEvent(NSEvent* event);
// Clip web view to rounded corner.
void ClipWebView();
protected:
void UpdateDraggableRegions(
const std::vector<DraggableRegion>& regions) override;
// NativeWindow:
void HandleKeyboardEvent(
content::WebContents*,
@@ -117,10 +109,6 @@ class NativeWindowMac : public NativeWindow {
// The presentation options before entering kiosk mode.
NSApplicationPresentationOptions kiosk_options_;
// For custom drag, the whole window is non-draggable and the draggable region
// has to been explicitly provided.
scoped_ptr<SkRegion> draggable_region_; // used in custom drag.
// Mouse location since the last mouse event, in screen coordinates. This is
// used in custom drag to compute the window movement.
NSPoint last_mouse_offset_;

View File

@@ -20,11 +20,23 @@
#include "content/public/browser/render_widget_host_view.h"
#include "native_mate/dictionary.h"
static const CGFloat kAtomWindowCornerRadius = 4.0;
namespace {
@interface NSView (PrivateMethods)
- (CGFloat)roundedCornerRadius;
@end
// Prevents window from resizing during the scope.
class ScopedDisableResize {
public:
ScopedDisableResize() { disable_resize_ = true; }
~ScopedDisableResize() { disable_resize_ = false; }
static bool IsResizeDisabled() { return disable_resize_; }
private:
static bool disable_resize_;
};
bool ScopedDisableResize::disable_resize_ = false;
} // namespace
// This view always takes the size of its superview. It is intended to be used
// as a NSWindow's contentView. It is needed because NSWindow's implementation
@@ -95,10 +107,45 @@ static const CGFloat kAtomWindowCornerRadius = 4.0;
shell_->NotifyWindowBlur();
}
- (void)windowDidResize:(NSNotification*)notification {
if (!shell_->has_frame())
shell_->ClipWebView();
- (NSSize)windowWillResize:(NSWindow*)sender toSize:(NSSize)frameSize {
NSSize newSize = frameSize;
double aspectRatio = shell_->GetAspectRatio();
if (aspectRatio > 0.0) {
gfx::Size windowSize = shell_->GetSize();
gfx::Size contentSize = shell_->GetContentSize();
gfx::Size extraSize = shell_->GetAspectRatioExtraSize();
double extraWidthPlusFrame =
windowSize.width() - contentSize.width() + extraSize.width();
double extraHeightPlusFrame =
windowSize.height() - contentSize.height() + extraSize.height();
newSize.width =
roundf((frameSize.height - extraHeightPlusFrame) * aspectRatio +
extraWidthPlusFrame);
// If the new width is less than the frame size use it as the primary
// constraint. This ensures that the value returned by this method will
// never be larger than the users requested window size.
if (newSize.width <= frameSize.width) {
newSize.height =
roundf((newSize.width - extraWidthPlusFrame) / aspectRatio +
extraHeightPlusFrame);
} else {
newSize.height =
roundf((frameSize.width - extraWidthPlusFrame) / aspectRatio +
extraHeightPlusFrame);
newSize.width =
roundf((newSize.height - extraHeightPlusFrame) * aspectRatio +
extraWidthPlusFrame);
}
}
return newSize;
}
- (void)windowDidResize:(NSNotification*)notification {
shell_->NotifyWindowResize();
}
@@ -176,8 +223,12 @@ static const CGFloat kAtomWindowCornerRadius = 4.0;
enable_larger_than_screen_ = enable;
}
// Enable the window to be larger than screen.
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen*)screen {
// Resizing is disabled.
if (ScopedDisableResize::IsResizeDisabled())
return [self frame];
// Enable the window to be larger than screen.
if (enable_larger_than_screen_)
return frameRect;
else
@@ -280,29 +331,6 @@ static const CGFloat kAtomWindowCornerRadius = 4.0;
namespace atom {
namespace {
// Convert draggable regions in raw format to SkRegion format. Caller is
// responsible for deleting the returned SkRegion instance.
SkRegion* DraggableRegionsToSkRegion(
const std::vector<DraggableRegion>& regions) {
SkRegion* sk_region = new SkRegion;
for (std::vector<DraggableRegion>::const_iterator iter = regions.begin();
iter != regions.end();
++iter) {
const DraggableRegion& region = *iter;
sk_region->op(
region.bounds.x(),
region.bounds.y(),
region.bounds.right(),
region.bounds.bottom(),
region.draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op);
}
return sk_region;
}
} // namespace
NativeWindowMac::NativeWindowMac(
brightray::InspectableWebContents* web_contents,
const mate::Dictionary& options)
@@ -323,11 +351,20 @@ NativeWindowMac::NativeWindowMac(
bool useStandardWindow = true;
options.Get(switches::kStandardWindow, &useStandardWindow);
// New title bar styles are available in Yosemite or newer
std::string titleBarStyle;
if (base::mac::IsOSYosemiteOrLater())
options.Get(switches::kTitleBarStyle, &titleBarStyle);
NSUInteger styleMask = NSTitledWindowMask | NSClosableWindowMask |
NSMiniaturizableWindowMask | NSResizableWindowMask;
if (!useStandardWindow || transparent_ || !has_frame_) {
if (!useStandardWindow || transparent() || !has_frame()) {
styleMask |= NSTexturedBackgroundWindowMask;
}
if ((titleBarStyle == "hidden") || (titleBarStyle == "hidden-inset")) {
styleMask |= NSFullSizeContentViewWindowMask;
styleMask |= NSUnifiedTitleAndToolbarWindowMask;
}
window_.reset([[AtomNSWindow alloc]
initWithContentRect:cocoa_bounds
@@ -335,12 +372,12 @@ NativeWindowMac::NativeWindowMac(
backing:NSBackingStoreBuffered
defer:YES]);
[window_ setShell:this];
[window_ setEnableLargerThanScreen:enable_larger_than_screen_];
[window_ setEnableLargerThanScreen:enable_larger_than_screen()];
window_delegate_.reset([[AtomNSWindowDelegate alloc] initWithShell:this]);
[window_ setDelegate:window_delegate_];
if (transparent_) {
if (transparent()) {
// Make window has transparent background.
[window_ setOpaque:NO];
[window_ setHasShadow:NO];
@@ -348,16 +385,30 @@ NativeWindowMac::NativeWindowMac(
}
// Remove non-transparent corners, see http://git.io/vfonD.
if (!has_frame_)
if (!has_frame())
[window_ setOpaque:NO];
// We will manage window's lifetime ourselves.
[window_ setReleasedWhenClosed:NO];
// Hide the title bar.
if ((titleBarStyle == "hidden") || (titleBarStyle == "hidden-inset")) {
[window_ setTitlebarAppearsTransparent:YES];
[window_ setTitleVisibility:NSWindowTitleHidden];
if (titleBarStyle == "hidden-inset") {
base::scoped_nsobject<NSToolbar> toolbar(
[[NSToolbar alloc] initWithIdentifier:@"titlebarStylingToolbar"]);
[toolbar setShowsBaselineSeparator:NO];
[window_ setToolbar:toolbar];
}
// We should be aware of draggable regions when using hidden titlebar.
set_force_using_draggable_region(true);
}
// On OS X the initial window size doesn't include window frame.
bool use_content_size = false;
options.Get(switches::kUseContentSize, &use_content_size);
if (has_frame_ && !use_content_size)
if (!has_frame() || !use_content_size)
SetSize(gfx::Size(width, height));
// Enable the NSView to accept first mouse event.
@@ -383,6 +434,11 @@ NativeWindowMac::NativeWindowMac(
[view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
InstallView();
// Install the DraggableRegionView if it is forced to use draggable regions
// for normal window.
if (has_frame() && force_using_draggable_region())
InstallDraggableRegionView();
}
NativeWindowMac::~NativeWindowMac() {
@@ -414,6 +470,8 @@ bool NativeWindowMac::IsFocused() {
}
void NativeWindowMac::Show() {
web_contents()->WasShown();
// This method is supposed to put focus on window, however if the app does not
// have focus then "makeKeyAndOrderFront" will only show the window.
[NSApp activateIgnoringOtherApps:YES];
@@ -422,11 +480,13 @@ void NativeWindowMac::Show() {
}
void NativeWindowMac::ShowInactive() {
web_contents()->WasShown();
[window_ orderFrontRegardless];
}
void NativeWindowMac::Hide() {
[window_ orderOut:nil];
web_contents()->WasHidden();
}
bool NativeWindowMac::IsVisible() {
@@ -494,6 +554,11 @@ gfx::Rect NativeWindowMac::GetBounds() {
}
void NativeWindowMac::SetContentSize(const gfx::Size& size) {
if (!has_frame()) {
SetSize(size);
return;
}
NSRect frame_nsrect = [window_ frame];
NSSize frame = frame_nsrect.size;
NSSize content = [window_ contentRectForFrameRect:frame_nsrect].size;
@@ -507,6 +572,9 @@ void NativeWindowMac::SetContentSize(const gfx::Size& size) {
}
gfx::Size NativeWindowMac::GetContentSize() {
if (!has_frame())
return GetSize();
NSRect bounds = [[window_ contentView] bounds];
return gfx::Size(bounds.size.width, bounds.size.height);
}
@@ -538,12 +606,15 @@ gfx::Size NativeWindowMac::GetMaximumSize() {
}
void NativeWindowMac::SetResizable(bool resizable) {
// Change styleMask for frameless causes the window to change size, so we have
// to explicitly disables that.
ScopedDisableResize disable_resize;
if (resizable) {
[[window_ standardWindowButton:NSWindowZoomButton] setEnabled:YES];
[window_ setStyleMask:[window_ styleMask] | NSResizableWindowMask];
} else {
[[window_ standardWindowButton:NSWindowZoomButton] setEnabled:NO];
[window_ setStyleMask:[window_ styleMask] ^ NSResizableWindowMask];
[window_ setStyleMask:[window_ styleMask] & (~NSResizableWindowMask)];
}
}
@@ -564,8 +635,8 @@ void NativeWindowMac::Center() {
}
void NativeWindowMac::SetTitle(const std::string& title) {
// We don't want the title to show in transparent window.
if (transparent_)
// We don't want the title to show in transparent or frameless window.
if (transparent() || !has_frame())
return;
[window_ setTitle:base::SysUTF8ToNSString(title)];
@@ -701,7 +772,7 @@ bool NativeWindowMac::IsVisibleOnAllWorkspaces() {
}
bool NativeWindowMac::IsWithinDraggableRegion(NSPoint point) const {
if (!draggable_region_)
if (!draggable_region())
return false;
if (!web_contents())
return false;
@@ -710,7 +781,7 @@ bool NativeWindowMac::IsWithinDraggableRegion(NSPoint point) const {
// |draggable_region_| is stored in local platform-indepdent coordiate system
// while |point| is in local Cocoa coordinate system. Do the conversion
// to match these two.
return draggable_region_->contains(point.x, webViewHeight - point.y);
return draggable_region()->contains(point.x, webViewHeight - point.y);
}
void NativeWindowMac::HandleMouseEvent(NSEvent* event) {
@@ -730,15 +801,6 @@ void NativeWindowMac::HandleMouseEvent(NSEvent* event) {
}
}
void NativeWindowMac::UpdateDraggableRegions(
const std::vector<DraggableRegion>& regions) {
// Draggable region is not supported for non-frameless window.
if (has_frame_)
return;
draggable_region_.reset(DraggableRegionsToSkRegion(regions));
}
void NativeWindowMac::HandleKeyboardEvent(
content::WebContents*,
const content::NativeWebKeyboardEvent& event) {
@@ -764,35 +826,27 @@ void NativeWindowMac::HandleKeyboardEvent(
}
void NativeWindowMac::InstallView() {
// Make sure the bottom corner is rounded: http://crbug.com/396264.
[[window_ contentView] setWantsLayer:YES];
NSView* view = inspectable_web_contents()->GetView()->GetNativeView();
if (has_frame_) {
// Add layer with white background for the contents view.
base::scoped_nsobject<CALayer> layer([[CALayer alloc] init]);
[layer setBackgroundColor:CGColorGetConstantColor(kCGColorWhite)];
[view setLayer:layer];
if (has_frame()) {
[view setFrame:[[window_ contentView] bounds]];
[[window_ contentView] addSubview:view];
} else {
if (base::mac::IsOSYosemiteOrLater()) {
// In OSX 10.10, adding subviews to the root view for the NSView hierarchy
// produces warnings. To eliminate the warnings, we resize the contentView
// to fill the window, and add subviews to that.
// http://crbug.com/380412
content_view_.reset([[FullSizeContentView alloc] init]);
[content_view_
setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
[content_view_ setFrame:[[[window_ contentView] superview] bounds]];
[window_ setContentView:content_view_];
// In OSX 10.10, adding subviews to the root view for the NSView hierarchy
// produces warnings. To eliminate the warnings, we resize the contentView
// to fill the window, and add subviews to that.
// http://crbug.com/380412
content_view_.reset([[FullSizeContentView alloc] init]);
[content_view_
setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
[content_view_ setFrame:[[[window_ contentView] superview] bounds]];
[window_ setContentView:content_view_];
[view setFrame:[content_view_ bounds]];
[content_view_ addSubview:view];
} else {
NSView* frameView = [[window_ contentView] superview];
[view setFrame:[frameView bounds]];
[frameView addSubview:view];
}
[view setFrame:[content_view_ bounds]];
[content_view_ addSubview:view];
ClipWebView();
InstallDraggableRegionView();
[[window_ standardWindowButton:NSWindowZoomButton] setHidden:YES];
@@ -811,14 +865,6 @@ void NativeWindowMac::UninstallView() {
[view removeFromSuperview];
}
void NativeWindowMac::ClipWebView() {
if (!web_contents())
return;
NSView* webView = web_contents()->GetNativeView();
webView.layer.masksToBounds = YES;
webView.layer.cornerRadius = kAtomWindowCornerRadius;
}
void NativeWindowMac::InstallDraggableRegionView() {
NSView* webView = web_contents()->GetNativeView();
base::scoped_nsobject<NSView> controlRegion(

View File

@@ -4,10 +4,6 @@
#include "atom/browser/native_window_views.h"
#if defined(OS_WIN)
#include <shobjidl.h>
#endif
#include <string>
#include <vector>
@@ -20,7 +16,6 @@
#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"
#include "ui/aura/window_tree_host.h"
#include "ui/base/hit_test.h"
#include "ui/gfx/image/image.h"
@@ -36,26 +31,20 @@
#include "atom/browser/browser.h"
#include "atom/browser/ui/views/global_menu_bar_x11.h"
#include "atom/browser/ui/views/frameless_view.h"
#include "atom/browser/ui/views/native_frame_view.h"
#include "atom/browser/ui/x/window_state_watcher.h"
#include "atom/browser/ui/x/x_window_utils.h"
#include "base/environment.h"
#include "base/nix/xdg_util.h"
#include "base/strings/string_util.h"
#include "chrome/browser/ui/libgtk2ui/unity_service.h"
#include "dbus/bus.h"
#include "dbus/object_proxy.h"
#include "dbus/message.h"
#include "ui/base/x/x11_util.h"
#include "ui/gfx/x/x11_types.h"
#include "ui/views/window/native_frame_view.h"
#elif defined(OS_WIN)
#include "atom/browser/ui/views/win_frame_view.h"
#include "base/win/scoped_comptr.h"
#include "base/win/windows_version.h"
#include "atom/browser/ui/win/atom_desktop_window_tree_host_win.h"
#include "ui/base/win/shell.h"
#include "ui/gfx/icon_util.h"
#include "ui/gfx/win/dpi.h"
#include "ui/views/win/hwnd_util.h"
#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
#endif
namespace atom {
@@ -69,42 +58,6 @@ const int kMenuBarHeight = 20;
const int kMenuBarHeight = 25;
#endif
#if defined(USE_X11)
// Returns true if the bus name "com.canonical.AppMenu.Registrar" is available.
bool ShouldUseGlobalMenuBar() {
dbus::Bus::Options options;
scoped_refptr<dbus::Bus> bus(new dbus::Bus(options));
dbus::ObjectProxy* object_proxy =
bus->GetObjectProxy(DBUS_SERVICE_DBUS, dbus::ObjectPath(DBUS_PATH_DBUS));
dbus::MethodCall method_call(DBUS_INTERFACE_DBUS, "ListNames");
scoped_ptr<dbus::Response> response(object_proxy->CallMethodAndBlock(
&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
if (!response) {
bus->ShutdownAndBlock();
return false;
}
dbus::MessageReader reader(response.get());
dbus::MessageReader array_reader(NULL);
if (!reader.PopArray(&array_reader)) {
bus->ShutdownAndBlock();
return false;
}
while (array_reader.HasMoreData()) {
std::string name;
if (array_reader.PopString(&name) &&
name == "com.canonical.AppMenu.Registrar") {
bus->ShutdownAndBlock();
return true;
}
}
bus->ShutdownAndBlock();
return false;
}
#endif
bool IsAltKey(const content::NativeWebKeyboardEvent& event) {
#if defined(USE_X11)
// 164 and 165 represent VK_LALT and VK_RALT.
@@ -183,7 +136,7 @@ const char* AppCommandToString(int command_id) {
case APPCOMMAND_DICTATE_OR_COMMAND_CONTROL_TOGGLE:
return "dictate-or-command-control-toggle";
default:
return "unkown";
return "unknown";
}
}
#endif
@@ -231,7 +184,7 @@ NativeWindowViews::NativeWindowViews(
options.Get(switches::kResizable, &resizable_);
#endif
if (enable_larger_than_screen_)
if (enable_larger_than_screen())
// We need to set a default maximum window size here otherwise Windows
// will not allow us to resize the window larger than scree.
// Setting directly to INT_MAX somehow doesn't work, so we just devide
@@ -251,12 +204,20 @@ NativeWindowViews::NativeWindowViews(
params.bounds = bounds;
params.delegate = this;
params.type = views::Widget::InitParams::TYPE_WINDOW;
params.remove_standard_frame = !has_frame_;
params.remove_standard_frame = !has_frame();
if (transparent_)
if (transparent())
params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
#if defined(USE_X11)
#if defined(OS_WIN)
params.native_widget =
new views::DesktopNativeWidgetAura(window_.get());
atom_desktop_window_tree_host_win_ = new AtomDesktopWindowTreeHostWin(
this,
window_.get(),
static_cast<views::DesktopNativeWidgetAura*>(params.native_widget));
params.desktop_window_tree_host = atom_desktop_window_tree_host_win_;
#elif defined(USE_X11)
std::string name = Browser::Get()->GetName();
// Set WM_WINDOW_ROLE.
params.wm_role_name = "browser-window";
@@ -311,24 +272,24 @@ NativeWindowViews::NativeWindowViews(
set_background(views::Background::CreateStandardPanelBackground());
AddChildView(web_view_);
if (has_frame_ &&
if (has_frame() &&
options.Get(switches::kUseContentSize, &use_content_size_) &&
use_content_size_)
bounds = ContentBoundsToWindowBounds(bounds);
#if defined(OS_WIN)
if (!has_frame_) {
if (!has_frame()) {
// Set Window style so that we get a minimize and maximize animation when
// frameless.
DWORD frame_style = WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX |
WS_CAPTION;
// We should not show a frame for transparent window.
if (transparent_)
if (transparent())
frame_style &= ~(WS_THICKFRAME | WS_CAPTION);
::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, frame_style);
}
if (transparent_) {
if (transparent()) {
// Transparent window on Windows has to have WS_EX_COMPOSITED style.
LONG ex_style = ::GetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE);
ex_style |= WS_EX_COMPOSITED;
@@ -338,14 +299,14 @@ NativeWindowViews::NativeWindowViews(
// TODO(zcbenz): This was used to force using native frame on Windows 2003, we
// should check whether setting it in InitParams can work.
if (has_frame_) {
if (has_frame()) {
window_->set_frame_type(views::Widget::FrameType::FRAME_TYPE_FORCE_NATIVE);
window_->FrameTypeChanged();
}
// The given window is most likely not rectangular since it uses
// transparency and has no standard frame, don't show a shadow for it.
if (transparent_ && !has_frame_)
if (transparent() && !has_frame())
wm::SetShadowType(GetNativeWindow(), wm::SHADOW_TYPE_NONE);
window_->UpdateWindowIcon();
@@ -377,15 +338,18 @@ bool NativeWindowViews::IsFocused() {
}
void NativeWindowViews::Show() {
web_contents()->WasShown();
window_->native_widget_private()->ShowWithWindowState(GetRestoredState());
}
void NativeWindowViews::ShowInactive() {
web_contents()->WasShown();
window_->ShowInactive();
}
void NativeWindowViews::Hide() {
window_->Hide();
web_contents()->WasHidden();
}
bool NativeWindowViews::IsVisible() {
@@ -468,7 +432,7 @@ gfx::Rect NativeWindowViews::GetBounds() {
}
void NativeWindowViews::SetContentSize(const gfx::Size& size) {
if (!has_frame_) {
if (!has_frame()) {
NativeWindow::SetSize(size);
return;
}
@@ -479,7 +443,7 @@ void NativeWindowViews::SetContentSize(const gfx::Size& size) {
}
gfx::Size NativeWindowViews::GetContentSize() {
if (!has_frame_)
if (!has_frame())
return GetSize();
gfx::Size content_size =
@@ -491,14 +455,6 @@ gfx::Size NativeWindowViews::GetContentSize() {
void NativeWindowViews::SetMinimumSize(const gfx::Size& size) {
minimum_size_ = size;
#if defined(USE_X11)
XSizeHints size_hints;
size_hints.flags = PMinSize;
size_hints.min_width = size.width();
size_hints.min_height = size.height();
XSetWMNormalHints(gfx::GetXDisplay(), GetAcceleratedWidget(), &size_hints);
#endif
}
gfx::Size NativeWindowViews::GetMinimumSize() {
@@ -507,14 +463,6 @@ gfx::Size NativeWindowViews::GetMinimumSize() {
void NativeWindowViews::SetMaximumSize(const gfx::Size& size) {
maximum_size_ = size;
#if defined(USE_X11)
XSizeHints size_hints;
size_hints.flags = PMaxSize;
size_hints.max_width = size.width();
size_hints.max_height = size.height();
XSetWMNormalHints(gfx::GetXDisplay(), GetAcceleratedWidget(), &size_hints);
#endif
}
gfx::Size NativeWindowViews::GetMaximumSize() {
@@ -643,7 +591,7 @@ void NativeWindowViews::SetMenu(ui::MenuModel* menu_model) {
#endif
// Do not show menu bar in frameless window.
if (!has_frame_)
if (!has_frame())
return;
if (!menu_bar_) {
@@ -668,24 +616,7 @@ gfx::NativeWindow NativeWindowViews::GetNativeWindow() {
void NativeWindowViews::SetProgressBar(double progress) {
#if defined(OS_WIN)
if (base::win::GetVersion() < base::win::VERSION_WIN7)
return;
base::win::ScopedComPtr<ITaskbarList3> taskbar;
if (FAILED(taskbar.CreateInstance(CLSID_TaskbarList, NULL,
CLSCTX_INPROC_SERVER) ||
FAILED(taskbar->HrInit()))) {
return;
}
HWND frame = views::HWNDForNativeWindow(GetNativeWindow());
if (progress > 1.0) {
taskbar->SetProgressState(frame, TBPF_INDETERMINATE);
} else if (progress < 0) {
taskbar->SetProgressState(frame, TBPF_NOPROGRESS);
} else if (progress >= 0) {
taskbar->SetProgressValue(frame,
static_cast<int>(progress * 100),
100);
}
taskbar_host_.SetProgressBar(GetAcceleratedWidget(), progress);
#elif defined(USE_X11)
if (unity::IsRunning()) {
unity::SetProgressFraction(progress);
@@ -696,22 +627,7 @@ void NativeWindowViews::SetProgressBar(double progress) {
void NativeWindowViews::SetOverlayIcon(const gfx::Image& overlay,
const std::string& description) {
#if defined(OS_WIN)
if (base::win::GetVersion() < base::win::VERSION_WIN7)
return;
base::win::ScopedComPtr<ITaskbarList3> taskbar;
if (FAILED(taskbar.CreateInstance(CLSID_TaskbarList, NULL,
CLSCTX_INPROC_SERVER) ||
FAILED(taskbar->HrInit()))) {
return;
}
HWND frame = views::HWNDForNativeWindow(GetNativeWindow());
std::wstring wstr = std::wstring(description.begin(), description.end());
taskbar->SetOverlayIcon(frame,
IconUtil::CreateHICONFromSkBitmap(overlay.AsBitmap()),
wstr.c_str());
taskbar_host_.SetOverlayIcon(GetAcceleratedWidget(), overlay, description);
#endif
}
@@ -768,29 +684,6 @@ gfx::AcceleratedWidget NativeWindowViews::GetAcceleratedWidget() {
return GetNativeWindow()->GetHost()->GetAcceleratedWidget();
}
void NativeWindowViews::UpdateDraggableRegions(
const std::vector<DraggableRegion>& regions) {
if (has_frame_)
return;
SkRegion* draggable_region = new SkRegion;
// By default, the whole window is non-draggable. We need to explicitly
// include those draggable regions.
for (std::vector<DraggableRegion>::const_iterator iter = regions.begin();
iter != regions.end(); ++iter) {
const DraggableRegion& region = *iter;
draggable_region->op(
region.bounds.x(),
region.bounds.y(),
region.bounds.right(),
region.bounds.bottom(),
region.draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op);
}
draggable_region_.reset(draggable_region);
}
void NativeWindowViews::OnWidgetActivationChanged(
views::Widget* widget, bool active) {
if (widget != window_.get())
@@ -850,7 +743,7 @@ bool NativeWindowViews::ShouldHandleSystemCommands() const {
}
gfx::ImageSkia NativeWindowViews::GetWindowAppIcon() {
return icon_;
return icon();
}
gfx::ImageSkia NativeWindowViews::GetWindowIcon() {
@@ -873,12 +766,12 @@ bool NativeWindowViews::ShouldDescendIntoChildForEventHandling(
gfx::NativeView child,
const gfx::Point& location) {
// App window should claim mouse events that fall within the draggable region.
if (draggable_region_ &&
draggable_region_->contains(location.x(), location.y()))
if (draggable_region() &&
draggable_region()->contains(location.x(), location.y()))
return false;
// And the events on border for dragging resizable frameless window.
if (!has_frame_ && CanResize()) {
if (!has_frame() && CanResize()) {
FramelessView* frame = static_cast<FramelessView*>(
window_->non_client_view()->frame_view());
return frame->ResizingBorderHitTest(location) == HTNOWHERE;
@@ -898,8 +791,8 @@ views::NonClientFrameView* NativeWindowViews::CreateNonClientFrameView(
frame_view->Init(this, widget);
return frame_view;
#else
if (has_frame_) {
return new views::NativeFrameView(widget);
if (has_frame()) {
return new NativeFrameView(this, widget);
} else {
FramelessView* frame_view = new FramelessView;
frame_view->Init(this, widget);
@@ -929,10 +822,8 @@ bool NativeWindowViews::ExecuteWindowsCommand(int command_id) {
} 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));
std::string command = AppCommandToString(command_id);
NotifyWindowExecuteWindowsCommand(command);
}
return false;
}
@@ -950,6 +841,17 @@ void NativeWindowViews::GetDevToolsWindowWMClass(
}
#endif
#if defined(OS_WIN)
bool NativeWindowViews::PreHandleMSG(
UINT message, WPARAM w_param, LPARAM l_param, LRESULT* result) {
// Handle thumbar button click message.
if (message == WM_COMMAND && HIWORD(w_param) == THBN_CLICKED)
return taskbar_host_.HandleThumbarButtonEvent(LOWORD(w_param));
else
return false;
}
#endif
void NativeWindowViews::HandleKeyboardEvent(
content::WebContents*,
const content::NativeWebKeyboardEvent& event) {

View File

@@ -14,6 +14,11 @@
#include "ui/views/widget/widget_delegate.h"
#include "ui/views/widget/widget_observer.h"
#if defined(OS_WIN)
#include "atom/browser/ui/win/message_handler_delegate.h"
#include "atom/browser/ui/win/taskbar_host.h"
#endif
namespace views {
class UnhandledKeyboardEventHandler;
}
@@ -24,7 +29,14 @@ class GlobalMenuBarX11;
class MenuBar;
class WindowStateWatcher;
#if defined(OS_WIN)
class AtomDesktopWindowTreeHostWin;
#endif
class NativeWindowViews : public NativeWindow,
#if defined(OS_WIN)
public MessageHandlerDelegate,
#endif
public views::WidgetDelegateView,
public views::WidgetObserver {
public:
@@ -82,14 +94,13 @@ class NativeWindowViews : public NativeWindow,
gfx::AcceleratedWidget GetAcceleratedWidget();
SkRegion* draggable_region() const { return draggable_region_.get(); }
views::Widget* widget() const { return window_.get(); }
private:
// NativeWindow:
void UpdateDraggableRegions(
const std::vector<DraggableRegion>& regions) override;
#if defined(OS_WIN)
TaskbarHost& taskbar_host() { return taskbar_host_; }
#endif
private:
// views::WidgetObserver:
void OnWidgetActivationChanged(
views::Widget* widget, bool active) override;
@@ -127,6 +138,12 @@ class NativeWindowViews : public NativeWindow,
std::string* name, std::string* class_name) override;
#endif
#if defined(OS_WIN)
// MessageHandlerDelegate:
bool PreHandleMSG(
UINT message, WPARAM w_param, LPARAM l_param, LRESULT* result) override;
#endif
// NativeWindow:
void HandleKeyboardEvent(
content::WebContents*,
@@ -159,9 +176,13 @@ class NativeWindowViews : public NativeWindow,
// Handles window state events.
scoped_ptr<WindowStateWatcher> window_state_watcher_;
#elif defined(OS_WIN)
// Weak ref.
AtomDesktopWindowTreeHostWin* atom_desktop_window_tree_host_win_;
// Records window was whether restored from minimized state or maximized
// state.
bool is_minimized_;
// In charge of running taskbar related APIs.
TaskbarHost taskbar_host_;
#endif
// Handles unhandled keyboard messages coming back from the renderer process.
@@ -177,8 +198,6 @@ class NativeWindowViews : public NativeWindow,
gfx::Size maximum_size_;
gfx::Size widget_size_;
scoped_ptr<SkRegion> draggable_region_;
DISALLOW_COPY_AND_ASSIGN(NativeWindowViews);
};

View File

@@ -1,141 +0,0 @@
// Copyright (c) 2013 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/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 "content/public/browser/browser_thread.h"
#include "net/base/net_errors.h"
#include "net/url_request/url_request_error_job.h"
#include "net/url_request/url_request_file_job.h"
namespace atom {
AdapterRequestJob::AdapterRequestJob(ProtocolHandler* protocol_handler,
net::URLRequest* request,
net::NetworkDelegate* network_delegate)
: URLRequestJob(request, network_delegate),
protocol_handler_(protocol_handler),
weak_factory_(this) {
}
void AdapterRequestJob::Start() {
DCHECK(!real_job_.get());
content::BrowserThread::PostTask(
content::BrowserThread::UI,
FROM_HERE,
base::Bind(&AdapterRequestJob::GetJobTypeInUI,
weak_factory_.GetWeakPtr()));
}
void AdapterRequestJob::Kill() {
if (real_job_.get()) // Kill could happen when real_job_ is created.
real_job_->Kill();
}
bool AdapterRequestJob::ReadRawData(net::IOBuffer* buf,
int buf_size,
int *bytes_read) {
DCHECK(!real_job_.get());
return real_job_->ReadRawData(buf, buf_size, bytes_read);
}
bool AdapterRequestJob::IsRedirectResponse(GURL* location,
int* http_status_code) {
DCHECK(!real_job_.get());
return real_job_->IsRedirectResponse(location, http_status_code);
}
net::Filter* AdapterRequestJob::SetupFilter() const {
DCHECK(!real_job_.get());
return real_job_->SetupFilter();
}
bool AdapterRequestJob::GetMimeType(std::string* mime_type) const {
DCHECK(!real_job_.get());
return real_job_->GetMimeType(mime_type);
}
bool AdapterRequestJob::GetCharset(std::string* charset) {
DCHECK(!real_job_.get());
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) {
real_job_ = new net::URLRequestErrorJob(
request(), network_delegate(), error_code);
real_job_->Start();
}
void AdapterRequestJob::CreateStringJobAndStart(const std::string& mime_type,
const std::string& charset,
const std::string& data) {
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,
scoped_refptr<base::RefCountedBytes> data) {
real_job_ = new URLRequestBufferJob(
request(), network_delegate(), mime_type, charset, data);
real_job_->Start();
}
void AdapterRequestJob::CreateFileJobAndStart(const base::FilePath& path) {
real_job_ = asar::CreateJobFromPath(
path,
request(),
network_delegate(),
content::BrowserThread::GetBlockingPool()->
GetTaskRunnerWithShutdownBehavior(
base::SequencedWorkerPool::SKIP_ON_SHUTDOWN));
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() {
real_job_ = protocol_handler_->MaybeCreateJob(request(),
network_delegate());
if (!real_job_.get())
CreateErrorJobAndStart(net::ERR_NOT_IMPLEMENTED);
else
real_job_->Start();
}
} // namespace atom

View File

@@ -1,84 +0,0 @@
// Copyright (c) 2013 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_ADAPTER_REQUEST_JOB_H_
#define ATOM_BROWSER_NET_ADAPTER_REQUEST_JOB_H_
#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"
namespace base {
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:
typedef net::URLRequestJobFactory::ProtocolHandler ProtocolHandler;
AdapterRequestJob(ProtocolHandler* protocol_handler,
net::URLRequest* request,
net::NetworkDelegate* network_delegate);
public:
// net::URLRequestJob:
void Start() override;
void Kill() override;
bool ReadRawData(net::IOBuffer* buf,
int buf_size,
int *bytes_read) override;
bool IsRedirectResponse(GURL* location,
int* http_status_code) override;
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();
ProtocolHandler* default_protocol_handler() { return protocol_handler_; }
// Override this function to determine which job should be started.
virtual void GetJobTypeInUI() = 0;
void CreateErrorJobAndStart(int error_code);
void CreateStringJobAndStart(const std::string& mime_type,
const std::string& charset,
const std::string& data);
void CreateBufferJobAndStart(const std::string& mime_type,
const std::string& charset,
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:
// The delegated request job.
scoped_refptr<net::URLRequestJob> real_job_;
// Default protocol handler.
ProtocolHandler* protocol_handler_;
base::WeakPtrFactory<AdapterRequestJob> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(AdapterRequestJob);
};
} // namespace atom
#endif // ATOM_BROWSER_NET_ADAPTER_REQUEST_JOB_H_

View File

@@ -5,45 +5,11 @@
#include "atom/browser/net/asar/asar_protocol_handler.h"
#include "atom/browser/net/asar/url_request_asar_job.h"
#include "atom/common/asar/archive.h"
#include "atom/common/asar/asar_util.h"
#include "net/base/filename_util.h"
#include "net/base/net_errors.h"
#include "net/url_request/url_request_error_job.h"
#include "net/url_request/url_request_file_job.h"
namespace asar {
// static
net::URLRequestJob* CreateJobFromPath(
const base::FilePath& full_path,
net::URLRequest* request,
net::NetworkDelegate* network_delegate,
const scoped_refptr<base::TaskRunner> file_task_runner) {
// Create asar:// job when the path contains "xxx.asar/", otherwise treat the
// URL request as file://.
base::FilePath asar_path, relative_path;
if (!GetAsarArchivePath(full_path, &asar_path, &relative_path))
return new net::URLRequestFileJob(request, network_delegate, full_path,
file_task_runner);
std::shared_ptr<Archive> archive = GetOrCreateAsarArchive(asar_path);
Archive::FileInfo file_info;
if (!archive || !archive->GetFileInfo(relative_path, &file_info))
return new net::URLRequestErrorJob(request, network_delegate,
net::ERR_FILE_NOT_FOUND);
if (file_info.unpacked) {
base::FilePath real_path;
archive->CopyFileOut(relative_path, &real_path);
return new net::URLRequestFileJob(request, network_delegate, real_path,
file_task_runner);
}
return new URLRequestAsarJob(request, network_delegate, archive,
relative_path, file_info, file_task_runner);
}
AsarProtocolHandler::AsarProtocolHandler(
const scoped_refptr<base::TaskRunner>& file_task_runner)
: file_task_runner_(file_task_runner) {}
@@ -56,8 +22,9 @@ net::URLRequestJob* AsarProtocolHandler::MaybeCreateJob(
net::NetworkDelegate* network_delegate) const {
base::FilePath full_path;
net::FileURLToFilePath(request->url(), &full_path);
return CreateJobFromPath(full_path, request, network_delegate,
file_task_runner_);
URLRequestAsarJob* job = new URLRequestAsarJob(request, network_delegate);
job->Initialize(file_task_runner_, full_path);
return job;
}
bool AsarProtocolHandler::IsSafeRedirectTarget(const GURL& location) const {

View File

@@ -5,48 +5,128 @@
#include "atom/browser/net/asar/url_request_asar_job.h"
#include <string>
#include <vector>
#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/strings/string_util.h"
#include "base/synchronization/lock.h"
#include "base/task_runner.h"
#include "atom/common/asar/archive.h"
#include "atom/common/asar/asar_util.h"
#include "net/base/file_stream.h"
#include "net/base/filename_util.h"
#include "net/base/io_buffer.h"
#include "net/base/load_flags.h"
#include "net/base/mime_util.h"
#include "net/base/net_errors.h"
#include "net/filter/filter.h"
#include "net/http/http_util.h"
#include "net/url_request/url_request_status.h"
#if defined(OS_WIN)
#include "base/win/shortcut.h"
#endif
namespace asar {
URLRequestAsarJob::FileMetaInfo::FileMetaInfo()
: file_size(0),
mime_type_result(false),
file_exists(false),
is_directory(false) {
}
URLRequestAsarJob::URLRequestAsarJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate,
std::shared_ptr<Archive> archive,
const base::FilePath& file_path,
const Archive::FileInfo& file_info,
const scoped_refptr<base::TaskRunner>& file_task_runner)
net::NetworkDelegate* network_delegate)
: net::URLRequestJob(request, network_delegate),
archive_(archive),
file_path_(file_path),
file_info_(file_info),
stream_(new net::FileStream(file_task_runner)),
type_(TYPE_ERROR),
remaining_bytes_(0),
file_task_runner_(file_task_runner),
weak_ptr_factory_(this) {}
URLRequestAsarJob::~URLRequestAsarJob() {}
void URLRequestAsarJob::Start() {
remaining_bytes_ = static_cast<int64>(file_info_.size);
void URLRequestAsarJob::Initialize(
const scoped_refptr<base::TaskRunner> file_task_runner,
const base::FilePath& file_path) {
// Determine whether it is an asar file.
base::FilePath asar_path, relative_path;
if (!GetAsarArchivePath(file_path, &asar_path, &relative_path)) {
InitializeFileJob(file_task_runner, file_path);
return;
}
int flags = base::File::FLAG_OPEN |
base::File::FLAG_READ |
base::File::FLAG_ASYNC;
int rv = stream_->Open(archive_->path(), flags,
base::Bind(&URLRequestAsarJob::DidOpen,
weak_ptr_factory_.GetWeakPtr()));
if (rv != net::ERR_IO_PENDING)
DidOpen(rv);
std::shared_ptr<Archive> archive = GetOrCreateAsarArchive(asar_path);
Archive::FileInfo file_info;
if (!archive || !archive->GetFileInfo(relative_path, &file_info)) {
type_ = TYPE_ERROR;
return;
}
if (file_info.unpacked) {
base::FilePath real_path;
archive->CopyFileOut(relative_path, &real_path);
InitializeFileJob(file_task_runner, real_path);
return;
}
InitializeAsarJob(file_task_runner, archive, relative_path, file_info);
}
void URLRequestAsarJob::InitializeAsarJob(
const scoped_refptr<base::TaskRunner> file_task_runner,
std::shared_ptr<Archive> archive,
const base::FilePath& file_path,
const Archive::FileInfo& file_info) {
type_ = TYPE_ASAR;
file_task_runner_ = file_task_runner;
stream_.reset(new net::FileStream(file_task_runner_));
archive_ = archive;
file_path_ = file_path;
file_info_ = file_info;
}
void URLRequestAsarJob::InitializeFileJob(
const scoped_refptr<base::TaskRunner> file_task_runner,
const base::FilePath& file_path) {
type_ = TYPE_FILE;
file_task_runner_ = file_task_runner;
stream_.reset(new net::FileStream(file_task_runner_));
file_path_ = file_path;
}
void URLRequestAsarJob::Start() {
if (type_ == TYPE_ASAR) {
remaining_bytes_ = static_cast<int64>(file_info_.size);
int flags = base::File::FLAG_OPEN |
base::File::FLAG_READ |
base::File::FLAG_ASYNC;
int rv = stream_->Open(archive_->path(), flags,
base::Bind(&URLRequestAsarJob::DidOpen,
weak_ptr_factory_.GetWeakPtr()));
if (rv != net::ERR_IO_PENDING)
DidOpen(rv);
} else if (type_ == TYPE_FILE) {
FileMetaInfo* meta_info = new FileMetaInfo();
file_task_runner_->PostTaskAndReply(
FROM_HERE,
base::Bind(&URLRequestAsarJob::FetchMetaInfo, file_path_,
base::Unretained(meta_info)),
base::Bind(&URLRequestAsarJob::DidFetchMetaInfo,
weak_ptr_factory_.GetWeakPtr(),
base::Owned(meta_info)));
} else {
NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED,
net::ERR_FILE_NOT_FOUND));
}
}
void URLRequestAsarJob::Kill() {
stream_.reset();
weak_ptr_factory_.InvalidateWeakPtrs();
URLRequestJob::Kill();
}
@@ -85,8 +165,97 @@ bool URLRequestAsarJob::ReadRawData(net::IOBuffer* dest,
return false;
}
bool URLRequestAsarJob::IsRedirectResponse(GURL* location,
int* http_status_code) {
if (type_ != TYPE_FILE)
return false;
#if defined(OS_WIN)
// Follow a Windows shortcut.
// We just resolve .lnk file, ignore others.
if (!base::LowerCaseEqualsASCII(file_path_.Extension(), ".lnk"))
return false;
base::FilePath new_path = file_path_;
bool resolved;
resolved = base::win::ResolveShortcut(new_path, &new_path, NULL);
// If shortcut is not resolved succesfully, do not redirect.
if (!resolved)
return false;
*location = net::FilePathToFileURL(new_path);
*http_status_code = 301;
return true;
#else
return false;
#endif
}
net::Filter* URLRequestAsarJob::SetupFilter() const {
// Bug 9936 - .svgz files needs to be decompressed.
return base::LowerCaseEqualsASCII(file_path_.Extension(), ".svgz")
? net::Filter::GZipFactory() : NULL;
}
bool URLRequestAsarJob::GetMimeType(std::string* mime_type) const {
return net::GetMimeTypeFromFile(file_path_, mime_type);
if (type_ == TYPE_ASAR) {
return net::GetMimeTypeFromFile(file_path_, mime_type);
} else {
if (meta_info_.mime_type_result) {
*mime_type = meta_info_.mime_type;
return true;
}
return false;
}
}
void URLRequestAsarJob::SetExtraRequestHeaders(
const net::HttpRequestHeaders& headers) {
std::string range_header;
if (headers.GetHeader(net::HttpRequestHeaders::kRange, &range_header)) {
// We only care about "Range" header here.
std::vector<net::HttpByteRange> ranges;
if (net::HttpUtil::ParseRangeHeader(range_header, &ranges)) {
if (ranges.size() == 1) {
byte_range_ = ranges[0];
} else {
NotifyDone(net::URLRequestStatus(
net::URLRequestStatus::FAILED,
net::ERR_REQUEST_RANGE_NOT_SATISFIABLE));
}
}
}
}
void URLRequestAsarJob::FetchMetaInfo(const base::FilePath& file_path,
FileMetaInfo* meta_info) {
base::File::Info file_info;
meta_info->file_exists = base::GetFileInfo(file_path, &file_info);
if (meta_info->file_exists) {
meta_info->file_size = file_info.size;
meta_info->is_directory = file_info.is_directory;
}
// On Windows GetMimeTypeFromFile() goes to the registry. Thus it should be
// done in WorkerPool.
meta_info->mime_type_result =
net::GetMimeTypeFromFile(file_path, &meta_info->mime_type);
}
void URLRequestAsarJob::DidFetchMetaInfo(const FileMetaInfo* meta_info) {
meta_info_ = *meta_info;
if (!meta_info_.file_exists || meta_info_.is_directory) {
DidOpen(net::ERR_FILE_NOT_FOUND);
return;
}
int flags = base::File::FLAG_OPEN |
base::File::FLAG_READ |
base::File::FLAG_ASYNC;
int rv = stream_->Open(file_path_, flags,
base::Bind(&URLRequestAsarJob::DidOpen,
weak_ptr_factory_.GetWeakPtr()));
if (rv != net::ERR_IO_PENDING)
DidOpen(rv);
}
void URLRequestAsarJob::DidOpen(int result) {
@@ -95,24 +264,57 @@ void URLRequestAsarJob::DidOpen(int result) {
return;
}
int rv = stream_->Seek(base::File::FROM_BEGIN,
file_info_.offset,
base::Bind(&URLRequestAsarJob::DidSeek,
weak_ptr_factory_.GetWeakPtr()));
if (rv != net::ERR_IO_PENDING) {
// stream_->Seek() failed, so pass an intentionally erroneous value
// into DidSeek().
DidSeek(-1);
if (type_ == TYPE_ASAR) {
int rv = stream_->Seek(file_info_.offset,
base::Bind(&URLRequestAsarJob::DidSeek,
weak_ptr_factory_.GetWeakPtr()));
if (rv != net::ERR_IO_PENDING) {
// stream_->Seek() failed, so pass an intentionally erroneous value
// into DidSeek().
DidSeek(-1);
}
} else {
if (!byte_range_.ComputeBounds(meta_info_.file_size)) {
NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED,
net::ERR_REQUEST_RANGE_NOT_SATISFIABLE));
return;
}
remaining_bytes_ = byte_range_.last_byte_position() -
byte_range_.first_byte_position() + 1;
if (remaining_bytes_ > 0 && byte_range_.first_byte_position() != 0) {
int rv = stream_->Seek(byte_range_.first_byte_position(),
base::Bind(&URLRequestAsarJob::DidSeek,
weak_ptr_factory_.GetWeakPtr()));
if (rv != net::ERR_IO_PENDING) {
// stream_->Seek() failed, so pass an intentionally erroneous value
// into DidSeek().
DidSeek(-1);
}
} else {
// We didn't need to call stream_->Seek() at all, so we pass to DidSeek()
// the value that would mean seek success. This way we skip the code
// handling seek failure.
DidSeek(byte_range_.first_byte_position());
}
}
}
void URLRequestAsarJob::DidSeek(int64 result) {
if (result != static_cast<int64>(file_info_.offset)) {
NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED,
net::ERR_REQUEST_RANGE_NOT_SATISFIABLE));
return;
if (type_ == TYPE_ASAR) {
if (result != static_cast<int64>(file_info_.offset)) {
NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED,
net::ERR_REQUEST_RANGE_NOT_SATISFIABLE));
return;
}
} else {
if (result != byte_range_.first_byte_position()) {
NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED,
net::ERR_REQUEST_RANGE_NOT_SATISFIABLE));
return;
}
}
set_expected_content_size(remaining_bytes_);
NotifyHeadersComplete();
}

View File

@@ -8,10 +8,12 @@
#include <memory>
#include <string>
#include "atom/browser/net/js_asker.h"
#include "atom/common/asar/archive.h"
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "net/http/http_byte_range.h"
#include "net/url_request/url_request_job.h"
namespace base {
@@ -34,11 +36,20 @@ net::URLRequestJob* CreateJobFromPath(
class URLRequestAsarJob : public net::URLRequestJob {
public:
URLRequestAsarJob(net::URLRequest* request,
net::NetworkDelegate* network_delegate,
std::shared_ptr<Archive> archive,
const base::FilePath& file_path,
const Archive::FileInfo& file_info,
const scoped_refptr<base::TaskRunner>& file_task_runner);
net::NetworkDelegate* network_delegate);
void Initialize(const scoped_refptr<base::TaskRunner> file_task_runner,
const base::FilePath& file_path);
protected:
virtual ~URLRequestAsarJob();
void InitializeAsarJob(const scoped_refptr<base::TaskRunner> file_task_runner,
std::shared_ptr<Archive> archive,
const base::FilePath& file_path,
const Archive::FileInfo& file_info);
void InitializeFileJob(const scoped_refptr<base::TaskRunner> file_task_runner,
const base::FilePath& file_path);
// net::URLRequestJob:
void Start() override;
@@ -46,12 +57,39 @@ class URLRequestAsarJob : public net::URLRequestJob {
bool ReadRawData(net::IOBuffer* buf,
int buf_size,
int* bytes_read) override;
bool IsRedirectResponse(GURL* location, int* http_status_code) override;
net::Filter* SetupFilter() const override;
bool GetMimeType(std::string* mime_type) const override;
protected:
virtual ~URLRequestAsarJob();
void SetExtraRequestHeaders(const net::HttpRequestHeaders& headers) override;
private:
// Meta information about the file. It's used as a member in the
// URLRequestFileJob and also passed between threads because disk access is
// necessary to obtain it.
struct FileMetaInfo {
FileMetaInfo();
// Size of the file.
int64 file_size;
// Mime type associated with the file.
std::string mime_type;
// Result returned from GetMimeTypeFromFile(), i.e. flag showing whether
// obtaining of the mime type was successful.
bool mime_type_result;
// Flag showing whether the file exists.
bool file_exists;
// Flag showing whether the file name actually refers to a directory.
bool is_directory;
};
// Fetches file info on a background thread.
static void FetchMetaInfo(const base::FilePath& file_path,
FileMetaInfo* meta_info);
// Callback after fetching file info on a background thread.
void DidFetchMetaInfo(const FileMetaInfo* meta_info);
// Callback after opening file on a background thread.
void DidOpen(int result);
@@ -62,14 +100,24 @@ class URLRequestAsarJob : public net::URLRequestJob {
// Callback after data is asynchronously read from the file into |buf|.
void DidRead(scoped_refptr<net::IOBuffer> buf, int result);
// The type of this job.
enum JobType {
TYPE_ERROR,
TYPE_ASAR,
TYPE_FILE,
};
JobType type_;
std::shared_ptr<Archive> archive_;
base::FilePath file_path_;
Archive::FileInfo file_info_;
scoped_ptr<net::FileStream> stream_;
int64 remaining_bytes_;
FileMetaInfo meta_info_;
scoped_refptr<base::TaskRunner> file_task_runner_;
const scoped_refptr<base::TaskRunner> file_task_runner_;
net::HttpByteRange byte_range_;
int64 remaining_bytes_;
base::WeakPtrFactory<URLRequestAsarJob> weak_ptr_factory_;

View File

@@ -23,10 +23,7 @@ AtomURLRequestJobFactory::~AtomURLRequestJobFactory() {
}
bool AtomURLRequestJobFactory::SetProtocolHandler(
const std::string& scheme,
ProtocolHandler* protocol_handler) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
const std::string& scheme, scoped_ptr<ProtocolHandler> protocol_handler) {
if (!protocol_handler) {
ProtocolHandlerMap::iterator it = protocol_handler_map_.find(scheme);
if (it == protocol_handler_map_.end())
@@ -39,21 +36,17 @@ bool AtomURLRequestJobFactory::SetProtocolHandler(
if (ContainsKey(protocol_handler_map_, scheme))
return false;
protocol_handler_map_[scheme] = protocol_handler;
protocol_handler_map_[scheme] = protocol_handler.release();
return true;
}
ProtocolHandler* AtomURLRequestJobFactory::ReplaceProtocol(
const std::string& scheme,
ProtocolHandler* protocol_handler) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(protocol_handler);
scoped_ptr<ProtocolHandler> AtomURLRequestJobFactory::ReplaceProtocol(
const std::string& scheme, scoped_ptr<ProtocolHandler> protocol_handler) {
if (!ContainsKey(protocol_handler_map_, scheme))
return nullptr;
ProtocolHandler* original_protocol_handler = protocol_handler_map_[scheme];
protocol_handler_map_[scheme] = protocol_handler;
return original_protocol_handler;
protocol_handler_map_[scheme] = protocol_handler.release();
return make_scoped_ptr(original_protocol_handler);
}
ProtocolHandler* AtomURLRequestJobFactory::GetProtocolHandler(

View File

@@ -10,8 +10,7 @@
#include <string>
#include <vector>
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "base/synchronization/lock.h"
#include "net/url_request/url_request_job_factory.h"
@@ -25,13 +24,13 @@ class AtomURLRequestJobFactory : public net::URLRequestJobFactory {
// Sets the ProtocolHandler for a scheme. Returns true on success, false on
// failure (a ProtocolHandler already exists for |scheme|). On success,
// URLRequestJobFactory takes ownership of |protocol_handler|.
bool SetProtocolHandler(const std::string& scheme,
ProtocolHandler* protocol_handler);
bool SetProtocolHandler(
const std::string& scheme, scoped_ptr<ProtocolHandler> protocol_handler);
// Intercepts the ProtocolHandler for a scheme. Returns the original protocol
// handler on success, otherwise returns NULL.
ProtocolHandler* ReplaceProtocol(const std::string& scheme,
ProtocolHandler* protocol_handler);
scoped_ptr<ProtocolHandler> ReplaceProtocol(
const std::string& scheme, scoped_ptr<ProtocolHandler> protocol_handler);
// Returns the protocol handler registered with scheme.
ProtocolHandler* GetProtocolHandler(const std::string& scheme) const;

View File

@@ -0,0 +1,131 @@
// 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/js_asker.h"
#include <vector>
#include "atom/common/native_mate_converters/callback.h"
#include "atom/common/native_mate_converters/v8_value_converter.h"
#include "native_mate/function_template.h"
namespace atom {
namespace internal {
namespace {
struct CallbackHolder {
ResponseCallback callback;
};
// Cached JavaScript version of |HandlerCallback|.
v8::Persistent<v8::FunctionTemplate> g_handler_callback_;
// The callback which is passed to |handler|.
void HandlerCallback(v8::Isolate* isolate,
v8::Local<v8::External> external,
v8::Local<v8::Object> state,
mate::Arguments* args) {
// Check if the callback has already been called.
v8::Local<v8::String> called_symbol = mate::StringToSymbol(isolate, "called");
if (state->Has(called_symbol))
return; // no nothing
else
state->Set(called_symbol, v8::Boolean::New(isolate, true));
// If there is no argument passed then we failed.
scoped_ptr<CallbackHolder> holder(
static_cast<CallbackHolder*>(external->Value()));
CHECK(holder);
v8::Local<v8::Value> value;
if (!args->GetNext(&value)) {
content::BrowserThread::PostTask(
content::BrowserThread::IO, FROM_HERE,
base::Bind(holder->callback, false, nullptr));
return;
}
// Pass whatever user passed to the actaul request job.
V8ValueConverter converter;
v8::Local<v8::Context> context = args->isolate()->GetCurrentContext();
scoped_ptr<base::Value> options(converter.FromV8Value(value, context));
content::BrowserThread::PostTask(
content::BrowserThread::IO, FROM_HERE,
base::Bind(holder->callback, true, base::Passed(&options)));
}
// func.bind(func, arg1, arg2).
// NB(zcbenz): Using C++11 version crashes VS.
v8::Local<v8::Value> BindFunctionWith(v8::Isolate* isolate,
v8::Local<v8::Context> context,
v8::Local<v8::Function> func,
v8::Local<v8::Value> arg1,
v8::Local<v8::Value> arg2) {
v8::MaybeLocal<v8::Value> bind = func->Get(mate::StringToV8(isolate, "bind"));
CHECK(!bind.IsEmpty());
v8::Local<v8::Function> bind_func =
v8::Local<v8::Function>::Cast(bind.ToLocalChecked());
v8::Local<v8::Value> converted[] = { func, arg1, arg2 };
return bind_func->Call(
context, func, arraysize(converted), converted).ToLocalChecked();
}
// Generate the callback that will be passed to |handler|.
v8::MaybeLocal<v8::Value> GenerateCallback(v8::Isolate* isolate,
v8::Local<v8::Context> context,
const ResponseCallback& callback) {
// The FunctionTemplate is cached.
if (g_handler_callback_.IsEmpty())
g_handler_callback_.Reset(
isolate,
mate::CreateFunctionTemplate(isolate, base::Bind(&HandlerCallback)));
v8::Local<v8::FunctionTemplate> handler_callback =
v8::Local<v8::FunctionTemplate>::New(isolate, g_handler_callback_);
CallbackHolder* holder = new CallbackHolder;
holder->callback = callback;
return BindFunctionWith(isolate, context, handler_callback->GetFunction(),
v8::External::New(isolate, holder),
v8::Object::New(isolate));
}
} // namespace
void AskForOptions(v8::Isolate* isolate,
const JavaScriptHandler& handler,
net::URLRequest* request,
const ResponseCallback& callback) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
v8::Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = isolate->GetCurrentContext();
v8::Context::Scope context_scope(context);
// We don't convert the callback to C++ directly because creating
// FunctionTemplate will cause memory leak since V8 never releases it. So we
// have to create the function object in JavaScript to work around it.
v8::MaybeLocal<v8::Value> wrapped_callback = GenerateCallback(
isolate, context, callback);
if (wrapped_callback.IsEmpty()) {
callback.Run(false, nullptr);
return;
}
handler.Run(request, wrapped_callback.ToLocalChecked());
}
bool IsErrorOptions(base::Value* value, int* error) {
if (value->IsType(base::Value::TYPE_DICTIONARY)) {
base::DictionaryValue* dict = static_cast<base::DictionaryValue*>(value);
if (dict->GetInteger("error", error))
return true;
} else if (value->IsType(base::Value::TYPE_INTEGER)) {
if (value->GetAsInteger(error))
return true;
}
return false;
}
} // namespace internal
} // namespace atom

102
atom/browser/net/js_asker.h Normal file
View File

@@ -0,0 +1,102 @@
// 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_JS_ASKER_H_
#define ATOM_BROWSER_NET_JS_ASKER_H_
#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/values.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/net_errors.h"
#include "net/http/http_response_headers.h"
#include "net/url_request/url_request_context_getter.h"
#include "net/url_request/url_request_job.h"
#include "v8/include/v8.h"
namespace atom {
using JavaScriptHandler =
base::Callback<void(const net::URLRequest*, v8::Local<v8::Value>)>;
namespace internal {
using ResponseCallback =
base::Callback<void(bool, scoped_ptr<base::Value> options)>;
// Ask handler for options in UI thread.
void AskForOptions(v8::Isolate* isolate,
const JavaScriptHandler& handler,
net::URLRequest* request,
const ResponseCallback& callback);
// Test whether the |options| means an error.
bool IsErrorOptions(base::Value* value, int* error);
} // namespace internal
template<typename RequestJob>
class JsAsker : public RequestJob {
public:
JsAsker(net::URLRequest* request, net::NetworkDelegate* network_delegate)
: RequestJob(request, network_delegate), weak_factory_(this) {}
// Called by |CustomProtocolHandler| to store handler related information.
void SetHandlerInfo(
v8::Isolate* isolate,
net::URLRequestContextGetter* request_context_getter,
const JavaScriptHandler& handler) {
isolate_ = isolate;
request_context_getter_ = request_context_getter;
handler_ = handler;
}
// Subclass should do initailze work here.
virtual void StartAsync(scoped_ptr<base::Value> options) = 0;
net::URLRequestContextGetter* request_context_getter() const {
return request_context_getter_;
}
private:
// RequestJob:
void Start() override {
content::BrowserThread::PostTask(
content::BrowserThread::UI, FROM_HERE,
base::Bind(&internal::AskForOptions,
isolate_,
handler_,
RequestJob::request(),
base::Bind(&JsAsker::OnResponse,
weak_factory_.GetWeakPtr())));
}
void GetResponseInfo(net::HttpResponseInfo* info) override {
info->headers = new net::HttpResponseHeaders("");
}
// Called when the JS handler has sent the response, we need to decide whether
// to start, or fail the job.
void OnResponse(bool success, scoped_ptr<base::Value> value) {
int error = net::ERR_NOT_IMPLEMENTED;
if (success && value && !internal::IsErrorOptions(value.get(), &error)) {
StartAsync(value.Pass());
} else {
RequestJob::NotifyStartError(
net::URLRequestStatus(net::URLRequestStatus::FAILED, error));
}
}
v8::Isolate* isolate_;
net::URLRequestContextGetter* request_context_getter_;
JavaScriptHandler handler_;
base::WeakPtrFactory<JsAsker> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(JsAsker);
};
} // namespace atom
#endif // ATOM_BROWSER_NET_JS_ASKER_H_

View File

@@ -0,0 +1,37 @@
// Copyright (c) 2014 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_async_asar_job.h"
namespace atom {
UrlRequestAsyncAsarJob::UrlRequestAsyncAsarJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate)
: JsAsker<asar::URLRequestAsarJob>(request, network_delegate) {
}
void UrlRequestAsyncAsarJob::StartAsync(scoped_ptr<base::Value> options) {
base::FilePath::StringType file_path;
if (options->IsType(base::Value::TYPE_DICTIONARY)) {
static_cast<base::DictionaryValue*>(options.get())->GetString(
"path", &file_path);
} else if (options->IsType(base::Value::TYPE_STRING)) {
options->GetAsString(&file_path);
}
if (file_path.empty()) {
NotifyStartError(net::URLRequestStatus(
net::URLRequestStatus::FAILED, net::ERR_NOT_IMPLEMENTED));
} else {
asar::URLRequestAsarJob::Initialize(
content::BrowserThread::GetBlockingPool()->
GetTaskRunnerWithShutdownBehavior(
base::SequencedWorkerPool::SKIP_ON_SHUTDOWN),
base::FilePath(file_path));
asar::URLRequestAsarJob::Start();
}
}
} // namespace atom

View File

@@ -0,0 +1,27 @@
// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_NET_URL_REQUEST_ASYNC_ASAR_JOB_H_
#define ATOM_BROWSER_NET_URL_REQUEST_ASYNC_ASAR_JOB_H_
#include "atom/browser/net/asar/url_request_asar_job.h"
#include "atom/browser/net/js_asker.h"
namespace atom {
// Like URLRequestAsarJob, but asks the JavaScript handler for file path.
class UrlRequestAsyncAsarJob : public JsAsker<asar::URLRequestAsarJob> {
public:
UrlRequestAsyncAsarJob(net::URLRequest*, net::NetworkDelegate*);
// JsAsker:
void StartAsync(scoped_ptr<base::Value> options) override;
private:
DISALLOW_COPY_AND_ASSIGN(UrlRequestAsyncAsarJob);
};
} // namespace atom
#endif // ATOM_BROWSER_NET_URL_REQUEST_ASYNC_ASAR_JOB_H_

View File

@@ -6,20 +6,58 @@
#include <string>
#include "base/strings/string_number_conversions.h"
#include "net/base/net_errors.h"
namespace atom {
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_(data) {
net::URLRequest* request, net::NetworkDelegate* network_delegate)
: JsAsker<net::URLRequestSimpleJob>(request, network_delegate),
status_code_(net::HTTP_NOT_IMPLEMENTED) {
}
void URLRequestBufferJob::StartAsync(scoped_ptr<base::Value> options) {
const base::BinaryValue* binary = nullptr;
if (options->IsType(base::Value::TYPE_DICTIONARY)) {
base::DictionaryValue* dict =
static_cast<base::DictionaryValue*>(options.get());
dict->GetString("mimeType", &mime_type_);
dict->GetString("charset", &charset_);
dict->GetBinary("data", &binary);
} else if (options->IsType(base::Value::TYPE_BINARY)) {
options->GetAsBinary(&binary);
}
if (!binary) {
NotifyStartError(net::URLRequestStatus(
net::URLRequestStatus::FAILED, net::ERR_NOT_IMPLEMENTED));
return;
}
data_ = new base::RefCountedBytes(
reinterpret_cast<const unsigned char*>(binary->GetBuffer()),
binary->GetSize());
status_code_ = net::HTTP_OK;
net::URLRequestSimpleJob::Start();
}
void URLRequestBufferJob::GetResponseInfo(net::HttpResponseInfo* info) {
std::string status("HTTP/1.1 ");
status.append(base::IntToString(status_code_));
status.append(" ");
status.append(net::GetHttpReasonPhrase(status_code_));
status.append("\0\0", 2);
net::HttpResponseHeaders* headers = new net::HttpResponseHeaders(status);
if (!mime_type_.empty()) {
std::string content_type_header(net::HttpRequestHeaders::kContentType);
content_type_header.append(": ");
content_type_header.append(mime_type_);
headers->AddHeader(content_type_header);
}
info->headers = headers;
}
int URLRequestBufferJob::GetRefCountedData(
@@ -29,7 +67,7 @@ int URLRequestBufferJob::GetRefCountedData(
const net::CompletionCallback& callback) const {
*mime_type = mime_type_;
*charset = charset_;
*data = buffer_data_;
*data = data_;
return net::OK;
}

View File

@@ -7,19 +7,22 @@
#include <string>
#include "atom/browser/net/js_asker.h"
#include "base/memory/ref_counted_memory.h"
#include "net/http/http_status_code.h"
#include "net/url_request/url_request_simple_job.h"
#include "atom/common/node_includes.h"
namespace atom {
class URLRequestBufferJob : public net::URLRequestSimpleJob {
class URLRequestBufferJob : public JsAsker<net::URLRequestSimpleJob> {
public:
URLRequestBufferJob(net::URLRequest* request,
net::NetworkDelegate* network_delegate,
const std::string& mime_type,
const std::string& charset,
scoped_refptr<base::RefCountedBytes> data);
URLRequestBufferJob(net::URLRequest*, net::NetworkDelegate*);
// JsAsker:
void StartAsync(scoped_ptr<base::Value> options) override;
// URLRequestJob:
void GetResponseInfo(net::HttpResponseInfo* info) override;
// URLRequestSimpleJob:
int GetRefCountedData(std::string* mime_type,
@@ -30,7 +33,8 @@ class URLRequestBufferJob : public net::URLRequestSimpleJob {
private:
std::string mime_type_;
std::string charset_;
scoped_refptr<base::RefCountedBytes> buffer_data_;
scoped_refptr<base::RefCountedBytes> data_;
net::HttpStatusCode status_code_;
DISALLOW_COPY_AND_ASSIGN(URLRequestBufferJob);
};

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