Compare commits

..

1561 Commits

Author SHA1 Message Date
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
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
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
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
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
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
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
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
huangruichang
625ee387f3 * add quick-start.md for zh-CN 2015-09-01 00:34:00 +08: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
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
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
Cheng Zhao
135aca02af Bump v0.30.0 2015-07-17 01:01:25 +08:00
Cheng Zhao
7ab8134613 Don't upload PDB files in CI
Somehow it is blocking.
2015-07-17 00:54:57 +08: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
Cheng Zhao
02cadde8de Merge pull request #2200 from atom/input_accept_attr
Enable 'accept' attribute in 'input' label.
2015-07-16 07:20:30 -07:00
Cheng Zhao
88ab23def9 Update brightray for #1852 2015-07-16 06:36:10 -07:00
Cheng Zhao
db6d8de5dc docs: Say more about standard scheme 2015-07-16 06:32:09 -07:00
Cheng Zhao
652843f447 Merge pull request #2234 from astoilkov/patch-1
fix typo in browser-window.md
2015-07-16 04:34:23 -07:00
Haojian Wu
21e5054fac Make <input type="file"\> remember last used directory. 2015-07-16 19:29:12 +08:00
Cheng Zhao
a2c26b8c74 Fix hanlding trailing slash in asar package, close #2222 2015-07-16 03:49:26 -07:00
Haojian Wu
2cd6ad1a97 More code style fixing. 2015-07-16 18:42:20 +08:00
Cheng Zhao
78e55414d4 Merge pull request #2235 from mhkeller/doc-json-fix
valid example json, fix https://github.com/atom/electron/issues/2228
2015-07-16 02:53:59 -07: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
Jeffrey Morgan
4baaf03ac7 Improve grammar and comments
Improve the grammar and sentence structure of the text and improve the code comments.
2015-07-15 16:48:24 -07:00
Cheng Zhao
c2bfc60a59 Merge pull request #2216 from UsabilityEtc/patch-1
Improve grammar and code formatting
2015-07-15 16:44:20 -07:00
Cheng Zhao
f78dcfb8e0 Merge pull request #2214 from PButcher/patch-1
Update window-open.md
2015-07-15 16:43:50 -07:00
Cheng Zhao
91bfd1f77c Merge pull request #2206 from dalinaum/patch-1
Update README-ko.md
2015-07-15 13:14:05 -07:00
Cheng Zhao
9ee0d46734 Use CTRL+SHIFT+I for toggling devtools, fix #2205 2015-07-15 13:11:01 -07:00
mhkeller
ca2cb9c9ba valid example json, fix https://github.com/atom/electron/issues/2228 2015-07-15 10:34:33 -04:00
Antonio Stoilkov
00c484c68b fix typo in browser-window.md 2015-07-15 17:29:02 +03: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
Cheng Zhao
1e9eccf959 Forward the crashed event to BrowserWindow, fix #2201 2015-07-14 15:13:41 -07:00
Cheng Zhao
4b06c0645c Merge pull request #2220 from atom/provide-user-agent
Provide default user agent in BrowserContext
2015-07-14 13:17:36 -07:00
Cheng Zhao
c6f870d4e4 Fix cpplint warnings 2015-07-14 12:16:13 -07:00
Cheng Zhao
053594eae8 Set default user agent for WebContents 2015-07-14 12:13:25 -07:00
Cheng Zhao
1615c97ce8 Don't set two "Electron"s in user agent 2015-07-14 12:12:55 -07:00
Cheng Zhao
940db1d1dd Provide default user agent in BrowserContext 2015-07-14 11:40:15 -07:00
Cheng Zhao
56dfef8d0d spec: Test user agent in websocket 2015-07-14 11:39:41 -07:00
Cheng Zhao
3ffd774405 Merge pull request #2197 from deepak1556/user_agent_patch
webContents: set http useragent settings when overriding user agent
2015-07-14 09:59:09 -07:00
Cheng Zhao
076942ca7a Merge pull request #2215 from atom/delete-global
Don't expose "global" when node integration is off
2015-07-14 09:53:44 -07:00
Cheng Zhao
b6e8420bf2 spec: Check if window.global is set 2015-07-14 09:15:03 -07:00
Cheng Zhao
096439dce7 Don't expose "global" when node integration is off 2015-07-14 09:15:03 -07:00
Cheng Zhao
346fb745f2 No need to actually create a page for cookie test 2015-07-14 09:14:22 -07:00
Cheng Zhao
020ccd8018 spec: Cookie test should not rely on cookie's count
Other apps can also write cookie to `file://` protocol.
2015-07-14 08:59:06 -07:00
Jeffrey Morgan
ce24226128 Update global-shortcut.md
Improved the grammar and code formatting of global-shortcut.md.
2015-07-14 16:58:15 +01:00
Peter Butcher
b3c51e46e7 Update window-open.md
Just an irritating typo.
2015-07-14 16:37:52 +01:00
Cheng Zhao
886db7a3f2 Merge pull request #2195 from atom/jl-docs-typo
Fix docs typo
2015-07-14 08:35:33 -07:00
Cheng Zhao
6c5dde60a3 Merge pull request #2211 from atom/no-heap-stl
Avoiding creating static STL containers
2015-07-14 02:48:05 -07:00
Cheng Zhao
7f06072420 Avoiding creating static STL containers
It is OK under most cases, but if you happen to also use COM in your
application, you will have heap corruptions.
2015-07-14 17:33:16 +08:00
Cheng Zhao
5708b7fbec Fix the ill cookie test 2015-07-14 02:32:20 -07:00
Cheng Zhao
5863ed4c33 win: Also map MESSAGE_BOX_TYPE_QUESTION to TD_INFORMATION_ICON 2015-07-13 21:51:19 -07:00
Cheng Zhao
14388feb23 Merge pull request #2187 from jprichardson/patch-1
emit error object on process.on('uncaughtException') in renderer
2015-07-13 21:46:06 -07:00
Cheng Zhao
e5f852d7d5 docs: Adds the dependencies of arm target
Close #2181
2015-07-13 15:26:35 -07:00
Cheng Zhao
83e8ceceda Fix session specs 2015-07-13 15:23:02 -07:00
Cheng Zhao
3ef54147c9 Merge pull request #2179 from deepak1556/proxy_patch
doc: kProxyPacUrl support
2015-07-13 15:14:58 -07:00
Cheng Zhao
f8df377631 Update brightray, refs #1599 2015-07-13 15:14:28 -07:00
Cheng Zhao
868dee55de The options of clearStorageData should be optional 2015-07-13 15:13:17 -07:00
Cheng Zhao
7dba4d1d8d Call callback of ClearCache after cache is doomed 2015-07-13 14:27:07 -07:00
Cheng Zhao
6840d424cd docs: Add WebContents.session 2015-07-13 12:41:07 -07:00
Cheng Zhao
34819140c3 Merge pull request #2102 from deepak1556/storage_cleanup_api_patch
app: api to clear data from different storage types
2015-07-13 12:34:48 -07:00
Cheng Zhao
9e8a118d10 Cleanup code 2015-07-14 03:23:19 +08:00
Cheng Zhao
0c7c6ddcc9 Merge pull request #2175 from atom/propagate-app-model-id
Propagate App Model User ID on Windows
2015-07-13 12:16:10 -07:00
LYK
eadd2f8de6 Update README-ko.md
Remove a personal email address and repository.
2015-07-13 23:29:06 +09:00
Haojian Wu
04606a9f97 Enable 'accept' attribute in 'input' label. 2015-07-13 14:47:30 +08:00
Robo
cb4309bbd9 webContents: set http useragent settings when overriding user agent 2015-07-13 02:20:15 +05:30
Jessica Lord
1249196118 Fix docs typo
It was breaking the docs site build because it's a code block type
2015-07-11 19:46:26 -07:00
JP Richardson
d6ae874038 emit error object on process.on('uncaughtException') in renderer
Chromium added the actual `error` object to the 5th parameter in `window.onerror`. This should be emitted as opposed to the `errorMsg` string. Worse yet, since `errorMsg` wasn't an instance of `Error`, any code that assumes this in any `process.on('uncaughtException')` handler would fail. Also, correctly emitting the error provides the stack trace.

This is now an HTML5 standard.

Sources:
- https://html.spec.whatwg.org/multipage/webappapis.html#errorevent
- https://mikewest.org/2013/08/debugging-runtime-errors-with-window-onerror
- https://code.google.com/p/chromium/issues/detail?id=147127
2015-07-10 14:38:03 -05:00
Robo
e0e4c1b54c doc: kProxyPacUrl support 2015-07-10 13:56:21 +05:30
Robo
628fb5f5e9 app: api to clear data from different storage types 2015-07-10 11:31:30 +05:30
Cheng Zhao
967c273ddb Always use top window's context for resolving url
Refs #2166.
2015-07-10 13:57:09 +08:00
Cheng Zhao
a24d2921af Merge pull request #2164 from hankbao/global-shortcut-doc-update
Update global-shortcut.md
2015-07-10 13:33:07 +08:00
Cheng Zhao
5ae57baf11 Allow more insecure content when web-security is off
Close #2076
2015-07-10 13:29:46 +08:00
Cheng Zhao
7a390bdd4c Merge pull request #2125 from deepak1556/protocol_cleanup
protocol: cleanup
2015-07-10 12:16:17 +08:00
Cheng Zhao
72f4884127 Merge pull request #2144 from deepak1556/clipboard_multiwrite_patch
clipboard: api to write multiple formats to same writer
2015-07-10 12:14:58 +08:00
Cheng Zhao
6383eb876e Fix failed specs caused by window.open url parsing 2015-07-10 12:14:25 +08:00
Robo
c56b3425a9 read/write protocol handler map in IO 2015-07-10 09:33:36 +05:30
Robo
2d3e938a7f clipboard: api to write multiple formats to same writer 2015-07-10 09:20:52 +05:30
Cheng Zhao
260ec96edd Resolve relative urls in window.open, fix #2166 2015-07-10 11:36:41 +08:00
Cheng Zhao
4379d24e9d Event "close" => "closed", fix #2149 2015-07-10 10:38:15 +08:00
Cheng Zhao
fedf764b7b Merge pull request #2161 from atom/close-test
Add a test to verify the WebView close event
2015-07-10 10:36:23 +08:00
Paul Betts
39c6e2d2e5 Linter fixes 2015-07-09 17:00:19 -07:00
Paul Betts
35aaad68d7 Set the AppUserModelId on the renderer side 2015-07-09 16:48:02 -07:00
Paul Betts
779583adf5 Append the app user model ID as a switch 2015-07-09 16:37:12 -07:00
Paul Betts
a0784bd038 Add a new renderer switch to pass down the app model ID 2015-07-09 16:37:11 -07:00
Hank Bao
fc9612a5ed Fix sample code indention 2015-07-09 22:49:16 +08:00
Robo
2cd5fb5694 add compatibility will old api 2015-07-09 14:48:58 +05:30
Robo
da00329d78 protocol: cleanup 2015-07-09 14:48:58 +05:30
Hank Bao
fb99bfac52 Update sample code in global-shortcut.md 2015-07-09 17:03:58 +08:00
Hank Bao
7b19b6b4f2 Update global-shortcut.md
Make it clear that the `global-shortcut` module should not be used until the ready event of app module gets emitted.
2015-07-09 12:30:37 +08:00
Kevin Sawicki
d661099322 Merge pull request #2159 from atom/code-of-conduct
Code of Conduct
2015-07-08 15:22:40 -07:00
Paul Betts
ea63a04388 Add a test to verify the webview close event 2015-07-08 14:34:44 -07:00
Brandon Keepers
6f92141587 Add code of conduct to README 2015-07-08 16:29:24 -04:00
Brandon Keepers
078bd7fb5b Add code of conduct to contributing guidelines 2015-07-08 16:23:06 -04:00
Cheng Zhao
1703a6f20e Merge pull request #2152 from atom/task-dialog
Implement showMessageBox with TaskDialogIndirect
2015-07-08 16:41:29 +08:00
Cheng Zhao
001b4a3179 Final cleanup 2015-07-08 16:24:39 +08:00
Cheng Zhao
aab78db8b8 On Windows "Cancel" button is also forced to be canclId 2015-07-08 16:00:30 +08:00
Cheng Zhao
9793473b10 Show custom buttons as links 2015-07-08 15:57:45 +08:00
Cheng Zhao
a89e5592f2 Use stock buttons on Windows when possible 2015-07-08 15:55:53 +08:00
Cheng Zhao
989351a41d Show user's icon when specified 2015-07-08 15:04:34 +08:00
Cheng Zhao
6fb8b2ce4f Show icon according to dialog's type 2015-07-08 14:46:06 +08:00
Cheng Zhao
f0be4025a5 If "detail" is empty then don't make message hilighted 2015-07-08 14:41:19 +08:00
Cheng Zhao
49da74f976 Handle when dialog is cancelled 2015-07-08 14:35:28 +08:00
Cheng Zhao
1146441c2a Implement ShowMessageBox with TaskDialog 2015-07-08 14:12:11 +08:00
Cheng Zhao
d01c200345 Set compilation requirements for using TaskDialogIndirect
* Link with Comctl32.lib
* Update manifest file to use common controls v6

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

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

Fix bug

Tranlsate the world web

Change the method

Translate tutorial/quick-start-jp.md

Translate docs

Translate

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

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

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

This patch unrestricts this time limit.
2015-05-30 08:47:52 +08:00
Haojian Wu
98a9d8a9e3 Enable crashpad test on OS X. 2015-05-30 07:34:56 +08:00
Haojian Wu
4e2f242ad0 Use Crashpad instead of Breakpad on OS X. 2015-05-29 23:25:11 +08:00
Cheng Zhao
02bdace366 Delete Node's symbols after Environment has been loaded
Fix #1803.
2015-05-29 22:20:20 +08:00
Cheng Zhao
6ed538b952 docs: Remove obsolete build instructions, close #1809 2015-05-29 18:21:25 +08:00
Cheng Zhao
dfbe158ca9 mac: Remove dead "Frameworks" link, close #1801 2015-05-29 18:14:59 +08:00
Cheng Zhao
fb37b5720d Update brightray to use correct Chrome version string
Close #1808
2015-05-29 17:52:46 +08:00
fraserxu
57ab704300 convert message to string for window.alert method 2015-05-29 15:55:11 +08:00
Cheng Zhao
4a310ad630 Merge pull request #1811 from atom/new-webview
Change how webview is resized
2015-05-29 14:14:23 +08:00
Cheng Zhao
a9ad783bca The ElementSizeChanged has been removed 2015-05-29 13:52:14 +08:00
Cheng Zhao
b5c9fe78f1 Listen to ElementSizeChanged event 2015-05-29 13:47:09 +08:00
Cheng Zhao
e4bb456964 Pass element size when attaching 2015-05-29 11:47:54 +08:00
Cheng Zhao
b45ed8d9a2 pendingGuestCreation is removed 2015-05-29 11:20:28 +08:00
Cheng Zhao
bdf73fcd4c Update to the new algorithm of setting webview size 2015-05-29 11:12:55 +08:00
Cheng Zhao
3e720bd611 Bump v0.27.1 2015-05-28 16:23:29 +08:00
Cheng Zhao
ad89a923e9 Merge pull request #1785 from deepak1556/browser_client_patch
browserClient: dont restart render process for javascript scheme
2015-05-28 16:22:45 +08:00
Cheng Zhao
725115e0b5 Merge pull request #1799 from atom/linux-travis-ci
Use gcc-4.8 on CI machine
2015-05-28 16:22:36 +08:00
Cheng Zhao
419a14a63f Use gcc-4.8 on CI machine 2015-05-28 16:03:06 +08:00
Cheng Zhao
d9102efff7 Merge pull request #1752 from deepak1556/clipboard_patch
clipboard: api to list supported types, reading and writing markup
2015-05-28 15:29:36 +08:00
Cheng Zhao
895ab49857 Merge pull request #1797 from deepak1556/response_headers_patch
fix accessing headers from resourcerequestdetails
2015-05-28 14:44:46 +08:00
Cheng Zhao
ebbb974aca Fix running spec on Windows 2015-05-28 14:43:16 +08:00
Cheng Zhao
8a6ba7c49f Update libchromiumcontent for race condition fix 2015-05-28 14:43:15 +08:00
deepak1556
f98da217e1 fix accessing headers from resourcerequestdetails 2015-05-28 11:20:07 +05:30
Jessica Lord
2060acd914 Merge pull request #1792 from atom/jl-cmd
Replace cmd with bash
2015-05-27 14:37:17 -07:00
Jessica Lord
014d80c359 Replace cmd with bash
Markdown parser doesn’t recognize cmd.
2015-05-27 12:51:19 -07:00
deepak1556
9b7ad675c6 browserClient: dont restart render process for javascript: scheme 2015-05-27 16:39:02 +05:30
Cheng Zhao
6ee8f6e4f2 Bump v0.27.0 2015-05-27 16:57:41 +08:00
deepak1556
4d56281972 restore clipboard.has api and fix docs 2015-05-27 13:35:51 +05:30
deepak1556
5584e3fd49 clipboard: api to list supported types, reading and writing markup 2015-05-27 13:21:56 +05:30
Cheng Zhao
4a376694b4 Merge pull request #1719 from deepak1556/service_worker_patch
devtools: api to inspect service worker
2015-05-27 15:47:41 +08:00
Cheng Zhao
fbdea15649 Update node, fix #634 2015-05-27 15:26:48 +08:00
Cheng Zhao
f961f0617f test: Add case for #634 2015-05-27 15:26:32 +08:00
Cheng Zhao
1c60575dc0 Merge pull request #1738 from deepak1556/http_ptach
webContents: providing header details with response event
2015-05-27 15:05:55 +08:00
Cheng Zhao
abf8ffd3a2 Merge pull request #1689 from deepak1556/ftp_patch
protocol: adding ftp scheme support
2015-05-27 15:04:21 +08:00
Cheng Zhao
935cd92ef3 Update brightray 2015-05-27 15:03:12 +08:00
Cheng Zhao
172a5a71fc docs: "move" and "moved" are platform-dependent 2015-05-27 14:57:14 +08:00
Cheng Zhao
c244e83e10 Merge pull request #1633 from deepak1556/window_event_patch
window: adding resize and move events
2015-05-27 14:54:36 +08:00
Cheng Zhao
291604515f Update libchromiumcontent for optional pdf.dll 2015-05-26 12:44:24 +08:00
Cheng Zhao
904b75ab4a Merge pull request #1669 from hokein/pdf-dll
Load pdf library dynamically
2015-05-26 12:41:51 +08:00
deepak1556
2de0b025f1 retrieve headers from response info 2015-05-24 10:56:25 +05:30
Cheng Zhao
5f52ca918f Merge pull request #1763 from samccone/patch-4
Fix grammatical issues take 3
2015-05-24 10:43:37 +08:00
Cheng Zhao
16a95a42ff Merge pull request #1761 from samccone/patch-3
docs: Fix grammatical issues
2015-05-24 10:42:53 +08:00
Cheng Zhao
4282ed6a3c Merge pull request #1760 from samccone/patch-2
Docs: Fix grammatical issue
2015-05-24 10:42:47 +08:00
Sam Saccone
a642782a00 💄 Fix grammatical issues 2015-05-23 18:44:58 -04:00
Sam Saccone
0bb4e0e44a 💄 Fix grammatical issues 2015-05-23 16:00:09 -04:00
Sam Saccone
d91ddc6177 💄 Fix grammatical issue 2015-05-23 15:41:36 -04:00
deepak1556
2b9826404a using mate::Dictionary instead of base::DictionaryValue 2015-05-23 19:26:47 +05:30
deepak1556
4d5790dc09 return headers as object 2015-05-23 19:26:47 +05:30
deepak1556
c22b138b67 webContents: providing header details with response event 2015-05-23 19:26:47 +05:30
Haojian Wu
fdad5892d9 📝 Add pdf.dll note doc. 2015-05-23 21:39:59 +08:00
Haojian Wu
c3791bba78 Remove duplicated macro. 2015-05-23 19:24:37 +08:00
Haojian Wu
bf5f85645e Remove the multiple rules generate pdf.dll warning in GYP during debug
build.
2015-05-23 19:24:35 +08:00
Haojian Wu
f1f801b7a2 Copy pdf.dll to build directory. 2015-05-23 19:24:30 +08:00
Haojian Wu
5ede62459c Rename PrintHandler to PrintHandlerWin since only used on Windows. 2015-05-23 19:24:29 +08:00
Haojian Wu
abd97a7513 Load pdf component dynamically.
Ship pdf as dll library, electron only loads pdf.dll when calling print
API. In this way, the developer who don't need print feature can safe
remove the pdf.dll in saving their binary size.
2015-05-23 19:24:27 +08:00
Cheng Zhao
30d815e28f Merge pull request #1755 from atom/chrome43
Upgrade to Chrome 43
2015-05-23 12:24:36 +08:00
Cheng Zhao
e233eab4f2 HandleMouseDown is deprecated 2015-05-23 11:58:20 +08:00
Cheng Zhao
b202bba2e6 Don't read Buffer in IO thread 2015-05-22 22:15:13 +08:00
Cheng Zhao
d78efe7c22 Use Local instead of Handle 2015-05-22 19:11:22 +08:00
Cheng Zhao
b169ac016e Start AtomRenderFrameObserver 2015-05-22 15:59:29 +08:00
Cheng Zhao
d1685f79a2 Initialize V8 in browser process
Previously it was initialized by ProxyResolverV8, but after Chrome 43 V8
started to initialize V8 lazily.
2015-05-22 15:30:02 +08:00
Cheng Zhao
01e891652f Fix compilation errors 2015-05-22 15:24:34 +08:00
Cheng Zhao
c82d21b39f Add AtomRenderFrameObserver 2015-05-22 15:01:13 +08:00
Cheng Zhao
63c2a7f1a9 Upgrade to Chrome 43 2015-05-22 14:57:00 +08:00
deepak1556
9a60fde59b alias move and moved event on OS X 2015-05-22 12:24:12 +05:30
Robo
f46fcd158a chnage move hook and add details to doc 2015-05-22 12:13:01 +05:30
Robo
1b1735bca9 avoid unnecessary api calls 2015-05-22 12:13:00 +05:30
deepak1556
3a5977e09f window: adding resize and move events 2015-05-22 12:13:00 +05:30
Cheng Zhao
d34800bb0a Merge pull request #1708 from kevva/patch-1
Add link to `awesome-electron`
2015-05-22 14:24:59 +08:00
Cheng Zhao
662261f84f Merge pull request #1724 from atom/jl-contrib
Add a CONTRIBUTING.md document
2015-05-22 10:33:39 +08:00
Cheng Zhao
33a926c5d3 Fix typo 2015-05-22 10:32:59 +08:00
Cheng Zhao
c372dcb462 Merge pull request #1706 from hammerandchisel/crash-reporter-reinit
Explicitly null the crash reporter before assigning it
2015-05-22 10:17:00 +08:00
Andy Dill
9a768dd4f0 Remove explicit nullptr and add clarifying comment. 2015-05-21 09:02:17 -07:00
deepak1556
27c3727ddb use generated constants 2015-05-21 11:07:25 +05:30
deepak1556
ea147c588f protocol: adding ftp scheme support 2015-05-21 10:59:56 +05:30
Jessica Lord
25019de690 Remove example 2015-05-19 11:18:22 -07:00
Jessica Lord
8fea373758 Use Electron repo search url 2015-05-19 11:08:43 -07:00
Jessica Lord
3387459be2 Start a contributing doc 2015-05-18 18:29:13 -07:00
deepak1556
9963ddc485 implement method on browser window 2015-05-18 20:08:08 +05:30
deepak1556
46d80e8f05 devtools: api to inspect service worker for current webcontents 2015-05-18 19:19:33 +05:30
Kevin Mårtensson
36c376b1ec Add link to awesome-electron 2015-05-16 17:03:19 +02:00
Andy Dill
dcbc6a127b Explicitly null the crash reporter before assigning it to allow the EH to unregister. 2015-05-15 22:37:00 -07:00
469 changed files with 25829 additions and 7373 deletions

5
.gitignore vendored
View File

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

9
.gitmodules vendored
View File

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

View File

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

75
CONTRIBUTING.md Normal file
View File

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

58
README-ko.md Normal file
View File

@@ -0,0 +1,58 @@
[![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에서 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에 대한 중요한 알림을 받고 싶다면 Twitter에서 [@ElectronJS](https://twitter.com/electronjs)를 팔로우 하세요.
이 프로젝트는 기여자 규약 1.2를 준수합니다. 이 프로젝트에 참여할 때 코드를 유지해야 합니다. 받아들일 수 없는 행동은 atom@github.com로 보고 하십시오.
## 다운로드
Linux, Windows, Mac용으로 미리 빌드된 Electron 바이너리와 디버그 심볼이 준비되어 있습니다. [releases](https://github.com/atom/electron/releases) 페이지에서 받아 볼 수 있습니다.
또한 [`npm`](https://docs.npmjs.com/)을 통해 미리 빌드된 Electron 바이너리를 받을 수도 있습니다:
```sh
# $PATH에 `electron` 커맨드를 등록하고 전역에 설치합니다.
npm install electron-prebuilt -g
# 개발 의존성 모듈 형태로 설치합니다.
npm install electron-prebuilt --save-dev
```
### 미러
- [China](https://npm.taobao.org/mirrors/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)
- [일본어](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` 채널
- Slack의 [`Atom`](http://atom-slack.herokuapp.com/) 채널
[awesome-electron](https://github.com/sindresorhus/awesome-electron) 프로젝트엔 커뮤니티가 운영중인 유용한 예제 어플리케이션과 도구, 리소스가 있으니 한번 참고해 보시기 바랍니다.

View File

@@ -2,8 +2,9 @@
[![Build Status](https://travis-ci.org/atom/electron.svg?branch=master)](https://travis-ci.org/atom/electron)
[![devDependency Status](https://david-dm.org/atom/electron/dev-status.svg)](https://david-dm.org/atom/electron#info=devDependencies)
[![Join the Electron Community on Slack](http://atom-slack.herokuapp.com/badge.svg)](http://atom-slack.herokuapp.com/)
:zap: *formerly known as Atom Shell* :zap:
: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
@@ -13,6 +14,10 @@ editor](https://github.com/atom/atom).
Follow [@ElectronJS](https://twitter.com/electronjs) on Twitter for important
announcements.
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
Prebuilt binaries and debug symbols of Electron for Linux, Windows and Mac can
@@ -39,7 +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)
- [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.

View File

@@ -4,9 +4,7 @@
'product_name%': 'Electron',
'company_name%': 'GitHub, Inc',
'company_abbr%': 'github',
'version%': '0.26.1',
'atom_source_root': '<!(["python", "tools/atom_source_root.py"])',
'version%': '0.33.0',
},
'includes': [
'filenames.gypi',
@@ -17,8 +15,12 @@
'ATOM_PRODUCT_NAME="<(product_name)"',
'ATOM_PROJECT_NAME="<(project_name)"',
],
'mac_framework_dirs': [
'<(atom_source_root)/external_binaries',
'conditions': [
['OS=="mac"', {
'mac_framework_dirs': [
'<(source_root)/external_binaries',
],
}],
],
},
'targets': [
@@ -114,6 +116,15 @@
],
}], # OS!="mac"
['OS=="win"', {
'include_dirs': [
'<(libchromiumcontent_dir)/gen/ui/resources',
],
'msvs_settings': {
'VCManifestTool': {
'EmbedManifest': 'true',
'AdditionalManifestFiles': 'atom/browser/resources/win/atom.manifest',
}
},
'copies': [
{
'variables': {
@@ -124,14 +135,15 @@
'<@(libchromiumcontent_shared_v8_libraries)',
],
}, {
'copied_libraries': [],
'copied_libraries': [
'<(libchromiumcontent_dir)/pdf.dll',
],
}],
],
},
'destination': '<(PRODUCT_DIR)',
'files': [
'<@(copied_libraries)',
'<(libchromiumcontent_dir)/ffmpegsumo.dll',
'<(libchromiumcontent_dir)/libEGL.dll',
'<(libchromiumcontent_dir)/libGLESv2.dll',
'<(libchromiumcontent_dir)/icudtl.dat',
@@ -154,6 +166,10 @@
]
},
],
}, {
'dependencies': [
'vendor/breakpad/breakpad.gyp:dump_syms#host',
],
}], # OS=="win"
['OS=="linux"', {
'copies': [
@@ -176,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',
@@ -209,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)',
@@ -255,8 +268,9 @@
'libraries': [
'-limm32.lib',
'-loleacc.lib',
'-lComdlg32.lib',
'-lWininet.lib',
'-lcomctl32.lib',
'-lcomdlg32.lib',
'-lwininet.lib',
],
},
'dependencies': [
@@ -273,7 +287,8 @@
}], # OS=="win"
['OS=="mac"', {
'dependencies': [
'vendor/breakpad/breakpad.gyp:breakpad',
'vendor/crashpad/client/client.gyp:crashpad_client',
'vendor/crashpad/handler/handler.gyp:crashpad_handler',
],
}], # OS=="mac"
['OS=="linux"', {
@@ -422,14 +437,12 @@
'destination': '<(PRODUCT_DIR)/<(product_name) Framework.framework/Versions/A/Libraries',
'files': [
'<@(copied_libraries)',
'<(libchromiumcontent_dir)/ffmpegsumo.so',
],
},
{
'destination': '<(PRODUCT_DIR)/<(product_name) Framework.framework/Versions/A/Resources',
'files': [
'<(PRODUCT_DIR)/Inspector',
'<(PRODUCT_DIR)/crash_report_sender.app',
'<(PRODUCT_DIR)/crashpad_handler',
],
},
],
@@ -444,13 +457,22 @@
'${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': [
'tools/mac/create-framework-subdir-symlinks.sh',
'<(product_name) Framework',
'Libraries',
'Frameworks',
],
},
],

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,9 +74,25 @@ 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) {
auto command_line = base::CommandLine::ForCurrentProcess();
auto custom_schemes = command_line->GetSwitchValueASCII(
switches::kRegisterStandardSchemes);
if (!custom_schemes.empty()) {
std::vector<std::string> schemes;
base::SplitString(custom_schemes, ',', &schemes);
standard_schemes->insert(standard_schemes->end(),
schemes.begin(),
schemes.end());
}
standard_schemes->push_back("chrome-extension");
}

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

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

View File

@@ -3,7 +3,6 @@
// found in the LICENSE file.
#include "atom/app/atom_main.h"
#include "atom/app/atom_main_args.h"
#include <stdlib.h>
#include <string.h>
@@ -33,6 +32,8 @@
#endif // defined(OS_MACOSX)
#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.
@@ -64,6 +66,10 @@ void AtomMainDelegate::PreSandboxStartup() {
std::string process_type = command_line->GetSwitchValueASCII(
switches::kProcessType);
if (process_type == switches::kUtilityProcess) {
AtomContentUtilityClient::PreSandboxStartup();
}
// Only append arguments for browser process.
if (!process_type.empty())
return;

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

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

View File

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

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

View File

@@ -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::Handle<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::Handle<v8::Value> val,
base::trace_event::TraceOptions* out) {
std::string options;
v8::Local<v8::Value> val,
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,22 +38,45 @@ struct Converter<base::trace_event::TraceOptions> {
namespace {
void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
v8::Handle<v8::Context> context, void* priv) {
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());
mate::Dictionary dict(context->GetIsolate(), exports);
dict.SetMethod("getCategories", base::Bind(
&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

@@ -0,0 +1,346 @@
// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_cookies.h"
#include "atom/common/native_mate_converters/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/dictionary.h"
#include "native_mate/object_template_builder.h"
#include "net/cookies/cookie_monster.h"
#include "net/cookies/cookie_store.h"
#include "net/cookies/cookie_util.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
using atom::api::Cookies;
using content::BrowserThread;
namespace {
bool GetCookieListFromStore(
net::CookieStore* cookie_store,
const std::string& url,
const net::CookieMonster::GetCookieListCallback& callback) {
DCHECK(cookie_store);
GURL gurl(url);
net::CookieMonster* monster = cookie_store->GetCookieMonster();
// Empty url will match all url cookies.
if (url.empty()) {
monster->GetAllCookiesAsync(callback);
return true;
}
if (!gurl.is_valid())
return false;
monster->GetAllCookiesForURLAsync(gurl, callback);
return true;
}
void RunGetCookiesCallbackOnUIThread(v8::Isolate* isolate,
const std::string& error_message,
const net::CookieList& cookie_list,
const Cookies::CookiesCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
v8::Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
if (!error_message.empty()) {
v8::Local<v8::Value> error = mate::ConvertToV8(isolate, error_message);
callback.Run(error, v8::Null(isolate));
return;
}
callback.Run(v8::Null(isolate), mate::ConvertToV8(isolate, cookie_list));
}
void RunRemoveCookiesCallbackOnUIThread(
v8::Isolate* isolate,
const std::string& error_message,
const Cookies::CookiesCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
v8::Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
if (!error_message.empty()) {
v8::Local<v8::Value> error = mate::ConvertToV8(isolate, error_message);
callback.Run(error, v8::Null(isolate));
return;
}
callback.Run(v8::Null(isolate), v8::Null(isolate));
}
void RunSetCookiesCallbackOnUIThread(v8::Isolate* isolate,
const std::string& error_message,
bool set_success,
const Cookies::CookiesCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
v8::Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
if (!error_message.empty()) {
v8::Local<v8::Value> error = mate::ConvertToV8(isolate, error_message);
callback.Run(error, v8::Null(isolate));
return;
}
if (!set_success) {
v8::Local<v8::Value> error = mate::ConvertToV8(
isolate, "Failed to set cookies");
callback.Run(error, v8::Null(isolate));
}
callback.Run(v8::Null(isolate), v8::Null(isolate));
}
bool MatchesDomain(const base::DictionaryValue* filter,
const std::string& cookie_domain) {
std::string filter_domain;
if (!filter->GetString("domain", &filter_domain))
return true;
// Add a leading '.' character to the filter domain if it doesn't exist.
if (net::cookie_util::DomainIsHostOnly(filter_domain))
filter_domain.insert(0, ".");
std::string sub_domain(cookie_domain);
// Strip any leading '.' character from the input cookie domain.
if (!net::cookie_util::DomainIsHostOnly(sub_domain))
sub_domain = sub_domain.substr(1);
// Now check whether the domain argument is a subdomain of the filter domain.
for (sub_domain.insert(0, ".");
sub_domain.length() >= filter_domain.length();) {
if (sub_domain == filter_domain) {
return true;
}
const size_t next_dot = sub_domain.find('.', 1); // Skip over leading dot.
sub_domain.erase(0, next_dot);
}
return false;
}
bool MatchesCookie(const base::DictionaryValue* filter,
const net::CanonicalCookie& cookie) {
std::string name, domain, path;
bool is_secure, session;
if (filter->GetString("name", &name) && name != cookie.Name())
return false;
if (filter->GetString("path", &path) && path != cookie.Path())
return false;
if (!MatchesDomain(filter, cookie.Domain()))
return false;
if (filter->GetBoolean("secure", &is_secure) &&
is_secure != cookie.IsSecure())
return false;
if (filter->GetBoolean("session", &session) &&
session != cookie.IsPersistent())
return false;
return true;
}
} // namespace
namespace mate {
template<>
struct Converter<net::CanonicalCookie> {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
const net::CanonicalCookie& val) {
mate::Dictionary dict(isolate, v8::Object::New(isolate));
dict.Set("name", val.Name());
dict.Set("value", val.Value());
dict.Set("domain", val.Domain());
dict.Set("host_only", net::cookie_util::DomainIsHostOnly(val.Domain()));
dict.Set("path", val.Path());
dict.Set("secure", val.IsSecure());
dict.Set("http_only", val.IsHttpOnly());
dict.Set("session", val.IsPersistent());
if (!val.IsPersistent())
dict.Set("expirationDate", val.ExpiryDate().ToDoubleT());
return dict.GetHandle();
}
};
} // namespace mate
namespace atom {
namespace api {
Cookies::Cookies(content::BrowserContext* browser_context)
: request_context_getter_(browser_context->GetRequestContext()) {
}
Cookies::~Cookies() {
}
void Cookies::Get(const base::DictionaryValue& options,
const CookiesCallback& callback) {
scoped_ptr<base::DictionaryValue> filter(
options.DeepCopyWithoutEmptyChildren());
content::BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&Cookies::GetCookiesOnIOThread, base::Unretained(this),
Passed(&filter), callback));
}
void Cookies::GetCookiesOnIOThread(scoped_ptr<base::DictionaryValue> filter,
const CookiesCallback& callback) {
std::string url;
filter->GetString("url", &url);
if (!GetCookieListFromStore(GetCookieStore(), url,
base::Bind(&Cookies::OnGetCookies, base::Unretained(this),
Passed(&filter), callback))) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::Bind(&RunGetCookiesCallbackOnUIThread, isolate(),
"Url is not valid", net::CookieList(), callback));
}
}
void Cookies::OnGetCookies(scoped_ptr<base::DictionaryValue> filter,
const CookiesCallback& callback,
const net::CookieList& cookie_list) {
net::CookieList result;
for (const auto& cookie : cookie_list) {
if (MatchesCookie(filter.get(), cookie))
result.push_back(cookie);
}
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
&RunGetCookiesCallbackOnUIThread, isolate(), "", result, callback));
}
void Cookies::Remove(const mate::Dictionary& details,
const CookiesCallback& callback) {
GURL url;
std::string name;
std::string error_message;
if (!details.Get("url", &url) || !details.Get("name", &name)) {
error_message = "Details(url, name) of removing cookie are required.";
}
if (error_message.empty() && !url.is_valid()) {
error_message = "Url is not valid.";
}
if (!error_message.empty()) {
RunRemoveCookiesCallbackOnUIThread(isolate(), error_message, callback);
return;
}
content::BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&Cookies::RemoveCookiesOnIOThread, base::Unretained(this),
url, name, callback));
}
void Cookies::RemoveCookiesOnIOThread(const GURL& url, const std::string& name,
const CookiesCallback& callback) {
GetCookieStore()->DeleteCookieAsync(url, name,
base::Bind(&Cookies::OnRemoveCookies, base::Unretained(this), callback));
}
void Cookies::OnRemoveCookies(const CookiesCallback& callback) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::Bind(&RunRemoveCookiesCallbackOnUIThread, isolate(), "", callback));
}
void Cookies::Set(const base::DictionaryValue& options,
const CookiesCallback& callback) {
std::string url;
std::string error_message;
if (!options.GetString("url", &url)) {
error_message = "The url field is required.";
}
GURL gurl(url);
if (error_message.empty() && !gurl.is_valid()) {
error_message = "Url is not valid.";
}
if (!error_message.empty()) {
RunSetCookiesCallbackOnUIThread(isolate(), error_message, false, callback);
return;
}
scoped_ptr<base::DictionaryValue> details(
options.DeepCopyWithoutEmptyChildren());
content::BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&Cookies::SetCookiesOnIOThread, base::Unretained(this),
Passed(&details), gurl, callback));
}
void Cookies::SetCookiesOnIOThread(scoped_ptr<base::DictionaryValue> details,
const GURL& url,
const CookiesCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
std::string name, value, domain, path;
bool secure = false;
bool http_only = false;
double expiration_date;
details->GetString("name", &name);
details->GetString("value", &value);
details->GetString("domain", &domain);
details->GetString("path", &path);
details->GetBoolean("secure", &secure);
details->GetBoolean("http_only", &http_only);
base::Time expiration_time;
if (details->GetDouble("expirationDate", &expiration_date)) {
expiration_time = (expiration_date == 0) ?
base::Time::UnixEpoch() :
base::Time::FromDoubleT(expiration_date);
}
GetCookieStore()->GetCookieMonster()->SetCookieWithDetailsAsync(
url,
name,
value,
domain,
path,
expiration_time,
secure,
http_only,
false,
net::COOKIE_PRIORITY_DEFAULT,
base::Bind(&Cookies::OnSetCookies, base::Unretained(this), callback));
}
void Cookies::OnSetCookies(const CookiesCallback& callback,
bool set_success) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::Bind(&RunSetCookiesCallbackOnUIThread, isolate(), "", set_success,
callback));
}
mate::ObjectTemplateBuilder Cookies::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
return mate::ObjectTemplateBuilder(isolate)
.SetMethod("get", &Cookies::Get)
.SetMethod("remove", &Cookies::Remove)
.SetMethod("set", &Cookies::Set);
}
net::CookieStore* Cookies::GetCookieStore() {
return request_context_getter_->GetURLRequestContext()->cookie_store();
}
// static
mate::Handle<Cookies> Cookies::Create(
v8::Isolate* isolate,
content::BrowserContext* browser_context) {
return mate::CreateHandle(isolate, new Cookies(browser_context));
}
} // namespace api
} // namespace atom

View File

@@ -0,0 +1,90 @@
// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_API_ATOM_API_COOKIES_H_
#define ATOM_BROWSER_API_ATOM_API_COOKIES_H_
#include <string>
#include "base/callback.h"
#include "native_mate/wrappable.h"
#include "native_mate/handle.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 {
class Cookies : public mate::Wrappable {
public:
// node.js style callback function(error, result)
typedef base::Callback<void(v8::Local<v8::Value>, v8::Local<v8::Value>)>
CookiesCallback;
static mate::Handle<Cookies> Create(v8::Isolate* isolate,
content::BrowserContext* browser_context);
protected:
explicit Cookies(content::BrowserContext* browser_context);
~Cookies();
void Get(const base::DictionaryValue& options,
const CookiesCallback& callback);
void Remove(const mate::Dictionary& details,
const CookiesCallback& callback);
void Set(const base::DictionaryValue& details,
const CookiesCallback& callback);
void GetCookiesOnIOThread(scoped_ptr<base::DictionaryValue> filter,
const CookiesCallback& callback);
void OnGetCookies(scoped_ptr<base::DictionaryValue> filter,
const CookiesCallback& callback,
const net::CookieList& cookie_list);
void RemoveCookiesOnIOThread(const GURL& url,
const std::string& name,
const CookiesCallback& callback);
void OnRemoveCookies(const CookiesCallback& callback);
void SetCookiesOnIOThread(scoped_ptr<base::DictionaryValue> details,
const GURL& url,
const CookiesCallback& callback);
void OnSetCookies(const CookiesCallback& callback,
bool set_success);
// mate::Wrappable:
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) override;
private:
// Must be called on IO thread.
net::CookieStore* GetCookieStore();
net::URLRequestContextGetter* request_context_getter_;
DISALLOW_COPY_AND_ASSIGN(Cookies);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_COOKIES_H_

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"
@@ -22,7 +22,7 @@ namespace mate {
template<>
struct Converter<file_dialog::Filter> {
static bool FromV8(v8::Isolate* isolate,
v8::Handle<v8::Value> val,
v8::Local<v8::Value> val,
file_dialog::Filter* out) {
mate::Dictionary dict;
if (!ConvertFromV8(isolate, val, &dict))
@@ -41,27 +41,25 @@ namespace {
void ShowMessageBox(int type,
const std::vector<std::string>& buttons,
const std::vector<std::string>& texts,
int cancel_id,
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::Handle<v8::Value> peek = args->PeekNext();
v8::Local<v8::Value> peek = args->PeekNext();
atom::MessageBoxCallback callback;
if (mate::Converter<atom::MessageBoxCallback>::FromV8(args->isolate(),
peek,
&callback)) {
atom::ShowMessageBox(window, (atom::MessageBoxType)type, buttons, title,
message, detail, icon, callback);
atom::ShowMessageBox(window, (atom::MessageBoxType)type, buttons, cancel_id,
options, title, message, detail, icon, callback);
} else {
int chosen = atom::ShowMessageBox(window, (atom::MessageBoxType)type,
buttons, title, message, detail, icon);
buttons, cancel_id, options, title,
message, detail, icon);
args->Return(chosen);
}
}
@@ -72,7 +70,7 @@ void ShowOpenDialog(const std::string& title,
int properties,
atom::NativeWindow* window,
mate::Arguments* args) {
v8::Handle<v8::Value> peek = args->PeekNext();
v8::Local<v8::Value> peek = args->PeekNext();
file_dialog::OpenDialogCallback callback;
if (mate::Converter<file_dialog::OpenDialogCallback>::FromV8(args->isolate(),
peek,
@@ -92,7 +90,7 @@ void ShowSaveDialog(const std::string& title,
const file_dialog::Filters& filters,
atom::NativeWindow* window,
mate::Arguments* args) {
v8::Handle<v8::Value> peek = args->PeekNext();
v8::Local<v8::Value> peek = args->PeekNext();
file_dialog::SaveDialogCallback callback;
if (mate::Converter<file_dialog::SaveDialogCallback>::FromV8(args->isolate(),
peek,
@@ -106,8 +104,8 @@ void ShowSaveDialog(const std::string& title,
}
}
void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
v8::Handle<v8::Context> context, void* priv) {
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
v8::Local<v8::Context> context, void* priv) {
mate::Dictionary dict(context->GetIsolate(), exports);
dict.SetMethod("showMessageBox", &ShowMessageBox);
dict.SetMethod("showErrorBox", &atom::ShowErrorBox);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,128 @@
// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_power_save_blocker.h"
#include <string>
#include "atom/common/node_includes.h"
#include "content/public/browser/power_save_blocker.h"
#include "native_mate/dictionary.h"
namespace mate {
template<>
struct Converter<content::PowerSaveBlocker::PowerSaveBlockerType> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
content::PowerSaveBlocker::PowerSaveBlockerType* out) {
using content::PowerSaveBlocker;
std::string type;
if (!ConvertFromV8(isolate, val, &type))
return false;
if (type == "prevent-app-suspension")
*out = PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension;
else if (type == "prevent-display-sleep")
*out = PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep;
else
return false;
return true;
}
};
} // namespace mate
namespace atom {
namespace api {
PowerSaveBlocker::PowerSaveBlocker()
: current_blocker_type_(
content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension) {
}
PowerSaveBlocker::~PowerSaveBlocker() {
}
void PowerSaveBlocker::UpdatePowerSaveBlocker() {
if (power_save_blocker_types_.empty()) {
power_save_blocker_.reset();
return;
}
// |kPowerSaveBlockPreventAppSuspension| keeps system active, but allows
// screen to be turned off.
// |kPowerSaveBlockPreventDisplaySleep| keeps system and screen active, has a
// higher precedence level than |kPowerSaveBlockPreventAppSuspension|.
//
// Only the highest-precedence blocker type takes effect.
content::PowerSaveBlocker::PowerSaveBlockerType new_blocker_type =
content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension;
for (const auto& element : power_save_blocker_types_) {
if (element.second ==
content::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep) {
new_blocker_type =
content::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep;
break;
}
}
if (!power_save_blocker_ || new_blocker_type != current_blocker_type_) {
scoped_ptr<content::PowerSaveBlocker> new_blocker =
content::PowerSaveBlocker::Create(
new_blocker_type,
content::PowerSaveBlocker::kReasonOther,
ATOM_PRODUCT_NAME);
power_save_blocker_.swap(new_blocker);
current_blocker_type_ = new_blocker_type;
}
}
int PowerSaveBlocker::Start(
content::PowerSaveBlocker::PowerSaveBlockerType type) {
static int count = 0;
power_save_blocker_types_[count] = type;
UpdatePowerSaveBlocker();
return count++;
}
bool PowerSaveBlocker::Stop(int id) {
bool success = power_save_blocker_types_.erase(id) > 0;
UpdatePowerSaveBlocker();
return success;
}
bool PowerSaveBlocker::IsStarted(int id) {
return power_save_blocker_types_.find(id) != power_save_blocker_types_.end();
}
mate::ObjectTemplateBuilder PowerSaveBlocker::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
return mate::ObjectTemplateBuilder(isolate)
.SetMethod("start", &PowerSaveBlocker::Start)
.SetMethod("stop", &PowerSaveBlocker::Stop)
.SetMethod("isStarted", &PowerSaveBlocker::IsStarted);
}
// static
mate::Handle<PowerSaveBlocker> PowerSaveBlocker::Create(v8::Isolate* isolate) {
return CreateHandle(isolate, new PowerSaveBlocker);
}
} // namespace api
} // namespace atom
namespace {
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
v8::Local<v8::Context> context, void* priv) {
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary dict(isolate, exports);
dict.Set("powerSaveBlocker", atom::api::PowerSaveBlocker::Create(isolate));
}
} // namespace
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_power_save_blocker, Initialize);

View File

@@ -0,0 +1,59 @@
// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_API_ATOM_API_POWER_SAVE_BLOCKER_H_
#define ATOM_BROWSER_API_ATOM_API_POWER_SAVE_BLOCKER_H_
#include <map>
#include "base/memory/scoped_ptr.h"
#include "content/public/browser/power_save_blocker.h"
#include "native_mate/handle.h"
#include "native_mate/wrappable.h"
namespace mate {
class Dictionary;
}
namespace atom {
namespace api {
class PowerSaveBlocker : public mate::Wrappable {
public:
static mate::Handle<PowerSaveBlocker> Create(v8::Isolate* isolate);
protected:
PowerSaveBlocker();
virtual ~PowerSaveBlocker();
// mate::Wrappable implementations:
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) override;
private:
void UpdatePowerSaveBlocker();
int Start(content::PowerSaveBlocker::PowerSaveBlockerType type);
bool Stop(int id);
bool IsStarted(int id);
scoped_ptr<content::PowerSaveBlocker> power_save_blocker_;
// Currnet blocker type used by |power_save_blocker_|
content::PowerSaveBlocker::PowerSaveBlockerType current_blocker_type_;
// Map from id to the corresponding blocker type for each request.
using PowerSaveBlockerTypeMap =
std::map<int, content::PowerSaveBlocker::PowerSaveBlockerType>;
PowerSaveBlockerTypeMap power_save_blocker_types_;
DISALLOW_COPY_AND_ASSIGN(PowerSaveBlocker);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_POWER_SAVE_BLOCKER_H_

View File

@@ -4,16 +4,16 @@
#include "atom/browser/api/atom_api_protocol.h"
#include "atom/browser/atom_browser_client.h"
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/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 "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/atom_browser_main_parts.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;
@@ -21,8 +21,8 @@ namespace mate {
template<>
struct Converter<const net::URLRequest*> {
static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
const net::URLRequest* val) {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
const net::URLRequest* val) {
return mate::ObjectTemplateBuilder(isolate)
.SetValue("method", val->method())
.SetValue("url", val->url().spec())
@@ -33,304 +33,132 @@ struct Converter<const net::URLRequest*> {
} // namespace mate
namespace atom {
namespace api {
namespace {
typedef net::URLRequestJobFactory::ProtocolHandler ProtocolHandler;
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(BrowserThread::CurrentlyOn(BrowserThread::UI));
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
// Call the JS handler.
Protocol::JsProtocolHandler callback =
registry_->GetProtocolHandler(request()->url().scheme());
v8::Handle<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::Handle<v8::Object> obj = result->ToObject();
mate::Dictionary dict(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::Handle<v8::Value> buffer;
dict.Get("mimeType", &mime_type);
dict.Get("encoding", &encoding);
dict.Get("data", &buffer);
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&AdapterRequestJob::CreateBufferJobAndStart,
GetWeakPtr(), mime_type, encoding, buffer->ToObject()));
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") {
// Default value net::ERR_NOT_IMPLEMENTED
int error = -11;
dict.Get("error", &error);
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&AdapterRequestJob::CreateErrorJobAndStart,
GetWeakPtr(), error));
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);
};
} // namespace
Protocol::Protocol()
: job_factory_(AtomBrowserContext::Get()->job_factory()) {
Protocol::Protocol(AtomBrowserContext* 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];
}
mate::ObjectTemplateBuilder Protocol::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
return mate::ObjectTemplateBuilder(isolate)
.SetMethod("registerProtocol",
base::Bind(&Protocol::RegisterProtocol,
base::Unretained(this)))
.SetMethod("unregisterProtocol",
base::Bind(&Protocol::UnregisterProtocol,
base::Unretained(this)))
.SetMethod("isHandledProtocol",
base::Bind(&Protocol::IsHandledProtocol,
base::Unretained(this)))
.SetMethod("interceptProtocol",
base::Bind(&Protocol::InterceptProtocol,
base::Unretained(this)))
.SetMethod("uninterceptProtocol",
base::Bind(&Protocol::UninterceptProtocol,
base::Unretained(this)));
.SetMethod("registerStandardSchemes", &Protocol::RegisterStandardSchemes)
.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::RegisterProtocol(const std::string& scheme,
const JsProtocolHandler& callback) {
if (ContainsKey(protocol_handlers_, scheme) ||
job_factory_->IsHandledProtocol(scheme))
return node::ThrowError("The scheme is already registered");
protocol_handlers_[scheme] = callback;
BrowserThread::PostTask(BrowserThread::IO,
FROM_HERE,
base::Bind(&Protocol::RegisterProtocolInIO,
base::Unretained(this), scheme));
void Protocol::RegisterStandardSchemes(
const std::vector<std::string>& schemes) {
atom::AtomBrowserClient::SetCustomSchemes(schemes);
}
void Protocol::UnregisterProtocol(const std::string& scheme) {
ProtocolHandlersMap::iterator it(protocol_handlers_.find(scheme));
if (it == protocol_handlers_.end())
return node::ThrowError("The scheme has not been registered");
protocol_handlers_.erase(it);
BrowserThread::PostTask(BrowserThread::IO,
FROM_HERE,
base::Bind(&Protocol::UnregisterProtocolInIO,
base::Unretained(this), 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));
}
bool Protocol::IsHandledProtocol(const std::string& scheme) {
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);
}
bool Protocol::IsProtocolHandledInIO(const std::string& scheme) {
return job_factory_->IsHandledProtocol(scheme);
}
void Protocol::InterceptProtocol(const std::string& scheme,
const JsProtocolHandler& callback) {
if (!job_factory_->HasProtocolHandler(scheme))
return node::ThrowError("Scheme does not exist.");
if (ContainsKey(protocol_handlers_, scheme))
return node::ThrowError("Cannot intercept custom procotols");
protocol_handlers_[scheme] = callback;
BrowserThread::PostTask(BrowserThread::IO,
FROM_HERE,
base::Bind(&Protocol::InterceptProtocolInIO,
base::Unretained(this), scheme));
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::OnIOCompleted,
base::Unretained(this), callback));
}
void Protocol::UninterceptProtocol(const std::string& scheme) {
ProtocolHandlersMap::iterator it(protocol_handlers_.find(scheme));
if (it == protocol_handlers_.end())
return node::ThrowError("The scheme has not been registered");
protocol_handlers_.erase(it);
BrowserThread::PostTask(BrowserThread::IO,
FROM_HERE,
base::Bind(&Protocol::UninterceptProtocolInIO,
base::Unretained(this), scheme));
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;
}
void Protocol::RegisterProtocolInIO(const std::string& scheme) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
job_factory_->SetProtocolHandler(scheme, new CustomProtocolHandler(this));
BrowserThread::PostTask(BrowserThread::UI,
FROM_HERE,
base::Bind(&Protocol::EmitEventInUI,
base::Unretained(this),
"registered", scheme));
}
void Protocol::UnregisterProtocolInIO(const std::string& scheme) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
job_factory_->SetProtocolHandler(scheme, NULL);
BrowserThread::PostTask(BrowserThread::UI,
FROM_HERE,
base::Bind(&Protocol::EmitEventInUI,
base::Unretained(this),
"unregistered", scheme));
}
void Protocol::InterceptProtocolInIO(const std::string& scheme) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
ProtocolHandler* original_handler = job_factory_->GetProtocolHandler(scheme);
if (original_handler == NULL) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
&Protocol::EmitEventInUI,
base::Unretained(this),
"error", "There is no protocol handler to intercpet"));
void Protocol::OnIOCompleted(
const CompletionCallback& callback, ProtocolError error) {
// The completion callback is optional.
if (callback.is_null())
return;
}
job_factory_->ReplaceProtocol(
scheme, new CustomProtocolHandler(this, original_handler));
BrowserThread::PostTask(BrowserThread::UI,
FROM_HERE,
base::Bind(&Protocol::EmitEventInUI,
base::Unretained(this),
"intercepted", scheme));
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)));
}
}
void Protocol::UninterceptProtocolInIO(const std::string& scheme) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
CustomProtocolHandler* handler = static_cast<CustomProtocolHandler*>(
job_factory_->GetProtocolHandler(scheme));
if (handler->original_handler() == NULL) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
&Protocol::EmitEventInUI,
base::Unretained(this),
"error", "The protocol is not intercpeted"));
return;
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";
}
// 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);
BrowserThread::PostTask(BrowserThread::UI,
FROM_HERE,
base::Bind(&Protocol::EmitEventInUI,
base::Unretained(this),
"unintercepted", scheme));
}
void Protocol::EmitEventInUI(const std::string& event,
const std::string& parameter) {
Emit(event, parameter);
}
// static
mate::Handle<Protocol> Protocol::Create(v8::Isolate* isolate) {
return CreateHandle(isolate, new Protocol);
mate::Handle<Protocol> Protocol::Create(
v8::Isolate* isolate, AtomBrowserContext* browser_context) {
return mate::CreateHandle(isolate, new Protocol(browser_context));
}
} // namespace api
@@ -339,11 +167,13 @@ mate::Handle<Protocol> Protocol::Create(v8::Isolate* isolate) {
namespace {
void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
v8::Handle<v8::Context> context, void* priv) {
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
v8::Local<v8::Context> context, void* priv) {
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary dict(isolate, exports);
dict.Set("protocol", atom::api::Protocol::Create(isolate));
auto browser_context = static_cast<atom::AtomBrowserContext*>(
atom::AtomBrowserMainParts::Get()->browser_context());
dict.Set("protocol", atom::api::Protocol::Create(isolate, browser_context));
}
} // namespace

View File

@@ -7,67 +7,180 @@
#include <string>
#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 "native_mate/wrappable.h"
namespace net {
class URLRequest;
class URLRequestContextGetter;
}
namespace atom {
class AtomBrowserContext;
class AtomURLRequestJobFactory;
namespace api {
class Protocol : public mate::EventEmitter {
class Protocol : public mate::Wrappable {
public:
typedef base::Callback<v8::Handle<v8::Value>(const net::URLRequest*)>
JsProtocolHandler;
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);
JsProtocolHandler GetProtocolHandler(const std::string& scheme);
static mate::Handle<Protocol> Create(
v8::Isolate* isolate, AtomBrowserContext* browser_context);
protected:
Protocol();
explicit Protocol(AtomBrowserContext* browser_context);
// mate::Wrappable implementations:
virtual mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
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,
};
// Register/unregister an networking |scheme| which would be handled by
// |callback|.
// 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);
// Register the protocol with certain request job.
template<typename RequestJob>
void RegisterProtocol(const std::string& scheme,
const JsProtocolHandler& callback);
void UnregisterProtocol(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;
}
// Returns whether a scheme has been registered.
// FIXME Should accept a callback and be asynchronous so we do not have to use
// locks.
bool IsHandledProtocol(const std::string& scheme);
// 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.
// Whether the protocol has handler registered.
void IsProtocolHandled(const std::string& scheme,
const BooleanCallback& callback);
bool IsProtocolHandledInIO(const std::string& scheme);
// Replace the protocol handler with a new one.
template<typename RequestJob>
void InterceptProtocol(const std::string& scheme,
const JsProtocolHandler& callback);
void UninterceptProtocol(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;
}
// The networking related operations have to be done in IO thread.
void RegisterProtocolInIO(const std::string& scheme);
void UnregisterProtocolInIO(const std::string& scheme);
void InterceptProtocolInIO(const std::string& scheme);
void UninterceptProtocolInIO(const std::string& scheme);
// Restore the |scheme| to its original protocol handler.
void UninterceptProtocol(const std::string& scheme, mate::Arguments* args);
ProtocolError UninterceptProtocolInIO(const std::string& scheme);
// Do protocol.emit(event, parameter) under UI thread.
void EmitEventInUI(const std::string& event, const std::string& parameter);
// Convert error code to JS exception and call the callback.
void OnIOCompleted(const CompletionCallback& callback, ProtocolError error);
AtomURLRequestJobFactory* job_factory_;
ProtocolHandlersMap protocol_handlers_;
// 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

@@ -111,15 +111,18 @@ mate::ObjectTemplateBuilder Screen::GetObjectTemplateBuilder(
}
// static
v8::Handle<v8::Value> Screen::Create(v8::Isolate* isolate) {
v8::Local<v8::Value> Screen::Create(v8::Isolate* isolate) {
if (!Browser::Get()->is_ready()) {
node::ThrowError("Cannot initialize \"screen\" module before app is ready");
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("Failed to get screen information");
isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
isolate, "Failed to get screen information")));
return v8::Null(isolate);
}
@@ -132,8 +135,8 @@ v8::Handle<v8::Value> Screen::Create(v8::Isolate* isolate) {
namespace {
void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
v8::Handle<v8::Context> context, void* priv) {
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
v8::Local<v8::Context> context, void* priv) {
mate::Dictionary dict(context->GetIsolate(), exports);
dict.Set("screen", atom::api::Screen::Create(context->GetIsolate()));
}

View File

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

View File

@@ -0,0 +1,372 @@
// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_session.h"
#include <string>
#include <vector>
#include "atom/browser/api/atom_api_cookies.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 "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/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"
using content::BrowserThread;
using content::StoragePartition;
namespace {
struct ClearStorageDataOptions {
GURL origin;
uint32 storage_types = StoragePartition::REMOVE_DATA_MASK_ALL;
uint32 quota_types = StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL;
};
uint32 GetStorageMask(const std::vector<std::string>& storage_types) {
uint32 storage_mask = 0;
for (const auto& it : storage_types) {
auto type = base::StringToLowerASCII(it);
if (type == "appcache")
storage_mask |= StoragePartition::REMOVE_DATA_MASK_APPCACHE;
else if (type == "cookies")
storage_mask |= StoragePartition::REMOVE_DATA_MASK_COOKIES;
else if (type == "filesystem")
storage_mask |= StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS;
else if (type == "indexdb")
storage_mask |= StoragePartition::REMOVE_DATA_MASK_INDEXEDDB;
else if (type == "localstorage")
storage_mask |= StoragePartition::REMOVE_DATA_MASK_LOCAL_STORAGE;
else if (type == "shadercache")
storage_mask |= StoragePartition::REMOVE_DATA_MASK_SHADER_CACHE;
else if (type == "websql")
storage_mask |= StoragePartition::REMOVE_DATA_MASK_WEBSQL;
else if (type == "serviceworkers")
storage_mask |= StoragePartition::REMOVE_DATA_MASK_SERVICE_WORKERS;
}
return storage_mask;
}
uint32 GetQuotaMask(const std::vector<std::string>& quota_types) {
uint32 quota_mask = 0;
for (const auto& it : quota_types) {
auto type = base::StringToLowerASCII(it);
if (type == "temporary")
quota_mask |= StoragePartition::QUOTA_MANAGED_STORAGE_MASK_TEMPORARY;
else if (type == "persistent")
quota_mask |= StoragePartition::QUOTA_MANAGED_STORAGE_MASK_PERSISTENT;
else if (type == "syncable")
quota_mask |= StoragePartition::QUOTA_MANAGED_STORAGE_MASK_SYNCABLE;
}
return quota_mask;
}
} // namespace
namespace mate {
template<>
struct Converter<ClearStorageDataOptions> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
ClearStorageDataOptions* out) {
mate::Dictionary options;
if (!ConvertFromV8(isolate, val, &options))
return false;
options.Get("origin", &out->origin);
std::vector<std::string> types;
if (options.Get("storages", &types))
out->storage_types = GetStorageMask(types);
if (options.Get("quotas", &types))
out->quota_types = GetQuotaMask(types);
return true;
}
};
template<>
struct Converter<content::DownloadItem*> {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
content::DownloadItem* val) {
mate::Dictionary dict(isolate, v8::Object::New(isolate));
dict.Set("url", val->GetURL());
dict.Set("filename", val->GetSuggestedFilename());
dict.Set("mimeType", val->GetMimeType());
dict.Set("hasUserGesture", val->HasUserGesture());
return dict.GetHandle();
}
};
} // namespace mate
namespace atom {
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,
const GURL& url,
Session::ResolveProxyCallback callback)
: callback_(callback),
original_thread_(base::ThreadTaskRunnerHandle::Get()) {
scoped_refptr<net::URLRequestContextGetter> context_getter =
browser_context->GetRequestContext();
context_getter->GetNetworkTaskRunner()->PostTask(
FROM_HERE,
base::Bind(&ResolveProxyHelper::ResolveProxy,
base::Unretained(this), context_getter, url));
}
void OnResolveProxyCompleted(int result) {
std::string proxy;
if (result == net::OK)
proxy = proxy_info_.ToPacString();
original_thread_->PostTask(FROM_HERE,
base::Bind(callback_, proxy));
delete this;
}
private:
void ResolveProxy(scoped_refptr<net::URLRequestContextGetter> context_getter,
const GURL& url) {
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
net::ProxyService* proxy_service =
context_getter->GetURLRequestContext()->proxy_service();
net::CompletionCallback completion_callback =
base::Bind(&ResolveProxyHelper::OnResolveProxyCompleted,
base::Unretained(this));
// Start the request.
int result = proxy_service->ResolveProxy(
url, net::LOAD_NORMAL, &proxy_info_, completion_callback,
&pac_req_, nullptr, net::BoundNetLog());
// Completed synchronously.
if (result != net::ERR_IO_PENDING)
completion_callback.Run(result);
}
Session::ResolveProxyCallback callback_;
net::ProxyInfo proxy_info_;
net::ProxyService::PacRequest* pac_req_;
scoped_refptr<base::SingleThreadTaskRunner> original_thread_;
DISALLOW_COPY_AND_ASSIGN(ResolveProxyHelper);
};
// Runs the callback in UI thread.
template <typename ...T>
void RunCallbackInUI(const base::Callback<void(T...)>& callback, T... result) {
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE, base::Bind(callback, result...));
}
// Callback of HttpCache::GetBackend.
void OnGetBackend(disk_cache::Backend** backend_ptr,
const net::CompletionCallback& callback,
int result) {
if (result != net::OK) {
RunCallbackInUI(callback, result);
} else if (backend_ptr && *backend_ptr) {
(*backend_ptr)->DoomAllEntries(base::Bind(&RunCallbackInUI<int>, callback));
} else {
RunCallbackInUI<int>(callback, net::ERR_FAILED);
}
}
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<int>(callback, net::ERR_FAILED);
// Call GetBackend and make the backend's ptr accessable in OnGetBackend.
using BackendPtr = disk_cache::Backend*;
BackendPtr* backend_ptr = new BackendPtr(nullptr);
net::CompletionCallback on_get_backend =
base::Bind(&OnGetBackend, base::Owned(backend_ptr), callback);
int rv = http_cache->GetBackend(backend_ptr, on_get_backend);
if (rv != net::ERR_IO_PENDING)
on_get_backend.Run(net::OK);
}
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", 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);
}
void Session::ClearCache(const net::CompletionCallback& callback) {
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&ClearHttpCacheInIO,
make_scoped_refptr(browser_context_->GetRequestContext()),
callback));
}
void Session::ClearStorageData(mate::Arguments* args) {
// clearStorageData([options, ]callback)
ClearStorageDataOptions options;
args->GetNext(&options);
base::Closure callback;
if (!args->GetNext(&callback)) {
args->ThrowError();
return;
}
auto storage_partition =
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());
cookies_.Reset(isolate, handle.ToV8());
}
return v8::Local<v8::Value>::New(isolate, cookies_);
}
mate::ObjectTemplateBuilder Session::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
return mate::ObjectTemplateBuilder(isolate)
.SetMethod("resolveProxy", &Session::ResolveProxy)
.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) {
auto existing = TrackableObject::FromWrappedClass(isolate, browser_context);
if (existing)
return mate::CreateHandle(isolate, static_cast<Session*>(existing));
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

@@ -0,0 +1,82 @@
// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_API_ATOM_API_SESSION_H_
#define ATOM_BROWSER_API_ATOM_API_SESSION_H_
#include <string>
#include "atom/browser/api/trackable_object.h"
#include "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;
}
namespace atom {
class AtomBrowserContext;
namespace api {
class Session: public mate::TrackableObject<Session>,
public content::DownloadManager::Observer {
public:
using ResolveProxyCallback = base::Callback<void(std::string)>;
// Gets or creates Session from the |browser_context|.
static mate::Handle<Session> CreateFrom(
v8::Isolate* isolate, AtomBrowserContext* browser_context);
// 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();
// 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_;
scoped_refptr<AtomBrowserContext> browser_context_;
DISALLOW_COPY_AND_ASSIGN(Session);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_SESSION_H_

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 {
@@ -32,20 +32,34 @@ Tray::~Tray() {
}
// static
mate::Wrappable* Tray::New(const gfx::Image& image) {
mate::Wrappable* Tray::New(v8::Isolate* isolate, const gfx::Image& image) {
if (!Browser::Get()->is_ready()) {
node::ThrowError("Cannot create Tray before app is ready");
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,45 +74,40 @@ 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_;
}
void Tray::Destroy() {
tray_icon_.reset();
}
void Tray::SetImage(mate::Arguments* args, const gfx::Image& image) {
if (!CheckTrayLife(args))
return;
tray_icon_->SetImage(image);
}
void Tray::SetPressedImage(mate::Arguments* args, const gfx::Image& image) {
if (!CheckTrayLife(args))
return;
tray_icon_->SetPressedImage(image);
}
void Tray::SetToolTip(mate::Arguments* args, const std::string& tool_tip) {
if (!CheckTrayLife(args))
return;
tray_icon_->SetToolTip(tool_tip);
}
void Tray::SetTitle(mate::Arguments* args, const std::string& title) {
if (!CheckTrayLife(args))
return;
tray_icon_->SetTitle(title);
}
void Tray::SetHighlightMode(mate::Arguments* args, bool highlight) {
if (!CheckTrayLife(args))
return;
tray_icon_->SetHighlightMode(highlight);
}
void Tray::DisplayBalloon(mate::Arguments* args,
const mate::Dictionary& options) {
if (!CheckTrayLife(args))
return;
gfx::Image icon;
options.Get("icon", &icon);
base::string16 title, content;
@@ -111,32 +120,38 @@ 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) {
if (!CheckTrayLife(args))
return;
tray_icon_->SetContextMenu(menu->model());
}
bool Tray::CheckTrayLife(mate::Arguments* args) {
if (!tray_icon_) {
args->ThrowError("Tray is already destroyed");
return false;
} else {
return true;
}
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::Handle<v8::ObjectTemplate> prototype) {
v8::Local<v8::ObjectTemplate> prototype) {
mate::ObjectTemplateBuilder(isolate, prototype)
.SetMethod("destroy", &Tray::Destroy)
.SetMethod("destroy", &Tray::Destroy, true)
.SetMethod("setImage", &Tray::SetImage)
.SetMethod("setPressedImage", &Tray::SetPressedImage)
.SetMethod("setToolTip", &Tray::SetToolTip)
.SetMethod("setTitle", &Tray::SetTitle)
.SetMethod("setHighlightMode", &Tray::SetHighlightMode)
.SetMethod("displayBalloon", &Tray::DisplayBalloon)
.SetMethod("popUpContextMenu", &Tray::PopUpContextMenu)
.SetMethod("_setContextMenu", &Tray::SetContextMenu);
}
@@ -147,14 +162,14 @@ void Tray::BuildPrototype(v8::Isolate* isolate,
namespace {
void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
v8::Handle<v8::Context> context, void* priv) {
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
v8::Local<v8::Context> context, void* priv) {
using atom::api::Tray;
v8::Isolate* isolate = context->GetIsolate();
v8::Handle<v8::Function> constructor = mate::CreateConstructor<Tray>(
v8::Local<v8::Function> constructor = mate::CreateConstructor<Tray>(
isolate, "Tray", base::Bind(&Tray::New));
mate::Dictionary dict(isolate, exports);
dict.Set("Tray", static_cast<v8::Handle<v8::Value>>(constructor));
dict.Set("Tray", static_cast<v8::Local<v8::Value>>(constructor));
}
} // namespace

View File

@@ -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"
@@ -31,21 +32,26 @@ class Menu;
class Tray : public mate::EventEmitter,
public TrayIconObserver {
public:
static mate::Wrappable* New(const gfx::Image& image);
static mate::Wrappable* New(v8::Isolate* isolate, const gfx::Image& image);
static void BuildPrototype(v8::Isolate* isolate,
v8::Handle<v8::ObjectTemplate> prototype);
v8::Local<v8::ObjectTemplate> prototype);
protected:
explicit Tray(const gfx::Image& image);
virtual ~Tray();
// TrayIconObserver:
void OnClicked(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;
void Destroy();
void SetImage(mate::Arguments* args, const gfx::Image& image);
@@ -54,10 +60,11 @@ 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:
bool CheckTrayLife(mate::Arguments* args);
v8::Local<v8::Object> ModifiersToObject(v8::Isolate* isolate, int modifiers);
scoped_ptr<TrayIcon> tray_icon_;

File diff suppressed because it is too large Load Diff

View File

@@ -8,13 +8,10 @@
#include <string>
#include <vector>
#include "atom/browser/api/event_emitter.h"
#include "brightray/browser/default_web_contents_delegate.h"
#include "content/public/browser/browser_plugin_guest_delegate.h"
#include "content/public/common/favicon_url.h"
#include "content/public/browser/web_contents_delegate.h"
#include "atom/browser/api/trackable_object.h"
#include "atom/browser/common_web_contents_delegate.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/gpu_data_manager_observer.h"
#include "content/public/common/favicon_url.h"
#include "native_mate/handle.h"
#include "ui/gfx/image/image.h"
@@ -23,22 +20,26 @@ class InspectableWebContents;
}
namespace mate {
class Arguments;
class Dictionary;
}
namespace atom {
class AtomJavaScriptDialogManager;
class WebDialogHelper;
struct SetSizeParams;
class AtomBrowserContext;
class WebViewGuestDelegate;
namespace api {
class WebContents : public mate::EventEmitter,
public content::BrowserPluginGuestDelegate,
public content::WebContentsDelegate,
public content::WebContentsObserver,
public content::GpuDataManagerObserver {
class WebContents : public mate::TrackableObject<WebContents>,
public CommonWebContentsDelegate,
public content::WebContentsObserver {
public:
// For node.js callback function type: function(error, buffer)
using PrintToPDFCallback =
base::Callback<void(v8::Local<v8::Value>, v8::Local<v8::Value>)>;
// Create from an existing WebContents.
static mate::Handle<WebContents> CreateFrom(
v8::Isolate* isolate, content::WebContents* web_contents);
@@ -47,9 +48,14 @@ class WebContents : public mate::EventEmitter,
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;
@@ -58,18 +64,32 @@ class WebContents : public mate::EventEmitter,
void GoBack();
void GoForward();
void GoToOffset(int offset);
int GetRoutingID() const;
int GetProcessID() const;
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 OpenDevTools();
void ExecuteJavaScript(const base::string16& code,
bool has_user_gesture);
void OpenDevTools(mate::Arguments* args);
void CloseDevTools();
bool IsDevToolsOpened();
void ToggleDevTools();
void InspectElement(int x, int y);
void InspectServiceWorker();
v8::Local<v8::Value> Session(v8::Isolate* isolate);
void HasServiceWorker(const base::Callback<void(bool)>&);
void UnregisterServiceWorker(const base::Callback<void(bool)>&);
void SetAudioMuted(bool muted);
bool IsAudioMuted();
void Print(mate::Arguments* args);
// Print current page as PDF.
void PrintToPDF(const base::DictionaryValue& setting,
const PrintToPDFCallback& callback);
// 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();
@@ -84,36 +104,28 @@ class WebContents : public mate::EventEmitter,
void Replace(const base::string16& word);
void ReplaceMisspelling(const base::string16& word);
// Focus.
void Focus();
void TabTraverse(bool reverse);
// Sending messages to browser.
bool SendIPCMessage(const base::string16& channel,
const base::ListValue& args);
// Toggles autosize mode for corresponding <webview>.
void SetAutoSize(bool enabled,
const gfx::Size& min_size,
const gfx::Size& max_size);
// Sets the transparency of the guest.
// Methods for creating <webview>.
void SetSize(const SetSizeParams& params);
void SetAllowTransparency(bool allow);
// Returns whether this is a guest view.
bool is_guest() const { return guest_instance_id_ != -1; }
// Returns whether this guest has an associated embedder.
bool attached() const { return !!embedder_web_contents_; }
content::WebContents* web_contents() const {
return content::WebContentsObserver::web_contents();
}
bool IsGuest() const;
protected:
explicit WebContents(content::WebContents* web_contents);
explicit WebContents(const mate::Dictionary& options);
WebContents(v8::Isolate* isolate, const mate::Dictionary& options);
~WebContents();
// mate::Wrappable:
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) override;
bool IsDestroyed() const override;
// content::WebContentsDelegate:
bool AddMessageToConsole(content::WebContents* source,
@@ -126,38 +138,32 @@ class WebContents : public mate::EventEmitter,
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;
void CloseContents(content::WebContents* source) override;
content::WebContents* OpenURLFromTab(
content::WebContents* source,
const content::OpenURLParams& params) override;
content::JavaScriptDialogManager* GetJavaScriptDialogManager(
content::WebContents* source) override;
void RunFileChooser(content::WebContents* web_contents,
const content::FileChooserParams& params) override;
void EnumerateDirectory(content::WebContents* web_contents,
int request_id,
const base::FilePath& path) override;
bool CheckMediaAccessPermission(content::WebContents* web_contents,
const GURL& security_origin,
content::MediaStreamType type) override;
void RequestMediaAccessPermission(
content::WebContents*,
const content::MediaStreamRequest&,
const content::MediaResponseCallback&) override;
void BeforeUnloadFired(content::WebContents* tab,
bool proceed,
bool* proceed_to_fire_unload) override;
void MoveContents(content::WebContents* source,
const gfx::Rect& pos) override;
void CloseContents(content::WebContents* source) override;
void ActivateContents(content::WebContents* contents) override;
bool IsPopupOrPanel(const content::WebContents* source) const override;
void HandleKeyboardEvent(
content::WebContents* source,
const content::NativeWebKeyboardEvent& event) override;
void EnterFullscreenModeForTab(content::WebContents* source,
const GURL& origin) override;
void ExitFullscreenModeForTab(content::WebContents* source) override;
bool IsFullscreenForTabOrPending(
const content::WebContents* source) const override;
void RendererUnresponsive(content::WebContents* source) override;
void RendererResponsive(content::WebContents* source) override;
// content::WebContentsObserver:
void BeforeUnloadFired(const base::TimeTicks& proceed_time) override;
void RenderViewDeleted(content::RenderViewHost*) override;
void RenderProcessGone(base::TerminationStatus status) override;
void DocumentLoadedInFrame(
@@ -167,13 +173,15 @@ class WebContents : public mate::EventEmitter,
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;
void DidStartLoading(content::RenderViewHost* render_view_host) override;
void DidStopLoading(content::RenderViewHost* render_view_host) override;
const base::string16& error_description,
bool was_ignored_by_handler) override;
void DidStartLoading() override;
void DidStopLoading() override;
void DidGetResourceResponseStart(
const content::ResourceRequestDetails& details) override;
void DidGetRedirectForResourceRequest(
@@ -183,7 +191,6 @@ class WebContents : public mate::EventEmitter,
const content::LoadCommittedDetails& details,
const content::FrameNavigateParams& params) override;
bool OnMessageReceived(const IPC::Message& message) override;
void RenderViewReady() override;
void WebContentsDestroyed() override;
void NavigationEntryCommitted(
const content::LoadCommittedDetails& load_details) override;
@@ -193,21 +200,15 @@ class WebContents : public mate::EventEmitter,
void PluginCrashed(const base::FilePath& plugin_path,
base::ProcessId plugin_pid) override;
// content::BrowserPluginGuestDelegate:
void DidAttach(int guest_proxy_routing_id) final;
void ElementSizeChanged(const gfx::Size& size) final;
content::WebContents* GetOwnerWebContents() const final;
void GuestSizeChanged(const gfx::Size& new_size) final;
void RegisterDestructionCallback(const DestructionCallback& callback) final;
void SetGuestSizer(content::GuestSizer* guest_sizer) final;
void WillAttach(content::WebContents* embedder_web_contents,
int element_instance_id,
bool is_full_page_plugin) final;
// content::GpuDataManagerObserver:
void OnGpuProcessCrashed(base::TerminationStatus exit_code) override;
private:
enum Type {
BROWSER_WINDOW, // Used by BrowserWindow.
WEB_VIEW, // Used by <webview>.
REMOTE, // Thin wrap around an existing WebContents.
};
AtomBrowserContext* GetBrowserContext() const;
// Called when received a message from renderer.
void OnRendererMessage(const base::string16& channel,
const base::ListValue& args);
@@ -217,48 +218,12 @@ class WebContents : public mate::EventEmitter,
const base::ListValue& args,
IPC::Message* message);
void GuestSizeChangedDueToAutoSize(const gfx::Size& old_size,
const gfx::Size& new_size);
v8::Global<v8::Value> session_;
scoped_ptr<WebDialogHelper> web_dialog_helper_;
scoped_ptr<AtomJavaScriptDialogManager> dialog_manager_;
scoped_ptr<WebViewGuestDelegate> guest_delegate_;
// Unique ID for a guest WebContents.
int guest_instance_id_;
// |element_instance_id_| is an identifer that's unique to a particular
// element.
int element_instance_id_;
DestructionCallback destruction_callback_;
// Stores whether the contents of the guest can be transparent.
bool guest_opaque_;
// Stores the WebContents that managed by this class.
scoped_ptr<brightray::InspectableWebContents> storage_;
// The WebContents that attaches this guest view.
content::WebContents* embedder_web_contents_;
// The size of the container element.
gfx::Size element_size_;
// The size of the guest content. Note: In autosize mode, the container
// element may not match the size of the guest.
gfx::Size guest_size_;
// A pointer to the guest_sizer.
content::GuestSizer* guest_sizer_;
// Indicates whether autosize mode is enabled or not.
bool auto_size_enabled_;
// The maximum size constraints of the container element in autosize mode.
gfx::Size max_auto_size_;
// The minimum size constraints of the container element in autosize mode.
gfx::Size min_auto_size_;
// The type of current WebContents.
Type type_;
DISALLOW_COPY_AND_ASSIGN(WebContents);
};

View File

@@ -3,19 +3,20 @@
// 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 {
template<>
struct Converter<content::WebContents*> {
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
content::WebContents** out) {
atom::api::WebContents* contents;
if (!Converter<atom::api::WebContents*>::FromV8(isolate, val, &contents))
@@ -25,28 +26,6 @@ struct Converter<content::WebContents*> {
}
};
template<>
struct Converter<atom::WebViewManager::WebViewInfo> {
static bool FromV8(v8::Isolate* isolate, v8::Handle<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) {
@@ -81,8 +59,8 @@ void RemoveGuest(content::WebContents* embedder, int guest_instance_id) {
manager->RemoveGuest(guest_instance_id);
}
void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
v8::Handle<v8::Context> context, void* priv) {
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
v8::Local<v8::Context> context, void* priv) {
mate::Dictionary dict(context->GetIsolate(), exports);
dict.SetMethod("addGuest", &AddGuest);
dict.SetMethod("removeGuest", &RemoveGuest);

View File

@@ -4,46 +4,47 @@
#include "atom/browser/api/atom_api_window.h"
#include "atom/browser/api/atom_api_menu.h"
#include "atom/browser/api/atom_api_web_contents.h"
#include "atom/browser/browser.h"
#include "atom/browser/native_window.h"
#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/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"
#if defined(OS_WIN)
#include "atom/browser/native_window_views.h"
#include "atom/browser/ui/win/taskbar_host.h"
#endif
#include "atom/common/node_includes.h"
namespace {
struct PrintSettings {
bool silent;
bool print_background;
};
} // namespace
#if defined(OS_WIN)
namespace mate {
template<>
struct Converter<PrintSettings> {
struct Converter<atom::TaskbarHost::ThumbarButton> {
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
PrintSettings* out) {
atom::TaskbarHost::ThumbarButton* out) {
mate::Dictionary dict;
if (!ConvertFromV8(isolate, val, &dict))
return false;
dict.Get("silent", &(out->silent));
dict.Get("printBackground", &(out->print_background));
return true;
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 {
@@ -63,8 +64,29 @@ void OnCapturePageDone(
} // namespace
Window::Window(const mate::Dictionary& options)
: window_(NativeWindow::Create(options)) {
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.
auto web_contents = WebContents::Create(isolate, web_preferences);
web_contents_.Reset(isolate, web_contents.ToV8());
api_web_contents_ = web_contents.get();
// Creates BrowserWindow.
window_.reset(NativeWindow::Create(web_contents->managed_web_contents(),
options));
web_contents->SetOwnerWindow(window_.get());
window_->InitFromOptions(options);
window_->AddObserver(this);
}
@@ -79,25 +101,24 @@ void Window::OnPageTitleUpdated(bool* prevent_default,
*prevent_default = Emit("page-title-updated", title);
}
void Window::WillCreatePopupWindow(const base::string16& frame_name,
const GURL& target_url,
const std::string& partition_id,
WindowOpenDisposition disposition) {
Emit("-new-window", target_url, frame_name, static_cast<int>(disposition));
}
void Window::WillNavigate(bool* prevent_default, const GURL& url) {
*prevent_default = Emit("-will-navigate", url);
}
void Window::WillCloseWindow(bool* prevent_default) {
*prevent_default = Emit("close");
}
void Window::OnWindowClosed() {
if (api_web_contents_) {
api_web_contents_->DestroyWebContents();
api_web_contents_ = nullptr;
web_contents_.Reset();
}
RemoveFromWeakMap();
window_->RemoveObserver(this);
Emit("closed");
window_->RemoveObserver(this);
// Clean up the resources after window has been closed.
base::MessageLoop::current()->DeleteSoon(FROM_HERE, window_.release());
}
void Window::OnWindowBlur() {
@@ -124,6 +145,18 @@ void Window::OnWindowRestore() {
Emit("restore");
}
void Window::OnWindowResize() {
Emit("resize");
}
void Window::OnWindowMove() {
Emit("move");
}
void Window::OnWindowMoved() {
Emit("moved");
}
void Window::OnWindowEnterFullScreen() {
Emit("enter-full-screen");
}
@@ -152,19 +185,46 @@ void Window::OnDevToolsFocus() {
Emit("devtools-focused");
}
void Window::OnDevToolsOpened() {
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() {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
devtools_web_contents_.Reset();
Emit("devtools-closed");
}
void Window::OnExecuteWindowsCommand(const std::string& command_name) {
Emit("app-command", command_name);
}
// static
mate::Wrappable* Window::New(v8::Isolate* isolate,
const mate::Dictionary& options) {
if (!Browser::Get()->is_ready()) {
node::ThrowError("Cannot create BrowserWindow before app is ready");
isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
isolate, "Cannot create BrowserWindow before app is ready")));
return nullptr;
}
return new Window(options);
return new Window(isolate, options);
}
bool Window::IsDestroyed() const {
return !window_ || window_->IsClosed();
}
void Window::Destroy() {
window_->DestroyWebContents();
window_->CloseImmediately();
if (window_)
window_->CloseContents(nullptr);
}
void Window::Close() {
@@ -343,22 +403,6 @@ bool Window::IsKiosk() {
return window_->IsKiosk();
}
void Window::OpenDevTools(bool can_dock) {
window_->OpenDevTools(can_dock);
}
void Window::CloseDevTools() {
window_->CloseDevTools();
}
bool Window::IsDevToolsOpened() {
return window_->IsDevToolsOpened();
}
void Window::InspectElement(int x, int y) {
window_->InspectElement(x, y);
}
void Window::FocusOnWebView() {
window_->FocusOnWebView();
}
@@ -371,6 +415,10 @@ bool Window::IsWebViewFocused() {
return window_->IsWebViewFocused();
}
bool Window::IsDevToolsFocused() {
return window_->IsDevToolsFocused();
}
void Window::SetRepresentedFilename(const std::string& filename) {
window_->SetRepresentedFilename(filename);
}
@@ -402,16 +450,6 @@ void Window::CapturePage(mate::Arguments* args) {
rect, base::Bind(&OnCapturePageDone, args->isolate(), callback));
}
void Window::Print(mate::Arguments* args) {
PrintSettings settings = { false, false };;
if (args->Length() == 1 && !args->GetNext(&settings)) {
args->ThrowError();
return;
}
window_->Print(settings.silent, settings.print_background);
}
void Window::SetProgressBar(double progress) {
window_->SetProgressBar(progress);
}
@@ -421,6 +459,37 @@ 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() &&
mate::V8ToString(value->ToObject()->GetConstructorName()) == "Menu" &&
mate::ConvertFromV8(isolate, value, &menu)) {
menu_.Reset(isolate, menu.ToV8());
window_->SetMenu(menu->model());
} else if (value->IsNull()) {
menu_.Reset();
window_->SetMenu(nullptr);
} else {
isolate->ThrowException(v8::Exception::TypeError(
mate::StringToV8(isolate, "Invalid Menu")));
}
}
void Window::SetAutoHideMenuBar(bool auto_hide) {
window_->SetAutoHideMenuBar(auto_hide);
}
@@ -443,6 +512,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);
}
@@ -451,20 +526,29 @@ bool Window::IsVisibleOnAllWorkspaces() {
return window_->IsVisibleOnAllWorkspaces();
}
mate::Handle<WebContents> Window::GetWebContents(v8::Isolate* isolate) const {
return WebContents::CreateFrom(isolate, window_->GetWebContents());
int32_t Window::ID() const {
return weak_map_id();
}
mate::Handle<WebContents> Window::GetDevToolsWebContents(
v8::Isolate* isolate) const {
return WebContents::CreateFrom(isolate, window_->GetDevToolsWebContents());
v8::Local<v8::Value> Window::WebContents(v8::Isolate* isolate) {
if (web_contents_.IsEmpty())
return v8::Null(isolate);
else
return v8::Local<v8::Value>::New(isolate, web_contents_);
}
v8::Local<v8::Value> Window::DevToolsWebContents(v8::Isolate* isolate) {
if (devtools_web_contents_.IsEmpty())
return v8::Null(isolate);
else
return v8::Local<v8::Value>::New(isolate, devtools_web_contents_);
}
// static
void Window::BuildPrototype(v8::Isolate* isolate,
v8::Handle<v8::ObjectTemplate> prototype) {
v8::Local<v8::ObjectTemplate> prototype) {
mate::ObjectTemplateBuilder(isolate, prototype)
.SetMethod("destroy", &Window::Destroy)
.SetMethod("destroy", &Window::Destroy, true)
.SetMethod("close", &Window::Close)
.SetMethod("isClosed", &Window::IsClosed)
.SetMethod("focus", &Window::Focus)
@@ -481,6 +565,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)
@@ -508,17 +593,15 @@ void Window::BuildPrototype(v8::Isolate* isolate,
.SetMethod("getRepresentedFilename", &Window::GetRepresentedFilename)
.SetMethod("setDocumentEdited", &Window::SetDocumentEdited)
.SetMethod("isDocumentEdited", &Window::IsDocumentEdited)
.SetMethod("_openDevTools", &Window::OpenDevTools)
.SetMethod("closeDevTools", &Window::CloseDevTools)
.SetMethod("isDevToolsOpened", &Window::IsDevToolsOpened)
.SetMethod("inspectElement", &Window::InspectElement)
.SetMethod("focusOnWebView", &Window::FocusOnWebView)
.SetMethod("blurWebView", &Window::BlurWebView)
.SetMethod("isWebViewFocused", &Window::IsWebViewFocused)
.SetMethod("isDevToolsFocused", &Window::IsDevToolsFocused)
.SetMethod("capturePage", &Window::CapturePage)
.SetMethod("print", &Window::Print)
.SetMethod("setProgressBar", &Window::SetProgressBar)
.SetMethod("setOverlayIcon", &Window::SetOverlayIcon)
.SetMethod("setThumbarButtons", &Window::SetThumbarButtons)
.SetMethod("setMenu", &Window::SetMenu)
.SetMethod("setAutoHideMenuBar", &Window::SetAutoHideMenuBar)
.SetMethod("isMenuBarAutoHide", &Window::IsMenuBarAutoHide)
.SetMethod("setMenuBarVisibility", &Window::SetMenuBarVisibility)
@@ -531,8 +614,9 @@ void Window::BuildPrototype(v8::Isolate* isolate,
.SetMethod("showDefinitionForSelection",
&Window::ShowDefinitionForSelection)
#endif
.SetMethod("_getWebContents", &Window::GetWebContents)
.SetMethod("_getDevToolsWebContents", &Window::GetDevToolsWebContents);
.SetProperty("id", &Window::ID, true)
.SetProperty("webContents", &Window::WebContents, true)
.SetProperty("devToolsWebContents", &Window::DevToolsWebContents, true);
}
} // namespace api
@@ -542,14 +626,21 @@ void Window::BuildPrototype(v8::Isolate* isolate,
namespace {
void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
v8::Handle<v8::Context> context, void* priv) {
using atom::api::Window;
using atom::api::Window;
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
v8::Local<v8::Context> context, void* priv) {
v8::Isolate* isolate = context->GetIsolate();
v8::Local<v8::Function> constructor = mate::CreateConstructor<Window>(
isolate, "BrowserWindow", base::Bind(&Window::New));
mate::Dictionary browser_window(isolate, constructor);
browser_window.SetMethod("fromId",
&mate::TrackableObject<Window>::FromWeakMapID);
browser_window.SetMethod("getAllWindows",
&mate::TrackableObject<Window>::GetAll);
mate::Dictionary dict(isolate, exports);
dict.Set("BrowserWindow", static_cast<v8::Handle<v8::Value>>(constructor));
dict.Set("BrowserWindow", browser_window);
}
} // namespace

View File

@@ -10,8 +10,9 @@
#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 "atom/browser/api/event_emitter.h"
#include "native_mate/handle.h"
class GURL;
@@ -33,29 +34,24 @@ namespace api {
class WebContents;
class Window : public mate::EventEmitter,
class Window : public mate::TrackableObject<Window>,
public NativeWindowObserver {
public:
static mate::Wrappable* New(v8::Isolate* isolate,
const mate::Dictionary& options);
static void BuildPrototype(v8::Isolate* isolate,
v8::Handle<v8::ObjectTemplate> prototype);
v8::Local<v8::ObjectTemplate> prototype);
NativeWindow* window() const { return window_.get(); }
protected:
explicit Window(const mate::Dictionary& options);
Window(v8::Isolate* isolate, const mate::Dictionary& options);
virtual ~Window();
// NativeWindowObserver:
void OnPageTitleUpdated(bool* prevent_default,
const std::string& title) override;
void WillCreatePopupWindow(const base::string16& frame_name,
const GURL& target_url,
const std::string& partition_id,
WindowOpenDisposition disposition) override;
void WillNavigate(bool* prevent_default, const GURL& url) override;
void WillCloseWindow(bool* prevent_default) override;
void OnWindowClosed() override;
void OnWindowBlur() override;
@@ -64,6 +60,9 @@ class Window : public mate::EventEmitter,
void OnWindowUnmaximize() override;
void OnWindowMinimize() override;
void OnWindowRestore() override;
void OnWindowResize() override;
void OnWindowMove() override;
void OnWindowMoved() override;
void OnWindowEnterFullScreen() override;
void OnWindowLeaveFullScreen() override;
void OnWindowEnterHtmlFullScreen() override;
@@ -71,10 +70,18 @@ class Window : public mate::EventEmitter,
void OnRendererUnresponsive() override;
void OnRendererResponsive() override;
void OnDevToolsFocus() override;
void OnDevToolsOpened() override;
void OnDevToolsClosed() override;
void OnExecuteWindowsCommand(const std::string& command_name) override;
// mate::Wrappable:
bool IsDestroyed() const override;
private:
// mate::TrackableObject:
void Destroy() override;
// APIs for NativeWindow.
void Destroy();
void Close();
bool IsClosed();
void Focus();
@@ -114,26 +121,25 @@ class Window : public mate::EventEmitter,
void SetSkipTaskbar(bool skip);
void SetKiosk(bool kiosk);
bool IsKiosk();
void OpenDevTools(bool can_dock);
void CloseDevTools();
bool IsDevToolsOpened();
void InspectElement(int x, int y);
void FocusOnWebView();
void BlurWebView();
bool IsWebViewFocused();
bool IsDevToolsFocused();
void SetRepresentedFilename(const std::string& filename);
std::string GetRepresentedFilename();
void SetDocumentEdited(bool edited);
bool IsDocumentEdited();
void CapturePage(mate::Arguments* args);
void Print(mate::Arguments* args);
void SetProgressBar(double progress);
void SetOverlayIcon(const gfx::Image& overlay,
const std::string& description);
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();
@@ -142,9 +148,15 @@ class Window : public mate::EventEmitter,
void SetVisibleOnAllWorkspaces(bool visible);
bool IsVisibleOnAllWorkspaces();
// APIs for WebContents.
mate::Handle<WebContents> GetWebContents(v8::Isolate* isolate) const;
mate::Handle<WebContents> GetDevToolsWebContents(v8::Isolate* isolate) const;
int32_t ID() const;
v8::Local<v8::Value> WebContents(v8::Isolate* isolate);
v8::Local<v8::Value> DevToolsWebContents(v8::Isolate* isolate);
v8::Global<v8::Value> web_contents_;
v8::Global<v8::Value> devtools_web_contents_;
v8::Global<v8::Value> menu_;
api::WebContents* api_web_contents_;
scoped_ptr<NativeWindow> window_;
@@ -160,7 +172,7 @@ namespace mate {
template<>
struct Converter<atom::NativeWindow*> {
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
atom::NativeWindow** out) {
// null would be tranfered to NULL.
if (val->IsNull()) {

View File

@@ -6,10 +6,9 @@
#include "atom/browser/api/event.h"
#include "native_mate/arguments.h"
#include "native_mate/dictionary.h"
#include "native_mate/object_template_builder.h"
#include "atom/common/node_includes.h"
namespace mate {
namespace {
@@ -17,8 +16,8 @@ namespace {
v8::Persistent<v8::ObjectTemplate> event_template;
void PreventDefault(mate::Arguments* args) {
args->GetThis()->Set(StringToV8(args->isolate(), "defaultPrevented"),
v8::True(args->isolate()));
mate::Dictionary self(args->isolate(), args->GetThis());
self.Set("defaultPrevented", true);
}
// Create a pure JavaScript Event object.
@@ -38,31 +37,28 @@ v8::Local<v8::Object> CreateEventObject(v8::Isolate* isolate) {
EventEmitter::EventEmitter() {
}
bool EventEmitter::CallEmit(v8::Isolate* isolate,
const base::StringPiece& name,
content::WebContents* sender,
IPC::Message* message,
ValueArray args) {
v8::Handle<v8::Object> event;
v8::Local<v8::Object> EventEmitter::CreateJSEvent(
v8::Isolate* isolate, content::WebContents* sender, IPC::Message* message) {
v8::Local<v8::Object> event;
bool use_native_event = sender && message;
if (use_native_event) {
mate::Handle<mate::Event> native_event = mate::Event::Create(isolate);
native_event->SetSenderAndMessage(sender, message);
event = v8::Handle<v8::Object>::Cast(native_event.ToV8());
event = v8::Local<v8::Object>::Cast(native_event.ToV8());
} else {
event = CreateEventObject(isolate);
}
mate::Dictionary(isolate, event).Set("sender", GetWrapper(isolate));
return event;
}
// args = [name, event, args...];
args.insert(args.begin(), event);
args.insert(args.begin(), mate::StringToV8(isolate, name));
// this.emit.apply(this, args);
node::MakeCallback(isolate, GetWrapper(isolate), "emit", args.size(),
&args[0]);
return event->Get(StringToV8(isolate, "defaultPrevented"))->BooleanValue();
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,6 +7,7 @@
#include <vector>
#include "atom/common/api/event_emitter_caller.h"
#include "native_mate/wrappable.h"
namespace content {
@@ -22,10 +23,15 @@ namespace mate {
// Provide helperers to emit event in JavaScript.
class EventEmitter : public Wrappable {
public:
typedef std::vector<v8::Handle<v8::Value>> ValueArray;
typedef std::vector<v8::Local<v8::Value>> ValueArray;
protected:
EventEmitter();
// 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>
@@ -39,21 +45,33 @@ class EventEmitter : public Wrappable {
content::WebContents* sender,
IPC::Message* message,
const Args&... args) {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
ValueArray converted = { ConvertToV8(isolate, args)... };
return CallEmit(isolate, name, sender, message, converted);
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
v8::Local<v8::Object> event = CreateJSEvent(isolate(), sender, message);
return EmitWithEvent(name, event, args...);
}
protected:
EventEmitter();
private:
// Lower level implementations.
bool CallEmit(v8::Isolate* isolate,
const base::StringPiece& name,
content::WebContents* sender,
IPC::Message* message,
ValueArray args);
// 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

@@ -1,10 +1,15 @@
EventEmitter = require('events').EventEmitter
bindings = process.atomBinding 'app'
sessionBindings = process.atomBinding 'session'
app = bindings.app
app.__proto__ = EventEmitter.prototype
wrapSession = (session) ->
# session is an Event Emitter.
session.__proto__ = EventEmitter.prototype
app.setApplicationMenu = (menu) ->
require('menu').setApplicationMenu menu
@@ -25,13 +30,26 @@ if process.platform is 'darwin'
show: bindings.dockShow
setMenu: bindings.dockSetMenu
appPath = null
app.setAppPath = (path) ->
appPath = path
app.getAppPath = ->
appPath
# Be compatible with old API.
app.once 'ready', -> app.emit 'finish-launching'
app.once 'ready', -> @emit 'finish-launching'
app.terminate = app.quit
app.exit = process.exit
app.getHomeDir = -> app.getPath 'home'
app.getDataPath = -> app.getPath 'userData'
app.setDataPath = (path) -> app.setPath 'userData', path
app.getHomeDir = -> @getPath 'home'
app.getDataPath = -> @getPath 'userData'
app.setDataPath = (path) -> @setPath 'userData', path
app.resolveProxy = -> @defaultSession.resolveProxy.apply @defaultSession, arguments
app.on 'activate', (event, hasVisibleWindows) -> @emit 'activate-with-no-open-windows' if not hasVisibleWindows
# Session wrapper.
sessionBindings._setWrapSession wrapSession
process.once 'exit', sessionBindings._clearWrapSession
# Only one App object pemitted.
module.exports = app

View File

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

View File

@@ -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

@@ -9,7 +9,10 @@ fileDialogProperties =
multiSelections: 1 << 2
createDirectory: 1 << 3
messageBoxTypes = ['none', 'info', 'warning']
messageBoxTypes = ['none', 'info', 'warning', 'error', 'question']
messageBoxOptions =
noLink: 1 << 0
parseArgs = (window, options, callback) ->
unless window is null or window?.constructor is BrowserWindow
@@ -93,9 +96,23 @@ module.exports =
options.detail ?= ''
options.icon ?= null
# Choose a default button to get selected when dialog is cancelled.
unless options.cancelId?
options.cancelId = 0
for text, i in options.buttons
if text.toLowerCase() in ['cancel', 'no']
options.cancelId = i
break
flags = if options.noLink then messageBoxOptions.noLink else 0
binding.showMessageBox messageBoxType,
options.buttons,
[options.title, options.message, options.detail],
options.cancelId,
flags,
options.title,
options.message,
options.detail,
options.icon,
window,
callback
@@ -104,4 +121,5 @@ module.exports =
binding.showErrorBox args...
# Mark standard asynchronous functions.
v8Util.setHiddenValue f, 'asynchronous', true for k, f of module.exports
for api in ['showMessageBox', 'showOpenDialog', 'showSaveDialog']
v8Util.setHiddenValue module.exports[api], 'asynchronous', true

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
@@ -130,10 +132,11 @@ Menu::_callMenuWillShow = ->
applicationMenu = null
Menu.setApplicationMenu = (menu) ->
throw new TypeError('Invalid menu') unless menu?.constructor is Menu
throw new TypeError('Invalid menu') unless menu is null or menu.constructor is Menu
applicationMenu = menu # Keep a reference.
if process.platform is 'darwin'
return if menu is null
menu._callMenuWillShow()
bindings.setApplicationMenu menu
else

View File

@@ -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

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

View File

@@ -2,36 +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
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) ->
# Warn about removed APIs.
logAndThrow = (callback, message) ->
console.error message
if callback then callback(new Error(message)) else throw new Error(message)
protocol.registerProtocol = (scheme, handler, callback) ->
logAndThrow callback,
'registerProtocol API has been replaced by the
register[File/Http/Buffer/String]Protocol API family, please
switch to the new APIs.'
protocol.isHandledProtocol = (scheme, callback) ->
logAndThrow callback,
'isHandledProtocol API has been replaced by isProtocolHandled.'
protocol.interceptProtocol = (scheme, handler, callback) ->
logAndThrow callback,
'interceptProtocol API has been replaced by the
intercept[File/Http/Buffer/String]Protocol API family, please
switch to the new APIs.'
module.exports = protocol

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

@@ -3,9 +3,38 @@ NavigationController = require './navigation-controller'
binding = process.atomBinding 'web_contents'
ipc = require 'ipc'
module.exports.wrap = (webContents) ->
return null unless webContents.isAlive()
nextId = 0
getNextId = -> ++nextId
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
@@ -15,17 +44,11 @@ module.exports.wrap = (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)
# The processId and routingId and identify a webContents.
webContents.getId = -> "#{@getProcessId()}-#{@getRoutingId()}"
webContents.equal = (other) -> @getId() is other.getId()
webContents.once 'did-finish-load', @_executeJavaScript.bind(this, code, hasUserGesture)
# The navigation controller.
controller = new NavigationController(webContents)
@@ -33,34 +56,57 @@ module.exports.wrap = (webContents) ->
do (name, method) ->
webContents[name] = -> method.apply controller, arguments
# Translate |disposition| to string for 'new-window' event.
webContents.on '-new-window', (args..., disposition) ->
disposition =
switch disposition
when 2 then 'default'
when 4 then 'foreground-tab'
when 5 then 'background-tab'
when 6, 7 then 'new-window'
else 'other'
@emit 'new-window', args..., disposition
# Tell the rpc server that a render view has been deleted and we need to
# release all objects owned by it.
webContents.on 'render-view-deleted', (event, processId, routingId) ->
process.emit 'ATOM_BROWSER_RELEASE_RENDER_VIEW', "#{processId}-#{routingId}"
# Dispatch IPC messages to the ipc module.
webContents.on 'ipc-message', (event, packed) ->
[channel, args...] = packed
Object.defineProperty event, 'sender', value: webContents
ipc.emit channel, event, args...
webContents.on 'ipc-message-sync', (event, packed) ->
[channel, args...] = packed
Object.defineProperty event, 'returnValue', set: (value) -> event.sendReply JSON.stringify(value)
Object.defineProperty event, 'sender', value: webContents
ipc.emit channel, event, args...
webContents
webContents.printToPDF = (options, callback) ->
printingSetting =
pageRage: []
mediaSize: {}
landscape: false
color: 2
headerFooterEnabled: false
marginsType: 0
isFirstRequest: false
requestID: getNextId()
previewModifiable: true
printToPDF: true
printWithCloudPrint: false
printWithPrivet: false
printWithExtension: false
deviceName: "Save as PDF"
generateDraftData: true
fitToPageEnabled: false
duplex: 0
copies: 1
collate: true
shouldPrintBackgrounds: false
shouldPrintSelectionOnly: false
if options.landscape
printingSetting.landscape = options.landscape
if options.marginsType
printingSetting.marginsType = options.marginsType
if options.printSelectionOnly
printingSetting.shouldPrintSelectionOnly = options.printSelectionOnly
if options.printBackground
printingSetting.shouldPrintBackgrounds = options.printBackground
if options.pageSize and PDFPageSize[options.pageSize]
printingSetting.mediaSize = PDFPageSize[options.pageSize]
else
printingSetting.mediaSize = PDFPageSize['A4']
@_printToPDF printingSetting, callback
binding._setWrapWebContents wrapWebContents
process.once 'exit', binding._clearWrapWebContents
module.exports.create = (options={}) ->
@wrap binding.create(options)
binding.create(options)

View File

@@ -0,0 +1,71 @@
// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/trackable_object.h"
#include "atom/browser/atom_browser_main_parts.h"
#include "base/bind.h"
#include "base/supports_user_data.h"
namespace mate {
namespace {
const char* kTrackedObjectKey = "TrackedObjectKey";
class IDUserData : public base::SupportsUserData::Data {
public:
explicit IDUserData(int32_t id) : id_(id) {}
operator int32_t() const { return id_; }
private:
int32_t id_;
DISALLOW_COPY_AND_ASSIGN(IDUserData);
};
} // namespace
TrackableObjectBase::TrackableObjectBase()
: weak_map_id_(0), wrapped_(nullptr), weak_factory_(this) {
RegisterDestructionCallback(
base::Bind(&TrackableObjectBase::Destroy, weak_factory_.GetWeakPtr()));
}
TrackableObjectBase::~TrackableObjectBase() {
}
void TrackableObjectBase::AfterInit(v8::Isolate* isolate) {
if (wrapped_)
AttachAsUserData(wrapped_);
}
void TrackableObjectBase::AttachAsUserData(base::SupportsUserData* wrapped) {
if (weak_map_id_ != 0) {
wrapped->SetUserData(kTrackedObjectKey, new IDUserData(weak_map_id_));
wrapped_ = nullptr;
} else {
// If the TrackableObjectBase is not ready yet then delay SetUserData until
// AfterInit is called.
wrapped_ = wrapped;
}
}
// static
int32_t TrackableObjectBase::GetIDFromWrappedClass(base::SupportsUserData* w) {
auto id = static_cast<IDUserData*>(w->GetUserData(kTrackedObjectKey));
if (id)
return *id;
else
return 0;
}
// static
void TrackableObjectBase::RegisterDestructionCallback(
const base::Closure& closure) {
atom::AtomBrowserMainParts::Get()->RegisterDestructionCallback(closure);
}
} // namespace mate

View File

@@ -0,0 +1,133 @@
// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_API_TRACKABLE_OBJECT_H_
#define ATOM_BROWSER_API_TRACKABLE_OBJECT_H_
#include <vector>
#include "atom/browser/api/event_emitter.h"
#include "atom/common/id_weak_map.h"
#include "base/bind.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
namespace base {
class SupportsUserData;
}
namespace mate {
// Users should use TrackableObject instead.
class TrackableObjectBase : public mate::EventEmitter {
public:
TrackableObjectBase();
// The ID in weak map.
int32_t weak_map_id() const { return weak_map_id_; }
// Wrap TrackableObject into a class that SupportsUserData.
void AttachAsUserData(base::SupportsUserData* wrapped);
// Subclasses should implement this to destroy their native types.
virtual void Destroy() = 0;
protected:
~TrackableObjectBase() override;
// mate::Wrappable:
void AfterInit(v8::Isolate* isolate) override;
// Get the weak_map_id from SupportsUserData.
static int32_t GetIDFromWrappedClass(base::SupportsUserData* wrapped);
// Register a callback that should be destroyed before JavaScript environment
// gets destroyed.
static void RegisterDestructionCallback(const base::Closure& closure);
int32_t weak_map_id_;
base::SupportsUserData* wrapped_;
private:
base::WeakPtrFactory<TrackableObjectBase> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(TrackableObjectBase);
};
// All instances of TrackableObject will be kept in a weak map and can be got
// from its ID.
template<typename T>
class TrackableObject : public TrackableObjectBase {
public:
// Finds out the TrackableObject from its ID in weak map.
static T* FromWeakMapID(v8::Isolate* isolate, int32_t id) {
if (!weak_map_)
return nullptr;
v8::MaybeLocal<v8::Object> object = weak_map_->Get(isolate, id);
if (object.IsEmpty())
return nullptr;
T* self = nullptr;
mate::ConvertFromV8(isolate, object.ToLocalChecked(), &self);
return self;
}
// Finds out the TrackableObject from the class it wraps.
static T* FromWrappedClass(v8::Isolate* isolate,
base::SupportsUserData* wrapped) {
int32_t id = GetIDFromWrappedClass(wrapped);
if (!id)
return nullptr;
return FromWeakMapID(isolate, id);
}
// Returns all objects in this class's weak map.
static std::vector<v8::Local<v8::Object>> GetAll(v8::Isolate* isolate) {
if (weak_map_)
return weak_map_->Values(isolate);
else
return std::vector<v8::Local<v8::Object>>();
}
TrackableObject() {
RegisterDestructionCallback(
base::Bind(&TrackableObject<T>::ReleaseAllWeakReferences));
}
// Removes this instance from the weak map.
void RemoveFromWeakMap() {
if (weak_map_ && weak_map_->Has(weak_map_id()))
weak_map_->Remove(weak_map_id());
}
protected:
~TrackableObject() override {
RemoveFromWeakMap();
}
void AfterInit(v8::Isolate* isolate) override {
if (!weak_map_)
weak_map_.reset(new atom::IDWeakMap);
weak_map_id_ = weak_map_->Add(isolate, GetWrapper(isolate));
TrackableObjectBase::AfterInit(isolate);
}
private:
// Releases all weak references in weak map, called when app is terminating.
static void ReleaseAllWeakReferences() {
weak_map_.reset();
}
static scoped_ptr<atom::IDWeakMap> weak_map_;
DISALLOW_COPY_AND_ASSIGN(TrackableObject);
};
template<typename T>
scoped_ptr<atom::IDWeakMap> TrackableObject<T>::weak_map_;
} // namespace mate
#endif // ATOM_BROWSER_API_TRACKABLE_OBJECT_H_

View File

@@ -7,7 +7,9 @@
#include <utility>
#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 {
@@ -23,6 +25,7 @@ const char* kGeolocationProviderUrl =
} // namespace
AtomAccessTokenStore::AtomAccessTokenStore() {
content::GeolocationProvider::GetInstance()->UserDidOptIntoLocationServices();
}
AtomAccessTokenStore::~AtomAccessTokenStore() {
@@ -39,8 +42,8 @@ void AtomAccessTokenStore::LoadAccessTokens(
token_pair.first = GURL(kGeolocationProviderUrl);
access_token_set.insert(token_pair);
callback.Run(access_token_set,
AtomBrowserContext::Get()->url_request_context_getter());
auto browser_context = AtomBrowserMainParts::Get()->browser_context();
callback.Run(access_token_set, browser_context->url_request_context_getter());
}
void AtomAccessTokenStore::SaveAccessToken(const GURL& server_url,

View File

@@ -4,54 +4,75 @@
#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"
#include "atom/browser/atom_quota_permission_context.h"
#include "atom/browser/atom_resource_dispatcher_host_delegate.h"
#include "atom/browser/atom_speech_recognition_manager_delegate.h"
#include "atom/browser/browser.h"
#include "atom/browser/native_window.h"
#include "atom/browser/web_view_manager.h"
#include "atom/browser/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"
#include "chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h"
#include "chrome/browser/speech/tts_message_filter.h"
#include "content/public/browser/browser_ppapi_host.h"
#include "content/public/browser/client_certificate_delegate.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/resource_dispatcher_host.h"
#include "content/public/browser/site_instance.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/web_preferences.h"
#include "net/cert/x509_certificate.h"
#include "net/ssl/ssl_cert_request_info.h"
#include "ppapi/host/ppapi_host.h"
#include "ui/base/l10n/l10n_util.h"
#include "v8/include/v8.h"
namespace atom {
namespace {
// The default routing id of WebContents.
// In Electron each RenderProcessHost only has one WebContents, so this ID is
// same for every WebContents.
int kDefaultRoutingID = 2;
// Next navigation should not restart renderer process.
bool g_suppress_renderer_process_restart = false;
struct FindByProcessId {
explicit FindByProcessId(int child_process_id)
: child_process_id_(child_process_id) {
}
// Custom schemes to be registered to standard.
std::string g_custom_schemes = "";
bool operator() (NativeWindow* const window) {
content::WebContents* web_contents = window->GetWebContents();
if (!web_contents)
return false;
scoped_refptr<net::X509Certificate> ImportCertFromFile(
const base::FilePath& path) {
if (path.empty())
return nullptr;
int id = window->GetWebContents()->GetRenderProcessHost()->GetID();
return id == child_process_id_;
}
std::string cert_data;
if (!base::ReadFileToString(path, &cert_data))
return nullptr;
int child_process_id_;
};
net::CertificateList certs =
net::X509Certificate::CreateCertificateListFromBytes(
cert_data.data(), cert_data.size(),
net::X509Certificate::FORMAT_AUTO);
if (certs.empty())
return nullptr;
return certs[0];
}
} // namespace
@@ -60,8 +81,12 @@ void AtomBrowserClient::SuppressRendererProcessRestartForOnce() {
g_suppress_renderer_process_restart = true;
}
AtomBrowserClient::AtomBrowserClient()
: dying_render_process_(nullptr) {
void AtomBrowserClient::SetCustomSchemes(
const std::vector<std::string>& schemes) {
g_custom_schemes = JoinString(schemes, ',');
}
AtomBrowserClient::AtomBrowserClient() {
}
AtomBrowserClient::~AtomBrowserClient() {
@@ -69,9 +94,9 @@ AtomBrowserClient::~AtomBrowserClient() {
void AtomBrowserClient::RenderProcessWillLaunch(
content::RenderProcessHost* host) {
int id = host->GetID();
host->AddFilter(new printing::PrintingMessageFilter(host->GetID()));
host->AddFilter(new TtsMessageFilter(id, host->GetBrowserContext()));
int process_id = host->GetID();
host->AddFilter(new printing::PrintingMessageFilter(process_id));
host->AddFilter(new TtsMessageFilter(process_id, host->GetBrowserContext()));
}
content::SpeechRecognitionManagerDelegate*
@@ -83,15 +108,8 @@ content::AccessTokenStore* AtomBrowserClient::CreateAccessTokenStore() {
return new AtomAccessTokenStore;
}
void AtomBrowserClient::ResourceDispatcherHostCreated() {
resource_dispatcher_delegate_.reset(new AtomResourceDispatcherHostDelegate);
content::ResourceDispatcherHost::Get()->SetDelegate(
resource_dispatcher_delegate_.get());
}
void AtomBrowserClient::OverrideWebkitPrefs(
content::RenderViewHost* render_view_host,
content::WebPreferences* prefs) {
content::RenderViewHost* host, content::WebPreferences* prefs) {
prefs->javascript_enabled = true;
prefs->web_security_enabled = true;
prefs->javascript_can_open_windows_automatically = true;
@@ -109,25 +127,9 @@ void AtomBrowserClient::OverrideWebkitPrefs(
prefs->allow_displaying_insecure_content = false;
prefs->allow_running_insecure_content = false;
// Turn off web security for devtools.
auto web_contents = content::WebContents::FromRenderViewHost(
render_view_host);
if (web_contents && web_contents->GetURL().SchemeIs("chrome-devtools")) {
prefs->web_security_enabled = false;
return;
}
// Custom preferences of guest page.
auto process = render_view_host->GetProcess();
WebViewManager::WebViewInfo info;
if (WebViewManager::GetInfoForProcess(process, &info)) {
prefs->web_security_enabled = !info.disable_web_security;
return;
}
NativeWindow* window = NativeWindow::FromWebContents(web_contents);
if (window)
window->OverrideWebkitPrefs(prefs);
auto web_contents = content::WebContents::FromRenderViewHost(host);
WebContentsPreferences::OverrideWebkitPrefs(web_contents, prefs);
}
std::string AtomBrowserClient::GetApplicationLocale() {
@@ -144,82 +146,59 @@ void AtomBrowserClient::OverrideSiteInstanceForNavigation(
return;
}
if (current_instance->HasProcess())
dying_render_process_ = current_instance->GetProcess();
// Restart renderer process for all navigations except "javacript:" scheme.
if (url.SchemeIs(url::kJavaScriptScheme))
return;
// Restart renderer process for all navigations.
*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(
base::CommandLine* command_line,
int child_process_id) {
int process_id) {
std::string process_type = command_line->GetSwitchValueASCII("type");
if (process_type != "renderer")
return;
WindowList* list = WindowList::GetInstance();
NativeWindow* window = nullptr;
// The registered standard schemes.
if (!g_custom_schemes.empty())
command_line->AppendSwitchASCII(switches::kRegisterStandardSchemes,
g_custom_schemes);
// Find the owner of this child process.
WindowList::const_iterator iter = std::find_if(
list->begin(), list->end(), FindByProcessId(child_process_id));
if (iter != list->end())
window = *iter;
// If the render process is a newly started one, which means the window still
// uses the old going-to-be-swapped render process, then we try to find the
// window from the swapped render process.
if (!window && dying_render_process_) {
int dying_process_id = dying_render_process_->GetID();
WindowList::const_iterator iter = std::find_if(
list->begin(), list->end(), FindByProcessId(dying_process_id));
if (iter != list->end()) {
window = *iter;
child_process_id = dying_process_id;
} else {
// It appears that the dying process doesn't belong to a BrowserWindow,
// then it might be a guest process, if it is we should update its
// process ID in the WebViewManager.
auto child_process = content::RenderProcessHost::FromID(child_process_id);
// Update the process ID in webview guests.
WebViewManager::UpdateGuestProcessID(dying_render_process_,
child_process);
}
#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 (window) {
window->AppendExtraCommandLineSwitches(command_line, child_process_id);
} else {
// Append commnad line arguments for guest web view.
auto child_process = content::RenderProcessHost::FromID(child_process_id);
WebViewManager::WebViewInfo info;
if (WebViewManager::GetInfoForProcess(child_process, &info)) {
command_line->AppendSwitchASCII(
switches::kGuestInstanceID,
base::IntToString(info.guest_instance_id));
command_line->AppendSwitchASCII(
switches::kNodeIntegration,
info.node_integration ? "true" : "false");
if (info.plugins)
command_line->AppendSwitch(switches::kEnablePlugins);
if (!info.preload_script.empty())
command_line->AppendSwitchPath(
switches::kPreloadScript,
info.preload_script);
}
}
// 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];
dying_render_process_ = nullptr;
// 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(
content::BrowserPpapiHost* browser_host) {
auto command_line = base::CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(switches::kEnablePlugins))
browser_host->GetPpapiHost()->AddHostFactoryFilter(
scoped_ptr<ppapi::host::HostFactory>(
new chrome::ChromeBrowserPepperHostFactory(browser_host)));
content::BrowserPpapiHost* host) {
host->GetPpapiHost()->AddHostFactoryFilter(
make_scoped_ptr(new chrome::ChromeBrowserPepperHostFactory(host)));
}
content::QuotaPermissionContext*
@@ -227,10 +206,41 @@ content::QuotaPermissionContext*
return new AtomQuotaPermissionContext;
}
void AtomBrowserClient::SelectClientCertificate(
content::WebContents* web_contents,
net::SSLCertRequestInfo* cert_request_info,
scoped_ptr<content::ClientCertificateDelegate> delegate) {
// --client-certificate=`path`
auto cmd = base::CommandLine::ForCurrentProcess();
if (cmd->HasSwitch(switches::kClientCertificate)) {
auto cert_path = cmd->GetSwitchValuePath(switches::kClientCertificate);
auto certificate = ImportCertFromFile(cert_path);
if (certificate.get())
delegate->ContinueWithCertificate(certificate.get());
return;
}
if (!cert_request_info->client_certs.empty())
Browser::Get()->ClientCertificateSelector(web_contents,
cert_request_info,
delegate.Pass());
}
brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts(
const content::MainFunctionParams&) {
v8::V8::Initialize(); // Init V8 before creating main parts.
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,25 +5,34 @@
#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;
class ClientCertificateDelegate;
}
namespace net {
class SSLCertRequestInfo;
}
namespace atom {
class AtomResourceDispatcherHostDelegate;
class AtomBrowserClient : public brightray::BrowserClient {
class AtomBrowserClient : public brightray::BrowserClient,
public content::RenderProcessHostObserver {
public:
AtomBrowserClient();
virtual ~AtomBrowserClient();
// Don't force renderer process to restart for once.
static void SuppressRendererProcessRestartForOnce();
// Custom schemes to be registered to standard.
static void SetCustomSchemes(const std::vector<std::string>& schemes);
protected:
// content::ContentBrowserClient:
@@ -31,7 +40,6 @@ class AtomBrowserClient : public brightray::BrowserClient {
content::SpeechRecognitionManagerDelegate*
CreateSpeechRecognitionManagerDelegate() override;
content::AccessTokenStore* CreateAccessTokenStore() override;
void ResourceDispatcherHostCreated() override;
void OverrideWebkitPrefs(content::RenderViewHost* render_view_host,
content::WebPreferences* prefs) override;
std::string GetApplicationLocale() override;
@@ -39,20 +47,26 @@ class AtomBrowserClient : public brightray::BrowserClient {
content::BrowserContext* browser_context,
content::SiteInstance* current_instance,
const GURL& dest_url,
content::SiteInstance** new_instance);
content::SiteInstance** new_instance) override;
void AppendExtraCommandLineSwitches(base::CommandLine* command_line,
int child_process_id) override;
void DidCreatePpapiPlugin(content::BrowserPpapiHost* browser_host) override;
content::QuotaPermissionContext* CreateQuotaPermissionContext() override;
void SelectClientCertificate(
content::WebContents* web_contents,
net::SSLCertRequestInfo* cert_request_info,
scoped_ptr<content::ClientCertificateDelegate> delegate) override;
private:
// brightray::BrowserClient:
brightray::BrowserMainParts* OverrideCreateBrowserMainParts(
const content::MainFunctionParams&) override;
scoped_ptr<AtomResourceDispatcherHostDelegate> resource_dispatcher_delegate_;
// content::RenderProcessHostObserver:
void RenderProcessHostDestroyed(content::RenderProcessHost* host) override;
// The render process which would be swapped out soon.
content::RenderProcessHost* dying_render_process_;
private:
// pending_render_process => current_render_process.
std::map<int, int> pending_processes_;
DISALLOW_COPY_AND_ASSIGN(AtomBrowserClient);
};

View File

@@ -5,19 +5,31 @@
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/atom_download_manager_delegate.h"
#include "atom/browser/browser.h"
#include "atom/browser/net/atom_url_request_job_factory.h"
#include "atom/browser/net/asar/asar_protocol_handler.h"
#include "atom/browser/net/http_protocol_handler.h"
#include "atom/browser/web_view_manager.h"
#include "atom/common/atom_version.h"
#include "atom/common/chrome_version.h"
#include "atom/common/options_switches.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/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/browser/browser_process.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"
#include "net/ftp/ftp_network_layer.h"
#include "net/url_request/data_protocol_handler.h"
#include "net/url_request/ftp_protocol_handler.h"
#include "net/url_request/url_request_intercepting_job_factory.h"
#include "net/url_request/url_request_context.h"
#include "url/url_constants.h"
using content::BrowserThread;
@@ -34,40 +46,78 @@ class NoCacheBackend : public net::HttpCache::BackendFactory {
}
};
std::string RemoveWhitespace(const std::string& str) {
std::string trimmed;
if (base::RemoveChars(str, " ", &trimmed))
return trimmed;
else
return str;
}
} // namespace
AtomBrowserContext::AtomBrowserContext()
: fake_browser_process_(new BrowserProcess),
AtomBrowserContext::AtomBrowserContext(const std::string& partition,
bool in_memory)
: brightray::BrowserContext(partition, in_memory),
job_factory_(new AtomURLRequestJobFactory) {
}
AtomBrowserContext::~AtomBrowserContext() {
}
std::string AtomBrowserContext::GetUserAgent() {
Browser* browser = Browser::Get();
std::string name = RemoveWhitespace(browser->GetName());
std::string user_agent;
if (name == ATOM_PRODUCT_NAME) {
user_agent = "Chrome/" CHROME_VERSION_STRING " "
ATOM_PRODUCT_NAME "/" ATOM_VERSION_STRING;
} else {
user_agent = base::StringPrintf(
"%s/%s Chrome/%s " ATOM_PRODUCT_NAME "/" ATOM_VERSION_STRING,
name.c_str(),
browser->GetVersion().c_str(),
CHROME_VERSION_STRING);
}
return content::BuildUserAgentFromProduct(user_agent);
}
net::URLRequestJobFactory* AtomBrowserContext::CreateURLRequestJobFactory(
content::ProtocolHandlerMap* handlers,
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();
job_factory->SetProtocolHandler(
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();
@@ -90,16 +140,37 @@ AtomBrowserContext::CreateHttpCacheBackendFactory(
return brightray::BrowserContext::CreateHttpCacheBackendFactory(base_path);
}
content::DownloadManagerDelegate*
AtomBrowserContext::GetDownloadManagerDelegate() {
if (!download_manager_delegate_.get()) {
auto download_manager = content::BrowserContext::GetDownloadManager(this);
download_manager_delegate_.reset(
new AtomDownloadManagerDelegate(download_manager));
}
return download_manager_delegate_.get();
}
content::BrowserPluginGuestManager* AtomBrowserContext::GetGuestManager() {
if (!guest_manager_)
guest_manager_.reset(new WebViewManager(this));
guest_manager_.reset(new WebViewManager);
return guest_manager_.get();
}
// static
AtomBrowserContext* AtomBrowserContext::Get() {
return static_cast<AtomBrowserContext*>(
AtomBrowserMainParts::Get()->browser_context());
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

@@ -5,24 +5,23 @@
#ifndef ATOM_BROWSER_ATOM_BROWSER_CONTEXT_H_
#define ATOM_BROWSER_ATOM_BROWSER_CONTEXT_H_
#include "brightray/browser/browser_context.h"
#include <string>
class BrowserProcess;
#include "brightray/browser/browser_context.h"
namespace atom {
class AtomDownloadManagerDelegate;
class AtomURLRequestJobFactory;
class WebViewManager;
class AtomBrowserContext : public brightray::BrowserContext {
public:
AtomBrowserContext();
virtual ~AtomBrowserContext();
// Returns the browser context singleton.
static AtomBrowserContext* Get();
AtomBrowserContext(const std::string& partition, bool in_memory);
~AtomBrowserContext() override;
// brightray::URLRequestContextGetter::Delegate:
std::string GetUserAgent() override;
net::URLRequestJobFactory* CreateURLRequestJobFactory(
content::ProtocolHandlerMap* handlers,
content::URLRequestInterceptorScopedVector* interceptors) override;
@@ -30,16 +29,20 @@ class AtomBrowserContext : public brightray::BrowserContext {
const base::FilePath& base_path) 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:
// A fake BrowserProcess object that used to feed the source code from chrome.
scoped_ptr<BrowserProcess> fake_browser_process_;
scoped_ptr<AtomDownloadManagerDelegate> download_manager_delegate_;
scoped_ptr<WebViewManager> guest_manager_;
AtomURLRequestJobFactory* job_factory_; // Weak reference.
// Managed by brightray::BrowserContext.
AtomURLRequestJobFactory* job_factory_;
DISALLOW_COPY_AND_ASSIGN(AtomBrowserContext);
};

View File

@@ -4,28 +4,33 @@
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/api/trackable_object.h"
#include "atom/browser/atom_browser_client.h"
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/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"
#if defined(USE_X11)
#include "chrome/browser/ui/libgtk2ui/gtk2_util.h"
#endif
#include "atom/common/node_includes.h"
namespace atom {
// static
AtomBrowserMainParts* AtomBrowserMainParts::self_ = NULL;
AtomBrowserMainParts::AtomBrowserMainParts()
: browser_(new Browser),
: fake_browser_process_(new BrowserProcess),
browser_(new Browser),
node_bindings_(NodeBindings::Create(true)),
atom_bindings_(new AtomBindings),
gc_timer_(true, true) {
@@ -42,8 +47,9 @@ AtomBrowserMainParts* AtomBrowserMainParts::Get() {
return self_;
}
brightray::BrowserContext* AtomBrowserMainParts::CreateBrowserContext() {
return new AtomBrowserContext();
void AtomBrowserMainParts::RegisterDestructionCallback(
const base::Closure& callback) {
destruction_callbacks_.push_back(callback);
}
void AtomBrowserMainParts::PostEarlyInitialization() {
@@ -53,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());
@@ -95,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

@@ -5,8 +5,15 @@
#ifndef ATOM_BROWSER_ATOM_BROWSER_MAIN_PARTS_H_
#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;
namespace atom {
@@ -14,6 +21,8 @@ class AtomBindings;
class Browser;
class JavascriptEnvironment;
class NodeBindings;
class NodeDebugger;
class BridgeTaskRunner;
class AtomBrowserMainParts : public brightray::BrowserMainParts {
public:
@@ -22,15 +31,17 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
static AtomBrowserMainParts* Get();
// Register a callback that should be destroyed before JavaScript environment
// gets destroyed.
void RegisterDestructionCallback(const base::Closure& callback);
Browser* browser() { return browser_.get(); }
protected:
// 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;
@@ -41,13 +52,24 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
void SetDPIFromGSettings();
#endif
// A fake BrowserProcess object that used to feed the source code from chrome.
scoped_ptr<BrowserProcess> fake_browser_process_;
// 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_;
// List of callbacks should be executed before destroying JS env.
std::list<base::Closure> destruction_callbacks_;
static AtomBrowserMainParts* self_;
DISALLOW_COPY_AND_ASSIGN(AtomBrowserMainParts);

View File

@@ -0,0 +1,151 @@
// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/atom_download_manager_delegate.h"
#include <string>
#include "atom/browser/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"
#include "net/base/filename_util.h"
namespace atom {
AtomDownloadManagerDelegate::AtomDownloadManagerDelegate(
content::DownloadManager* manager)
: download_manager_(manager),
weak_ptr_factory_(this) {}
AtomDownloadManagerDelegate::~AtomDownloadManagerDelegate() {
if (download_manager_) {
DCHECK_EQ(static_cast<content::DownloadManagerDelegate*>(this),
download_manager_->GetDelegate());
download_manager_->SetDelegate(nullptr);
download_manager_ = nullptr;
}
}
void AtomDownloadManagerDelegate::CreateDownloadPath(
const GURL& url,
const std::string& content_disposition,
const std::string& suggested_filename,
const std::string& mime_type,
const base::FilePath& default_download_path,
const CreateDownloadPathCallback& callback) {
DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
auto generated_name = net::GenerateFileName(url,
content_disposition,
std::string(),
suggested_filename,
mime_type,
std::string());
if (!base::PathExists(default_download_path))
base::CreateDirectory(default_download_path);
base::FilePath path(default_download_path.Append(generated_name));
content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
base::Bind(callback, path));
}
void AtomDownloadManagerDelegate::OnDownloadPathGenerated(
uint32 download_id,
const content::DownloadTargetCallback& callback,
const base::FilePath& default_path) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
auto item = download_manager_->GetDownload(download_id);
if (!item)
return;
NativeWindow* window = nullptr;
auto relay = NativeWindowRelay::FromWebContents(item->GetWebContents());
if (relay)
window = relay->window.get();
file_dialog::Filters filters;
base::FilePath path;
if (!file_dialog::ShowSaveDialog(window, item->GetURL().spec(), default_path,
filters, &path)) {
return;
}
// Remeber the last selected download directory.
AtomBrowserContext* browser_context = static_cast<AtomBrowserContext*>(
download_manager_->GetBrowserContext());
browser_context->prefs()->SetFilePath(prefs::kDownloadDefaultDirectory,
path.DirName());
callback.Run(path,
content::DownloadItem::TARGET_DISPOSITION_PROMPT,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, path);
}
void AtomDownloadManagerDelegate::Shutdown() {
weak_ptr_factory_.InvalidateWeakPtrs();
download_manager_ = nullptr;
}
bool AtomDownloadManagerDelegate::DetermineDownloadTarget(
content::DownloadItem* download,
const content::DownloadTargetCallback& callback) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
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"));
}
if (!download->GetForcedFilePath().empty()) {
callback.Run(download->GetForcedFilePath(),
content::DownloadItem::TARGET_DISPOSITION_OVERWRITE,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
download->GetForcedFilePath());
return true;
}
CreateDownloadPathCallback download_path_callback =
base::Bind(&AtomDownloadManagerDelegate::OnDownloadPathGenerated,
weak_ptr_factory_.GetWeakPtr(),
download->GetId(), callback);
content::BrowserThread::PostTask(
content::BrowserThread::FILE, FROM_HERE,
base::Bind(&AtomDownloadManagerDelegate::CreateDownloadPath,
weak_ptr_factory_.GetWeakPtr(),
download->GetURL(),
download->GetContentDisposition(),
download->GetSuggestedFilename(),
download->GetMimeType(),
default_download_path,
download_path_callback));
return true;
}
bool AtomDownloadManagerDelegate::ShouldOpenDownload(
content::DownloadItem* download,
const content::DownloadOpenDelayedCallback& callback) {
return true;
}
void AtomDownloadManagerDelegate::GetNextId(
const content::DownloadIdCallback& callback) {
static uint32 next_id = content::DownloadItem::kInvalidId + 1;
callback.Run(next_id++);
}
} // namespace atom

View File

@@ -0,0 +1,57 @@
// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_ATOM_DOWNLOAD_MANAGER_DELEGATE_H_
#define ATOM_BROWSER_ATOM_DOWNLOAD_MANAGER_DELEGATE_H_
#include <string>
#include "base/memory/weak_ptr.h"
#include "content/public/browser/download_manager_delegate.h"
namespace content {
class DownloadManager;
}
namespace atom {
class AtomDownloadManagerDelegate : public content::DownloadManagerDelegate {
public:
using CreateDownloadPathCallback =
base::Callback<void(const base::FilePath&)>;
explicit AtomDownloadManagerDelegate(content::DownloadManager* manager);
virtual ~AtomDownloadManagerDelegate();
// Generate default file path to save the download.
void CreateDownloadPath(const GURL& url,
const std::string& suggested_filename,
const std::string& content_disposition,
const std::string& mime_type,
const base::FilePath& path,
const CreateDownloadPathCallback& callback);
void OnDownloadPathGenerated(uint32 download_id,
const content::DownloadTargetCallback& callback,
const base::FilePath& default_path);
// content::DownloadManagerDelegate:
void Shutdown() override;
bool DetermineDownloadTarget(
content::DownloadItem* download,
const content::DownloadTargetCallback& callback) override;
bool ShouldOpenDownload(
content::DownloadItem* download,
const content::DownloadOpenDelayedCallback& callback) override;
void GetNextId(const content::DownloadIdCallback& callback) override;
private:
content::DownloadManager* download_manager_;
base::WeakPtrFactory<AtomDownloadManagerDelegate> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(AtomDownloadManagerDelegate);
};
} // namespace atom
#endif // ATOM_BROWSER_ATOM_DOWNLOAD_MANAGER_DELEGATE_H_

View File

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

View File

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

View File

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

View File

@@ -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

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

View File

@@ -108,13 +108,20 @@ 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();
void DidFinishLaunching();
// Called when client certificate is required.
void ClientCertificateSelector(
content::WebContents* web_contents,
net::SSLCertRequestInfo* cert_request_info,
scoped_ptr<content::ClientCertificateDelegate> delegate);
void AddObserver(BrowserObserver* obs) {
observers_.AddObserver(obs);
}
@@ -147,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

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

View File

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

View File

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

View File

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

View File

@@ -2,6 +2,8 @@ var app = require('app');
var dialog = require('dialog');
var fs = require('fs');
var path = require('path');
var Menu = require('menu');
var BrowserWindow = require('browser-window');
// Quit when all windows are closed and no other one is listening to this.
app.on('window-all-closed', function() {
@@ -29,6 +31,187 @@ for (var i in argv) {
}
}
// Create default menu.
app.once('ready', function() {
if (Menu.getApplicationMenu())
return;
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.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(
{
type: 'separator'
},
{
label: 'Bring All to Front',
role: 'front'
}
);
}
var menu = Menu.buildFromTemplate(template);
Menu.setApplicationMenu(menu);
});
// Start the specified app if there is one specified in command line, otherwise
// start the default app.
if (option.file && !option.webdriver) {
@@ -46,6 +229,7 @@ if (option.file && !option.webdriver) {
app.setName(packageJson.name);
app.setPath('userData', path.join(app.getPath('appData'), app.getName()));
app.setPath('userCache', path.join(app.getPath('cache'), app.getName()));
app.setAppPath(packagePath);
}
// Run the app.
@@ -53,7 +237,7 @@ if (option.file && !option.webdriver) {
} catch(e) {
if (e.code == 'MODULE_NOT_FOUND') {
app.focus();
dialog.showErrorBox('Error opening app', 'The app provided is not a valid electron app, please read the docs on how to write one:\nhttps://github.com/atom/electron/tree/master/docs');
dialog.showErrorBox('Error opening app', 'The app provided is not a valid electron app, please read the docs on how to write one:\nhttps://github.com/atom/electron/tree/master/docs\n\n' + e.toString());
process.exit(1);
} else {
console.error('App threw an error when running', e);

View File

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

View File

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

View File

@@ -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,17 +43,20 @@ createGuest = (embedder, params) ->
webViewManager ?= process.atomBinding 'web_view_manager'
id = getNextInstanceId embedder
guest = webContents.create
isGuest: true
guestInstanceId: id
storagePartitionId: params.storagePartitionId
guest = webContents.create {isGuest: true, 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
@@ -58,14 +66,19 @@ createGuest = (embedder, params) ->
delete @attachParams
@viewInstanceId = params.instanceId
min = width: params.minwidth, height: params.minheight
max = width: params.maxwidth, height: params.maxheight
@setAutoSize params.autosize, min, max
@setSize
normal:
width: params.elementWidth, height: params.elementHeight
enableAutoSize: params.autosize
min:
width: params.minwidth, height: params.minheight
max:
width: params.maxwidth, height: params.maxheight
if params.src
opts = {}
opts.httpreferrer = params.httpreferrer if params.httpreferrer
opts.useragent = params.useragent if params.useragent
opts.httpReferrer = params.httpreferrer if params.httpreferrer
opts.userAgent = params.useragent if params.useragent
@loadUrl params.src, opts
if params.allowtransparency?
@@ -102,11 +115,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
@@ -123,7 +138,7 @@ destroyGuest = (embedder, id) ->
delete reverseEmbedderElementsMap[id]
delete embedderElementsMap[key]
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_CREATE_GUEST', (event, type, params, requestId) ->
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_CREATE_GUEST', (event, params, requestId) ->
event.sender.send "ATOM_SHELL_RESPONSE_#{requestId}", createGuest(event.sender, params)
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_ATTACH_GUEST', (event, elementInstanceId, guestInstanceId, params) ->
@@ -132,8 +147,8 @@ ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_ATTACH_GUEST', (event, elementInstanceId,
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_DESTROY_GUEST', (event, id) ->
destroyGuest event.sender, id
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_SET_AUTO_SIZE', (event, id, params) ->
guestInstances[id]?.guest.setAutoSize params.enableAutoSize, params.min, params.max
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_SET_SIZE', (event, id, params) ->
guestInstances[id]?.guest.setSize params
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_SET_ALLOW_TRANSPARENCY', (event, id, allowtransparency) ->
guestInstances[id]?.guest.setAllowTransparency allowtransparency

View File

@@ -21,9 +21,8 @@ createGuest = (embedder, url, frameName, options) ->
# guest is closed by user then we should prevent |embedder| from double
# closing guest.
closedByEmbedder = ->
embedder.send 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_CLOSED', guest.id
guest.removeListener 'closed', closedByUser
guest.destroy() unless guest.isClosed()
guest.destroy()
closedByUser = ->
embedder.send 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_CLOSED', guest.id
embedder.removeListener 'render-view-deleted', closedByEmbedder
@@ -41,31 +40,36 @@ createGuest = (embedder, url, frameName, options) ->
# Routed window.open messages.
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPEN', (event, args...) ->
[url, frameName, options] = args
event.sender.emit '-new-window', event, url, frameName, 7
event.sender.emit 'new-window', event, url, frameName, 'new-window'
if event.sender.isGuest() or event.defaultPrevented
event.returnValue = null
else
event.returnValue = createGuest event.sender, args...
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_CLOSE', (event, guestId) ->
return unless BrowserWindow.windows.has guestId
BrowserWindow.windows.get(guestId).destroy()
BrowserWindow.fromId(guestId)?.destroy()
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_METHOD', (event, guestId, method, args...) ->
return unless BrowserWindow.windows.has guestId
BrowserWindow.windows.get(guestId)[method] args...
BrowserWindow.fromId(guestId)?[method] args...
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', (event, guestId, message, targetOrigin) ->
return unless BrowserWindow.windows.has guestId
guestContents = BrowserWindow.windows.get(guestId).webContents
if guestContents.getUrl().indexOf(targetOrigin) is 0 or targetOrigin is '*'
guestContents = BrowserWindow.fromId(guestId)?.webContents
if guestContents?.getUrl().indexOf(targetOrigin) is 0 or targetOrigin is '*'
guestContents.send 'ATOM_SHELL_GUEST_WINDOW_POSTMESSAGE', message, targetOrigin
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPENER_POSTMESSAGE', (event, message, targetOrigin) ->
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...) ->
return unless BrowserWindow.windows.has guestId
BrowserWindow.windows.get(guestId).webContents?[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'
@@ -87,9 +87,13 @@ app.commandLine.appendSwitch 'enable-npapi'
# Set the user path according to application's name.
app.setPath 'userData', path.join(app.getPath('appData'), app.getName())
app.setPath 'userCache', path.join(app.getPath('cache'), app.getName())
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 = require 'id-weak-map'
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,11 +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?
@@ -22,10 +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
@@ -43,6 +53,8 @@ unwrapArgs = (sender, args) ->
when 'value' then meta.value
when 'remote-object' then objectsRegistry.get meta.id
when 'array' then unwrapArgs sender, meta.value
when 'buffer' then new Buffer(meta.value)
when 'promise' then Promise.resolve(then: metaToValue(meta.then))
when 'object'
ret = v8Util.createObjectWithName meta.name
for member in meta.members
@@ -72,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) ->
@@ -162,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

@@ -9,45 +9,26 @@
#include <vector>
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/atom_javascript_dialog_manager.h"
#include "atom/browser/browser.h"
#include "atom/browser/ui/file_dialog.h"
#include "atom/browser/web_dialog_helper.h"
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/window_list.h"
#include "atom/common/api/api_messages.h"
#include "atom/common/atom_version.h"
#include "atom/common/chrome_version.h"
#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/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "brightray/browser/inspectable_web_contents.h"
#include "brightray/browser/inspectable_web_contents_view.h"
#include "chrome/browser/printing/print_view_manager_basic.h"
#include "chrome/browser/ui/browser_dialogs.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/invalidate_type.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/plugin_service.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/renderer_preferences.h"
#include "content/public/common/user_agent.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"
@@ -58,59 +39,51 @@
#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,
};
std::string RemoveWhitespace(const std::string& str) {
std::string trimmed;
if (base::RemoveChars(str, " ", &trimmed))
return trimmed;
else
return str;
// 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
NativeWindow::NativeWindow(content::WebContents* web_contents,
const mate::Dictionary& options)
: content::WebContentsObserver(web_contents),
NativeWindow::NativeWindow(
brightray::InspectableWebContents* inspectable_web_contents,
const mate::Dictionary& options)
: content::WebContentsObserver(inspectable_web_contents->GetWebContents()),
has_frame_(true),
transparent_(false),
enable_larger_than_screen_(false),
is_closed_(false),
node_integration_(true),
has_dialog_attached_(false),
html_fullscreen_(false),
native_fullscreen_(false),
zoom_factor_(1.0),
weak_factory_(this),
inspectable_web_contents_(
brightray::InspectableWebContents::Create(web_contents)) {
printing::PrintViewManagerBasic::CreateForWebContents(web_contents);
aspect_ratio_(0.0),
inspectable_web_contents_(inspectable_web_contents),
weak_factory_(this) {
inspectable_web_contents->GetView()->SetDelegate(this);
options.Get(switches::kFrame, &has_frame_);
options.Get(switches::kTransparent, &transparent_);
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.
@@ -119,43 +92,7 @@ NativeWindow::NativeWindow(content::WebContents* web_contents,
// 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_);
web_contents->SetDelegate(this);
inspectable_web_contents()->SetDelegate(this);
WindowList::AddWindow(this);
// Override the user agent to contain application and atom-shell's version.
Browser* browser = Browser::Get();
std::string product_name = base::StringPrintf(
"%s/%s Chrome/%s " ATOM_PRODUCT_NAME "/" ATOM_VERSION_STRING,
RemoveWhitespace(browser->GetName()).c_str(),
browser->GetVersion().c_str(),
CHROME_VERSION_STRING);
web_contents->GetMutableRendererPrefs()->user_agent_override =
content::BuildUserAgentFromProduct(product_name);
// Get notified of title updated message.
registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED,
content::Source<content::WebContents>(web_contents));
}
NativeWindow::~NativeWindow() {
@@ -164,18 +101,12 @@ NativeWindow::~NativeWindow() {
NotifyWindowClosed();
}
// static
NativeWindow* NativeWindow::Create(const mate::Dictionary& options) {
content::WebContents::CreateParams create_params(AtomBrowserContext::Get());
return Create(content::WebContents::Create(create_params), options);
}
// static
NativeWindow* NativeWindow::FromWebContents(
content::WebContents* web_contents) {
WindowList& window_list = *WindowList::GetInstance();
for (NativeWindow* window : window_list) {
if (window->GetWebContents() == web_contents)
if (window->web_contents() == web_contents)
return window;
}
return nullptr;
@@ -211,10 +142,12 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) {
if (options.Get(switches::kAlwaysOnTop, &top) && top) {
SetAlwaysOnTop(true);
}
#if defined(OS_MACOSX) || defined(OS_WIN)
bool fullscreen;
if (options.Get(switches::kFullscreen, &fullscreen) && fullscreen) {
SetFullScreen(true);
}
#endif
bool skip;
if (options.Get(switches::kSkipTaskbar, &skip) && skip) {
SetSkipTaskbar(skip);
@@ -267,11 +200,6 @@ bool NativeWindow::IsDocumentEdited() {
void NativeWindow::SetMenu(ui::MenuModel* menu) {
}
void NativeWindow::Print(bool silent, bool print_background) {
printing::PrintViewManagerBasic::FromWebContents(GetWebContents())->
PrintNow(silent, print_background);
}
void NativeWindow::ShowDefinitionForSelection() {
NOTIMPLEMENTED();
}
@@ -290,49 +218,45 @@ 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;
}
bool NativeWindow::HasModalDialog() {
return has_dialog_attached_;
}
void NativeWindow::OpenDevTools(bool can_dock) {
inspectable_web_contents()->SetCanDock(can_dock);
inspectable_web_contents()->ShowDevTools();
}
void NativeWindow::CloseDevTools() {
inspectable_web_contents()->CloseDevTools();
}
bool NativeWindow::IsDevToolsOpened() {
return inspectable_web_contents()->IsDevToolsViewShowing();
}
void NativeWindow::InspectElement(int x, int y) {
OpenDevTools(true);
scoped_refptr<content::DevToolsAgentHost> agent(
content::DevToolsAgentHost::GetOrCreateFor(GetWebContents()));
agent->InspectElement(x, y);
}
void NativeWindow::FocusOnWebView() {
GetWebContents()->GetRenderViewHost()->Focus();
web_contents()->GetRenderViewHost()->Focus();
}
void NativeWindow::BlurWebView() {
GetWebContents()->GetRenderViewHost()->Blur();
web_contents()->GetRenderViewHost()->Blur();
}
bool NativeWindow::IsWebViewFocused() {
RenderWidgetHostView* host_view =
GetWebContents()->GetRenderViewHost()->GetView();
auto host_view = web_contents()->GetRenderViewHost()->GetView();
return host_view && host_view->HasFocus();
}
bool NativeWindow::IsDevToolsFocused() {
return inspectable_web_contents_->GetView()->IsDevToolsViewFocused();
}
void NativeWindow::CapturePage(const gfx::Rect& rect,
const CapturePageCallback& callback) {
content::WebContents* contents = GetWebContents();
RenderWidgetHostView* const view = contents->GetRenderWidgetHostView();
RenderWidgetHost* const host = view ? view->GetRenderWidgetHost() : nullptr;
const auto view = web_contents()->GetRenderWidgetHostView();
const auto host = view ? view->GetRenderWidgetHost() : nullptr;
if (!view || !host) {
callback.Run(SkBitmap());
return;
@@ -362,14 +286,7 @@ void NativeWindow::CapturePage(const gfx::Rect& rect,
kBGRA_8888_SkColorType);
}
void NativeWindow::DestroyWebContents() {
if (!inspectable_web_contents_)
return;
inspectable_web_contents_.reset();
}
void NativeWindow::CloseWebContents() {
void NativeWindow::RequestToClosePage() {
bool prevent_default = false;
FOR_EACH_OBSERVER(NativeWindowObserver,
observers_,
@@ -379,12 +296,6 @@ void NativeWindow::CloseWebContents() {
return;
}
content::WebContents* web_contents(GetWebContents());
if (!web_contents) {
CloseImmediately();
return;
}
// Assume the window is not responding if it doesn't cancel the close and is
// not closed in 5s, in this way we can quickly show the unresponsive
// dialog when the window is busy executing some script withouth waiting for
@@ -392,123 +303,55 @@ void NativeWindow::CloseWebContents() {
if (window_unresposive_closure_.IsCancelled())
ScheduleUnresponsiveEvent(5000);
if (web_contents->NeedToFireBeforeUnload())
web_contents->DispatchBeforeUnload(false);
if (web_contents()->NeedToFireBeforeUnload())
web_contents()->DispatchBeforeUnload(false);
else
web_contents->Close();
web_contents()->Close();
}
content::WebContents* NativeWindow::GetWebContents() const {
void NativeWindow::CloseContents(content::WebContents* source) {
if (!inspectable_web_contents_)
return nullptr;
return inspectable_web_contents()->GetWebContents();
}
content::WebContents* NativeWindow::GetDevToolsWebContents() const {
if (!inspectable_web_contents_)
return nullptr;
return inspectable_web_contents()->devtools_web_contents();
}
void NativeWindow::AppendExtraCommandLineSwitches(
base::CommandLine* command_line, int child_process_id) {
// 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 (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
inspectable_web_contents_->GetView()->SetDelegate(nullptr);
inspectable_web_contents_ = nullptr;
Observe(nullptr);
// Check if plugins are enabled.
if (web_preferences_.Get("plugins", &b) && b)
command_line->AppendSwitch(switches::kEnablePlugins);
// When the web contents is gone, close the window immediately, but the
// memory will not be freed until you call delete.
// In this way, it would be safe to manage windows via smart pointers. If you
// want to free memory when the window is closed, you can do deleting by
// overriding the OnWindowClosed method in the observer.
CloseImmediately();
// 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");
}
// Do not sent "unresponsive" event after window is closed.
window_unresposive_closure_.Cancel();
}
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("web-security", &b))
prefs->web_security_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("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::RendererUnresponsive(content::WebContents* source) {
// Schedule the unresponsive shortly later, since we may receive the
// responsive event soon. This could happen after the whole application had
// blocked for a while.
// Also notice that when closing this event would be ignored because we have
// explicity started a close timeout counter. This is on purpose because we
// don't want the unresponsive event to be sent too early when user is closing
// the window.
ScheduleUnresponsiveEvent(50);
}
void NativeWindow::SetHtmlApiFullscreen(bool enter_fullscreen) {
// Window is already in fullscreen mode, save the state.
if (enter_fullscreen && IsFullscreen()) {
native_fullscreen_ = true;
html_fullscreen_ = true;
return;
}
// Exit html fullscreen state but not window's fullscreen mode.
if (!enter_fullscreen && native_fullscreen_) {
html_fullscreen_ = false;
return;
}
SetFullScreen(enter_fullscreen);
html_fullscreen_ = enter_fullscreen;
native_fullscreen_ = false;
void NativeWindow::RendererResponsive(content::WebContents* source) {
window_unresposive_closure_.Cancel();
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnRendererResponsive());
}
void NativeWindow::NotifyWindowClosed() {
if (is_closed_)
return;
WindowList::RemoveWindow(this);
is_closed_ = true;
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnWindowClosed());
// Do not receive any notification after window has been closed, there is a
// crash that seems to be caused by this: http://git.io/YqMG5g.
registrar_.RemoveAll();
WindowList::RemoveWindow(this);
}
void NativeWindow::NotifyWindowBlur() {
@@ -535,6 +378,18 @@ void NativeWindow::NotifyWindowRestore() {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnWindowRestore());
}
void NativeWindow::NotifyWindowResize() {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnWindowResize());
}
void NativeWindow::NotifyWindowMove() {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnWindowMove());
}
void NativeWindow::NotifyWindowMoved() {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnWindowMoved());
}
void NativeWindow::NotifyWindowEnterFullScreen() {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_,
OnWindowEnterFullScreen());
@@ -555,70 +410,22 @@ void NativeWindow::NotifyWindowLeaveHtmlFullScreen() {
OnWindowLeaveHtmlFullScreen());
}
bool NativeWindow::ShouldCreateWebContents(
content::WebContents* web_contents,
int route_id,
int main_frame_route_id,
WindowContainerType window_container_type,
const base::string16& frame_name,
const GURL& target_url,
const std::string& partition_id,
content::SessionStorageNamespace* session_storage_namespace) {
FOR_EACH_OBSERVER(NativeWindowObserver,
observers_,
WillCreatePopupWindow(frame_name,
target_url,
partition_id,
NEW_FOREGROUND_TAB));
return false;
void NativeWindow::NotifyWindowExecuteWindowsCommand(
const std::string& command) {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_,
OnExecuteWindowsCommand(command));
}
// In atom-shell all reloads and navigations started by renderer process would
// be redirected to this method, so we can have precise control of how we
// would open the url (in our case, is to restart the renderer process). See
// AtomRendererClient::ShouldFork for how this is done.
content::WebContents* NativeWindow::OpenURLFromTab(
content::WebContents* source,
const content::OpenURLParams& params) {
if (params.disposition != CURRENT_TAB) {
FOR_EACH_OBSERVER(NativeWindowObserver,
observers_,
WillCreatePopupWindow(base::string16(),
params.url,
"",
params.disposition));
return nullptr;
}
// Give user a chance to prevent navigation.
bool prevent_default = false;
FOR_EACH_OBSERVER(NativeWindowObserver,
observers_,
WillNavigate(&prevent_default, params.url));
if (prevent_default)
return nullptr;
content::NavigationController::LoadURLParams load_url_params(params.url);
load_url_params.referrer = params.referrer;
load_url_params.transition_type = params.transition;
load_url_params.extra_headers = params.extra_headers;
load_url_params.should_replace_current_entry =
params.should_replace_current_entry;
load_url_params.is_renderer_initiated = params.is_renderer_initiated;
load_url_params.transferred_global_request_id =
params.transferred_global_request_id;
load_url_params.should_clear_history_list = true;
source->GetController().LoadURLWithParams(load_url_params);
return source;
void NativeWindow::DevToolsFocused() {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnDevToolsFocus());
}
content::JavaScriptDialogManager* NativeWindow::GetJavaScriptDialogManager(
content::WebContents* source) {
if (!dialog_manager_)
dialog_manager_.reset(new AtomJavaScriptDialogManager);
void NativeWindow::DevToolsOpened() {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnDevToolsOpened());
}
return dialog_manager_.get();
void NativeWindow::DevToolsClosed() {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnDevToolsClosed());
}
void NativeWindow::RenderViewCreated(
@@ -633,117 +440,22 @@ void NativeWindow::RenderViewCreated(
impl->SetBackgroundOpaque(false);
}
void NativeWindow::BeforeUnloadFired(content::WebContents* tab,
bool proceed,
bool* proceed_to_fire_unload) {
*proceed_to_fire_unload = proceed;
void NativeWindow::BeforeUnloadDialogCancelled() {
WindowList::WindowCloseCancelled(this);
if (!proceed) {
WindowList::WindowCloseCancelled(this);
// Cancel unresponsive event when window close is cancelled.
window_unresposive_closure_.Cancel();
}
}
content::ColorChooser* NativeWindow::OpenColorChooser(
content::WebContents* web_contents,
SkColor color,
const std::vector<content::ColorSuggestion>& suggestions) {
return chrome::ShowColorChooser(web_contents, color);
}
void NativeWindow::RunFileChooser(content::WebContents* web_contents,
const content::FileChooserParams& params) {
if (!web_dialog_helper_)
web_dialog_helper_.reset(new WebDialogHelper(this));
web_dialog_helper_->RunFileChooser(web_contents, params);
}
void NativeWindow::EnumerateDirectory(content::WebContents* web_contents,
int request_id,
const base::FilePath& path) {
if (!web_dialog_helper_)
web_dialog_helper_.reset(new WebDialogHelper(this));
web_dialog_helper_->EnumerateDirectory(web_contents, request_id, path);
}
void NativeWindow::RequestToLockMouse(content::WebContents* web_contents,
bool user_gesture,
bool last_unlocked_by_target) {
GetWebContents()->GotResponseToLockMouseRequest(true);
}
bool NativeWindow::CanOverscrollContent() const {
return false;
}
void NativeWindow::ActivateContents(content::WebContents* contents) {
FocusOnWebView();
}
void NativeWindow::DeactivateContents(content::WebContents* contents) {
BlurWebView();
}
void NativeWindow::MoveContents(content::WebContents* source,
const gfx::Rect& pos) {
SetBounds(pos);
}
void NativeWindow::CloseContents(content::WebContents* source) {
// Destroy the WebContents before we close the window.
DestroyWebContents();
// When the web contents is gone, close the window immediately, but the
// memory will not be freed until you call delete.
// In this way, it would be safe to manage windows via smart pointers. If you
// want to free memory when the window is closed, you can do deleting by
// overriding the OnWindowClosed method in the observer.
CloseImmediately();
// Do not sent "unresponsive" event after window is closed.
// Cancel unresponsive event when window close is cancelled.
window_unresposive_closure_.Cancel();
}
bool NativeWindow::IsPopupOrPanel(const content::WebContents* source) const {
// Only popup window can use things like window.moveTo.
return true;
}
void NativeWindow::RendererUnresponsive(content::WebContents* source) {
// Schedule the unresponsive shortly later, since we may receive the
// responsive event soon. This could happen after the whole application had
// blocked for a while.
// Also notice that when closing this event would be ignored because we have
// explicity started a close timeout counter. This is on purpose because we
// don't want the unresponsive event to be sent too early when user is closing
// the window.
ScheduleUnresponsiveEvent(50);
}
void NativeWindow::RendererResponsive(content::WebContents* source) {
window_unresposive_closure_.Cancel();
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnRendererResponsive());
}
void NativeWindow::EnterFullscreenModeForTab(content::WebContents* source,
const GURL& origin) {
SetHtmlApiFullscreen(true);
}
void NativeWindow::ExitFullscreenModeForTab(content::WebContents* source) {
SetHtmlApiFullscreen(false);
}
bool NativeWindow::IsFullscreenForTabOrPending(
const content::WebContents* source) const {
return is_html_api_fullscreen();
}
void NativeWindow::BeforeUnloadFired(const base::TimeTicks& proceed_time) {
// Do nothing, we override this method just to avoid compilation error since
// there are two virtual functions named BeforeUnloadFired.
void NativeWindow::TitleWasSet(content::NavigationEntry* entry,
bool explicit_set) {
bool prevent_default = false;
std::string text = entry ? base::UTF16ToUTF8(entry->GetTitle()) : "";
FOR_EACH_OBSERVER(NativeWindowObserver,
observers_,
OnPageTitleUpdated(&prevent_default, text));
if (!prevent_default)
SetTitle(text);
}
bool NativeWindow::OnMessageReceived(const IPC::Message& message) {
@@ -757,65 +469,12 @@ bool NativeWindow::OnMessageReceived(const IPC::Message& message) {
return handled;
}
void NativeWindow::Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
if (type == content::NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED) {
std::pair<NavigationEntry*, bool>* title =
content::Details<std::pair<NavigationEntry*, bool>>(details).ptr();
if (title->first) {
bool prevent_default = false;
std::string text = base::UTF16ToUTF8(title->first->GetTitle());
FOR_EACH_OBSERVER(NativeWindowObserver,
observers_,
OnPageTitleUpdated(&prevent_default, text));
if (!prevent_default)
SetTitle(text);
}
}
}
void NativeWindow::DevToolsSaveToFile(const std::string& url,
const std::string& content,
bool save_as) {
base::FilePath path;
PathsMap::iterator it = saved_files_.find(url);
if (it != saved_files_.end() && !save_as) {
path = it->second;
} else {
file_dialog::Filters filters;
base::FilePath default_path(base::FilePath::FromUTF8Unsafe(url));
if (!file_dialog::ShowSaveDialog(this, url, default_path, filters, &path)) {
base::StringValue url_value(url);
CallDevToolsFunction("DevToolsAPI.canceledSaveURL", &url_value);
return;
}
}
saved_files_[url] = path;
base::WriteFile(path, content.data(), content.size());
// Notify devtools.
base::StringValue url_value(url);
CallDevToolsFunction("DevToolsAPI.savedURL", &url_value);
}
void NativeWindow::DevToolsAppendToFile(const std::string& url,
const std::string& content) {
PathsMap::iterator it = saved_files_.find(url);
if (it == saved_files_.end())
void NativeWindow::UpdateDraggableRegions(
const std::vector<DraggableRegion>& regions) {
// Draggable region is not supported for non-frameless window.
if (has_frame_)
return;
base::AppendToFile(it->second, content.data(), content.size());
// Notify devtools.
base::StringValue url_value(url);
CallDevToolsFunction("DevToolsAPI.appendedToURL", &url_value);
}
void NativeWindow::DevToolsFocused() {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnDevToolsFocus());
draggable_region_ = DraggableRegionsToSkRegion(regions);
}
void NativeWindow::ScheduleUnresponsiveEvent(int ms) {
@@ -846,27 +505,4 @@ void NativeWindow::OnCapturePageDone(const CapturePageCallback& callback,
callback.Run(bitmap);
}
void NativeWindow::CallDevToolsFunction(const std::string& function_name,
const base::Value* arg1,
const base::Value* arg2,
const base::Value* arg3) {
std::string params;
if (arg1) {
std::string json;
base::JSONWriter::Write(arg1, &json);
params.append(json);
if (arg2) {
base::JSONWriter::Write(arg2, &json);
params.append(", " + json);
if (arg3) {
base::JSONWriter::Write(arg3, &json);
params.append(", " + json);
}
}
}
base::string16 javascript =
base::UTF8ToUTF16(function_name + "(" + params + ");");
GetDevToolsWebContents()->GetMainFrame()->ExecuteJavaScript(javascript);
}
} // namespace atom

View File

@@ -15,23 +15,21 @@
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "brightray/browser/default_web_contents_delegate.h"
#include "brightray/browser/inspectable_web_contents_delegate.h"
#include "brightray/browser/inspectable_web_contents_impl.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/notification_observer.h"
#include "brightray/browser/inspectable_web_contents_view_delegate.h"
#include "content/public/browser/readback_types.h"
#include "native_mate/persistent_dictionary.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_user_data.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia.h"
namespace base {
class CommandLine;
class SkRegion;
namespace brightray {
class InspectableWebContents;
}
namespace content {
class BrowserContext;
class WebContents;
struct WebPreferences;
struct NativeWebKeyboardEvent;
}
namespace gfx {
@@ -50,16 +48,12 @@ class MenuModel;
namespace atom {
class AtomJavaScriptDialogManager;
struct DraggableRegion;
class WebDialogHelper;
class NativeWindow : public brightray::DefaultWebContentsDelegate,
public brightray::InspectableWebContentsDelegate,
public content::WebContentsObserver,
public content::NotificationObserver {
class NativeWindow : public content::WebContentsObserver,
public brightray::InspectableWebContentsViewDelegate {
public:
typedef base::Callback<void(const SkBitmap& bitmap)> CapturePageCallback;
using CapturePageCallback = base::Callback<void(const SkBitmap& bitmap)>;
class DialogScope {
public:
@@ -84,12 +78,9 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
// Create window with existing WebContents, the caller is responsible for
// managing the window's live.
static NativeWindow* Create(content::WebContents* web_contents,
const mate::Dictionary& options);
// Create window with new WebContents, the caller is responsible for
// managing the window's live.
static NativeWindow* Create(const mate::Dictionary& options);
static NativeWindow* Create(
brightray::InspectableWebContents* inspectable_web_contents,
const mate::Dictionary& options);
// Find a window from its WebContents
static NativeWindow* FromWebContents(content::WebContents* web_contents);
@@ -98,6 +89,7 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
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;
@@ -142,30 +134,27 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
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_; }
virtual void OpenDevTools(bool can_dock);
virtual void CloseDevTools();
virtual bool IsDevToolsOpened();
virtual void InspectElement(int x, int y);
// 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.
virtual void CapturePage(const gfx::Rect& rect,
const CapturePageCallback& callback);
// Print current page.
virtual void Print(bool silent, bool print_background);
// Show popup dictionary.
virtual void ShowDefinitionForSelection();
@@ -175,28 +164,25 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
virtual void SetMenuBarVisibility(bool visible);
virtual bool IsMenuBarVisible();
// The same with closing a tab in a real browser.
//
// Should be called by platform code when user want to close the window.
virtual void CloseWebContents();
// Destroy the WebContents immediately.
virtual void DestroyWebContents();
// 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();
}
content::WebContents* GetWebContents() const;
content::WebContents* GetDevToolsWebContents() const;
// Requests the WebContents to close, can be cancelled by the page.
virtual void RequestToClosePage();
// Called when renderer process is going to be started.
void AppendExtraCommandLineSwitches(base::CommandLine* command_line,
int child_process_id);
void OverrideWebkitPrefs(content::WebPreferences* prefs);
// Set fullscreen mode triggered by html api.
void SetHtmlApiFullscreen(bool enter_fullscreen);
// Methods called by the WebContents.
virtual void CloseContents(content::WebContents* source);
virtual void RendererUnresponsive(content::WebContents* source);
virtual void RendererResponsive(content::WebContents* source);
virtual void HandleKeyboardEvent(
content::WebContents*,
const content::NativeWebKeyboardEvent& event) {}
// Public API used by platform-dependent delegates and observers to send UI
// related notifications.
@@ -207,103 +193,66 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
void NotifyWindowUnmaximize();
void NotifyWindowMinimize();
void NotifyWindowRestore();
void NotifyWindowMove();
void NotifyWindowResize();
void NotifyWindowMoved();
void NotifyWindowEnterFullScreen();
void NotifyWindowLeaveFullScreen();
void NotifyWindowEnterHtmlFullScreen();
void NotifyWindowLeaveHtmlFullScreen();
void NotifyWindowExecuteWindowsCommand(const std::string& command);
void AddObserver(NativeWindowObserver* obs) {
observers_.AddObserver(obs);
}
void RemoveObserver(NativeWindowObserver* obs) {
observers_.RemoveObserver(obs);
}
bool has_frame() const { return has_frame_; }
brightray::InspectableWebContents* inspectable_web_contents() const {
return inspectable_web_contents_;
}
bool is_html_api_fullscreen() const { return html_fullscreen_; }
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_; }
void set_has_dialog_attached(bool has_dialog_attached) {
has_dialog_attached_ = has_dialog_attached;
}
protected:
explicit NativeWindow(content::WebContents* web_contents,
const mate::Dictionary& options);
NativeWindow(brightray::InspectableWebContents* inspectable_web_contents,
const mate::Dictionary& options);
brightray::InspectableWebContentsImpl* inspectable_web_contents() const {
return static_cast<brightray::InspectableWebContentsImpl*>(
inspectable_web_contents_.get());
}
// brightray::InspectableWebContentsViewDelegate:
void DevToolsFocused() override;
void DevToolsOpened() override;
void DevToolsClosed() override;
// Called when the window needs to update its draggable region.
virtual void UpdateDraggableRegions(
const std::vector<DraggableRegion>& regions) = 0;
// Implementations of content::WebContentsDelegate.
bool ShouldCreateWebContents(
content::WebContents* web_contents,
int route_id,
int main_frame_route_id,
WindowContainerType window_container_type,
const base::string16& frame_name,
const GURL& target_url,
const std::string& partition_id,
content::SessionStorageNamespace* session_storage_namespace) override;
content::WebContents* OpenURLFromTab(
content::WebContents* source,
const content::OpenURLParams& params) override;
content::JavaScriptDialogManager* GetJavaScriptDialogManager(
content::WebContents* source) override;
void BeforeUnloadFired(content::WebContents* tab,
bool proceed,
bool* proceed_to_fire_unload) override;
content::ColorChooser* OpenColorChooser(
content::WebContents* web_contents,
SkColor color,
const std::vector<content::ColorSuggestion>& suggestions) override;
void RunFileChooser(content::WebContents* web_contents,
const content::FileChooserParams& params) override;
void EnumerateDirectory(content::WebContents* web_contents,
int request_id,
const base::FilePath& path) override;
void RequestToLockMouse(content::WebContents* web_contents,
bool user_gesture,
bool last_unlocked_by_target) override;
bool CanOverscrollContent() const override;
void ActivateContents(content::WebContents* contents) override;
void DeactivateContents(content::WebContents* contents) override;
void MoveContents(content::WebContents* source,
const gfx::Rect& pos) override;
void CloseContents(content::WebContents* source) override;
bool IsPopupOrPanel(
const content::WebContents* source) const override;
void RendererUnresponsive(content::WebContents* source) override;
void RendererResponsive(content::WebContents* source) override;
void EnterFullscreenModeForTab(content::WebContents* source,
const GURL& origin) override;
void ExitFullscreenModeForTab(content::WebContents* source) override;
bool IsFullscreenForTabOrPending(
const content::WebContents* source) const override;
// Implementations of content::WebContentsObserver.
// content::WebContentsObserver:
void RenderViewCreated(content::RenderViewHost* render_view_host) override;
void BeforeUnloadFired(const base::TimeTicks& proceed_time) override;
void BeforeUnloadDialogCancelled() override;
void TitleWasSet(content::NavigationEntry* entry, bool explicit_set) override;
bool OnMessageReceived(const IPC::Message& message) override;
// Implementations of content::NotificationObserver.
void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) override;
private:
// Called when the window needs to update its draggable region.
void UpdateDraggableRegions(
const std::vector<DraggableRegion>& regions);
// Implementations of brightray::InspectableWebContentsDelegate.
void DevToolsSaveToFile(const std::string& url,
const std::string& content,
bool save_as) override;
void DevToolsAppendToFile(const std::string& url,
const std::string& content) override;
void DevToolsFocused() override;
// Schedule a notification unresponsive event.
void ScheduleUnresponsiveEvent(int ms);
// Dispatch unresponsive event to observers.
void NotifyWindowUnresponsive();
// Called when CapturePage has done.
void OnCapturePageDone(const CapturePageCallback& callback,
const SkBitmap& bitmap,
content::ReadbackResponse response);
// Whether window has standard frame.
bool has_frame_;
@@ -311,81 +260,57 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
// 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_;
private:
// Schedule a notification unresponsive event.
void ScheduleUnresponsiveEvent(int ms);
// Dispatch unresponsive event to observers.
void NotifyWindowUnresponsive();
// Call a function in devtools.
void CallDevToolsFunction(const std::string& function_name,
const base::Value* arg1 = NULL,
const base::Value* arg2 = NULL,
const base::Value* arg3 = NULL);
// Called when CapturePage has done.
void OnCapturePageDone(const CapturePageCallback& callback,
const SkBitmap& bitmap,
content::ReadbackResponse response);
// Notification manager.
content::NotificationRegistrar registrar_;
// Observers of this window.
ObserverList<NativeWindowObserver> observers_;
// The windows has been closed.
bool is_closed_;
// Whether node integration is enabled.
bool node_integration_;
// There is a dialog that has been attached to window.
bool has_dialog_attached_;
// Whether window is fullscreened by HTML5 api.
bool html_fullscreen_;
// Whether window is fullscreened by window api.
bool native_fullscreen_;
// Closure that would be called when window is unresponsive when closing,
// it should be cancelled when we can prove that the window is responsive.
base::CancelableClosure window_unresposive_closure_;
// Web preferences.
mate::PersistentDictionary web_preferences_;
// 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 script to load before page's JavaScript starts to run.
base::FilePath preload_script_;
// The page this window is viewing.
brightray::InspectableWebContents* inspectable_web_contents_;
// Page's default zoom factor.
double zoom_factor_;
// Observers of this window.
base::ObserverList<NativeWindowObserver> observers_;
base::WeakPtrFactory<NativeWindow> weak_factory_;
scoped_ptr<WebDialogHelper> web_dialog_helper_;
scoped_ptr<AtomJavaScriptDialogManager> dialog_manager_;
// Notice that inspectable_web_contents_ must be placed after dialog_manager_,
// so we can make sure inspectable_web_contents_ is destroyed before
// dialog_manager_, otherwise a crash would happen.
scoped_ptr<brightray::InspectableWebContents> inspectable_web_contents_;
// Maps url to file path, used by the file requests sent from devtools.
typedef std::map<std::string, base::FilePath> PathsMap;
PathsMap saved_files_;
DISALLOW_COPY_AND_ASSIGN(NativeWindow);
};
// This class provides a hook to get a NativeWindow from a WebContents.
class NativeWindowRelay :
public content::WebContentsUserData<NativeWindowRelay> {
public:
explicit NativeWindowRelay(base::WeakPtr<NativeWindow> window)
: key(UserDataKey()), window(window) {}
void* key;
base::WeakPtr<NativeWindow> window;
private:
friend class content::WebContentsUserData<NativeWindow>;
};
} // namespace atom
#endif // ATOM_BROWSER_NATIVE_WINDOW_H_

View File

@@ -11,23 +11,21 @@
#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 {
class NativeWindowMac : public NativeWindow {
public:
explicit NativeWindowMac(content::WebContents* web_contents,
const mate::Dictionary& options);
virtual ~NativeWindowMac();
NativeWindowMac(brightray::InspectableWebContents* inspectable_web_contents,
const mate::Dictionary& options);
~NativeWindowMac() override;
// NativeWindow implementation.
// NativeWindow:
void Close() override;
void CloseImmediately() override;
void Focus(bool focus) override;
@@ -84,14 +82,8 @@ 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;
// Implementations of content::WebContentsDelegate.
// NativeWindow:
void HandleKeyboardEvent(
content::WebContents*,
const content::NativeWebKeyboardEvent&) override;
@@ -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
@@ -68,7 +80,7 @@ static const CGFloat kAtomWindowCornerRadius = 4.0;
}
- (void)windowDidBecomeMain:(NSNotification*)notification {
content::WebContents* web_contents = shell_->GetWebContents();
content::WebContents* web_contents = shell_->web_contents();
if (!web_contents)
return;
@@ -82,7 +94,7 @@ static const CGFloat kAtomWindowCornerRadius = 4.0;
}
- (void)windowDidResignMain:(NSNotification*)notification {
content::WebContents* web_contents = shell_->GetWebContents();
content::WebContents* web_contents = shell_->web_contents();
if (!web_contents)
return;
@@ -95,9 +107,53 @@ static const CGFloat kAtomWindowCornerRadius = 4.0;
shell_->NotifyWindowBlur();
}
- (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 {
if (!shell_->has_frame())
shell_->ClipWebView();
shell_->NotifyWindowResize();
}
- (void)windowDidMove:(NSNotification*)notification {
// TODO(zcbenz): Remove the alias after figuring out a proper
// way to disptach move.
shell_->NotifyWindowMove();
shell_->NotifyWindowMoved();
}
- (void)windowDidMiniaturize:(NSNotification*)notification {
@@ -140,7 +196,7 @@ static const CGFloat kAtomWindowCornerRadius = 4.0;
// When user tries to close the window by clicking the close button, we do
// not close the window immediately, instead we try to close the web page
// fisrt, and when the web page is closed the window will also be closed.
shell_->CloseWebContents();
shell_->RequestToClosePage();
return NO;
}
@@ -167,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
@@ -271,31 +331,9 @@ 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(content::WebContents* web_contents,
const mate::Dictionary& options)
NativeWindowMac::NativeWindowMac(
brightray::InspectableWebContents* web_contents,
const mate::Dictionary& options)
: NativeWindow(web_contents, options),
is_kiosk_(false),
attention_request_id_(0) {
@@ -315,22 +353,33 @@ NativeWindowMac::NativeWindowMac(content::WebContents* web_contents,
NSUInteger styleMask = NSTitledWindowMask | NSClosableWindowMask |
NSMiniaturizableWindowMask | NSResizableWindowMask;
if (!useStandardWindow || transparent_ || !has_frame_) {
if (!useStandardWindow || transparent() || !has_frame()) {
styleMask |= NSTexturedBackgroundWindowMask;
}
std::string titleBarStyle = "default";
options.Get(switches::kTitleBarStyle, &titleBarStyle);
if (base::mac::IsOSYosemiteOrLater()) {
// New title bar styles are available in Yosemite or newer
if ((titleBarStyle == "hidden") || (titleBarStyle == "hidden-inset")) {
styleMask |= NSFullSizeContentViewWindowMask;
styleMask |= NSUnifiedTitleAndToolbarWindowMask;
}
}
window_.reset([[AtomNSWindow alloc]
initWithContentRect:cocoa_bounds
styleMask:styleMask
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];
@@ -338,16 +387,30 @@ NativeWindowMac::NativeWindowMac(content::WebContents* web_contents,
}
// 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];
// Configure title bar look on Yosemite or newer
if (base::mac::IsOSYosemiteOrLater()) {
if ((titleBarStyle == "hidden") || (titleBarStyle == "hidden-inset")) {
[window_ setTitlebarAppearsTransparent:YES];
[window_ setTitleVisibility:NSWindowTitleHidden];
if (titleBarStyle == "hidden-inset") {
NSToolbar *toolbar = [[NSToolbar alloc] initWithIdentifier:@"titlebarStylingToolbar"];
toolbar.showsBaselineSeparator = NO;
[window_ setToolbar:toolbar];
[toolbar release];
}
}
}
// 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.
@@ -376,9 +439,7 @@ NativeWindowMac::NativeWindowMac(content::WebContents* web_contents,
}
NativeWindowMac::~NativeWindowMac() {
// Force InspectableWebContents to be destroyed before we destroy window,
// because it may still be observing the window at this time.
DestroyWebContents();
Observe(nullptr);
}
void NativeWindowMac::Close() {
@@ -486,6 +547,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;
@@ -499,6 +565,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);
}
@@ -530,12 +599,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)];
}
}
@@ -556,8 +628,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)];
@@ -669,10 +741,9 @@ void NativeWindowMac::SetOverlayIcon(const gfx::Image& overlay,
}
void NativeWindowMac::ShowDefinitionForSelection() {
content::WebContents* web_contents = GetWebContents();
if (!web_contents)
if (!web_contents())
return;
content::RenderWidgetHostView* rwhv = web_contents->GetRenderWidgetHostView();
auto rwhv = web_contents()->GetRenderWidgetHostView();
if (!rwhv)
return;
rwhv->ShowDefinitionForSelection();
@@ -694,17 +765,16 @@ bool NativeWindowMac::IsVisibleOnAllWorkspaces() {
}
bool NativeWindowMac::IsWithinDraggableRegion(NSPoint point) const {
if (!draggable_region_)
if (!draggable_region())
return false;
content::WebContents* web_contents = GetWebContents();
if (!web_contents)
if (!web_contents())
return false;
NSView* webView = web_contents->GetNativeView();
NSView* webView = web_contents()->GetNativeView();
NSInteger webViewHeight = NSHeight([webView bounds]);
// |draggable_region_| is stored in local platform-indepdent coordiate system
// while |point| is in local Cocoa coordinate system. Do the conversion
// 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) {
@@ -724,15 +794,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) {
@@ -758,35 +819,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];
@@ -805,17 +858,8 @@ void NativeWindowMac::UninstallView() {
[view removeFromSuperview];
}
void NativeWindowMac::ClipWebView() {
content::WebContents* web_contents = GetWebContents();
if (!web_contents)
return;
NSView* webView = web_contents->GetNativeView();
webView.layer.masksToBounds = YES;
webView.layer.cornerRadius = kAtomWindowCornerRadius;
}
void NativeWindowMac::InstallDraggableRegionView() {
NSView* webView = GetWebContents()->GetNativeView();
NSView* webView = web_contents()->GetNativeView();
base::scoped_nsobject<NSView> controlRegion(
[[ControlRegionView alloc] initWithShellWindow:this]);
[controlRegion setFrame:NSMakeRect(0, 0,
@@ -825,9 +869,10 @@ void NativeWindowMac::InstallDraggableRegionView() {
}
// static
NativeWindow* NativeWindow::Create(content::WebContents* web_contents,
const mate::Dictionary& options) {
return new NativeWindowMac(web_contents, options);
NativeWindow* NativeWindow::Create(
brightray::InspectableWebContents* inspectable_web_contents,
const mate::Dictionary& options) {
return new NativeWindowMac(inspectable_web_contents, options);
}
} // namespace atom

View File

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

View File

@@ -4,10 +4,6 @@
#include "atom/browser/native_window_views.h"
#if defined(OS_WIN)
#include <shobjidl.h>
#endif
#include <string>
#include <vector>
@@ -16,10 +12,10 @@
#include "atom/common/draggable_region.h"
#include "atom/common/options_switches.h"
#include "base/strings/utf_string_conversions.h"
#include "browser/inspectable_web_contents_view.h"
#include "brightray/browser/inspectable_web_contents.h"
#include "brightray/browser/inspectable_web_contents_view.h"
#include "content/public/browser/native_web_keyboard_event.h"
#include "native_mate/dictionary.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/hit_test.h"
#include "ui/gfx/image/image.h"
@@ -35,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 {
@@ -68,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.
@@ -123,6 +77,70 @@ bool IsAltModifier(const content::NativeWebKeyboardEvent& event) {
(modifiers == (Modifiers::AltKey | Modifiers::IsRight));
}
#if defined(OS_WIN)
// Convert Win32 WM_APPCOMMANDS to strings.
const char* AppCommandToString(int command_id) {
switch (command_id) {
case APPCOMMAND_BROWSER_BACKWARD : return "browser-backward";
case APPCOMMAND_BROWSER_FORWARD : return "browser-forward";
case APPCOMMAND_BROWSER_REFRESH : return "browser-refresh";
case APPCOMMAND_BROWSER_STOP : return "browser-stop";
case APPCOMMAND_BROWSER_SEARCH : return "browser-search";
case APPCOMMAND_BROWSER_FAVORITES : return "browser-favorites";
case APPCOMMAND_BROWSER_HOME : return "browser-home";
case APPCOMMAND_VOLUME_MUTE : return "volume-mute";
case APPCOMMAND_VOLUME_DOWN : return "volume-down";
case APPCOMMAND_VOLUME_UP : return "volume-up";
case APPCOMMAND_MEDIA_NEXTTRACK : return "media-nexttrack";
case APPCOMMAND_MEDIA_PREVIOUSTRACK : return "media-previoustrack";
case APPCOMMAND_MEDIA_STOP : return "media-stop";
case APPCOMMAND_MEDIA_PLAY_PAUSE : return "media-play_pause";
case APPCOMMAND_LAUNCH_MAIL : return "launch-mail";
case APPCOMMAND_LAUNCH_MEDIA_SELECT : return "launch-media-select";
case APPCOMMAND_LAUNCH_APP1 : return "launch-app1";
case APPCOMMAND_LAUNCH_APP2 : return "launch-app2";
case APPCOMMAND_BASS_DOWN : return "bass-down";
case APPCOMMAND_BASS_BOOST : return "bass-boost";
case APPCOMMAND_BASS_UP : return "bass-up";
case APPCOMMAND_TREBLE_DOWN : return "treble-down";
case APPCOMMAND_TREBLE_UP : return "treble-up";
case APPCOMMAND_MICROPHONE_VOLUME_MUTE : return "microphone-volume-mute";
case APPCOMMAND_MICROPHONE_VOLUME_DOWN : return "microphone-volume-down";
case APPCOMMAND_MICROPHONE_VOLUME_UP : return "microphone-volume-up";
case APPCOMMAND_HELP : return "help";
case APPCOMMAND_FIND : return "find";
case APPCOMMAND_NEW : return "new";
case APPCOMMAND_OPEN : return "open";
case APPCOMMAND_CLOSE : return "close";
case APPCOMMAND_SAVE : return "save";
case APPCOMMAND_PRINT : return "print";
case APPCOMMAND_UNDO : return "undo";
case APPCOMMAND_REDO : return "redo";
case APPCOMMAND_COPY : return "copy";
case APPCOMMAND_CUT : return "cut";
case APPCOMMAND_PASTE : return "paste";
case APPCOMMAND_REPLY_TO_MAIL : return "reply-to-mail";
case APPCOMMAND_FORWARD_MAIL : return "forward-mail";
case APPCOMMAND_SEND_MAIL : return "send-mail";
case APPCOMMAND_SPELL_CHECK : return "spell-check";
case APPCOMMAND_MIC_ON_OFF_TOGGLE : return "mic-on-off-toggle";
case APPCOMMAND_CORRECTION_LIST : return "correction-list";
case APPCOMMAND_MEDIA_PLAY : return "media-play";
case APPCOMMAND_MEDIA_PAUSE : return "media-pause";
case APPCOMMAND_MEDIA_RECORD : return "media-record";
case APPCOMMAND_MEDIA_FAST_FORWARD : return "media-fast-forward";
case APPCOMMAND_MEDIA_REWIND : return "media-rewind";
case APPCOMMAND_MEDIA_CHANNEL_UP : return "media-channel-up";
case APPCOMMAND_MEDIA_CHANNEL_DOWN : return "media-channel-down";
case APPCOMMAND_DELETE : return "delete";
case APPCOMMAND_DICTATE_OR_COMMAND_CONTROL_TOGGLE:
return "dictate-or-command-control-toggle";
default:
return "unknown";
}
}
#endif
class NativeWindowClientView : public views::ClientView {
public:
NativeWindowClientView(views::Widget* widget,
@@ -132,7 +150,7 @@ class NativeWindowClientView : public views::ClientView {
virtual ~NativeWindowClientView() {}
bool CanClose() override {
static_cast<NativeWindowViews*>(contents_view())->CloseWebContents();
static_cast<NativeWindowViews*>(contents_view())->RequestToClosePage();
return false;
}
@@ -142,8 +160,9 @@ class NativeWindowClientView : public views::ClientView {
} // namespace
NativeWindowViews::NativeWindowViews(content::WebContents* web_contents,
const mate::Dictionary& options)
NativeWindowViews::NativeWindowViews(
brightray::InspectableWebContents* web_contents,
const mate::Dictionary& options)
: NativeWindow(web_contents, options),
window_(new views::Widget),
web_view_(inspectable_web_contents()->GetView()->GetView()),
@@ -165,7 +184,7 @@ NativeWindowViews::NativeWindowViews(content::WebContents* web_contents,
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
@@ -176,6 +195,7 @@ NativeWindowViews::NativeWindowViews(content::WebContents* web_contents,
options.Get(switches::kWidth, &width);
options.Get(switches::kHeight, &height);
gfx::Rect bounds(0, 0, width, height);
widget_size_ = bounds.size();
window_->AddObserver(this);
@@ -184,12 +204,20 @@ NativeWindowViews::NativeWindowViews(content::WebContents* web_contents,
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";
@@ -218,14 +246,21 @@ NativeWindowViews::NativeWindowViews(content::WebContents* web_contents,
// Before the window is mapped the SetWMSpecState can not work, so we have
// to manually set the _NET_WM_STATE.
std::vector<::Atom> state_atom_list;
bool skip_taskbar = false;
if (options.Get(switches::kSkipTaskbar, &skip_taskbar) && skip_taskbar) {
std::vector<::Atom> state_atom_list;
state_atom_list.push_back(GetAtom("_NET_WM_STATE_SKIP_TASKBAR"));
ui::SetAtomArrayProperty(GetAcceleratedWidget(), "_NET_WM_STATE", "ATOM",
state_atom_list);
}
// Before the window is mapped, there is no SHOW_FULLSCREEN_STATE.
bool fullscreen = false;
if (options.Get(switches::kFullscreen, & fullscreen) && fullscreen) {
state_atom_list.push_back(GetAtom("_NET_WM_STATE_FULLSCREEN"));
}
ui::SetAtomArrayProperty(GetAcceleratedWidget(), "_NET_WM_STATE", "ATOM",
state_atom_list);
// Set the _NET_WM_WINDOW_TYPE.
std::string window_type;
if (options.Get(switches::kType, &window_type))
@@ -237,24 +272,24 @@ NativeWindowViews::NativeWindowViews(content::WebContents* web_contents,
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;
@@ -264,14 +299,14 @@ NativeWindowViews::NativeWindowViews(content::WebContents* web_contents,
// 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();
@@ -351,17 +386,19 @@ bool NativeWindowViews::IsMinimized() {
}
void NativeWindowViews::SetFullScreen(bool fullscreen) {
#if defined(OS_WIN)
// There is no native fullscreen state on Windows.
window_->SetFullscreen(fullscreen);
if (fullscreen)
NotifyWindowEnterFullScreen();
else
NotifyWindowLeaveFullScreen();
#else
if (IsVisible())
window_->SetFullscreen(fullscreen);
else
window_->native_widget_private()->ShowWithWindowState(
ui::SHOW_STATE_FULLSCREEN);
#if defined(OS_WIN)
// There is no native fullscreen state on Windows.
if (fullscreen)
NotifyWindowEnterFullScreen();
else
NotifyWindowLeaveFullScreen();
#endif
}
@@ -392,7 +429,7 @@ gfx::Rect NativeWindowViews::GetBounds() {
}
void NativeWindowViews::SetContentSize(const gfx::Size& size) {
if (!has_frame_) {
if (!has_frame()) {
NativeWindow::SetSize(size);
return;
}
@@ -403,7 +440,7 @@ void NativeWindowViews::SetContentSize(const gfx::Size& size) {
}
gfx::Size NativeWindowViews::GetContentSize() {
if (!has_frame_)
if (!has_frame())
return GetSize();
gfx::Size content_size =
@@ -415,14 +452,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() {
@@ -431,14 +460,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() {
@@ -540,6 +561,19 @@ bool NativeWindowViews::IsKiosk() {
}
void NativeWindowViews::SetMenu(ui::MenuModel* menu_model) {
if (menu_model == nullptr) {
// Remove accelerators
accelerator_table_.clear();
GetFocusManager()->UnregisterAccelerators(this);
// and menu bar.
#if defined(USE_X11)
global_menu_bar_.reset();
#endif
SetMenuBarVisibility(false);
menu_bar_.reset();
return;
}
RegisterAccelerators(menu_model);
#if defined(USE_X11)
@@ -554,7 +588,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_) {
@@ -579,24 +613,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);
@@ -607,22 +624,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
}
@@ -679,29 +681,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())
@@ -712,14 +691,26 @@ void NativeWindowViews::OnWidgetActivationChanged(
else
NotifyWindowBlur();
if (active && GetWebContents() && !IsDevToolsOpened())
GetWebContents()->Focus();
if (active && inspectable_web_contents() &&
!inspectable_web_contents()->IsDevToolsViewShowing())
web_contents()->Focus();
// Hide menu bar when window is blured.
if (!active && menu_bar_autohide_ && menu_bar_visible_)
SetMenuBarVisibility(false);
}
void NativeWindowViews::OnWidgetBoundsChanged(
views::Widget* widget, const gfx::Rect& bounds) {
if (widget != window_.get())
return;
if (widget_size_ != bounds.size()) {
NotifyWindowResize();
widget_size_ = bounds.size();
}
}
void NativeWindowViews::DeleteDelegate() {
NotifyWindowClosed();
}
@@ -749,7 +740,7 @@ bool NativeWindowViews::ShouldHandleSystemCommands() const {
}
gfx::ImageSkia NativeWindowViews::GetWindowAppIcon() {
return icon_;
return icon();
}
gfx::ImageSkia NativeWindowViews::GetWindowIcon() {
@@ -772,12 +763,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;
@@ -797,8 +788,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);
@@ -807,6 +798,10 @@ views::NonClientFrameView* NativeWindowViews::CreateNonClientFrameView(
#endif
}
void NativeWindowViews::OnWidgetMove() {
NotifyWindowMove();
}
#if defined(OS_WIN)
bool NativeWindowViews::ExecuteWindowsCommand(int command_id) {
// Windows uses the 4 lower order bits of |command_id| for type-specific
@@ -823,6 +818,9 @@ bool NativeWindowViews::ExecuteWindowsCommand(int command_id) {
is_minimized_ = false;
} else if ((command_id & sc_mask) == SC_MAXIMIZE) {
NotifyWindowMaximize();
} else {
std::string command = AppCommandToString(command_id);
NotifyWindowExecuteWindowsCommand(command);
}
return false;
}
@@ -840,11 +838,16 @@ void NativeWindowViews::GetDevToolsWindowWMClass(
}
#endif
void NativeWindowViews::HandleMouseDown() {
// Hide menu bar when web view is clicked.
if (menu_bar_autohide_ && menu_bar_visible_)
SetMenuBarVisibility(false);
#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*,
@@ -914,6 +917,7 @@ void NativeWindowViews::RegisterAccelerators(ui::MenuModel* menu_model) {
gfx::Rect NativeWindowViews::ContentBoundsToWindowBounds(
const gfx::Rect& bounds) {
gfx::Point origin = bounds.origin();
#if defined(OS_WIN)
gfx::Rect dpi_bounds = gfx::win::DIPToScreenRect(bounds);
gfx::Rect window_bounds = gfx::win::ScreenToDIPRect(
@@ -922,6 +926,9 @@ gfx::Rect NativeWindowViews::ContentBoundsToWindowBounds(
gfx::Rect window_bounds =
window_->non_client_view()->GetWindowBoundsForClientBounds(bounds);
#endif
// The window's position would also be changed, but we only want to change
// the size.
window_bounds.set_origin(origin);
if (menu_bar_ && menu_bar_visible_)
window_bounds.set_height(window_bounds.height() + kMenuBarHeight);
@@ -938,9 +945,10 @@ ui::WindowShowState NativeWindowViews::GetRestoredState() {
}
// static
NativeWindow* NativeWindow::Create(content::WebContents* web_contents,
const mate::Dictionary& options) {
return new NativeWindowViews(web_contents, options);
NativeWindow* NativeWindow::Create(
brightray::InspectableWebContents* inspectable_web_contents,
const mate::Dictionary& options) {
return new NativeWindowViews(inspectable_web_contents, options);
}
} // namespace atom

View File

@@ -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,13 +29,20 @@ 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:
explicit NativeWindowViews(content::WebContents* web_contents,
const mate::Dictionary& options);
virtual ~NativeWindowViews();
NativeWindowViews(brightray::InspectableWebContents* inspectable_web_contents,
const mate::Dictionary& options);
~NativeWindowViews() override;
// NativeWindow:
void Close() override;
@@ -82,17 +94,18 @@ 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;
void OnWidgetBoundsChanged(
views::Widget* widget, const gfx::Rect& bounds) override;
// views::WidgetDelegate:
void DeleteDelegate() override;
@@ -113,19 +126,25 @@ class NativeWindowViews : public NativeWindow,
views::ClientView* CreateClientView(views::Widget* widget) override;
views::NonClientFrameView* CreateNonClientFrameView(
views::Widget* widget) override;
void OnWidgetMove() override;
#if defined(OS_WIN)
bool ExecuteWindowsCommand(int command_id) override;
#endif
// brightray::InspectableWebContentsDelegate:
// brightray::InspectableWebContentsViewDelegate:
gfx::ImageSkia GetDevToolsWindowIcon() override;
#if defined(USE_X11)
void GetDevToolsWindowWMClass(
std::string* name, std::string* class_name) override;
#endif
// content::WebContentsDelegate:
void HandleMouseDown() override;
#if defined(OS_WIN)
// MessageHandlerDelegate:
bool PreHandleMSG(
UINT message, WPARAM w_param, LPARAM l_param, LRESULT* result) override;
#endif
// NativeWindow:
void HandleKeyboardEvent(
content::WebContents*,
const content::NativeWebKeyboardEvent& event) override;
@@ -157,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.
@@ -173,8 +196,7 @@ class NativeWindowViews : public NativeWindow,
std::string title_;
gfx::Size minimum_size_;
gfx::Size maximum_size_;
scoped_ptr<SkRegion> draggable_region_;
gfx::Size widget_size_;
DISALLOW_COPY_AND_ASSIGN(NativeWindowViews);
};

View File

@@ -1,124 +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 "base/threading/sequenced_worker_pool.h"
#include "atom/browser/net/url_request_buffer_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);
}
base::WeakPtr<AdapterRequestJob> AdapterRequestJob::GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
void AdapterRequestJob::CreateErrorJobAndStart(int error_code) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
real_job_ = new net::URLRequestErrorJob(
request(), network_delegate(), error_code);
real_job_->Start();
}
void AdapterRequestJob::CreateStringJobAndStart(const std::string& mime_type,
const std::string& charset,
const std::string& data) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
real_job_ = new URLRequestStringJob(
request(), network_delegate(), mime_type, charset, data);
real_job_->Start();
}
void AdapterRequestJob::CreateBufferJobAndStart(const std::string& mime_type,
const std::string& charset,
v8::Local<v8::Object> buffer) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
real_job_ = new URLRequestBufferJob(
request(), network_delegate(), mime_type, charset, buffer);
real_job_->Start();
}
void AdapterRequestJob::CreateFileJobAndStart(const base::FilePath& path) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
real_job_ = asar::CreateJobFromPath(
path,
request(),
network_delegate(),
content::BrowserThread::GetBlockingPool()->
GetTaskRunnerWithShutdownBehavior(
base::SequencedWorkerPool::SKIP_ON_SHUTDOWN));
real_job_->Start();
}
void AdapterRequestJob::CreateJobFromProtocolHandlerAndStart() {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
DCHECK(protocol_handler_);
real_job_ = protocol_handler_->MaybeCreateJob(request(),
network_delegate());
if (!real_job_.get())
CreateErrorJobAndStart(net::ERR_NOT_IMPLEMENTED);
else
real_job_->Start();
}
} // namespace atom

View File

@@ -1,74 +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/weak_ptr.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 {
// 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;
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,
v8::Local<v8::Object> buffer);
void CreateFileJobAndStart(const base::FilePath& path);
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();
}

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