Compare commits

...

183 Commits

Author SHA1 Message Date
Cheng Zhao
99410217b9 Bump v0.22.1 2015-03-18 22:36:44 +08:00
Cheng Zhao
46cb6e68f6 Ship snapshot file, fixes #1260 2015-03-18 22:36:27 +08:00
Cheng Zhao
8b88dc6a94 libudev.so is now dynamically loaded from Chrome 41 2015-03-18 13:07:03 +00:00
Cheng Zhao
d6b36bb487 Bump v0.22.0 2015-03-18 20:57:21 +08:00
Cheng Zhao
b8d918d24f Merge pull request #1254 from austinmoore-/master
Add check for root in script/bootstrap.py
2015-03-18 20:36:29 +08:00
Cheng Zhao
b19cfba98e Merge pull request #1240 from suyash/rename-node-webkit-to-nwjs
rename node-webkit to NW.js in development docs
2015-03-18 18:01:37 +08:00
Cheng Zhao
c497eef3b3 Merge pull request #1243 from atom/chrome41
Upgrade to Chrome 41
2015-03-18 18:01:14 +08:00
Cheng Zhao
57812616b9 win: Fix tests and compilation errors 2015-03-18 13:58:33 +08:00
Cheng Zhao
b43386b273 Upgrade libchromiumcontent 2015-03-18 09:57:49 +08:00
Cheng Zhao
f8f7ca1d57 linux: Upgrade libchromiumcontent to fix linking 2015-03-18 09:57:48 +08:00
Cheng Zhao
105ad369ab linux: Fix compilation error 2015-03-18 09:57:48 +08:00
Cheng Zhao
ff724634f2 js_stream is a new module of io.js 2015-03-18 09:57:47 +08:00
Cheng Zhao
0b8eb6ad90 ⬆️ apm@0.144.0 2015-03-18 09:57:47 +08:00
Cheng Zhao
66292a2787 Upgrade brightray to fix invalid commit to libchromiumcontent 2015-03-18 09:57:46 +08:00
Cheng Zhao
12d5474077 Fix webview for the new API 2015-03-18 09:57:46 +08:00
Cheng Zhao
8328bce3f6 Initialize AtExitManager before calling MainApplicationBundlePath
Some singleton calsses require the existence of AtExitManager.
2015-03-18 09:57:45 +08:00
Cheng Zhao
c62c943bdb Define our own Node entry
Chromium's V8 is using external startup snapshot file while Node does
not, so we have to use Chromium's gin for V8 initialization.
2015-03-18 09:57:45 +08:00
Cheng Zhao
ceccf1b48a Fix devtools override for its new architecture 2015-03-18 09:57:44 +08:00
Cheng Zhao
6af7388ac0 Use DevToolsAPI instead of InspectorFrontendAPI 2015-03-18 09:57:43 +08:00
Cheng Zhao
d16d5b290a Remove the "X-Frame-Options" from response headers for devtools 2015-03-18 09:57:43 +08:00
Cheng Zhao
fbd9501c61 Upgrade to io.js v1.5.2 2015-03-18 09:57:42 +08:00
Cheng Zhao
578b24ae8a Ship with snapshot files 2015-03-18 09:57:42 +08:00
Cheng Zhao
5b2c0110dc Fix other compilation errors 2015-03-18 09:57:41 +08:00
Cheng Zhao
98fbe5127b The "subpixel-font-scaling" option is removed 2015-03-18 09:57:41 +08:00
Cheng Zhao
8e2fdc178b Fix API changes of CopyFromBackingStore 2015-03-18 09:57:40 +08:00
Cheng Zhao
757df39941 Upgrade native_mate for unsigned long conversion 2015-03-18 09:57:40 +08:00
Cheng Zhao
dfad907530 Fix API changes of tracing API 2015-03-18 09:57:39 +08:00
Cheng Zhao
04d1075db5 Fix API changes of ContentBrowserClient 2015-03-18 09:57:39 +08:00
Cheng Zhao
8a138fafd4 Fix API changes of WebContentsDelegate 2015-03-18 09:57:38 +08:00
Cheng Zhao
819ab5cd0c Fix ui/gfx/geometry headers 2015-03-18 09:57:38 +08:00
Cheng Zhao
dead7caab2 CommandLine moved to base::CommandLine 2015-03-18 09:57:37 +08:00
Cheng Zhao
14542f4fc8 Upgrade to Chrome 41 2015-03-18 09:57:37 +08:00
Kevin Sawicki
8a52374951 Update brightray repo url to be under atom org 2015-03-17 11:22:39 -07:00
Cheng Zhao
cfc615a6c1 Fix accidental update of submodules, closes #1255 2015-03-17 21:26:10 +08:00
Cheng Zhao
af0690fb88 docs: "Quick start" should also be a "tutorial"
Guides should include information that not available in the API
references, and tutorials should be step-by-step walkthrough or
introductory text on certain APIs.
2015-03-17 18:41:54 +08:00
Cheng Zhao
c80aaa2980 docs: Separate guides and tutorials 2015-03-17 18:37:32 +08:00
Austin Moore
521f61d7db Add argument that allows for non-interactive use
The newly added 'check_root()' method introduced an interactive prompt
that would ask the user if they wanted to continue. The new argument '-y'
will now skip the prompt, so that if a user needs to run this script
un-interactively, they can do so easily.
2015-03-17 01:42:23 -06:00
Austin Moore
2d1f70c1cf Add check for root in script/bootstrap.py 2015-03-17 01:01:33 -06:00
Suyash
327c7bc3cc 📝 avoid breaking everyone's stuff 2015-03-16 16:50:23 +05:30
Cheng Zhao
9e2842c9ca Merge pull request #1235 from suyash/update-linux-development-docs
add troubleshooting instructions for libudev.so.0 failure
2015-03-16 16:55:48 +08:00
Cheng Zhao
7457eccdee Merge pull request #1238 from deepak1556/browser_window_lib_patch
define devToolsWebContents for use from remote module
2015-03-16 16:43:46 +08:00
Cheng Zhao
2942eae9f2 Merge pull request #1242 from deepak1556/web_contents_patch
add DidFailProvisionalLoad method
2015-03-16 16:27:32 +08:00
Robo
87cb2ece80 add DidFailProvisionalLoad method 2015-03-14 08:58:30 +05:30
Kevin Sawicki
042074cab1 Merge pull request #1241 from ylaassel/patch-1
Fix a typo
2015-03-12 08:09:58 -07:00
Yassine Laassel
bd81b24b99 Fix a typo 2015-03-11 17:38:31 -07:00
Cheng Zhao
bb2f3a82d9 Merge pull request #1224 from deepak1556/chromium_flag_patch
test for ignoreCertificateError
2015-03-11 13:40:06 -07:00
Suyash
cda129b073 📝 rename node-webkit to NW.js in development docs
Replaces all occurences of node-webkit with NW.js in the development
docs.
2015-03-12 01:58:58 +05:30
deepak1556
adb130cefa define devToolsWebContents for use from remote module 2015-03-11 19:58:12 +05:30
Suyash
860b15ef8a 📝 add troubleshooting instructions for libudev.so.0 failure
Adding the easiest solution for solving the missing libudev.so.0 error
on ubuntu 13.04+.

I had to do this on my own machine running ubuntu 14.04.2 to build atom.

The solution is also referenced in
https://github.com/nwjs/nw.js/wiki/The-solution-of-lacking-libudev.so.0
2015-03-11 12:17:22 +05:30
Cheng Zhao
1679115302 Merge pull request #1225 from deepak1556/remote_lib_patch
using Object.defineProperty instead of __defineMethods__
2015-03-10 16:03:22 -07:00
deepak1556
8395745cc1 using Object.defineProperty instead of __defineMethods__ 2015-03-11 04:18:11 +05:30
deepak1556
dd706ea6e2 test for ignoreCertificateError 2015-03-10 12:39:23 +05:30
Cheng Zhao
6856d203c5 Merge pull request #1215 from deepak1556/dialog_patch
avoid overriding type value of showMessageBox
2015-03-09 13:50:18 -07:00
Cheng Zhao
29471ff8b5 Fix styling of #1209 2015-03-09 13:46:46 -07:00
Cheng Zhao
2495583b5e Merge pull request #1209 from deepak1556/webcontents_patch
using WebContentsObserver::NavigationEntryCommitted to set virtualurl
2015-03-09 13:41:27 -07:00
deepak1556
0b780def24 avoid overriding type value of showMessageBox 2015-03-06 17:56:26 +05:30
Cheng Zhao
5a50ce4157 Merge pull request #1210 from paulyoung/update-readme
Update README to replace node.js with io.js
2015-03-05 13:42:40 -08:00
Paul Young
4b9f78e375 Update README to replace node.js with io.js 2015-03-05 13:33:02 -08:00
Cheng Zhao
c9b549ae69 Fix styling of #1199 2015-03-05 12:31:45 -08:00
Cheng Zhao
bb0e68e563 Merge pull request #1199 from deepak1556/protocol_asar_patch
read files from asar archives in custom protocol
2015-03-05 12:26:42 -08:00
Robo
0663b9dae2 using WebContentsObserver::NavigationEntryCommitted to set virtualurl 2015-03-05 20:09:27 +05:30
Robo
2ce42af6e4 read files from asar archives in custom protocol 2015-03-05 09:26:34 +05:30
Kevin Sawicki
47463ae5cb 📝 Tweak Windows installer sentence 2015-03-04 14:36:56 -08:00
Kevin Sawicki
d813537e38 Merge pull request #1206 from joaomoreno/patch-1
Refer grunt-atom-shell-installer to Windows users
2015-03-04 14:35:26 -08:00
João Moreno
7148f6d144 Refer grunt-atom-shell-installer to Windows users 2015-03-04 22:38:25 +01:00
Cheng Zhao
52d596e576 Merge pull request #1202 from xfq/patch-2
Update application-packaging.md
2015-03-04 09:36:51 -08:00
Cheng Zhao
1f849ec7b0 Merge pull request #1203 from xfq/patch-3
Update online-offline-events.md
2015-03-04 09:27:54 -08:00
Cheng Zhao
610ab0c0a5 Merge pull request #1204 from xfq/patch-4
Update using-selenium-and-webdriver.md
2015-03-04 09:27:34 -08:00
Cheng Zhao
4e93b567e2 Merge pull request #1200 from xfq/patch-1
Update quick-start.md
2015-03-04 09:26:02 -08:00
Cheng Zhao
2d6dd9f4d2 docs: Put window.open docs in its own chapter, regards #1137 2015-03-04 08:47:04 -08:00
Cheng Zhao
eb31df2940 Rename FakeWindow to BrowserWindowProxy 2015-03-04 08:46:45 -08:00
Cheng Zhao
99f6bf045f Improve #1137 2015-03-04 07:58:06 -08:00
Cheng Zhao
fac9ea3356 Merge pull request #1137 from bundyo/implement-some-popup-methods
Implement FakeWindow.postMessage, window.opener.postMessage and window.closed flag for popup windows
2015-03-04 07:28:33 -08:00
Xue Fuqiao
246d6cbcf7 Update using-selenium-and-webdriver.md
Update the URI  of ChromeDriver.
2015-03-04 21:59:27 +08:00
Xue Fuqiao
29c6d1e46f Update online-offline-events.md
Add HTML5 doctype.
2015-03-04 21:29:02 +08:00
Xue Fuqiao
92c76bac2b Update application-packaging.md
`BrowserWindow` should be used in browser scripts instead of client scripts. Move it to the "Node API" section.
2015-03-04 20:16:22 +08:00
Bundyo
dbbc35bd13 Fixes after code review. 2015-03-04 11:29:52 +02:00
Xue Fuqiao
dab9dad9db Update quick-start.md
node-webkit has been renamed to nw.js.
2015-03-04 16:18:51 +08:00
Cheng Zhao
4176d542a5 Bump v0.21.3 2015-03-03 13:42:29 -08:00
Kevin Sawicki
e19c50223b Merge pull request #1192 from senorflor/fix-error-text
Fix tense of error message
2015-03-02 12:19:14 -08:00
Patrick Flor
5bdc200376 Fix tense of error message
Thanks for putting this project together; really enjoying hacking with
it so far!
2015-03-02 12:08:12 -08:00
Cheng Zhao
f2c8ea085b Merge pull request #1177 from maxogden/patch-1
add npm installation instructions to README
2015-03-02 09:10:04 -08:00
Max Ogden
d8d0f15ca8 fix readme style 2015-03-01 11:58:33 -08:00
Cheng Zhao
38a871aa4b Merge pull request #1176 from CharlieHess/before-quit-event
App Before-Quit Event
2015-03-01 02:20:03 -08:00
bundyo
e8d648bcba Change the link to use dashes. 2015-02-28 10:34:26 +02:00
bundyo
c7562dbfd0 Add FakeWindow documentation. 2015-02-28 10:31:07 +02:00
Cheng Zhao
54c948409e Merge pull request #1167 from mal/patch-1
Prevent overflow on webview with height: 100%
2015-02-27 15:30:17 -08:00
Cheng Zhao
70a83ad069 Merge pull request #1148 from bundyo/fix-window-open-options
Fix window.open options parsing
2015-02-27 12:24:13 -08:00
Cheng Zhao
e98953a5a5 win: Fix calling FILE_PATH_LITERAL for variable, fixes #1143 2015-02-27 12:21:19 -08:00
Charlie Hess
78b856268e Fix cpplint errors. 2015-02-25 21:57:25 -08:00
Max Ogden
1d1db66abd add npm installation instructions to README 2015-02-25 21:56:47 -08:00
Charlie Hess
b6787a9b34 Emit a new before-quit event at the start of Browser::Quit, which gives us a chance to cancel before any windows are closed. 2015-02-25 19:33:42 -08:00
Mal Graty
7eecb84898 Prevent overflow on webview with height: 100%
Without this, the object element gets displayed `inline` which in chromium means that it slightly exceeds it's bounds. Unfortunately there's no nice way to mitigate this issue as I can't find a way to get extra css into this intermediate page. However, forcing a block display solves the issue.
2015-02-21 22:34:57 +00:00
Kevin Sawicki
0c99f3baa6 Merge pull request #1158 from beardicus/patch-1
Broken link in docs, api/synopsis
2015-02-20 15:39:05 -08:00
Brian Boucheron
72d6a13e9e Broken link in docs, api/synopsis
Link to using-native-node-modules.md instead of use-native-node-modules. Filename changed with 268508764f
2015-02-19 12:03:05 -05:00
Bundyo
43e44f8c35 Fix window.open options parsing:
remove excessive whitespace (gets inserted in property names),
avoid creating dummy properties if not needed,
turn 1/0 to true/false, convert integer strings to strings (fixes width/height).
2015-02-18 14:36:05 +02:00
Bundyo
4e82f4c672 Remove two semicolons. 2015-02-13 18:54:18 +02:00
Bundyo
7fa1296a17 Implement FakeWindow.postMessage, window.opener.postMessage and window.closed flag for popup windows. 2015-02-13 18:45:12 +02:00
Cheng Zhao
f1ad8836d1 Merge pull request #1136 from atom/no-js
Bundle all the .js files in asar archive
2015-02-13 14:10:09 +08:00
Cheng Zhao
4834eed520 Set process.resourcesPath in C++ 2015-02-13 13:32:58 +08:00
Cheng Zhao
0f15dd04af Put compiled coffee sources into asar archive 2015-02-13 13:05:51 +08:00
Cheng Zhao
0b8efc434d Use __dirname when setting globalPaths 2015-02-13 12:55:06 +08:00
Cheng Zhao
3f3e66916a asar@0.2.2 2015-02-13 12:40:25 +08:00
Cheng Zhao
fd9a8f4b91 Merge pull request #1134 from atom/menu-icon
Enable setting icon for MenuItem
2015-02-13 12:32:41 +08:00
Cheng Zhao
ac6c2ce69a docs: "icon" attribute 2015-02-13 12:12:40 +08:00
Cheng Zhao
e81baf759a Enable setting icon of menu item 2015-02-13 12:11:50 +08:00
Cheng Zhao
b28a241dbf Simplify the code to call delegate method 2015-02-13 11:47:22 +08:00
Cheng Zhao
afd4052bde Merge pull request #1129 from atom/asar-image
Recognize asar archive in NativeImage
2015-02-12 21:04:34 +08:00
Cheng Zhao
a8c227d5f5 Fix cpplint warnings 2015-02-12 19:50:28 +08:00
Cheng Zhao
9646c28a41 spec: native-image should read asar archive 2015-02-12 19:34:39 +08:00
Cheng Zhao
3678f13dfb Make NativeImage work with asar archive 2015-02-12 19:34:21 +08:00
Cheng Zhao
98a7f08be2 Move GetAsarArchivePath to asar_util.h 2015-02-12 17:31:14 +08:00
Cheng Zhao
3b3a025ed4 Move GetsOrCreateAsarArchive to asar_util.h 2015-02-12 17:23:49 +08:00
Cheng Zhao
64622ceae3 Merge pull request #1128 from atom/native-image
Introduce NativeImage
2015-02-12 16:48:42 +08:00
Cheng Zhao
06d681c66a docs: Update NativeImage 2015-02-12 15:38:16 +08:00
Cheng Zhao
c8738a88a4 Add nativeImage.createFromBuffer() 2015-02-12 15:19:05 +08:00
Cheng Zhao
faf40457c5 spec: Fix BrowserWindow.capturePage 2015-02-12 14:37:32 +08:00
Cheng Zhao
353b485202 Add NativeImage.toDataUrl() 2015-02-12 14:32:51 +08:00
Cheng Zhao
8e94856cc8 Add nativeImage.createFromDataUrl() 2015-02-12 14:27:53 +08:00
Cheng Zhao
b9f6d6dffc Add nativeImage.createEmpty() 2015-02-12 13:55:45 +08:00
Cheng Zhao
8093300a43 docs: Use NativeImage to replace Image 2015-02-12 13:52:28 +08:00
Cheng Zhao
da407200d2 Return NativeImage in BrowserWindow.capturePage 2015-02-12 13:45:50 +08:00
Cheng Zhao
443a4b8f2f mac: Use AsNSImage instead of ToNSImage
It can get rid of the empty check.
2015-02-12 12:29:49 +08:00
Cheng Zhao
509ce0d5cb mac: Don't rely on NSImage to read file
It doesn't work with asar.
2015-02-12 12:24:18 +08:00
Cheng Zhao
903ff0b61a Upgrade native_mate for security check 2015-02-12 10:45:04 +08:00
Cheng Zhao
2ca6be69e2 Fix cpplint warnings 2015-02-12 10:45:04 +08:00
Cheng Zhao
054b6a9817 Use NativeImage when converting images from V8 2015-02-12 10:45:04 +08:00
Cheng Zhao
6556602bdc Enable creating NativeImage from file path 2015-02-12 10:45:04 +08:00
Cheng Zhao
2876f15063 Enable creating NativeImage with native-image module 2015-02-12 10:45:04 +08:00
Cheng Zhao
85f5ef2ab1 Enable creating NativeImage from PNG and JPEG 2015-02-12 10:45:04 +08:00
Cheng Zhao
53fca43d89 Add NativeImage.ToJPEG 2015-02-12 10:45:03 +08:00
Cheng Zhao
549df36f00 Add a few more methods for NativeImage 2015-02-12 10:45:03 +08:00
Cheng Zhao
aae576b484 Convert gfx::Image to NativeImage instance 2015-02-12 10:45:03 +08:00
Cheng Zhao
b76615f3e7 Add clipboard.readImage method 2015-02-12 10:45:03 +08:00
Cheng Zhao
878d25e91e Enable converting gfx::Image to Buffer 2015-02-12 10:45:03 +08:00
Cheng Zhao
ab315e502f Upgrade brightray for gyp 2015-02-12 10:43:53 +08:00
Cheng Zhao
564c0b41df Merge pull request #1122 from atom/window-type
Add "type" option to change window type of BrowserWindow
2015-02-11 12:31:44 +08:00
Cheng Zhao
382a00493b docs: "type" option of BrowserWindow 2015-02-11 12:19:39 +08:00
Cheng Zhao
f0924df68a Add "type" option to change window type 2015-02-11 12:19:39 +08:00
Cheng Zhao
6b37f30bd6 Merge pull request #1106 from paulcbetts/set-overlay-icon
Set window overlay icon
2015-02-11 11:51:01 +08:00
Paul Betts
86de75deef Style fixups 2015-02-10 17:14:26 -08:00
Cheng Zhao
bedd0a11ba Suppress SSL verification, fixes #1115 2015-02-10 17:52:33 +08:00
Cheng Zhao
778078973b Merge pull request #1107 from yoshuawuyts/patch-1
docs: update wording in `application-packaging`
2015-02-10 12:12:34 +08:00
Yoshua Wuyts
a26976a161 docs: update wording in application-packagaging
Minor tweak, should make the sentence a bit more fluent. Thanks!
2015-02-08 12:04:02 +01:00
Paul Betts
8a7acfc6c0 icon_util is Windows-only 2015-02-07 11:57:00 -08:00
Paul Betts
03a88883b6 Fix build on OS X 2015-02-07 11:56:03 -08:00
Paul Betts
59a8be53c2 Documentation 2015-02-06 17:11:54 -08:00
Paul Betts
f55379ed5b Add missing trampoline method 2015-02-06 17:07:29 -08:00
Paul Betts
ef869fb2ff We need a UTF-16 string here 2015-02-06 17:00:38 -08:00
Paul Betts
1b9649b481 Switch to gfx::Image 2015-02-06 17:00:26 -08:00
Paul Betts
fa6d499a4e Come correct with line length and constness 2015-02-06 16:32:27 -08:00
Paul Betts
0afac1e05a Plumb code all the way up 2015-02-06 16:12:32 -08:00
Paul Betts
66f2d18d8b First hack at setting the window icon overlay 2015-02-06 15:58:49 -08:00
Cheng Zhao
b75bfe0e92 Bump v0.21.2 2015-02-05 13:46:09 -08:00
Cheng Zhao
1cae81c0d6 Merge pull request #1100 from christoth/master
Remove MFC lib dependency
2015-02-05 12:01:25 -08:00
christoth
92ab227397 Update atom.rc 2015-02-05 14:55:32 -05:00
christoth
076535bc06 Remove MFC lib dependency
Replace afxres.h with windows.h to remove dependency on MFC for compilation on Windows
2015-02-05 13:09:19 -05:00
Cheng Zhao
071a55974a A little clean up 2015-02-05 00:19:30 -08:00
Kevin Sawicki
c21c89c0ce Merge pull request #1098 from dpatou/patch-1
Event name typo
2015-02-04 16:27:01 -08:00
Damien Patou
8e6e1610a4 Event name typo 2015-02-05 01:23:16 +01:00
Cheng Zhao
0b694dffd8 Merge pull request #1097 from atom/fix-webview-race-condition
Fix the race condition when updating webview info
2015-02-04 16:13:18 -08:00
Cheng Zhao
7c8bed7bfc Get the WebViewManager from embedder WebContents
This make our lives easier when we have multiple BrowserContext support.
2015-02-04 15:52:59 -08:00
Cheng Zhao
209840871c Seperate the API implementation of WebViewManager 2015-02-04 15:39:41 -08:00
Cheng Zhao
ea99037f3b Clean up WebViewManager 2015-02-04 15:28:26 -08:00
Cheng Zhao
331d0481bb Move web_view_manager to atom/browser 2015-02-04 15:17:28 -08:00
Cheng Zhao
2c61070b36 Avoid using global BrowserContext 2015-02-04 15:08:29 -08:00
Cheng Zhao
502c0f0df7 Remove the WebViewRendererState class 2015-02-04 14:58:03 -08:00
Cheng Zhao
aa49e4790f Update WebViewRendererState immediately 2015-02-04 12:59:46 -08:00
Cheng Zhao
3490ce507a Remove WebViewRendererState::IsGuest 2015-02-04 12:51:15 -08:00
Cheng Zhao
c1f3d22910 Add lock for WebViewRendererState 2015-02-04 12:50:24 -08:00
Cheng Zhao
f1bca5dd0f Merge pull request #1096 from atom/generic-asar-support
Support asar archives in scripts forked with child_process.fork
2015-02-04 12:18:13 -08:00
Cheng Zhao
7861eec426 linux: Fix building 2015-02-04 11:18:25 -08:00
Cheng Zhao
a02707f998 Fix cpplint warnings 2015-02-04 11:01:01 -08:00
Cheng Zhao
f214e88784 spec: Script forked with child_process supports asar archives 2015-02-04 10:52:09 -08:00
Cheng Zhao
45e2dd2ab5 Init asar support without external .js files 2015-02-04 10:45:17 -08:00
Cheng Zhao
f905bb64f6 Compile asar.coffee to .c 2015-02-03 16:46:52 -08:00
Cheng Zhao
8612ad0459 generate_sources => compile_coffee 2015-02-03 16:07:29 -08:00
Cheng Zhao
3bbcc1efd8 compile-coffee.py should be put under tools/ 2015-02-03 15:56:58 -08:00
Cheng Zhao
6dac8da91f Merge pull request #1092 from paulcbetts/patch-2
Use 'atomScreen' for the variable name
2015-02-03 12:12:59 -08:00
Cheng Zhao
137f3b8439 docs: forBrowser is now required for webdriver 2015-02-03 11:38:22 -08:00
Paul Betts
b77ed51594 Use 'atomScreen' for the variable name
Even though it's not screen's fault, it's super easy in the DevTools to write `screen = require('screen')`, then wonder why it doesn't work (because `window.screen` is reserved by the DOM). This makes people who just type in the example more likely to get it right.
2015-02-03 11:32:33 -08:00
Cheng Zhao
d17e6a3857 Upgrade brightray 2015-02-03 10:59:19 -08:00
Cheng Zhao
a2c38ed48c Upgrade brightray 2015-02-03 10:43:24 -08:00
143 changed files with 1962 additions and 962 deletions

1
.gitignore vendored
View File

@@ -10,3 +10,4 @@ node_modules/
*.xcodeproj
*.swp
*.pyc
npm-debug.log

2
.gitmodules vendored
View File

@@ -1,6 +1,6 @@
[submodule "vendor/brightray"]
path = vendor/brightray
url = https://github.com/brightray/brightray.git
url = https://github.com/atom/brightray.git
[submodule "vendor/node"]
path = vendor/node
url = https://github.com/atom/node.git

View File

@@ -1,7 +1,7 @@
# Atom Shell [![Build Status](https://travis-ci.org/atom/atom-shell.svg?branch=master)](https://travis-ci.org/atom/atom-shell)
The Atom Shell framework lets you write cross-platform desktop applications
using JavaScript, HTML and CSS. It is based on [node.js](http://nodejs.org) and
using JavaScript, HTML and CSS. It is based on [io.js](http://iojs.org) and
[Chromium](http://www.chromium.org) and is used in the [Atom
editor](https://github.com/atom/atom).
@@ -10,6 +10,16 @@ editor](https://github.com/atom/atom).
Prebuilt binaries of atom-shell for Linux, Windows and Mac can be found on the
[releases](https://github.com/atom/atom-shell/releases) page.
You can also use [`npm`](https://docs.npmjs.com/) to install prebuilt atom-shell binaries:
```
# Install globally in your $PATH
npm install atom-shell -g
# Install as a development dependency
npm install atom-shell --save-dev
```
### Mirrors
- [China Mirror](https://npm.taobao.org/mirrors/atom-shell): Improve download speeds for Chinese user.

116
atom.gyp
View File

@@ -38,10 +38,10 @@
'atom/common/api/lib/clipboard.coffee',
'atom/common/api/lib/crash-reporter.coffee',
'atom/common/api/lib/id-weak-map.coffee',
'atom/common/api/lib/native-image.coffee',
'atom/common/api/lib/original-fs.coffee',
'atom/common/api/lib/shell.coffee',
'atom/common/lib/init.coffee',
'atom/common/lib/asar.coffee',
'atom/renderer/lib/chrome-api.coffee',
'atom/renderer/lib/init.coffee',
'atom/renderer/lib/inspector.coffee',
@@ -55,12 +55,18 @@
'atom/renderer/api/lib/screen.coffee',
'atom/renderer/api/lib/web-frame.coffee',
],
'coffee2c_sources': [
'atom/common/lib/asar.coffee',
'atom/common/lib/asar_init.coffee',
],
'lib_sources': [
'atom/app/atom_content_client.cc',
'atom/app/atom_content_client.h',
'atom/app/atom_main_delegate.cc',
'atom/app/atom_main_delegate.h',
'atom/app/atom_main_delegate_mac.mm',
'atom/app/node_main.cc',
'atom/app/node_main.h',
'atom/browser/api/atom_api_app.cc',
'atom/browser/api/atom_api_app.h',
'atom/browser/api/atom_api_auto_updater.cc',
@@ -85,6 +91,7 @@
'atom/browser/api/atom_api_tray.h',
'atom/browser/api/atom_api_web_contents.cc',
'atom/browser/api/atom_api_web_contents.h',
'atom/browser/api/atom_api_web_view_manager.cc',
'atom/browser/api/atom_api_window.cc',
'atom/browser/api/atom_api_window.h',
'atom/browser/api/event.cc',
@@ -109,6 +116,8 @@
'atom/browser/atom_browser_main_parts_mac.mm',
'atom/browser/atom_javascript_dialog_manager.cc',
'atom/browser/atom_javascript_dialog_manager.h',
'atom/browser/atom_resource_dispatcher_host_delegate.cc',
'atom/browser/atom_resource_dispatcher_host_delegate.h',
'atom/browser/atom_speech_recognition_manager_delegate.cc',
'atom/browser/atom_speech_recognition_manager_delegate.h',
'atom/browser/browser.cc',
@@ -187,10 +196,8 @@
'atom/browser/ui/x/window_state_watcher.h',
'atom/browser/ui/x/x_window_utils.cc',
'atom/browser/ui/x/x_window_utils.h',
'atom/browser/web_view/web_view_manager.cc',
'atom/browser/web_view/web_view_manager.h',
'atom/browser/web_view/web_view_renderer_state.cc',
'atom/browser/web_view/web_view_renderer_state.h',
'atom/browser/web_view_manager.cc',
'atom/browser/web_view_manager.h',
'atom/browser/web_dialog_helper.cc',
'atom/browser/web_dialog_helper.h',
'atom/browser/window_list.cc',
@@ -202,6 +209,9 @@
'atom/common/api/atom_api_crash_reporter.cc',
'atom/common/api/atom_api_id_weak_map.cc',
'atom/common/api/atom_api_id_weak_map.h',
'atom/common/api/atom_api_native_image.cc',
'atom/common/api/atom_api_native_image.h',
'atom/common/api/atom_api_native_image_mac.mm',
'atom/common/api/atom_api_shell.cc',
'atom/common/api/atom_api_v8_util.cc',
'atom/common/api/atom_bindings.cc',
@@ -210,6 +220,8 @@
'atom/common/api/object_life_monitor.h',
'atom/common/asar/archive.cc',
'atom/common/asar/archive.h',
'atom/common/asar/asar_util.cc',
'atom/common/asar/asar_util.h',
'atom/common/asar/scoped_temporary_file.cc',
'atom/common/asar/scoped_temporary_file.h',
'atom/common/common_message_generator.cc',
@@ -240,7 +252,6 @@
'atom/common/native_mate_converters/gurl_converter.h',
'atom/common/native_mate_converters/image_converter.cc',
'atom/common/native_mate_converters/image_converter.h',
'atom/common/native_mate_converters/image_converter_mac.mm',
'atom/common/native_mate_converters/string16_converter.h',
'atom/common/native_mate_converters/v8_value_converter.cc',
'atom/common/native_mate_converters/v8_value_converter.h',
@@ -270,6 +281,8 @@
'atom/renderer/atom_render_view_observer.h',
'atom/renderer/atom_renderer_client.cc',
'atom/renderer/atom_renderer_client.h',
'atom/renderer/guest_view_container.cc',
'atom/renderer/guest_view_container.h',
'chromium_src/chrome/browser/browser_process.cc',
'chromium_src/chrome/browser/browser_process.h',
'chromium_src/chrome/browser/chrome_notification_types.h',
@@ -333,6 +346,7 @@
'chromium_src/library_loaders/libspeechd_loader.cc',
'chromium_src/library_loaders/libspeechd.h',
'<@(native_mate_files)',
'<(SHARED_INTERMEDIATE_DIR)/atom_natives.h',
],
'lib_sources_win': [
'chromium_src/chrome/browser/ui/views/color_chooser_dialog.cc',
@@ -386,7 +400,7 @@
'target_name': '<(project_name)',
'type': 'executable',
'dependencies': [
'generated_sources',
'compile_coffee',
'<(project_name)_lib',
],
'sources': [
@@ -484,6 +498,8 @@
'<(libchromiumcontent_resources_dir)/content_resources_200_percent.pak',
'<(libchromiumcontent_resources_dir)/content_shell.pak',
'<(libchromiumcontent_resources_dir)/ui_resources_200_percent.pak',
'<(libchromiumcontent_resources_dir)/natives_blob.bin',
'<(libchromiumcontent_resources_dir)/snapshot_blob.bin',
'external_binaries/d3dcompiler_46.dll',
'external_binaries/msvcp120.dll',
'external_binaries/msvcr120.dll',
@@ -508,6 +524,8 @@
'<(libchromiumcontent_library_dir)/libffmpegsumo.so',
'<(libchromiumcontent_resources_dir)/icudtl.dat',
'<(libchromiumcontent_resources_dir)/content_shell.pak',
'<(libchromiumcontent_resources_dir)/natives_blob.bin',
'<(libchromiumcontent_resources_dir)/snapshot_blob.bin',
],
},
{
@@ -524,6 +542,7 @@
'target_name': '<(project_name)_lib',
'type': 'static_library',
'dependencies': [
'atom_coffee2c',
'vendor/brightray/brightray.gyp:brightray',
'vendor/node/node.gyp:node_lib',
],
@@ -533,6 +552,9 @@
'SK_SUPPORT_LEGACY_GETTOPDEVICE',
# Disable warnings for g_settings_list_schemas.
'GLIB_DISABLE_DEPRECATION_WARNINGS',
# Defined in Chromium but not exposed in its gyp file.
'V8_USE_EXTERNAL_STARTUP_DATA',
'ENABLE_PLUGINS',
],
'sources': [
'<@(lib_sources)',
@@ -542,6 +564,8 @@
'chromium_src',
'vendor/brightray',
'vendor/native_mate',
# Include atom_natives.h.
'<(SHARED_INTERMEDIATE_DIR)',
# Include directories for uv and node.
'vendor/node/src',
'vendor/node/deps/http_parser',
@@ -612,44 +636,56 @@
],
}, # target <(product_name)_lib
{
'target_name': 'generated_sources',
'target_name': 'compile_coffee',
'type': 'none',
'sources': [
'<@(coffee_sources)',
],
'rules': [
'actions': [
{
'rule_name': 'coffee',
'extension': 'coffee',
'action_name': 'compile_coffee',
'variables': {
'conditions': [
['OS=="mac"', {
'resources_path': '<(PRODUCT_DIR)/<(product_name).app/Contents/Resources',
},{
'resources_path': '<(PRODUCT_DIR)/resources',
}],
],
},
'inputs': [
'script/compile-coffee.py',
'<@(coffee_sources)',
],
'conditions': [
['OS=="mac"', {
'outputs': [
'<(PRODUCT_DIR)/<(product_name).app/Contents/Resources/<(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).js',
],
'action': [
'python',
'script/compile-coffee.py',
'<(RULE_INPUT_PATH)',
'<(PRODUCT_DIR)/<(product_name).app/Contents/Resources/<(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).js',
],
},{ # OS=="mac"
'outputs': [
'<(PRODUCT_DIR)/resources/<(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).js',
],
'action': [
'python',
'script/compile-coffee.py',
'<(RULE_INPUT_PATH)',
'<(PRODUCT_DIR)/resources/<(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).js',
],
}], # OS=="win" or OS=="linux"
'outputs': [
'<(resources_path)/atom.asar',
],
},
'action': [
'python',
'tools/coffee2asar.py',
'<@(_outputs)',
'<@(_inputs)',
],
}
],
}, # target generated_sources
}, # target compile_coffee
{
'target_name': 'atom_coffee2c',
'type': 'none',
'actions': [
{
'action_name': 'atom_coffee2c',
'inputs': [
'<@(coffee2c_sources)',
],
'outputs': [
'<(SHARED_INTERMEDIATE_DIR)/atom_natives.h',
],
'action': [
'python',
'tools/coffee2c.py',
'<@(_outputs)',
'<@(_inputs)',
],
}
],
}, # target atom_coffee2c
{
'target_name': '<(project_name)_dump_symbols',
'type': 'none',
@@ -821,6 +857,8 @@
'atom/common/resources/mac/MainMenu.xib',
'<(libchromiumcontent_resources_dir)/content_shell.pak',
'<(libchromiumcontent_resources_dir)/icudtl.dat',
'<(libchromiumcontent_resources_dir)/natives_blob.bin',
'<(libchromiumcontent_resources_dir)/snapshot_blob.bin',
],
'xcode_settings': {
'INFOPLIST_FILE': 'atom/common/resources/mac/Info.plist',

View File

@@ -13,7 +13,7 @@ __attribute__((visibility("default")))
int AtomMain(int argc, const char* argv[]);
__attribute__((visibility("default")))
void AtomInitializeICU();
int AtomInitializeICUandStartNode(int argc, char *argv[]);
}
#endif // OS_MACOSX

View File

@@ -5,6 +5,8 @@
#include "atom/app/atom_library_main.h"
#include "atom/app/atom_main_delegate.h"
#include "atom/app/node_main.h"
#include "base/at_exit.h"
#include "base/i18n/icu_util.h"
#include "base/mac/bundle_locations.h"
#include "brightray/common/mac/main_application_bundle.h"
@@ -19,12 +21,14 @@ int AtomMain(int argc, const char* argv[]) {
return content::ContentMain(params);
}
void AtomInitializeICU() {
int AtomInitializeICUandStartNode(int argc, char *argv[]) {
base::AtExitManager atexit_manager;
base::mac::SetOverrideFrameworkBundlePath(
brightray::MainApplicationBundlePath()
.Append("Contents")
.Append("Frameworks")
.Append(PRODUCT_NAME " Framework.framework"));
base::i18n::InitializeICU();
return atom::NodeMain(argc, argv);
}
#endif // OS_MACOSX

View File

@@ -31,13 +31,9 @@
#include "atom/app/atom_library_main.h"
#endif // defined(OS_MACOSX)
#include "atom/app/node_main.h"
#include "base/i18n/icu_util.h"
// Declaration of node::Start.
namespace node {
int Start(int argc, char *argv[]);
}
#if defined(OS_WIN)
namespace {
@@ -137,7 +133,7 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
}
// Now that conversion is done, we can finally start.
base::i18n::InitializeICU();
return node::Start(argc, argv);
return atom::NodeMain(argc, argv);
} else if (env->GetVar("ATOM_SHELL_INTERNAL_CRASH_SERVICE",
&crash_service_indicator) &&
crash_service_indicator == "1") {
@@ -166,7 +162,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();
return node::Start(argc, const_cast<char**>(argv));
return atom::NodeMain(argc, const_cast<char**>(argv));
}
atom::AtomMainDelegate delegate;
@@ -181,8 +177,7 @@ int main(int argc, const char* argv[]) {
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) {
AtomInitializeICU();
return node::Start(argc, const_cast<char**>(argv));
return AtomInitializeICUandStartNode(argc, const_cast<char**>(argv));
}
return AtomMain(argc, argv);

View File

@@ -59,7 +59,7 @@ void AtomMainDelegate::PreSandboxStartup() {
if (!env->HasVar("GOOGLE_API_KEY"))
env->SetVar("GOOGLE_API_KEY", GOOGLEAPIS_API_KEY);
CommandLine* command_line = CommandLine::ForCurrentProcess();
auto command_line = base::CommandLine::ForCurrentProcess();
std::string process_type = command_line->GetSwitchValueASCII(
switches::kProcessType);

56
atom/app/node_main.cc Normal file
View File

@@ -0,0 +1,56 @@
// 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/node_main.h"
#include "atom/browser/javascript_environment.h"
#include "atom/common/node_includes.h"
#include "gin/array_buffer.h"
#include "gin/public/isolate_holder.h"
namespace atom {
int NodeMain(int argc, char *argv[]) {
argv = uv_setup_args(argc, argv);
int exec_argc;
const char** exec_argv;
node::Init(&argc, const_cast<const char**>(argv), &exec_argc, &exec_argv);
int exit_code = 1;
{
gin::IsolateHolder::LoadV8Snapshot();
gin::IsolateHolder::Initialize(
gin::IsolateHolder::kNonStrictMode,
gin::ArrayBufferAllocator::SharedInstance());
JavascriptEnvironment gin_env;
node::Environment* env = node::CreateEnvironment(
gin_env.isolate(), gin_env.context(), argc, argv, exec_argc, exec_argv);
bool more;
do {
more = uv_run(env->event_loop(), UV_RUN_ONCE);
if (more == false) {
node::EmitBeforeExit(env);
// Emit `beforeExit` if the loop became alive either after emitting
// event, or after running some callbacks.
more = uv_loop_alive(env->event_loop());
if (uv_run(env->event_loop(), UV_RUN_NOWAIT) != 0)
more = true;
}
} while (more == true);
exit_code = node::EmitExit(env);
node::RunAtExit(env);
env->Dispose();
}
v8::V8::Dispose();
return exit_code;
}
} // namespace atom

14
atom/app/node_main.h Normal file
View File

@@ -0,0 +1,14 @@
// 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_NODE_MAIN_H_
#define ATOM_APP_NODE_MAIN_H_
namespace atom {
int NodeMain(int argc, char *argv[]);
} // namespace atom
#endif // ATOM_APP_NODE_MAIN_H_

View File

@@ -131,6 +131,10 @@ App::~App() {
Browser::Get()->RemoveObserver(this);
}
void App::OnBeforeQuit(bool* prevent_default) {
*prevent_default = Emit("before-quit");
}
void App::OnWillQuit(bool* prevent_default) {
*prevent_default = Emit("will-quit");
}
@@ -234,11 +238,12 @@ mate::Handle<App> App::Create(v8::Isolate* isolate) {
namespace {
void AppendSwitch(const std::string& switch_string, mate::Arguments* args) {
auto command_line = base::CommandLine::ForCurrentProcess();
std::string value;
if (args->GetNext(&value))
CommandLine::ForCurrentProcess()->AppendSwitchASCII(switch_string, value);
command_line->AppendSwitchASCII(switch_string, value);
else
CommandLine::ForCurrentProcess()->AppendSwitch(switch_string);
command_line->AppendSwitch(switch_string);
}
#if defined(OS_MACOSX)
@@ -259,13 +264,13 @@ void DockSetMenu(atom::api::Menu* menu) {
void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
v8::Handle<v8::Context> context, void* priv) {
v8::Isolate* isolate = context->GetIsolate();
CommandLine* command_line = CommandLine::ForCurrentProcess();
auto command_line = base::CommandLine::ForCurrentProcess();
mate::Dictionary dict(isolate, exports);
dict.Set("app", atom::api::App::Create(isolate));
dict.SetMethod("appendSwitch", &AppendSwitch);
dict.SetMethod("appendArgument",
base::Bind(&CommandLine::AppendArg,
base::Bind(&base::CommandLine::AppendArg,
base::Unretained(command_line)));
#if defined(OS_MACOSX)
auto browser = base::Unretained(Browser::Get());

View File

@@ -38,6 +38,7 @@ class App : public mate::EventEmitter,
virtual ~App();
// BrowserObserver:
void OnBeforeQuit(bool* prevent_default) override;
void OnWillQuit(bool* prevent_default) override;
void OnWindowAllClosed() override;
void OnQuit() override;

View File

@@ -62,31 +62,26 @@ namespace {
void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
v8::Handle<v8::Context> context, void* priv) {
TracingController* controller = TracingController::GetInstance();
auto controller = base::Unretained(TracingController::GetInstance());
mate::Dictionary dict(context->GetIsolate(), exports);
dict.SetMethod("getCategories", base::Bind(
&TracingController::GetCategories, base::Unretained(controller)));
&TracingController::GetCategories, controller));
dict.SetMethod("startRecording", base::Bind(
&TracingController::EnableRecording, base::Unretained(controller)));
&TracingController::EnableRecording, controller));
dict.SetMethod("stopRecording", base::Bind(
&TracingController::DisableRecording,
base::Unretained(controller),
nullptr));
&TracingController::DisableRecording, controller, nullptr));
dict.SetMethod("startMonitoring", base::Bind(
&TracingController::EnableMonitoring, base::Unretained(controller)));
&TracingController::EnableMonitoring, controller));
dict.SetMethod("stopMonitoring", base::Bind(
&TracingController::DisableMonitoring, base::Unretained(controller)));
&TracingController::DisableMonitoring, controller));
dict.SetMethod("captureMonitoringSnapshot", base::Bind(
&TracingController::CaptureMonitoringSnapshot,
base::Unretained(controller),
nullptr));
dict.SetMethod("getTraceBufferPercentFull", base::Bind(
&TracingController::GetTraceBufferPercentFull,
base::Unretained(controller)));
&TracingController::CaptureMonitoringSnapshot, controller, nullptr));
dict.SetMethod("getTraceBufferUsage", base::Bind(
&TracingController::GetTraceBufferUsage, controller));
dict.SetMethod("setWatchEvent", base::Bind(
&TracingController::SetWatchEvent, base::Unretained(controller)));
&TracingController::SetWatchEvent, controller));
dict.SetMethod("cancelWatchEvent", base::Bind(
&TracingController::CancelWatchEvent, base::Unretained(controller)));
&TracingController::CancelWatchEvent, controller));
}
} // namespace

View File

@@ -6,7 +6,9 @@
#include "atom/browser/native_window.h"
#include "atom/common/native_mate_converters/accelerator_converter.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"
@@ -17,30 +19,6 @@ namespace atom {
namespace api {
namespace {
// Call method of delegate object.
v8::Handle<v8::Value> CallDelegate(v8::Isolate* isolate,
v8::Handle<v8::Value> default_value,
v8::Handle<v8::Object> menu,
const char* method,
int command_id) {
v8::Handle<v8::Value> delegate = menu->Get(
MATE_STRING_NEW(isolate, "delegate"));
if (!delegate->IsObject())
return default_value;
v8::Handle<v8::Function> function = v8::Handle<v8::Function>::Cast(
delegate->ToObject()->Get(MATE_STRING_NEW(isolate, method)));
if (!function->IsFunction())
return default_value;
v8::Handle<v8::Value> argv = MATE_INTEGER_NEW(isolate, command_id);
return function->Call(isolate->GetCurrentContext()->Global(), 1, &argv);
}
} // namespace
Menu::Menu()
: model_(new ui::SimpleMenuModel(this)),
parent_(NULL) {
@@ -49,37 +27,30 @@ Menu::Menu()
Menu::~Menu() {
}
void Menu::AfterInit(v8::Isolate* isolate) {
mate::Dictionary wrappable(isolate, GetWrapper(isolate));
mate::Dictionary delegate;
if (!wrappable.Get("delegate", &delegate))
return;
delegate.Get("isCommandIdChecked", &is_checked_);
delegate.Get("isCommandIdEnabled", &is_enabled_);
delegate.Get("isCommandIdVisible", &is_visible_);
delegate.Get("getAcceleratorForCommandId", &get_accelerator_);
delegate.Get("executeCommand", &execute_command_);
delegate.Get("menuWillShow", &menu_will_show_);
}
bool Menu::IsCommandIdChecked(int command_id) const {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
return CallDelegate(isolate,
MATE_FALSE(isolate),
const_cast<Menu*>(this)->GetWrapper(isolate),
"isCommandIdChecked",
command_id)->BooleanValue();
return is_checked_.Run(command_id);
}
bool Menu::IsCommandIdEnabled(int command_id) const {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
return CallDelegate(isolate,
MATE_TRUE(isolate),
const_cast<Menu*>(this)->GetWrapper(isolate),
"isCommandIdEnabled",
command_id)->BooleanValue();
return is_enabled_.Run(command_id);
}
bool Menu::IsCommandIdVisible(int command_id) const {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
return CallDelegate(isolate,
MATE_TRUE(isolate),
const_cast<Menu*>(this)->GetWrapper(isolate),
"isCommandIdVisible",
command_id)->BooleanValue();
return is_visible_.Run(command_id);
}
bool Menu::GetAcceleratorForCommandId(int command_id,
@@ -87,69 +58,16 @@ bool Menu::GetAcceleratorForCommandId(int command_id,
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
v8::Handle<v8::Value> shortcut = CallDelegate(isolate,
MATE_UNDEFINED(isolate),
GetWrapper(isolate),
"getAcceleratorForCommandId",
command_id);
return mate::ConvertFromV8(isolate, shortcut, accelerator);
}
bool Menu::IsItemForCommandIdDynamic(int command_id) const {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
return CallDelegate(isolate,
MATE_FALSE(isolate),
const_cast<Menu*>(this)->GetWrapper(isolate),
"isItemForCommandIdDynamic",
command_id)->BooleanValue();
}
base::string16 Menu::GetLabelForCommandId(int command_id) const {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
v8::Handle<v8::Value> result = CallDelegate(
isolate,
MATE_FALSE(isolate),
const_cast<Menu*>(this)->GetWrapper(isolate),
"getLabelForCommandId",
command_id);
base::string16 label;
mate::ConvertFromV8(isolate, result, &label);
return label;
}
base::string16 Menu::GetSublabelForCommandId(int command_id) const {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
v8::Handle<v8::Value> result = CallDelegate(
isolate,
MATE_FALSE(isolate),
const_cast<Menu*>(this)->GetWrapper(isolate),
"getSubLabelForCommandId",
command_id);
base::string16 label;
mate::ConvertFromV8(isolate, result, &label);
return label;
v8::Handle<v8::Value> val = get_accelerator_.Run(command_id);
return mate::ConvertFromV8(isolate, val, accelerator);
}
void Menu::ExecuteCommand(int command_id, int event_flags) {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
CallDelegate(isolate, MATE_FALSE(isolate), GetWrapper(isolate),
"executeCommand", command_id);
execute_command_.Run(command_id);
}
void Menu::MenuWillShow(ui::SimpleMenuModel* source) {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
CallDelegate(isolate, MATE_FALSE(isolate), GetWrapper(isolate),
"menuWillShow", -1);
menu_will_show_.Run();
}
void Menu::AttachToWindow(Window* window) {
@@ -186,6 +104,10 @@ void Menu::InsertSubMenuAt(int index,
model_->InsertSubMenuAt(index, command_id, label, menu->model_.get());
}
void Menu::SetIcon(int index, const gfx::Image& image) {
model_->SetIcon(index, image);
}
void Menu::SetSublabel(int index, const base::string16& sublabel) {
model_->SetSublabel(index, sublabel);
}
@@ -235,6 +157,7 @@ void Menu::BuildPrototype(v8::Isolate* isolate,
.SetMethod("insertRadioItem", &Menu::InsertRadioItemAt)
.SetMethod("insertSeparator", &Menu::InsertSeparatorAt)
.SetMethod("insertSubMenu", &Menu::InsertSubMenuAt)
.SetMethod("setIcon", &Menu::SetIcon)
.SetMethod("setSublabel", &Menu::SetSublabel)
.SetMethod("clear", &Menu::Clear)
.SetMethod("getIndexOfCommandId", &Menu::GetIndexOfCommandId)

View File

@@ -8,6 +8,7 @@
#include <string>
#include "atom/browser/api/atom_api_window.h"
#include "base/callback.h"
#include "base/memory/scoped_ptr.h"
#include "ui/base/models/simple_menu_model.h"
#include "native_mate/wrappable.h"
@@ -16,8 +17,6 @@ namespace atom {
namespace api {
class MenuMac;
class Menu : public mate::Wrappable,
public ui::SimpleMenuModel::Delegate {
public:
@@ -40,16 +39,15 @@ class Menu : public mate::Wrappable,
Menu();
virtual ~Menu();
// mate::Wrappable:
void AfterInit(v8::Isolate* isolate) override;
// ui::SimpleMenuModel::Delegate implementations:
bool IsCommandIdChecked(int command_id) const override;
bool IsCommandIdEnabled(int command_id) const override;
bool IsCommandIdVisible(int command_id) const override;
bool GetAcceleratorForCommandId(
int command_id,
ui::Accelerator* accelerator) override;
bool IsItemForCommandIdDynamic(int command_id) const override;
base::string16 GetLabelForCommandId(int command_id) const override;
base::string16 GetSublabelForCommandId(int command_id) const override;
bool GetAcceleratorForCommandId(int command_id,
ui::Accelerator* accelerator) override;
void ExecuteCommand(int command_id, int event_flags) override;
void MenuWillShow(ui::SimpleMenuModel* source) override;
@@ -74,6 +72,7 @@ class Menu : public mate::Wrappable,
int command_id,
const base::string16& label,
Menu* menu);
void SetIcon(int index, const gfx::Image& image);
void SetSublabel(int index, const base::string16& sublabel);
void Clear();
int GetIndexOfCommandId(int command_id);
@@ -85,6 +84,14 @@ class Menu : public mate::Wrappable,
bool IsEnabledAt(int index) const;
bool IsVisibleAt(int index) const;
// Stored delegate methods.
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<void(int)> execute_command_;
base::Callback<void()> menu_will_show_;
DISALLOW_COPY_AND_ASSIGN(Menu);
};

View File

@@ -7,7 +7,7 @@
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/native_window.h"
#include "atom/browser/web_dialog_helper.h"
#include "atom/browser/web_view/web_view_renderer_state.h"
#include "atom/browser/web_view_manager.h"
#include "atom/common/api/api_messages.h"
#include "atom/common/native_mate_converters/gfx_converter.h"
#include "atom/common/native_mate_converters/gurl_converter.h"
@@ -16,6 +16,7 @@
#include "base/strings/utf_string_conversions.h"
#include "brightray/browser/inspectable_web_contents.h"
#include "content/public/browser/navigation_details.h"
#include "content/public/browser/navigation_entry.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"
@@ -39,13 +40,13 @@ v8::Persistent<v8::ObjectTemplate> template_;
// Get the window that has the |guest| embedded.
NativeWindow* GetWindowFromGuest(const content::WebContents* guest) {
int guest_process_id = guest->GetRenderProcessHost()->GetID();
WebViewRendererState::WebViewInfo info;
if (!WebViewRendererState::GetInstance()->GetInfo(guest_process_id, &info))
WebViewManager::WebViewInfo info;
if (WebViewManager::GetInfoForProcess(guest->GetRenderProcessHost(), &info))
return NativeWindow::FromRenderView(
info.embedder->GetRenderProcessHost()->GetID(),
info.embedder->GetRoutingID());
else
return nullptr;
return NativeWindow::FromRenderView(
info.embedder->GetRenderProcessHost()->GetID(),
info.embedder->GetRoutingID());
}
} // namespace
@@ -55,6 +56,7 @@ WebContents::WebContents(content::WebContents* web_contents)
guest_instance_id_(-1),
element_instance_id_(-1),
guest_opaque_(true),
guest_sizer_(nullptr),
auto_size_enabled_(false) {
}
@@ -62,6 +64,7 @@ WebContents::WebContents(const mate::Dictionary& options)
: guest_instance_id_(-1),
element_instance_id_(-1),
guest_opaque_(true),
guest_sizer_(nullptr),
auto_size_enabled_(false) {
options.Get("guestInstanceId", &guest_instance_id_);
@@ -95,6 +98,7 @@ bool WebContents::AddMessageToConsole(content::WebContents* source,
bool WebContents::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,
@@ -196,6 +200,15 @@ void WebContents::DidFinishLoad(content::RenderFrameHost* render_frame_host,
Emit("did-finish-load");
}
// this error occurs when host could not be found
void WebContents::DidFailProvisionalLoad(
content::RenderFrameHost* render_frame_host,
const GURL& validated_url,
int error_code,
const base::string16& error_description) {
Emit("did-fail-load", error_code, error_description);
}
void WebContents::DidFailLoad(content::RenderFrameHost* render_frame_host,
const GURL& validated_url,
int error_code,
@@ -212,7 +225,7 @@ void WebContents::DidStopLoading(content::RenderViewHost* render_view_host) {
}
void WebContents::DidGetRedirectForResourceRequest(
content::RenderViewHost* render_view_host,
content::RenderFrameHost* render_frame_host,
const content::ResourceRedirectDetails& details) {
Emit("did-get-redirect-request",
details.url,
@@ -264,13 +277,26 @@ void WebContents::WebContentsDestroyed() {
Emit("destroyed");
}
void WebContents::NavigationEntryCommitted(
const content::LoadCommittedDetails& load_details) {
auto entry = web_contents()->GetController().GetLastCommittedEntry();
entry->SetVirtualURL(load_details.entry->GetOriginalRequestURL());
}
void WebContents::DidAttach(int guest_proxy_routing_id) {
Emit("did-attach");
}
void WebContents::ElementSizeChanged(const gfx::Size& old_size,
const gfx::Size& new_size) {
element_size_ = new_size;
void WebContents::ElementSizeChanged(const gfx::Size& size) {
element_size_ = size;
// Only resize if needed.
if (!size.IsEmpty())
guest_sizer_->SizeContents(size);
}
content::WebContents* WebContents::GetOwnerWebContents() const {
return embedder_web_contents_;
}
void WebContents::GuestSizeChanged(const gfx::Size& old_size,
@@ -286,10 +312,15 @@ void WebContents::RegisterDestructionCallback(
destruction_callback_ = callback;
}
void WebContents::SetGuestSizer(content::GuestSizer* guest_sizer) {
guest_sizer_ = guest_sizer;
}
void WebContents::WillAttach(content::WebContents* embedder_web_contents,
int browser_plugin_instance_id) {
int element_instance_id,
bool is_full_page_plugin) {
embedder_web_contents_ = embedder_web_contents;
element_instance_id_ = browser_plugin_instance_id;
element_instance_id_ = element_instance_id;
}
void WebContents::Destroy() {
@@ -323,7 +354,8 @@ void WebContents::LoadURL(const GURL& url, const mate::Dictionary& options) {
}
GURL WebContents::GetURL() const {
return web_contents()->GetURL();
auto entry = web_contents()->GetController().GetLastCommittedEntry();
return entry->GetVirtualURL();
}
base::string16 WebContents::GetTitle() const {

View File

@@ -120,6 +120,7 @@ class WebContents : public mate::EventEmitter,
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,
@@ -154,10 +155,14 @@ class WebContents : public mate::EventEmitter,
const GURL& validated_url,
int error_code,
const base::string16& error_description) 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;
void DidGetRedirectForResourceRequest(
content::RenderViewHost* render_view_host,
content::RenderFrameHost* render_frame_host,
const content::ResourceRedirectDetails& details) override;
void DidNavigateMainFrame(
const content::LoadCommittedDetails& details,
@@ -165,16 +170,20 @@ class WebContents : public mate::EventEmitter,
bool OnMessageReceived(const IPC::Message& message) override;
void RenderViewReady() override;
void WebContentsDestroyed() override;
void NavigationEntryCommitted(
const content::LoadCommittedDetails& load_details) override;
// content::BrowserPluginGuestDelegate:
void DidAttach(int guest_proxy_routing_id) final;
void ElementSizeChanged(const gfx::Size& old_size,
const gfx::Size& new_size) final;
void ElementSizeChanged(const gfx::Size& size) final;
content::WebContents* GetOwnerWebContents() const final;
void GuestSizeChanged(const gfx::Size& old_size,
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 browser_plugin_instance_id) final;
int element_instance_id,
bool is_full_page_plugin) final;
private:
// Called when received a message from renderer.
@@ -216,6 +225,9 @@ class WebContents : public mate::EventEmitter,
// 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_;

View File

@@ -0,0 +1,93 @@
// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_web_contents.h"
#include "atom/browser/web_view_manager.h"
#include "atom/common/native_mate_converters/gurl_converter.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"
namespace mate {
template<>
struct Converter<content::WebContents*> {
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
content::WebContents** out) {
atom::api::WebContents* contents;
if (!Converter<atom::api::WebContents*>::FromV8(isolate, val, &contents))
return false;
*out = contents->web_contents();
return true;
}
};
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 {
atom::WebViewManager* GetWebViewManager(content::WebContents* web_contents) {
auto context = web_contents->GetBrowserContext();
if (context) {
auto manager = context->GetGuestManager();
return static_cast<atom::WebViewManager*>(manager);
} else {
return nullptr;
}
}
void AddGuest(int guest_instance_id,
int element_instance_id,
content::WebContents* embedder,
content::WebContents* guest_web_contents,
atom::WebViewManager::WebViewInfo info) {
auto manager = GetWebViewManager(embedder);
if (manager) {
info.guest_instance_id = guest_instance_id;
info.embedder = embedder;
manager->AddGuest(guest_instance_id, element_instance_id, embedder,
guest_web_contents, info);
}
}
void RemoveGuest(content::WebContents* embedder, int guest_instance_id) {
auto manager = GetWebViewManager(embedder);
if (manager)
manager->RemoveGuest(guest_instance_id);
}
void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
v8::Handle<v8::Context> context, void* priv) {
mate::Dictionary dict(context->GetIsolate(), exports);
dict.SetMethod("addGuest", &AddGuest);
dict.SetMethod("removeGuest", &RemoveGuest);
}
} // namespace
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_web_view_manager, Initialize)

View File

@@ -9,6 +9,7 @@
#include "atom/browser/native_window.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 "content/public/browser/render_process_host.h"
#include "native_mate/callback.h"
@@ -51,15 +52,11 @@ namespace {
void OnCapturePageDone(
v8::Isolate* isolate,
const base::Callback<void(v8::Handle<v8::Value>)>& callback,
const base::Callback<void(const gfx::Image&)>& callback,
const std::vector<unsigned char>& data) {
v8::Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Value> buffer = node::Buffer::New(
reinterpret_cast<const char*>(data.data()),
data.size());
callback.Run(buffer);
callback.Run(gfx::Image::CreateFrom1xPNGBytes(&data.front(), data.size()));
}
} // namespace
@@ -373,7 +370,7 @@ bool Window::IsDocumentEdited() {
void Window::CapturePage(mate::Arguments* args) {
gfx::Rect rect;
base::Callback<void(v8::Handle<v8::Value>)> callback;
base::Callback<void(const gfx::Image&)> callback;
if (!(args->Length() == 1 && args->GetNext(&callback)) &&
!(args->Length() == 2 && args->GetNext(&rect)
@@ -400,6 +397,11 @@ void Window::SetProgressBar(double progress) {
window_->SetProgressBar(progress);
}
void Window::SetOverlayIcon(const gfx::Image& overlay,
const std::string& description) {
window_->SetOverlayIcon(overlay, description);
}
void Window::SetAutoHideMenuBar(bool auto_hide) {
window_->SetAutoHideMenuBar(auto_hide);
}
@@ -487,6 +489,7 @@ void Window::BuildPrototype(v8::Isolate* isolate,
.SetMethod("capturePage", &Window::CapturePage)
.SetMethod("print", &Window::Print)
.SetMethod("setProgressBar", &Window::SetProgressBar)
.SetMethod("setOverlayIcon", &Window::SetOverlayIcon)
.SetMethod("setAutoHideMenuBar", &Window::SetAutoHideMenuBar)
.SetMethod("isMenuBarAutoHide", &Window::IsMenuBarAutoHide)
.SetMethod("setMenuBarVisibility", &Window::SetMenuBarVisibility)

View File

@@ -9,6 +9,7 @@
#include <vector>
#include "base/memory/scoped_ptr.h"
#include "ui/gfx/image/image.h"
#include "atom/browser/native_window_observer.h"
#include "atom/browser/api/event_emitter.h"
#include "native_mate/handle.h"
@@ -118,6 +119,8 @@ class Window : public mate::EventEmitter,
void CapturePage(mate::Arguments* args);
void Print(mate::Arguments* args);
void SetProgressBar(double progress);
void SetOverlayIcon(const gfx::Image& overlay,
const std::string& description);
void SetAutoHideMenuBar(bool auto_hide);
bool IsMenuBarAutoHide();
void SetMenuBarVisibility(bool visible);

View File

@@ -17,6 +17,7 @@ BrowserWindow::_init = ->
@setMenu menu if menu?
@webContents = @getWebContents()
@devToolsWebContents = null
@webContents.once 'destroyed', => @webContents = null
# Remember the window ID.

View File

@@ -83,8 +83,8 @@ module.exports =
options ?= type: 'none'
options.type ?= 'none'
options.type = messageBoxTypes.indexOf options.type
throw new TypeError('Invalid message box type') unless options.type > -1
messageBoxType = messageBoxTypes.indexOf options.type
throw new TypeError('Invalid message box type') unless messageBoxType > -1
throw new TypeError('Buttons need to be array') unless Array.isArray options.buttons
@@ -93,7 +93,7 @@ module.exports =
options.detail ?= ''
options.icon ?= null
binding.showMessageBox options.type,
binding.showMessageBox messageBoxType,
options.buttons,
[options.title, options.message, options.detail],
options.icon,

View File

@@ -9,13 +9,14 @@ class MenuItem
constructor: (options) ->
Menu = require 'menu'
{click, @selector, @type, @label, @sublabel, @accelerator, @enabled, @visible, @checked, @submenu} = options
{click, @selector, @type, @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 'accelerator'
@overrideReadOnlyProperty 'icon'
@overrideReadOnlyProperty 'submenu'
@overrideProperty 'label', ''
@overrideProperty 'sublabel', ''

View File

@@ -35,6 +35,7 @@ Menu::_init = ->
isCommandIdEnabled: (commandId) => @commandsMap[commandId]?.enabled
isCommandIdVisible: (commandId) => @commandsMap[commandId]?.visible
getAcceleratorForCommandId: (commandId) => @commandsMap[commandId]?.accelerator
getIconForCommandId: (commandId) => @commandsMap[commandId]?.icon
executeCommand: (commandId) => @commandsMap[commandId]?.click()
menuWillShow: =>
# Make sure radio groups have at least one menu item seleted.
@@ -82,6 +83,7 @@ Menu::insert = (pos, item) ->
@insertRadioItem pos, item.commandId, item.label, item.groupId
@setSublabel pos, item.sublabel if item.sublabel?
@setIcon pos, item.icon if item.icon?
# Make menu accessable to items.
item.overrideReadOnlyProperty 'menu', this

View File

@@ -7,9 +7,10 @@
#include "atom/browser/atom_access_token_store.h"
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/atom_resource_dispatcher_host_delegate.h"
#include "atom/browser/atom_speech_recognition_manager_delegate.h"
#include "atom/browser/native_window.h"
#include "atom/browser/web_view/web_view_renderer_state.h"
#include "atom/browser/web_view_manager.h"
#include "atom/browser/window_list.h"
#include "atom/common/options_switches.h"
#include "base/command_line.h"
@@ -18,6 +19,7 @@
#include "chrome/browser/speech/tts_message_filter.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"
@@ -61,7 +63,7 @@ void AtomBrowserClient::RenderProcessWillLaunch(
}
content::SpeechRecognitionManagerDelegate*
AtomBrowserClient::GetSpeechRecognitionManagerDelegate() {
AtomBrowserClient::CreateSpeechRecognitionManagerDelegate() {
return new AtomSpeechRecognitionManagerDelegate;
}
@@ -69,6 +71,12 @@ 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,
const GURL& url,
@@ -97,16 +105,15 @@ void AtomBrowserClient::OverrideWebkitPrefs(
}
// Custom preferences of guest page.
int guest_process_id = render_view_host->GetProcess()->GetID();
WebViewRendererState::WebViewInfo info;
if (WebViewRendererState::GetInstance()->GetInfo(guest_process_id, &info)) {
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::FromRenderView(
render_view_host->GetProcess()->GetID(),
render_view_host->GetRoutingID());
process->GetID(), render_view_host->GetRoutingID());
if (window)
window->OverrideWebkitPrefs(url, prefs);
}
@@ -154,8 +161,9 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches(
window->AppendExtraCommandLineSwitches(command_line, child_process_id);
} else {
// Append commnad line arguments for guest web view.
WebViewRendererState::WebViewInfo info;
if (WebViewRendererState::GetInstance()->GetInfo(child_process_id, &info)) {
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));

View File

@@ -11,6 +11,8 @@
namespace atom {
class AtomResourceDispatcherHostDelegate;
class AtomBrowserClient : public brightray::BrowserClient {
public:
AtomBrowserClient();
@@ -20,8 +22,9 @@ class AtomBrowserClient : public brightray::BrowserClient {
// content::ContentBrowserClient:
void RenderProcessWillLaunch(content::RenderProcessHost* host) override;
content::SpeechRecognitionManagerDelegate*
GetSpeechRecognitionManagerDelegate() override;
CreateSpeechRecognitionManagerDelegate() override;
content::AccessTokenStore* CreateAccessTokenStore() override;
void ResourceDispatcherHostCreated() override;
void OverrideWebkitPrefs(content::RenderViewHost* render_view_host,
const GURL& url,
content::WebPreferences* prefs) override;
@@ -37,6 +40,8 @@ class AtomBrowserClient : public brightray::BrowserClient {
brightray::BrowserMainParts* OverrideCreateBrowserMainParts(
const content::MainFunctionParams&) override;
scoped_ptr<AtomResourceDispatcherHostDelegate> resource_dispatcher_delegate_;
// The render process which would be swapped out soon.
content::RenderProcessHost* dying_render_process_;

View File

@@ -7,7 +7,7 @@
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/net/atom_url_request_job_factory.h"
#include "atom/browser/net/asar/asar_protocol_handler.h"
#include "atom/browser/web_view/web_view_manager.h"
#include "atom/browser/web_view_manager.h"
#include "atom/common/options_switches.h"
#include "base/command_line.h"
#include "base/threading/sequenced_worker_pool.h"

View File

@@ -93,7 +93,7 @@ void AtomBrowserMainParts::PreMainMessageLoopRun() {
brightray::BrowserMainParts::PreMainMessageLoopRun();
#if defined(USE_X11)
libgtk2ui::GtkInitFromCommandLine(*CommandLine::ForCurrentProcess());
libgtk2ui::GtkInitFromCommandLine(*base::CommandLine::ForCurrentProcess());
#endif
#if !defined(OS_MACOSX)

View File

@@ -0,0 +1,33 @@
// 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

@@ -0,0 +1,30 @@
// 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

@@ -28,7 +28,9 @@ Browser* Browser::Get() {
}
void Browser::Quit() {
is_quiting_ = true;
is_quiting_ = HandleBeforeQuit();
if (!is_quiting_)
return;
atom::WindowList* window_list = atom::WindowList::GetInstance();
if (window_list->size() == 0)
@@ -114,6 +116,15 @@ void Browser::NotifyAndShutdown() {
Shutdown();
}
bool Browser::HandleBeforeQuit() {
bool prevent_default = false;
FOR_EACH_OBSERVER(BrowserObserver,
observers_,
OnBeforeQuit(&prevent_default));
return !prevent_default;
}
void Browser::OnWindowCloseCancelled(NativeWindow* window) {
if (is_quiting_)
// Once a beforeunload handler has prevented the closing, we think the quit

View File

@@ -136,6 +136,9 @@ class Browser : public WindowListObserver {
// Send the will-quit message and then shutdown the application.
void NotifyAndShutdown();
// Send the before-quit message and start closing windows.
bool HandleBeforeQuit();
bool is_quiting_;
private:

View File

@@ -11,6 +11,9 @@ namespace atom {
class BrowserObserver {
public:
// The browser is about to close all windows.
virtual void OnBeforeQuit(bool* prevent_default) {}
// The browser has closed all windows and will quit.
virtual void OnWillQuit(bool* prevent_default) {}

View File

@@ -53,7 +53,7 @@ if (option.file && !option.webdriver) {
dialog.showErrorBox('Error opening app', 'The app provided is not a valid atom-shell app, please read the docs on how to write one:\nhttps://github.com/atom/atom-shell/tree/master/docs');
process.exit(1);
} else {
console.error('App throwed an error when running', e);
console.error('App threw an error when running', e);
throw e;
}
}

View File

@@ -74,7 +74,7 @@ app.once 'ready', ->
return new protocol.RequestFileJob(path.join(directory, parsed.path))
BrowserWindow::_loadDevToolsExtensions = (extensionInfoArray) ->
@devToolsWebContents?.executeJavaScript "WebInspector.addExtensions(#{JSON.stringify(extensionInfoArray)});"
@devToolsWebContents?.executeJavaScript "DevToolsAPI.addExtensions(#{JSON.stringify(extensionInfoArray)});"
BrowserWindow.addDevToolsExtension = (srcDirectory) ->
extensionInfo = getExtensionInfoFromPath srcDirectory

View File

@@ -39,7 +39,7 @@ createGuest = (embedder, params) ->
# Destroy guest when the embedder is gone or navigated.
destroyEvents = ['destroyed', 'crashed', 'did-navigate-to-different-page']
destroy = ->
destroyGuest id if guestInstances[id]?
destroyGuest embedder, id if guestInstances[id]?
embedder.once event, destroy for event in destroyEvents
guest.once 'destroyed', ->
embedder.removeListener event, destroy for event in destroyEvents
@@ -90,7 +90,7 @@ attachGuest = (embedder, elementInstanceId, guestInstanceId, params) ->
return unless oldGuestInstanceId != guestInstanceId
return unless guestInstances[oldGuestInstanceId]?
destroyGuest oldGuestInstanceId
destroyGuest embedder, oldGuestInstanceId
webViewManager.addGuest guestInstanceId, elementInstanceId, embedder, guest,
nodeIntegration: params.nodeintegration
@@ -103,8 +103,8 @@ attachGuest = (embedder, elementInstanceId, guestInstanceId, params) ->
reverseEmbedderElementsMap[guestInstanceId] = key
# Destroy an existing guest instance.
destroyGuest = (id) ->
webViewManager.removeGuest id
destroyGuest = (embedder, id) ->
webViewManager.removeGuest embedder, id
guestInstances[id].guest.destroy()
delete guestInstances[id]
@@ -120,7 +120,7 @@ ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_ATTACH_GUEST', (event, elementInstanceId,
attachGuest event.sender, elementInstanceId, guestInstanceId, params
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_DESTROY_GUEST', (event, id) ->
destroyGuest 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

View File

@@ -1,4 +1,5 @@
ipc = require 'ipc'
v8Util = process.atomBinding 'v8_util'
BrowserWindow = require 'browser-window'
frameToGuest = {}
@@ -13,13 +14,18 @@ createGuest = (embedder, url, frameName, options) ->
guest = new BrowserWindow(options)
guest.loadUrl url
# Remember the embedder, will be used by window.opener methods.
v8Util.setHiddenValue guest.webContents, 'embedder', embedder
# When |embedder| is destroyed we should also destroy attached guest, and if
# 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()
closedByUser = ->
embedder.send 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_CLOSED', guest.id
embedder.removeListener 'render-view-deleted', closedByEmbedder
embedder.once 'render-view-deleted', closedByEmbedder
guest.once 'closed', closedByUser
@@ -49,6 +55,17 @@ ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_METHOD', (event, guestId, method,
return unless BrowserWindow.windows.has guestId
BrowserWindow.windows.get(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.send 'ATOM_SHELL_GUEST_WINDOW_POSTMESSAGE', message, targetOrigin
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPENER_POSTMESSAGE', (event, message, targetOrigin) ->
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
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...

View File

@@ -3,10 +3,6 @@ path = require 'path'
module = require 'module'
util = require 'util'
# Expose information of current process.
process.type = 'browser'
process.resourcesPath = path.resolve process.argv[1], '..', '..', '..', '..'
# We modified the original process.argv to let node.js load the atom.js,
# we need to restore it here.
process.argv.splice 1, 1
@@ -21,7 +17,7 @@ process.argv.splice startMark, endMark - startMark + 1
# Add browser/api/lib to require's search paths,
# which contains javascript part of Atom's built-in libraries.
globalPaths = module.globalPaths
globalPaths.push path.join process.resourcesPath, 'atom', 'browser', 'api', 'lib'
globalPaths.push path.resolve(__dirname, '..', 'api', 'lib')
# Import common settings.
require path.resolve(__dirname, '..', '..', 'common', 'lib', 'init')

View File

@@ -52,10 +52,10 @@
#include "native_mate/dictionary.h"
#include "ui/gfx/codec/png_codec.h"
#include "ui/gfx/geometry/size_conversions.h"
#include "ui/gfx/point.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/screen.h"
#include "ui/gfx/size.h"
#include "ui/gfx/geometry/size.h"
#if defined(OS_WIN)
#include "ui/gfx/switches.h"
@@ -77,7 +77,6 @@ namespace {
const char* kWebRuntimeFeatures[] = {
switches::kExperimentalFeatures,
switches::kExperimentalCanvasFeatures,
switches::kSubpixelFontScaling,
switches::kOverlayScrollbars,
switches::kOverlayFullscreenVideo,
switches::kSharedWorker,
@@ -515,6 +514,7 @@ void NativeWindow::NotifyWindowLeaveFullScreen() {
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,
@@ -568,7 +568,8 @@ content::WebContents* NativeWindow::OpenURLFromTab(
return source;
}
content::JavaScriptDialogManager* NativeWindow::GetJavaScriptDialogManager() {
content::JavaScriptDialogManager* NativeWindow::GetJavaScriptDialogManager(
content::WebContents* source) {
if (!dialog_manager_)
dialog_manager_.reset(new AtomJavaScriptDialogManager);
@@ -730,7 +731,7 @@ void NativeWindow::DevToolsSaveToFile(const std::string& url,
base::FilePath default_path(base::FilePath::FromUTF8Unsafe(url));
if (!file_dialog::ShowSaveDialog(this, url, default_path, filters, &path)) {
base::StringValue url_value(url);
CallDevToolsFunction("InspectorFrontendAPI.canceledSaveURL", &url_value);
CallDevToolsFunction("DevToolsAPI.canceledSaveURL", &url_value);
return;
}
}
@@ -740,7 +741,7 @@ void NativeWindow::DevToolsSaveToFile(const std::string& url,
// Notify devtools.
base::StringValue url_value(url);
CallDevToolsFunction("InspectorFrontendAPI.savedURL", &url_value);
CallDevToolsFunction("DevToolsAPI.savedURL", &url_value);
}
void NativeWindow::DevToolsAppendToFile(const std::string& url,
@@ -752,7 +753,7 @@ void NativeWindow::DevToolsAppendToFile(const std::string& url,
// Notify devtools.
base::StringValue url_value(url);
CallDevToolsFunction("InspectorFrontendAPI.appendedToURL", &url_value);
CallDevToolsFunction("DevToolsAPI.appendedToURL", &url_value);
}
void NativeWindow::ScheduleUnresponsiveEvent(int ms) {
@@ -778,11 +779,11 @@ void NativeWindow::NotifyWindowUnresponsive() {
}
void NativeWindow::OnCapturePageDone(const CapturePageCallback& callback,
bool succeed,
const SkBitmap& bitmap) {
const SkBitmap& bitmap,
content::ReadbackResponse response) {
SkAutoLockPixels screen_capture_lock(bitmap);
std::vector<unsigned char> data;
if (succeed)
if (response == content::READBACK_SUCCESS)
gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, true, &data);
callback.Run(data);
}

View File

@@ -20,8 +20,9 @@
#include "brightray/browser/inspectable_web_contents_impl.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/readback_types.h"
#include "native_mate/persistent_dictionary.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/image/image.h"
namespace base {
class CommandLine;
@@ -142,6 +143,8 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
virtual bool HasModalDialog();
virtual gfx::NativeWindow GetNativeWindow() = 0;
virtual void SetProgressBar(double progress) = 0;
virtual void SetOverlayIcon(const gfx::Image& overlay,
const std::string& description) = 0;
virtual bool IsClosed() const { return is_closed_; }
virtual void OpenDevTools();
@@ -233,6 +236,7 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
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,
@@ -241,7 +245,8 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
content::WebContents* OpenURLFromTab(
content::WebContents* source,
const content::OpenURLParams& params) override;
content::JavaScriptDialogManager* GetJavaScriptDialogManager() override;
content::JavaScriptDialogManager* GetJavaScriptDialogManager(
content::WebContents* source) override;
void BeforeUnloadFired(content::WebContents* tab,
bool proceed,
bool* proceed_to_fire_unload) override;
@@ -312,8 +317,8 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
// Called when CapturePage has done.
void OnCapturePageDone(const CapturePageCallback& callback,
bool succeed,
const SkBitmap& bitmap);
const SkBitmap& bitmap,
content::ReadbackResponse response);
// Notification manager.
content::NotificationRegistrar registrar_;

View File

@@ -71,6 +71,8 @@ class NativeWindowMac : public NativeWindow {
bool HasModalDialog() override;
gfx::NativeWindow GetNativeWindow() override;
void SetProgressBar(double progress) override;
void SetOverlayIcon(const gfx::Image& overlay,
const std::string& description) override;
void ShowDefinitionForSelection() override;
// Returns true if |point| in local Cocoa coordinate system falls within

View File

@@ -678,6 +678,10 @@ void NativeWindowMac::SetProgressBar(double progress) {
[dock_tile display];
}
void NativeWindowMac::SetOverlayIcon(const gfx::Image& overlay,
const std::string& description) {
}
void NativeWindowMac::ShowDefinitionForSelection() {
content::WebContents* web_contents = GetWebContents();
if (!web_contents)

View File

@@ -22,6 +22,7 @@
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/hit_test.h"
#include "ui/gfx/image/image.h"
#include "ui/views/background.h"
#include "ui/views/controls/webview/unhandled_keyboard_event_handler.h"
#include "ui/views/controls/webview/webview.h"
@@ -51,6 +52,7 @@
#include "base/win/scoped_comptr.h"
#include "base/win/windows_version.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"
#endif
@@ -223,6 +225,11 @@ NativeWindowViews::NativeWindowViews(content::WebContents* web_contents,
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))
SetWindowType(GetAcceleratedWidget(), window_type);
#endif
// Add web view.
@@ -613,6 +620,28 @@ void NativeWindowViews::SetProgressBar(double progress) {
#endif
}
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());
#endif
}
void NativeWindowViews::SetAutoHideMenuBar(bool auto_hide) {
menu_bar_autohide_ = auto_hide;
}

View File

@@ -73,6 +73,8 @@ class NativeWindowViews : public NativeWindow,
bool IsKiosk() override;
void SetMenu(ui::MenuModel* menu_model) override;
gfx::NativeWindow GetNativeWindow() override;
void SetOverlayIcon(const gfx::Image& overlay,
const std::string& description) override;
void SetProgressBar(double value) override;
void SetAutoHideMenuBar(bool auto_hide) override;
bool IsMenuBarAutoHide() override;

View File

@@ -6,6 +6,8 @@
#include "base/threading/sequenced_worker_pool.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"
@@ -88,13 +90,31 @@ void AdapterRequestJob::CreateStringJobAndStart(const std::string& mime_type,
void AdapterRequestJob::CreateFileJobAndStart(const base::FilePath& path) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
real_job_ = new net::URLRequestFileJob(
request(),
network_delegate(),
path,
content::BrowserThread::GetBlockingPool()->
GetTaskRunnerWithShutdownBehavior(
base::SequencedWorkerPool::SKIP_ON_SHUTDOWN));
base::FilePath asar_path, relative_path;
if (!asar::GetAsarArchivePath(path, &asar_path, &relative_path)) {
real_job_ = new net::URLRequestFileJob(
request(),
network_delegate(),
path,
content::BrowserThread::GetBlockingPool()->
GetTaskRunnerWithShutdownBehavior(
base::SequencedWorkerPool::SKIP_ON_SHUTDOWN));
} else {
auto archive = asar::GetOrCreateAsarArchive(asar_path);
if (archive)
real_job_ = new asar::URLRequestAsarJob(
request(),
network_delegate(),
archive,
relative_path,
content::BrowserThread::GetBlockingPool()->
GetTaskRunnerWithShutdownBehavior(
base::SequencedWorkerPool::SKIP_ON_SHUTDOWN));
else
real_job_ = new net::URLRequestErrorJob(
request(), network_delegate(), net::ERR_FILE_NOT_FOUND);
}
real_job_->Start();
}

View File

@@ -6,6 +6,7 @@
#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"
@@ -13,35 +14,6 @@
namespace asar {
namespace {
const base::FilePath::CharType kAsarExtension[] = FILE_PATH_LITERAL(".asar");
// Get the relative path in asar archive.
bool GetAsarPath(const base::FilePath& full_path,
base::FilePath* asar_path,
base::FilePath* relative_path) {
base::FilePath iter = full_path;
while (true) {
base::FilePath dirname = iter.DirName();
if (iter.MatchesExtension(kAsarExtension))
break;
else if (iter == dirname)
return false;
iter = dirname;
}
base::FilePath tail;
if (!iter.AppendRelativePath(full_path, &tail))
return false;
*asar_path = iter;
*relative_path = tail;
return true;
}
} // namespace
AsarProtocolHandler::AsarProtocolHandler(
const scoped_refptr<base::TaskRunner>& file_task_runner)
: file_task_runner_(file_task_runner) {}
@@ -49,19 +21,6 @@ AsarProtocolHandler::AsarProtocolHandler(
AsarProtocolHandler::~AsarProtocolHandler() {
}
Archive* AsarProtocolHandler::GetOrCreateAsarArchive(
const base::FilePath& path) const {
if (!archives_.contains(path)) {
scoped_ptr<Archive> archive(new Archive(path));
if (!archive->Init())
return nullptr;
archives_.set(path, archive.Pass());
}
return archives_.get(path);
}
net::URLRequestJob* AsarProtocolHandler::MaybeCreateJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate) const {
@@ -71,11 +30,11 @@ net::URLRequestJob* AsarProtocolHandler::MaybeCreateJob(
// Create asar:// job when the path contains "xxx.asar/", otherwise treat the
// URL request as file://.
base::FilePath asar_path, relative_path;
if (!GetAsarPath(full_path, &asar_path, &relative_path))
if (!GetAsarArchivePath(full_path, &asar_path, &relative_path))
return new net::URLRequestFileJob(request, network_delegate, full_path,
file_task_runner_);
Archive* archive = GetOrCreateAsarArchive(asar_path);
std::shared_ptr<Archive> archive = GetOrCreateAsarArchive(asar_path);
if (!archive)
return new net::URLRequestErrorJob(request, network_delegate,
net::ERR_FILE_NOT_FOUND);

View File

@@ -5,8 +5,6 @@
#ifndef ATOM_BROWSER_NET_ASAR_ASAR_PROTOCOL_HANDLER_H_
#define ATOM_BROWSER_NET_ASAR_ASAR_PROTOCOL_HANDLER_H_
#include "base/containers/scoped_ptr_hash_map.h"
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
#include "net/url_request/url_request_job_factory.h"
@@ -16,16 +14,12 @@ class TaskRunner;
namespace asar {
class Archive;
class AsarProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler {
public:
explicit AsarProtocolHandler(
const scoped_refptr<base::TaskRunner>& file_task_runner);
virtual ~AsarProtocolHandler();
Archive* GetOrCreateAsarArchive(const base::FilePath& path) const;
// net::URLRequestJobFactory::ProtocolHandler:
net::URLRequestJob* MaybeCreateJob(
net::URLRequest* request,
@@ -35,8 +29,6 @@ class AsarProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler {
private:
const scoped_refptr<base::TaskRunner> file_task_runner_;
mutable base::ScopedPtrHashMap<base::FilePath, Archive> archives_;
DISALLOW_COPY_AND_ASSIGN(AsarProtocolHandler);
};

View File

@@ -17,7 +17,7 @@ namespace asar {
URLRequestAsarJob::URLRequestAsarJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate,
Archive* archive,
std::shared_ptr<Archive> archive,
const base::FilePath& file_path,
const scoped_refptr<base::TaskRunner>& file_task_runner)
: net::URLRequestJob(request, network_delegate),

View File

@@ -5,6 +5,7 @@
#ifndef ATOM_BROWSER_NET_ASAR_URL_REQUEST_ASAR_JOB_H_
#define ATOM_BROWSER_NET_ASAR_URL_REQUEST_ASAR_JOB_H_
#include <memory>
#include <string>
#include "atom/common/asar/archive.h"
@@ -27,7 +28,7 @@ class URLRequestAsarJob : public net::URLRequestJob {
public:
URLRequestAsarJob(net::URLRequest* request,
net::NetworkDelegate* network_delegate,
Archive* archive,
std::shared_ptr<Archive> archive,
const base::FilePath& file_path,
const scoped_refptr<base::TaskRunner>& file_task_runner);
@@ -53,7 +54,7 @@ class URLRequestAsarJob : public net::URLRequestJob {
// Callback after data is asynchronously read from the file into |buf|.
void DidRead(scoped_refptr<net::IOBuffer> buf, int result);
Archive* archive_;
std::shared_ptr<Archive> archive_;
Archive::FileInfo file_info_;
base::FilePath file_path_;

View File

@@ -17,7 +17,7 @@
<key>CFBundleIconFile</key>
<string>atom.icns</string>
<key>CFBundleVersion</key>
<string>0.21.1</string>
<string>0.22.1</string>
<key>LSMinimumSystemVersion</key>
<string>10.8.0</string>
<key>NSMainNibFile</key>

View File

@@ -7,7 +7,7 @@
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
#include "windows.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
@@ -31,7 +31,7 @@ END
2 TEXTINCLUDE
BEGIN
"#include ""afxres.h""\r\n"
"#include ""windows.h""\r\n"
"\0"
END
@@ -50,8 +50,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,21,1,0
PRODUCTVERSION 0,21,1,0
FILEVERSION 0,22,1,0
PRODUCTVERSION 0,22,1,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -68,12 +68,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "GitHub, Inc."
VALUE "FileDescription", "Atom-Shell"
VALUE "FileVersion", "0.21.1"
VALUE "FileVersion", "0.22.1"
VALUE "InternalName", "atom.exe"
VALUE "LegalCopyright", "Copyright (C) 2013 GitHub, Inc. All rights reserved."
VALUE "OriginalFilename", "atom.exe"
VALUE "ProductName", "Atom-Shell"
VALUE "ProductVersion", "0.21.1"
VALUE "ProductVersion", "0.22.1"
VALUE "SquirrelAwareVersion", "1"
END
END

View File

@@ -9,6 +9,7 @@
#include "atom/browser/native_window.h"
#include "base/files/file_util.h"
#include "base/mac/foundation_util.h"
#include "base/mac/mac_util.h"
#include "base/mac/scoped_cftyperef.h"
#include "base/strings/sys_string_conversions.h"

View File

@@ -54,13 +54,11 @@ TrayIconCocoa::~TrayIconCocoa() {
}
void TrayIconCocoa::SetImage(const gfx::Image& image) {
if (!image.IsEmpty())
[item_ setImage:image.ToNSImage()];
[item_ setImage:image.AsNSImage()];
}
void TrayIconCocoa::SetPressedImage(const gfx::Image& image) {
if (!image.IsEmpty())
[item_ setAlternateImage:image.ToNSImage()];
[item_ setAlternateImage:image.AsNSImage()];
}
void TrayIconCocoa::SetToolTip(const std::string& tool_tip) {

View File

@@ -11,8 +11,8 @@
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/icon_util.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/point.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/views/controls/menu/menu_runner.h"
namespace atom {

View File

@@ -4,6 +4,9 @@
#include "atom/browser/ui/x/x_window_utils.h"
#include <X11/Xatom.h>
#include "base/strings/string_util.h"
#include "ui/base/x/x11_util.h"
namespace atom {
@@ -31,4 +34,16 @@ void SetWMSpecState(::Window xwindow, bool enabled, ::Atom state) {
&xclient);
}
void SetWindowType(::Window xwindow, const std::string& type) {
XDisplay* xdisplay = gfx::GetXDisplay();
std::string type_prefix = "_NET_WM_WINDOW_TYPE_";
::Atom window_type = XInternAtom(
xdisplay, (type_prefix + StringToUpperASCII(type)).c_str(), False);
XChangeProperty(xdisplay, xwindow,
XInternAtom(xdisplay, "_NET_WM_WINDOW_TYPE", False),
XA_ATOM,
32, PropModeReplace,
reinterpret_cast<unsigned char*>(&window_type), 1);
}
} // namespace atom

View File

@@ -9,6 +9,8 @@
#include <X11/extensions/Xrandr.h>
#include <X11/Xlib.h>
#include <string>
namespace atom {
::Atom GetAtom(const char* name);
@@ -17,6 +19,9 @@ namespace atom {
// for _NET_WM_STATE.
void SetWMSpecState(::Window xwindow, bool enabled, ::Atom state);
// Sets the _NET_WM_WINDOW_TYPE of window.
void SetWindowType(::Window xwindow, const std::string& type);
} // namespace atom
#endif // ATOM_BROWSER_UI_X_X_WINDOW_UTILS_H_

View File

@@ -1,154 +0,0 @@
// Copyright (c) 2014 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/web_view/web_view_manager.h"
#include "atom/browser/api/atom_api_web_contents.h"
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/web_view/web_view_renderer_state.h"
#include "atom/common/native_mate_converters/gurl_converter.h"
#include "base/bind.h"
#include "base/stl_util.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "native_mate/dictionary.h"
#include "native_mate/object_template_builder.h"
#include "net/base/filename_util.h"
#include "atom/common/node_includes.h"
namespace mate {
template<>
struct Converter<content::WebContents*> {
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
content::WebContents** out) {
atom::api::WebContents* contents;
if (!Converter<atom::api::WebContents*>::FromV8(isolate, val, &contents))
return false;
*out = contents->web_contents();
return true;
}
};
template<>
struct Converter<atom::WebViewManager::WebViewOptions> {
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
atom::WebViewManager::WebViewOptions* out) {
Dictionary options;
if (!ConvertFromV8(isolate, val, &options))
return false;
return options.Get("nodeIntegration", &(out->node_integration)) &&
options.Get("plugins", &(out->plugins)) &&
options.Get("preloadUrl", &(out->preload_url)) &&
options.Get("disableWebSecurity", &(out->disable_web_security));
}
};
} // namespace mate
namespace atom {
WebViewManager::WebViewManager(content::BrowserContext* context) {
}
WebViewManager::~WebViewManager() {
}
void WebViewManager::AddGuest(int guest_instance_id,
int element_instance_id,
content::WebContents* embedder,
content::WebContents* web_contents,
const WebViewOptions& options) {
web_contents_map_[guest_instance_id] = { web_contents, embedder };
WebViewRendererState::WebViewInfo web_view_info = {
guest_instance_id,
embedder,
options.node_integration,
options.plugins,
options.disable_web_security,
};
net::FileURLToFilePath(options.preload_url, &web_view_info.preload_script);
content::BrowserThread::PostTask(
content::BrowserThread::IO,
FROM_HERE,
base::Bind(&WebViewRendererState::AddGuest,
base::Unretained(WebViewRendererState::GetInstance()),
web_contents->GetRenderProcessHost()->GetID(),
web_view_info));
// Map the element in embedder to guest.
ElementInstanceKey key(embedder, element_instance_id);
element_instance_id_to_guest_map_[key] = guest_instance_id;
}
void WebViewManager::RemoveGuest(int guest_instance_id) {
if (!ContainsKey(web_contents_map_, guest_instance_id)) {
return;
}
auto web_contents = web_contents_map_[guest_instance_id].web_contents;
content::BrowserThread::PostTask(
content::BrowserThread::IO, FROM_HERE,
base::Bind(
&WebViewRendererState::RemoveGuest,
base::Unretained(WebViewRendererState::GetInstance()),
web_contents->GetRenderProcessHost()->GetID()));
web_contents_map_.erase(guest_instance_id);
// Remove the record of element in embedder too.
for (const auto& element : element_instance_id_to_guest_map_)
if (element.second == guest_instance_id) {
element_instance_id_to_guest_map_.erase(element.first);
break;
}
}
content::WebContents* WebViewManager::GetGuestByInstanceID(
content::WebContents* embedder,
int element_instance_id) {
ElementInstanceKey key(embedder, element_instance_id);
if (!ContainsKey(element_instance_id_to_guest_map_, key))
return nullptr;
int guest_instance_id = element_instance_id_to_guest_map_[key];
if (ContainsKey(web_contents_map_, guest_instance_id))
return web_contents_map_[guest_instance_id].web_contents;
else
return nullptr;
}
bool WebViewManager::ForEachGuest(content::WebContents* embedder_web_contents,
const GuestCallback& callback) {
for (auto& item : web_contents_map_)
if (item.second.embedder == embedder_web_contents &&
callback.Run(item.second.web_contents))
return true;
return false;
}
} // namespace atom
namespace {
void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
v8::Handle<v8::Context> context, void* priv) {
using atom::WebViewManager;
auto manager = static_cast<WebViewManager*>(
atom::AtomBrowserContext::Get()->GetGuestManager());
mate::Dictionary dict(context->GetIsolate(), exports);
dict.SetMethod("addGuest",
base::Bind(&WebViewManager::AddGuest,
base::Unretained(manager)));
dict.SetMethod("removeGuest",
base::Bind(&WebViewManager::RemoveGuest,
base::Unretained(manager)));
}
} // namespace
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_web_view_manager, Initialize)

View File

@@ -1,46 +0,0 @@
// Copyright (c) 2014 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/web_view/web_view_renderer_state.h"
#include "content/public/browser/browser_thread.h"
namespace atom {
// static
WebViewRendererState* WebViewRendererState::GetInstance() {
return Singleton<WebViewRendererState>::get();
}
WebViewRendererState::WebViewRendererState() {
}
WebViewRendererState::~WebViewRendererState() {
}
bool WebViewRendererState::IsGuest(int render_process_id) {
return webview_info_map_.find(render_process_id) !=
webview_info_map_.end();
}
void WebViewRendererState::AddGuest(int guest_process_id,
const WebViewInfo& webview_info) {
webview_info_map_[guest_process_id] = webview_info;
}
void WebViewRendererState::RemoveGuest(int guest_process_id) {
webview_info_map_.erase(guest_process_id);
}
bool WebViewRendererState::GetInfo(int guest_process_id,
WebViewInfo* webview_info) {
WebViewInfoMap::iterator iter = webview_info_map_.find(guest_process_id);
if (iter != webview_info_map_.end()) {
*webview_info = iter->second;
return true;
}
return false;
}
} // namespace atom

View File

@@ -1,65 +0,0 @@
// Copyright (c) 2014 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_WEB_VIEW_WEB_VIEW_RENDERER_STATE_H_
#define ATOM_BROWSER_WEB_VIEW_WEB_VIEW_RENDERER_STATE_H_
#include <map>
#include <string>
#include <utility>
#include "base/files/file_path.h"
#include "base/memory/singleton.h"
namespace content {
class WebContents;
}
namespace atom {
class WebViewManager;
// This class keeps track of <webview> renderer state for use on the IO thread.
// All methods should be called on the IO thread.
class WebViewRendererState {
public:
struct WebViewInfo {
int guest_instance_id;
content::WebContents* embedder;
bool node_integration;
bool plugins;
bool disable_web_security;
base::FilePath preload_script;
};
static WebViewRendererState* GetInstance();
// Looks up the information for the embedder <webview> for a given render
// view, if one exists. Called on the IO thread.
bool GetInfo(int guest_process_id, WebViewInfo* webview_info);
// Returns true if the given renderer is used by webviews.
bool IsGuest(int render_process_id);
private:
friend class WebViewManager;
friend struct DefaultSingletonTraits<WebViewRendererState>;
typedef std::map<int, WebViewInfo> WebViewInfoMap;
WebViewRendererState();
~WebViewRendererState();
// Adds or removes a <webview> guest render process from the set.
void AddGuest(int render_process_id, const WebViewInfo& webview_info);
void RemoveGuest(int render_process_id);
WebViewInfoMap webview_info_map_;
DISALLOW_COPY_AND_ASSIGN(WebViewRendererState);
};
} // namespace atom
#endif // ATOM_BROWSER_WEB_VIEW_WEB_VIEW_RENDERER_STATE_H_

View File

@@ -0,0 +1,101 @@
// Copyright (c) 2014 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/web_view_manager.h"
#include "atom/browser/atom_browser_context.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
namespace atom {
// static
bool WebViewManager::GetInfoForProcess(content::RenderProcessHost* process,
WebViewInfo* info) {
if (!process)
return false;
auto context = process->GetBrowserContext();
if (!context)
return false;
auto manager = context->GetGuestManager();
if (!manager)
return false;
return static_cast<WebViewManager*>(manager)->GetInfo(process->GetID(), info);
}
WebViewManager::WebViewManager(content::BrowserContext* context) {
}
WebViewManager::~WebViewManager() {
}
void WebViewManager::AddGuest(int guest_instance_id,
int element_instance_id,
content::WebContents* embedder,
content::WebContents* web_contents,
const WebViewInfo& info) {
base::AutoLock auto_lock(lock_);
web_contents_embdder_map_[guest_instance_id] = { web_contents, embedder };
int guest_process_id = web_contents->GetRenderProcessHost()->GetID();
webview_info_map_[guest_process_id] = info;
// Map the element in embedder to guest.
ElementInstanceKey key(embedder, element_instance_id);
element_instance_id_to_guest_map_[key] = guest_instance_id;
}
void WebViewManager::RemoveGuest(int guest_instance_id) {
base::AutoLock auto_lock(lock_);
if (!ContainsKey(web_contents_embdder_map_, guest_instance_id))
return;
auto web_contents = web_contents_embdder_map_[guest_instance_id].web_contents;
web_contents_embdder_map_.erase(guest_instance_id);
int guest_process_id = web_contents->GetRenderProcessHost()->GetID();
webview_info_map_.erase(guest_process_id);
// Remove the record of element in embedder too.
for (const auto& element : element_instance_id_to_guest_map_)
if (element.second == guest_instance_id) {
element_instance_id_to_guest_map_.erase(element.first);
break;
}
}
bool WebViewManager::GetInfo(int guest_process_id, WebViewInfo* webview_info) {
base::AutoLock auto_lock(lock_);
WebViewInfoMap::iterator iter = webview_info_map_.find(guest_process_id);
if (iter != webview_info_map_.end()) {
*webview_info = iter->second;
return true;
}
return false;
}
content::WebContents* WebViewManager::GetGuestByInstanceID(
content::WebContents* embedder,
int element_instance_id) {
ElementInstanceKey key(embedder, element_instance_id);
if (!ContainsKey(element_instance_id_to_guest_map_, key))
return nullptr;
int guest_instance_id = element_instance_id_to_guest_map_[key];
if (ContainsKey(web_contents_embdder_map_, guest_instance_id))
return web_contents_embdder_map_[guest_instance_id].web_contents;
else
return nullptr;
}
bool WebViewManager::ForEachGuest(content::WebContents* embedder_web_contents,
const GuestCallback& callback) {
for (auto& item : web_contents_embdder_map_)
if (item.second.embedder == embedder_web_contents &&
callback.Run(item.second.web_contents))
return true;
return false;
}
} // namespace atom

View File

@@ -2,39 +2,52 @@
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_WEB_VIEW_WEB_VIEW_MANAGER_H_
#define ATOM_BROWSER_WEB_VIEW_WEB_VIEW_MANAGER_H_
#ifndef ATOM_BROWSER_WEB_VIEW_MANAGER_H_
#define ATOM_BROWSER_WEB_VIEW_MANAGER_H_
#include <map>
#include "base/files/file_path.h"
#include "base/synchronization/lock.h"
#include "content/public/browser/browser_plugin_guest_manager.h"
#include "url/gurl.h"
namespace content {
class BrowserContext;
class RenderProcessHost;
}
namespace atom {
class WebViewManager : public content::BrowserPluginGuestManager {
public:
explicit WebViewManager(content::BrowserContext* context);
virtual ~WebViewManager();
struct WebViewOptions {
struct WebViewInfo {
int guest_instance_id;
content::WebContents* embedder;
bool node_integration;
bool plugins;
bool disable_web_security;
GURL preload_url;
base::FilePath preload_script;
};
// Finds the WebViewManager attached with |process| and returns the
// WebViewInfo of it.
static bool GetInfoForProcess(content::RenderProcessHost* process,
WebViewInfo* info);
explicit WebViewManager(content::BrowserContext* context);
virtual ~WebViewManager();
void AddGuest(int guest_instance_id,
int element_instance_id,
content::WebContents* embedder,
content::WebContents* web_contents,
const WebViewOptions& options);
const WebViewInfo& info);
void RemoveGuest(int guest_instance_id);
// Looks up the information for the embedder <webview> for a given render
// view, if one exists. Called on the IO thread.
bool GetInfo(int guest_process_id, WebViewInfo* webview_info);
protected:
// content::BrowserPluginGuestManager:
content::WebContents* GetGuestByInstanceID(
@@ -45,19 +58,16 @@ class WebViewManager : public content::BrowserPluginGuestManager {
private:
struct WebContentsWithEmbedder {
content::WebContents* web_contents; // Weak ref.
content::WebContents* web_contents;
content::WebContents* embedder;
};
std::map<int, WebContentsWithEmbedder> web_contents_map_;
// guest_instance_id => (web_contents, embedder)
std::map<int, WebContentsWithEmbedder> web_contents_embdder_map_;
struct ElementInstanceKey {
content::WebContents* owner_web_contents;
int element_instance_id;
ElementInstanceKey()
: owner_web_contents(nullptr),
element_instance_id(0) {}
ElementInstanceKey(content::WebContents* owner_web_contents,
int element_instance_id)
: owner_web_contents(owner_web_contents),
@@ -74,11 +84,18 @@ class WebViewManager : public content::BrowserPluginGuestManager {
(element_instance_id == other.element_instance_id);
}
};
// (web_contents, element_instance_id) => guest_instance_id
std::map<ElementInstanceKey, int> element_instance_id_to_guest_map_;
typedef std::map<int, WebViewInfo> WebViewInfoMap;
// guest_process_id => (guest_instance_id, embedder, ...)
WebViewInfoMap webview_info_map_;
base::Lock lock_;
DISALLOW_COPY_AND_ASSIGN(WebViewManager);
};
} // namespace atom
#endif // ATOM_BROWSER_WEB_VIEW_WEB_VIEW_MANAGER_H_
#endif // ATOM_BROWSER_WEB_VIEW_MANAGER_H_

View File

@@ -2,11 +2,15 @@
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include <stddef.h>
#include <vector>
#include "atom_natives.h" // NOLINT: This file is generated with coffee2c.
#include "atom/common/asar/archive.h"
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "native_mate/arguments.h"
#include "native_mate/callback.h"
#include "native_mate/dictionary.h"
#include "native_mate/object_template_builder.h"
#include "native_mate/wrappable.h"
@@ -106,10 +110,33 @@ class Archive : public mate::Wrappable {
DISALLOW_COPY_AND_ASSIGN(Archive);
};
void InitAsarSupport(v8::Isolate* isolate,
v8::Handle<v8::Value> process,
v8::Handle<v8::Value> require) {
// Evaluate asar_init.coffee.
v8::Local<v8::Script> asar_init = v8::Script::Compile(v8::String::NewFromUtf8(
isolate,
node::asar_init_native,
v8::String::kNormalString,
sizeof(node::asar_init_native) -1));
v8::Local<v8::Value> result = asar_init->Run();
// Initialize asar support.
base::Callback<void(v8::Handle<v8::Value>,
v8::Handle<v8::Value>,
std::string)> init;
if (mate::ConvertFromV8(isolate, result, &init)) {
init.Run(process,
require,
std::string(node::asar_native, sizeof(node::asar_native) - 1));
}
}
void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
v8::Handle<v8::Context> context, void* priv) {
mate::Dictionary dict(context->GetIsolate(), exports);
dict.SetMethod("createArchive", &Archive::Create);
dict.SetMethod("initAsarSupport", &InitAsarSupport);
}
} // namespace

View File

@@ -5,10 +5,13 @@
#include <string>
#include <vector>
#include "atom/common/native_mate_converters/image_converter.h"
#include "atom/common/native_mate_converters/string16_converter.h"
#include "native_mate/dictionary.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/clipboard/clipboard.h"
#include "ui/base/clipboard/scoped_clipboard_writer.h"
#include "ui/gfx/image/image.h"
#include "atom/common/node_includes.h"
@@ -16,8 +19,7 @@ namespace mate {
template<>
struct Converter<ui::ClipboardType> {
static bool FromV8(v8::Isolate* isolate,
v8::Handle<v8::Value> val,
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
ui::ClipboardType* out) {
std::string type;
if (!Converter<std::string>::FromV8(isolate, val, &type))
@@ -62,6 +64,11 @@ void WriteText(const base::string16& text, ui::ClipboardType type) {
writer.WriteText(text);
}
gfx::Image ReadImage(ui::ClipboardType type) {
SkBitmap bitmap = ui::Clipboard::GetForCurrentThread()->ReadImage(type);
return gfx::Image::CreateFrom1xBitmap(bitmap);
}
void Clear(ui::ClipboardType type) {
ui::Clipboard::GetForCurrentThread()->Clear(type);
}
@@ -73,6 +80,7 @@ void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
dict.SetMethod("_read", &Read);
dict.SetMethod("_readText", &ReadText);
dict.SetMethod("_writeText", &WriteText);
dict.SetMethod("_readImage", &ReadImage);
dict.SetMethod("_clear", &Clear);
}

View File

@@ -0,0 +1,266 @@
// 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/common/api/atom_api_native_image.h"
#include <string>
#include <vector>
#include "atom/common/asar/asar_util.h"
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "atom/common/native_mate_converters/gfx_converter.h"
#include "atom/common/native_mate_converters/gurl_converter.h"
#include "base/base64.h"
#include "base/strings/string_util.h"
#include "native_mate/dictionary.h"
#include "native_mate/object_template_builder.h"
#include "net/base/data_url.h"
#include "ui/base/layout.h"
#include "ui/gfx/codec/jpeg_codec.h"
#include "ui/gfx/codec/png_codec.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/image/image_util.h"
#include "atom/common/node_includes.h"
namespace atom {
namespace api {
namespace {
struct ScaleFactorPair {
const char* name;
float scale;
};
ScaleFactorPair kScaleFactorPairs[] = {
// The "@2x" is put as first one to make scale matching faster.
{ "@2x" , 2.0f },
{ "@3x" , 3.0f },
{ "@1x" , 1.0f },
{ "@4x" , 4.0f },
{ "@5x" , 5.0f },
{ "@1.25x" , 1.25f },
{ "@1.33x" , 1.33f },
{ "@1.4x" , 1.4f },
{ "@1.5x" , 1.5f },
{ "@1.8x" , 1.8f },
{ "@2.5x" , 2.5f },
};
float GetScaleFactorFromPath(const base::FilePath& path) {
std::string filename(path.BaseName().RemoveExtension().AsUTF8Unsafe());
// We don't try to convert string to float here because it is very very
// expensive.
for (unsigned i = 0; i < arraysize(kScaleFactorPairs); ++i) {
if (EndsWith(filename, kScaleFactorPairs[i].name, true))
return kScaleFactorPairs[i].scale;
}
return 1.0f;
}
bool AddImageSkiaRep(gfx::ImageSkia* image,
const unsigned char* data,
size_t size,
double scale_factor) {
scoped_ptr<SkBitmap> decoded(new SkBitmap());
// Try PNG first.
if (!gfx::PNGCodec::Decode(data, size, decoded.get()))
// Try JPEG.
decoded.reset(gfx::JPEGCodec::Decode(data, size));
if (!decoded)
return false;
image->AddRepresentation(gfx::ImageSkiaRep(*decoded.release(), scale_factor));
return true;
}
bool AddImageSkiaRep(gfx::ImageSkia* image,
const base::FilePath& path,
double scale_factor) {
std::string file_contents;
if (!asar::ReadFileToString(path, &file_contents))
return false;
const unsigned char* data =
reinterpret_cast<const unsigned char*>(file_contents.data());
size_t size = file_contents.size();
return AddImageSkiaRep(image, data, size, scale_factor);
}
bool PopulateImageSkiaRepsFromPath(gfx::ImageSkia* image,
const base::FilePath& path) {
bool succeed = false;
std::string filename(path.BaseName().RemoveExtension().AsUTF8Unsafe());
if (MatchPattern(filename, "*@*x"))
// Don't search for other representations if the DPI has been specified.
return AddImageSkiaRep(image, path, GetScaleFactorFromPath(path));
else
succeed |= AddImageSkiaRep(image, path, 1.0f);
for (const ScaleFactorPair& pair : kScaleFactorPairs)
succeed |= AddImageSkiaRep(image,
path.InsertBeforeExtensionASCII(pair.name),
pair.scale);
return succeed;
}
#if defined(OS_MACOSX)
bool IsTemplateImage(const base::FilePath& path) {
return (MatchPattern(path.value(), "*Template.*") ||
MatchPattern(path.value(), "*Template@*x.*"));
}
#endif
v8::Persistent<v8::ObjectTemplate> template_;
} // namespace
NativeImage::NativeImage() {}
NativeImage::NativeImage(const gfx::Image& image) : image_(image) {}
NativeImage::~NativeImage() {}
mate::ObjectTemplateBuilder NativeImage::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
if (template_.IsEmpty())
template_.Reset(isolate, mate::ObjectTemplateBuilder(isolate)
.SetMethod("toPng", &NativeImage::ToPNG)
.SetMethod("toJpeg", &NativeImage::ToJPEG)
.SetMethod("toDataUrl", &NativeImage::ToDataURL)
.SetMethod("isEmpty", &NativeImage::IsEmpty)
.SetMethod("getSize", &NativeImage::GetSize)
.Build());
return mate::ObjectTemplateBuilder(
isolate, v8::Local<v8::ObjectTemplate>::New(isolate, template_));
}
v8::Handle<v8::Value> NativeImage::ToPNG(v8::Isolate* isolate) {
scoped_refptr<base::RefCountedMemory> png = image_.As1xPNGBytes();
return node::Buffer::New(isolate,
reinterpret_cast<const char*>(png->front()),
png->size());
}
v8::Handle<v8::Value> NativeImage::ToJPEG(v8::Isolate* isolate, int quality) {
std::vector<unsigned char> output;
gfx::JPEG1xEncodedDataFromImage(image_, quality, &output);
return node::Buffer::New(isolate,
reinterpret_cast<const char*>(&output.front()),
output.size());
}
std::string NativeImage::ToDataURL() {
scoped_refptr<base::RefCountedMemory> png = image_.As1xPNGBytes();
std::string data_url;
data_url.insert(data_url.end(), png->front(), png->front() + png->size());
base::Base64Encode(data_url, &data_url);
data_url.insert(0, "data:image/png;base64,");
return data_url;
}
bool NativeImage::IsEmpty() {
return image_.IsEmpty();
}
gfx::Size NativeImage::GetSize() {
return image_.Size();
}
// static
mate::Handle<NativeImage> NativeImage::CreateEmpty(v8::Isolate* isolate) {
return mate::CreateHandle(isolate, new NativeImage);
}
// static
mate::Handle<NativeImage> NativeImage::Create(
v8::Isolate* isolate, const gfx::Image& image) {
return mate::CreateHandle(isolate, new NativeImage(image));
}
// static
mate::Handle<NativeImage> NativeImage::CreateFromPNG(
v8::Isolate* isolate, const char* buffer, size_t length) {
gfx::Image image = gfx::Image::CreateFrom1xPNGBytes(
reinterpret_cast<const unsigned char*>(buffer), length);
return Create(isolate, image);
}
// static
mate::Handle<NativeImage> NativeImage::CreateFromJPEG(
v8::Isolate* isolate, const char* buffer, size_t length) {
gfx::Image image = gfx::ImageFrom1xJPEGEncodedData(
reinterpret_cast<const unsigned char*>(buffer), length);
return Create(isolate, image);
}
// static
mate::Handle<NativeImage> NativeImage::CreateFromPath(
v8::Isolate* isolate, const base::FilePath& path) {
gfx::ImageSkia image_skia;
PopulateImageSkiaRepsFromPath(&image_skia, path);
gfx::Image image(image_skia);
#if defined(OS_MACOSX)
if (IsTemplateImage(path))
MakeTemplateImage(&image);
#endif
return Create(isolate, image);
}
// static
mate::Handle<NativeImage> NativeImage::CreateFromBuffer(
mate::Arguments* args, v8::Handle<v8::Value> buffer) {
double scale_factor = 1.;
args->GetNext(&scale_factor);
gfx::ImageSkia image_skia;
AddImageSkiaRep(&image_skia,
reinterpret_cast<unsigned char*>(node::Buffer::Data(buffer)),
node::Buffer::Length(buffer),
scale_factor);
return Create(args->isolate(), gfx::Image(image_skia));
}
// static
mate::Handle<NativeImage> NativeImage::CreateFromDataURL(
v8::Isolate* isolate, const GURL& url) {
std::string mime_type, charset, data;
if (net::DataURL::Parse(url, &mime_type, &charset, &data)) {
if (mime_type == "image/png")
return CreateFromPNG(isolate, data.c_str(), data.size());
else if (mime_type == "image/jpeg")
return CreateFromJPEG(isolate, data.c_str(), data.size());
}
return CreateEmpty(isolate);
}
} // namespace api
} // namespace atom
namespace {
void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
v8::Handle<v8::Context> context, void* priv) {
mate::Dictionary dict(context->GetIsolate(), exports);
dict.SetMethod("createEmpty", &atom::api::NativeImage::CreateEmpty);
dict.SetMethod("createFromPath", &atom::api::NativeImage::CreateFromPath);
dict.SetMethod("createFromBuffer", &atom::api::NativeImage::CreateFromBuffer);
dict.SetMethod("createFromDataUrl",
&atom::api::NativeImage::CreateFromDataURL);
}
} // namespace
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_common_native_image, 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_COMMON_API_ATOM_API_NATIVE_IMAGE_H_
#define ATOM_COMMON_API_ATOM_API_NATIVE_IMAGE_H_
#include <string>
#include "native_mate/handle.h"
#include "native_mate/wrappable.h"
#include "ui/gfx/image/image.h"
class GURL;
namespace base {
class FilePath;
}
namespace gfx {
class Size;
}
namespace mate {
class Arguments;
}
namespace atom {
namespace api {
class NativeImage : public mate::Wrappable {
public:
static mate::Handle<NativeImage> CreateEmpty(v8::Isolate* isolate);
static mate::Handle<NativeImage> Create(
v8::Isolate* isolate, const gfx::Image& image);
static mate::Handle<NativeImage> CreateFromPNG(
v8::Isolate* isolate, const char* buffer, size_t length);
static mate::Handle<NativeImage> CreateFromJPEG(
v8::Isolate* isolate, const char* buffer, size_t length);
static mate::Handle<NativeImage> CreateFromPath(
v8::Isolate* isolate, const base::FilePath& path);
static mate::Handle<NativeImage> CreateFromBuffer(
mate::Arguments* args, v8::Handle<v8::Value> buffer);
static mate::Handle<NativeImage> CreateFromDataURL(
v8::Isolate* isolate, const GURL& url);
// The default constructor should only be used by image_converter.cc.
NativeImage();
const gfx::Image& image() const { return image_; }
protected:
explicit NativeImage(const gfx::Image& image);
virtual ~NativeImage();
// mate::Wrappable:
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) override;
private:
#if defined(OS_MACOSX)
// Mark the image as template image if possible.
static void MakeTemplateImage(gfx::Image* image);
#endif
v8::Handle<v8::Value> ToPNG(v8::Isolate* isolate);
v8::Handle<v8::Value> ToJPEG(v8::Isolate* isolate, int quality);
std::string ToDataURL();
bool IsEmpty();
gfx::Size GetSize();
gfx::Image image_;
DISALLOW_COPY_AND_ASSIGN(NativeImage);
};
} // namespace api
} // namespace atom
#endif // ATOM_COMMON_API_ATOM_API_NATIVE_IMAGE_H_

View File

@@ -0,0 +1,20 @@
// 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/common/api/atom_api_native_image.h"
#import <Cocoa/Cocoa.h>
namespace atom {
namespace api {
// static
void NativeImage::MakeTemplateImage(gfx::Image* image) {
[image->AsNSImage() setTemplate:YES];
}
} // namespace api
} // namespace atom

View File

@@ -9,4 +9,5 @@ else
read: (format, type='standard') -> binding._read format, type
readText: (type='standard') -> binding._readText type
writeText: (text, type='standard') -> binding._writeText text, type
readImage: (type='standard') -> binding._readImage type
clear: (type='standard') -> binding._clear type

View File

@@ -0,0 +1 @@
module.exports = process.atomBinding 'native_image'

View File

@@ -0,0 +1,83 @@
// 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/common/asar/asar_util.h"
#include <map>
#include <string>
#include "atom/common/asar/archive.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/lazy_instance.h"
#include "base/stl_util.h"
namespace asar {
namespace {
// The global instance of ArchiveMap, will be destroyed on exit.
typedef std::map<base::FilePath, std::shared_ptr<Archive>> ArchiveMap;
static base::LazyInstance<ArchiveMap> g_archive_map = LAZY_INSTANCE_INITIALIZER;
const base::FilePath::CharType kAsarExtension[] = FILE_PATH_LITERAL(".asar");
} // namespace
std::shared_ptr<Archive> GetOrCreateAsarArchive(const base::FilePath& path) {
ArchiveMap& archive_map = *g_archive_map.Pointer();
if (!ContainsKey(archive_map, path)) {
std::shared_ptr<Archive> archive(new Archive(path));
if (!archive->Init())
return nullptr;
archive_map[path] = archive;
}
return archive_map[path];
}
bool GetAsarArchivePath(const base::FilePath& full_path,
base::FilePath* asar_path,
base::FilePath* relative_path) {
base::FilePath iter = full_path;
while (true) {
base::FilePath dirname = iter.DirName();
if (iter.MatchesExtension(kAsarExtension))
break;
else if (iter == dirname)
return false;
iter = dirname;
}
base::FilePath tail;
if (!iter.AppendRelativePath(full_path, &tail))
return false;
*asar_path = iter;
*relative_path = tail;
return true;
}
bool ReadFileToString(const base::FilePath& path, std::string* contents) {
base::FilePath asar_path, relative_path;
if (!GetAsarArchivePath(path, &asar_path, &relative_path))
return base::ReadFileToString(path, contents);
std::shared_ptr<Archive> archive = GetOrCreateAsarArchive(asar_path);
if (!archive)
return false;
Archive::FileInfo info;
if (!archive->GetFileInfo(relative_path, &info))
return false;
base::File src(asar_path, base::File::FLAG_OPEN | base::File::FLAG_READ);
if (!src.IsValid())
return false;
contents->resize(info.size);
return static_cast<int>(info.size) == src.Read(
info.offset, const_cast<char*>(contents->data()), contents->size());
}
} // namespace asar

View File

@@ -0,0 +1,32 @@
// 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_COMMON_ASAR_ASAR_UTIL_H_
#define ATOM_COMMON_ASAR_ASAR_UTIL_H_
#include <memory>
#include <string>
namespace base {
class FilePath;
}
namespace asar {
class Archive;
// Gets or creates a new Archive from the path.
std::shared_ptr<Archive> GetOrCreateAsarArchive(const base::FilePath& path);
// Separates the path to Archive out.
bool GetAsarArchivePath(const base::FilePath& full_path,
base::FilePath* asar_path,
base::FilePath* relative_path);
// Same with base::ReadFileToString but supports asar Archive.
bool ReadFileToString(const base::FilePath& path, std::string* contents);
} // namespace asar
#endif // ATOM_COMMON_ASAR_ASAR_UTIL_H_

View File

@@ -6,7 +6,7 @@
#define ATOM_VERSION_H
#define ATOM_MAJOR_VERSION 0
#define ATOM_MINOR_VERSION 21
#define ATOM_MINOR_VERSION 22
#define ATOM_PATCH_VERSION 1
#define ATOM_VERSION_IS_RELEASE 1

View File

@@ -8,7 +8,7 @@
#ifndef ATOM_COMMON_CHROME_VERSION_H_
#define ATOM_COMMON_CHROME_VERSION_H_
#define CHROME_VERSION_STRING "40.0.2214.91"
#define CHROME_VERSION_STRING "41.0.2272.76"
#define CHROME_VERSION "v" CHROME_VERSION_STRING
#endif // ATOM_COMMON_CHROME_VERSION_H_

View File

@@ -12,8 +12,8 @@
namespace crash_reporter {
CrashReporter::CrashReporter() {
const CommandLine& command = *CommandLine::ForCurrentProcess();
is_browser_ = command.GetSwitchValueASCII(switches::kProcessType).empty();
auto cmd = base::CommandLine::ForCurrentProcess();
is_browser_ = cmd->GetSwitchValueASCII(switches::kProcessType).empty();
}
CrashReporter::~CrashReporter() {

View File

@@ -205,7 +205,7 @@ bool CrashService::Initialize(const base::FilePath& operating_dir,
// reports per day quota. Does not seem to serve any other purpose.
base::FilePath checkpoint_path = operating_dir.Append(kCheckPointFile);
CommandLine& cmd_line = *CommandLine::ForCurrentProcess();
base::CommandLine& cmd_line = *base::CommandLine::ForCurrentProcess();
base::FilePath dumps_path_to_use = dumps_path;

View File

@@ -39,8 +39,8 @@ bool GetCrashServiceDirectory(const std::wstring& application_name,
int Main(const wchar_t* cmd) {
// Initialize all Chromium things.
base::AtExitManager exit_manager;
CommandLine::Init(0, NULL);
CommandLine& cmd_line = *CommandLine::ForCurrentProcess();
base::CommandLine::Init(0, NULL);
base::CommandLine& cmd_line = *base::CommandLine::ForCurrentProcess();
// Use the application's name as pipe name and output directory.
if (!cmd_line.HasSwitch(kApplicationName)) {

View File

@@ -5,7 +5,7 @@
#ifndef ATOM_COMMON_DRAGGABLE_REGION_H_
#define ATOM_COMMON_DRAGGABLE_REGION_H_
#include "ui/gfx/rect.h"
#include "ui/gfx/geometry/rect.h"
namespace atom {

View File

@@ -1,4 +1,4 @@
asar = process.atomBinding 'asar'
asar = process.binding 'atom_common_asar'
child_process = require 'child_process'
path = require 'path'
util = require 'util'

View File

@@ -0,0 +1,22 @@
return (process, require, asarSource) ->
{createArchive} = process.binding 'atom_common_asar'
# Make asar.coffee accessible via "require".
process.binding('natives').ATOM_SHELL_ASAR = asarSource
# Monkey-patch the fs module.
require('ATOM_SHELL_ASAR').wrapFsWithAsar require('fs')
# Make graceful-fs work with asar.
source = process.binding 'natives'
source.originalFs = source.fs
source.fs = """
var src = '(function (exports, require, module, __filename, __dirname) { ' +
process.binding('natives').originalFs +
' });';
var vm = require('vm');
var fn = vm.runInThisContext(src, { filename: 'fs.js' });
fn(exports, require, module);
var asar = require('ATOM_SHELL_ASAR');
asar.wrapFsWithAsar(exports);
"""

View File

@@ -12,7 +12,7 @@ process.atomBinding = (name) ->
# Add common/api/lib to module search paths.
globalPaths = Module.globalPaths
globalPaths.push path.join(process.resourcesPath, 'atom', 'common', 'api', 'lib')
globalPaths.push path.resolve(__dirname, '..', 'api', 'lib')
# setImmediate and process.nextTick makes use of uv_check and uv_prepare to
# run the callbacks, however since we only run uv loop on requests, the
@@ -35,21 +35,3 @@ global.clearImmediate = timers.clearImmediate
if process.type is 'browser'
global.setTimeout = wrapWithActivateUvLoop timers.setTimeout
global.setInterval = wrapWithActivateUvLoop timers.setInterval
# Add support for asar packages.
asar = require './asar'
asar.wrapFsWithAsar fs
# Make graceful-fs work with asar.
source = process.binding 'natives'
source.originalFs = source.fs
source.fs = """
var src = '(function (exports, require, module, __filename, __dirname) { ' +
process.binding('natives').originalFs +
' });';
var vm = require('vm');
var fn = vm.runInThisContext(src, { filename: 'fs.js' });
fn(exports, require, module);
var asar = require(#{JSON.stringify(__dirname)} + '/asar');
asar.wrapFsWithAsar(exports);
"""

View File

@@ -5,10 +5,10 @@
#include "atom/common/native_mate_converters/gfx_converter.h"
#include "native_mate/dictionary.h"
#include "ui/gfx/point.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/screen.h"
#include "ui/gfx/size.h"
#include "ui/gfx/geometry/size.h"
namespace mate {

View File

@@ -4,124 +4,48 @@
#include "atom/common/native_mate_converters/image_converter.h"
#include <string>
#include <vector>
#include "atom/common/api/atom_api_native_image.h"
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "base/files/file_util.h"
#include "base/strings/string_util.h"
#include "ui/gfx/codec/jpeg_codec.h"
#include "ui/gfx/codec/png_codec.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/base/layout.h"
#if !defined(OS_MACOSX)
namespace mate {
namespace {
struct ScaleFactorPair {
const char* name;
float scale;
};
ScaleFactorPair kScaleFactorPairs[] = {
// The "@2x" is put as first one to make scale matching faster.
{ "@2x" , 2.0f },
{ "@3x" , 3.0f },
{ "@1x" , 1.0f },
{ "@4x" , 4.0f },
{ "@5x" , 5.0f },
{ "@1.25x" , 1.25f },
{ "@1.33x" , 1.33f },
{ "@1.4x" , 1.4f },
{ "@1.5x" , 1.5f },
{ "@1.8x" , 1.8f },
{ "@2.5x" , 2.5f },
};
float GetScaleFactorFromPath(const base::FilePath& path) {
std::string filename(path.BaseName().RemoveExtension().AsUTF8Unsafe());
// We don't try to convert string to float here because it is very very
// expensive.
for (unsigned i = 0; i < arraysize(kScaleFactorPairs); ++i) {
if (EndsWith(filename, kScaleFactorPairs[i].name, true))
return kScaleFactorPairs[i].scale;
}
return 1.0f;
}
bool AddImageSkiaRep(gfx::ImageSkia* image,
const base::FilePath& path,
double scale_factor) {
std::string file_contents;
if (!base::ReadFileToString(path, &file_contents))
return false;
const unsigned char* data =
reinterpret_cast<const unsigned char*>(file_contents.data());
size_t size = file_contents.size();
scoped_ptr<SkBitmap> decoded(new SkBitmap());
// Try PNG first.
if (!gfx::PNGCodec::Decode(data, size, decoded.get()))
// Try JPEG.
decoded.reset(gfx::JPEGCodec::Decode(data, size));
if (!decoded)
return false;
image->AddRepresentation(gfx::ImageSkiaRep(*decoded.release(), scale_factor));
return true;
}
bool PopulateImageSkiaRepsFromPath(gfx::ImageSkia* image,
const base::FilePath& path) {
bool succeed = false;
std::string filename(path.BaseName().RemoveExtension().AsUTF8Unsafe());
if (MatchPattern(filename, "*@*x"))
// Don't search for other representations if the DPI has been specified.
return AddImageSkiaRep(image, path, GetScaleFactorFromPath(path));
else
succeed |= AddImageSkiaRep(image, path, 1.0f);
for (const ScaleFactorPair& pair : kScaleFactorPairs)
succeed |= AddImageSkiaRep(image,
path.InsertBeforeExtensionASCII(pair.name),
pair.scale);
return succeed;
}
} // namespace
bool Converter<gfx::ImageSkia>::FromV8(v8::Isolate* isolate,
v8::Handle<v8::Value> val,
gfx::ImageSkia* out) {
if (val->IsNull())
return true;
base::FilePath path;
if (!Converter<base::FilePath>::FromV8(isolate, val, &path))
gfx::Image image;
if (!ConvertFromV8(isolate, val, &image))
return false;
return PopulateImageSkiaRepsFromPath(out, path);
*out = image.AsImageSkia();
return true;
}
bool Converter<gfx::Image>::FromV8(v8::Isolate* isolate,
v8::Handle<v8::Value> val,
gfx::Image* out) {
gfx::ImageSkia image;
if (!ConvertFromV8(isolate, val, &image))
return false;
if (val->IsNull())
return true;
*out = gfx::Image(image);
Handle<atom::api::NativeImage> native_image;
if (!ConvertFromV8(isolate, val, &native_image)) {
// Try converting from file path.
base::FilePath path;
if (!Converter<base::FilePath>::FromV8(isolate, val, &path))
return false;
native_image = atom::api::NativeImage::CreateFromPath(isolate, path);
if (native_image->image().IsEmpty())
return false;
}
*out = native_image->image();
return true;
}
} // namespace mate
v8::Handle<v8::Value> Converter<gfx::Image>::ToV8(v8::Isolate* isolate,
const gfx::Image& val) {
return ConvertToV8(isolate, atom::api::NativeImage::Create(isolate, val));
}
#endif // !defined(OS_MACOSX)
} // namespace mate

View File

@@ -26,6 +26,8 @@ struct Converter<gfx::Image> {
static bool FromV8(v8::Isolate* isolate,
v8::Handle<v8::Value> val,
gfx::Image* out);
static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
const gfx::Image& val);
};
} // namespace mate

View File

@@ -1,60 +0,0 @@
// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/common/native_mate_converters/image_converter.h"
#import <Cocoa/Cocoa.h>
#include "base/mac/foundation_util.h"
#include "base/mac/scoped_nsobject.h"
#include "base/strings/string_util.h"
#include "base/strings/sys_string_conversions.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia.h"
namespace {
bool IsTemplateImage(const std::string& path) {
return (MatchPattern(path, "*Template.*") ||
MatchPattern(path, "*Template@*x.*"));
}
} // namespace
namespace mate {
bool Converter<gfx::ImageSkia>::FromV8(v8::Isolate* isolate,
v8::Handle<v8::Value> val,
gfx::ImageSkia* out) {
gfx::Image image;
if (!ConvertFromV8(isolate, val, &image))
return false;
*out = image.AsImageSkia();
return true;
}
bool Converter<gfx::Image>::FromV8(v8::Isolate* isolate,
v8::Handle<v8::Value> val,
gfx::Image* out) {
if (val->IsNull())
return true;
std::string path;
if (!ConvertFromV8(isolate, val, &path))
return false;
base::scoped_nsobject<NSImage> image([[NSImage alloc]
initByReferencingFile:base::SysUTF8ToNSString(path)]);
if (![image isValid])
return false;
if (IsTemplateImage(path))
[image setTemplate:YES];
*out = gfx::Image(image.release());
return true;
}
} // namespace mate

View File

@@ -7,6 +7,7 @@
#include <string>
#include <vector>
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "base/command_line.h"
#include "base/base_paths.h"
#include "base/files/file_path.h"
@@ -14,6 +15,7 @@
#include "base/path_service.h"
#include "content/public/browser/browser_thread.h"
#include "native_mate/locker.h"
#include "native_mate/dictionary.h"
#if defined(OS_WIN)
#include "base/strings/utf_string_conversions.h"
@@ -55,6 +57,7 @@ REFERENCE_MODULE(tls_wrap);
REFERENCE_MODULE(tty_wrap);
REFERENCE_MODULE(udp_wrap);
REFERENCE_MODULE(uv);
REFERENCE_MODULE(js_stream);
// Atom Shell's builtin modules.
REFERENCE_MODULE(atom_browser_app);
REFERENCE_MODULE(atom_browser_auto_updater);
@@ -66,11 +69,13 @@ REFERENCE_MODULE(atom_browser_protocol);
REFERENCE_MODULE(atom_browser_global_shortcut);
REFERENCE_MODULE(atom_browser_tray);
REFERENCE_MODULE(atom_browser_web_contents);
REFERENCE_MODULE(atom_browser_web_view_manager);
REFERENCE_MODULE(atom_browser_window);
REFERENCE_MODULE(atom_common_asar);
REFERENCE_MODULE(atom_common_clipboard);
REFERENCE_MODULE(atom_common_crash_reporter);
REFERENCE_MODULE(atom_common_id_weak_map);
REFERENCE_MODULE(atom_common_native_image);
REFERENCE_MODULE(atom_common_screen);
REFERENCE_MODULE(atom_common_shell);
REFERENCE_MODULE(atom_common_v8_util);
@@ -108,6 +113,21 @@ std::vector<std::string> String16VectorToStringVector(
}
#endif
base::FilePath GetResourcesPath(base::CommandLine* command_line,
bool is_browser) {
base::FilePath exec_path(command_line->argv()[0]);
PathService::Get(base::FILE_EXE, &exec_path);
base::FilePath resources_path =
#if defined(OS_MACOSX)
is_browser ? exec_path.DirName().DirName().Append("Resources") :
exec_path.DirName().DirName().DirName().DirName().DirName()
.Append("Resources");
#else
exec_path.DirName().Append(FILE_PATH_LITERAL("resources"));
#endif
return resources_path;
}
} // namespace
node::Environment* global_env = nullptr;
@@ -147,7 +167,7 @@ void NodeBindings::Initialize() {
node::Environment* NodeBindings::CreateEnvironment(
v8::Handle<v8::Context> context) {
CommandLine* command_line = CommandLine::ForCurrentProcess();
auto command_line = base::CommandLine::ForCurrentProcess();
std::vector<std::string> args =
#if defined(OS_WIN)
String16VectorToStringVector(command_line->argv());
@@ -156,31 +176,26 @@ node::Environment* NodeBindings::CreateEnvironment(
#endif
// Feed node the path to initialization script.
base::FilePath exec_path(command_line->argv()[0]);
PathService::Get(base::FILE_EXE, &exec_path);
base::FilePath resources_path =
#if defined(OS_MACOSX)
is_browser_ ? exec_path.DirName().DirName().Append("Resources") :
exec_path.DirName().DirName().DirName().DirName().DirName()
.Append("Resources");
#else
exec_path.DirName().Append(FILE_PATH_LITERAL("resources"));
#endif
base::FilePath::StringType process_type = is_browser_ ?
FILE_PATH_LITERAL("browser") : FILE_PATH_LITERAL("renderer");
base::FilePath resources_path = GetResourcesPath(command_line, is_browser_);
base::FilePath script_path =
resources_path.Append(FILE_PATH_LITERAL("atom"))
.Append(is_browser_ ? FILE_PATH_LITERAL("browser") :
FILE_PATH_LITERAL("renderer"))
resources_path.Append(FILE_PATH_LITERAL("atom.asar"))
.Append(process_type)
.Append(FILE_PATH_LITERAL("lib"))
.Append(FILE_PATH_LITERAL("init.js"));
std::string script_path_str = script_path.AsUTF8Unsafe();
args.insert(args.begin() + 1, script_path_str.c_str());
scoped_ptr<const char*[]> c_argv = StringVectorToArgArray(args);
return node::CreateEnvironment(context->GetIsolate(),
uv_default_loop(),
context,
args.size(), c_argv.get(),
0, nullptr);
node::Environment* env = node::CreateEnvironment(
context->GetIsolate(), uv_default_loop(), context,
args.size(), c_argv.get(), 0, nullptr);
mate::Dictionary process(context->GetIsolate(), env->process_object());
process.Set("type", process_type);
process.Set("resourcesPath", resources_path);
return env;
}
void NodeBindings::LoadEnvironment(node::Environment* env) {

View File

@@ -72,10 +72,12 @@ const char kPreloadScript[] = "preload";
// Whether the window should be transparent.
const char kTransparent[] = "transparent";
// Window type hint.
const char kType[] = "type";
// Web runtime features.
const char kExperimentalFeatures[] = "experimental-features";
const char kExperimentalCanvasFeatures[] = "experimental-canvas-features";
const char kSubpixelFontScaling[] = "subpixel-font-scaling";
const char kOverlayScrollbars[] = "overlay-scrollbars";
const char kOverlayFullscreenVideo[] = "overlay-fullscreen-video";
const char kSharedWorker[] = "shared-worker";

View File

@@ -40,10 +40,10 @@ extern const char kEnablePlugins[];
extern const char kGuestInstanceID[];
extern const char kPreloadScript[];
extern const char kTransparent[];
extern const char kType[];
extern const char kExperimentalFeatures[];
extern const char kExperimentalCanvasFeatures[];
extern const char kSubpixelFontScaling[];
extern const char kOverlayScrollbars[];
extern const char kOverlayFullscreenVideo[];
extern const char kSharedWorker[];

View File

@@ -29,8 +29,8 @@ namespace {
// is empty. This function tells if it is.
bool ValidateShellCommandForScheme(const std::string& scheme) {
base::win::RegKey key;
std::wstring registry_path = base::ASCIIToWide(scheme) +
L"\\shell\\open\\command";
base::string16 registry_path = base::ASCIIToUTF16(scheme) +
L"\\shell\\open\\command";
key.Open(HKEY_CLASSES_ROOT, registry_path.c_str(), KEY_READ);
if (!key.Valid())
return false;

View File

@@ -69,15 +69,18 @@ metaToValue = (meta) ->
ret = ipc.sendSync 'ATOM_BROWSER_MEMBER_CALL', meta.id, member.name, wrapArgs(arguments)
return metaToValue ret
else
ret.__defineSetter__ member.name, (value) ->
# Set member data.
ipc.sendSync 'ATOM_BROWSER_MEMBER_SET', meta.id, member.name, value
value
Object.defineProperty ret, member.name,
enumerable: true,
configurable: false,
set: (value) ->
# Set member data.
ipc.sendSync 'ATOM_BROWSER_MEMBER_SET', meta.id, member.name, value
value
ret.__defineGetter__ member.name, ->
# Get member data.
ret = ipc.sendSync 'ATOM_BROWSER_MEMBER_GET', meta.id, member.name
metaToValue ret
get: ->
# Get member data.
ret = ipc.sendSync 'ATOM_BROWSER_MEMBER_GET', meta.id, member.name
metaToValue ret
# Track delegate object's life time, and tell the browser to clean up
# when the object is GCed.

View File

@@ -67,7 +67,7 @@ void AtomRenderViewObserver::DidCreateDocumentElement(
document_created_ = true;
// Read --zoom-factor from command line.
std::string zoom_factor_str = CommandLine::ForCurrentProcess()->
std::string zoom_factor_str = base::CommandLine::ForCurrentProcess()->
GetSwitchValueASCII(switches::kZoomFactor);;
if (zoom_factor_str.empty())
return;

View File

@@ -10,6 +10,7 @@
#include "atom/common/node_bindings.h"
#include "atom/common/options_switches.h"
#include "atom/renderer/atom_render_view_observer.h"
#include "atom/renderer/guest_view_container.h"
#include "chrome/renderer/printing/print_web_view_helper.h"
#include "chrome/renderer/tts_dispatcher.h"
#include "content/public/common/content_constants.h"
@@ -149,6 +150,17 @@ bool AtomRendererClient::ShouldFork(blink::WebFrame* frame,
return http_method == "GET";
}
content::BrowserPluginDelegate* AtomRendererClient::CreateBrowserPluginDelegate(
content::RenderFrame* render_frame,
const std::string& mime_type,
const GURL& original_url) {
if (mime_type == content::kBrowserPluginMimeType) {
return new GuestViewContainer(render_frame);
} else {
return nullptr;
}
}
void AtomRendererClient::EnableWebRuntimeFeatures() {
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
bool b;
@@ -156,8 +168,6 @@ void AtomRendererClient::EnableWebRuntimeFeatures() {
blink::WebRuntimeFeatures::enableExperimentalFeatures(b);
if (IsSwitchEnabled(command_line, switches::kExperimentalCanvasFeatures, &b))
blink::WebRuntimeFeatures::enableExperimentalCanvasFeatures(b);
if (IsSwitchEnabled(command_line, switches::kSubpixelFontScaling, &b))
blink::WebRuntimeFeatures::enableSubpixelFontScaling(b);
if (IsSwitchEnabled(command_line, switches::kOverlayScrollbars, &b))
blink::WebRuntimeFeatures::enableOverlayScrollbars(b);
if (IsSwitchEnabled(command_line, switches::kOverlayFullscreenVideo, &b))

View File

@@ -51,6 +51,10 @@ class AtomRendererClient : public content::ContentRendererClient,
bool is_initial_navigation,
bool is_server_redirect,
bool* send_referrer) override;
content::BrowserPluginDelegate* CreateBrowserPluginDelegate(
content::RenderFrame* render_frame,
const std::string& mime_type,
const GURL& original_url) override;
void EnableWebRuntimeFeatures();

View File

@@ -0,0 +1,15 @@
// 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/renderer/guest_view_container.h"
namespace atom {
GuestViewContainer::GuestViewContainer(content::RenderFrame* render_frame) {
}
GuestViewContainer::~GuestViewContainer() {
}
} // namespace atom

View File

@@ -0,0 +1,24 @@
// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_RENDERER_GUEST_VIEW_CONTAINER_H_
#define ATOM_RENDERER_GUEST_VIEW_CONTAINER_H_
#include "content/public/renderer/browser_plugin_delegate.h"
#include "v8/include/v8.h"
namespace atom {
class GuestViewContainer : public content::BrowserPluginDelegate {
public:
explicit GuestViewContainer(content::RenderFrame* render_frame);
~GuestViewContainer() override;
private:
DISALLOW_COPY_AND_ASSIGN(GuestViewContainer);
};
} // namespace atom
#endif // ATOM_RENDERER_GUEST_VIEW_CONTAINER_H_

View File

@@ -4,10 +4,6 @@ path = require 'path'
url = require 'url'
Module = require 'module'
# Expose information of current process.
process.type = 'renderer'
process.resourcesPath = path.resolve process.argv[1], '..', '..', '..', '..'
# We modified the original process.argv to let node.js load the
# atom-renderer.js, we need to restore it here.
process.argv.splice 1, 1
@@ -15,9 +11,10 @@ process.argv.splice 1, 1
# Add renderer/api/lib to require's search paths, which contains javascript part
# of Atom's built-in libraries.
globalPaths = Module.globalPaths
globalPaths.push path.join(process.resourcesPath, 'atom', 'renderer', 'api', 'lib')
globalPaths.push path.resolve(__dirname, '..', 'api', 'lib')
# And also app.
globalPaths.push path.join(process.resourcesPath, 'app')
globalPaths.push path.join(process.resourcesPath, 'app.asar')
# Import common settings.
require path.resolve(__dirname, '..', '..', 'common', 'lib', 'init')

View File

@@ -1,14 +1,11 @@
window.onload = ->
inspectorFrame = document.getElementById('inspector-app-iframe').contentWindow
# Use menu API to show context menu.
InspectorFrontendHost.showContextMenuAtPoint = (x, y, items, document) ->
createMenu items
inspectorFrame.eval 'InspectorFrontendHost.showContextMenuAtPoint = parent.createMenu'
# Use dialog API to override file chooser dialog.
WebInspector.createFileSelectorElement = (callback) ->
fileSelectorElement = document.createElement 'span'
fileSelectorElement.style.display = 'none'
fileSelectorElement.click = showFileChooserDialog.bind this, callback
return fileSelectorElement
inspectorFrame.eval 'WebInspector.createFileSelectorElement = parent.createFileSelectorElement'
convertToMenuTemplate = (items) ->
template = []
@@ -32,11 +29,11 @@ convertToMenuTemplate = (items) ->
label: item.label
enabled: item.enabled
if item.id?
transformed.click = -> InspectorFrontendAPI.contextMenuItemSelected item.id
transformed.click = -> DevToolsAPI.contextMenuItemSelected item.id
template.push transformed
template
createMenu = (items) ->
createMenu = (x, y, items, document) ->
remote = require 'remote'
Menu = remote.require 'menu'
@@ -44,7 +41,7 @@ createMenu = (items) ->
# The menu is expected to show asynchronously.
setImmediate ->
menu.popup remote.getCurrentWindow()
InspectorFrontendAPI.contextMenuCleared()
DevToolsAPI.contextMenuCleared()
showFileChooserDialog = (callback) ->
remote = require 'remote'
@@ -57,3 +54,13 @@ pathToHtml5FileObject = (path) ->
blob = new Blob([fs.readFileSync(path)])
blob.name = path
blob
createFileSelectorElement = (callback) ->
fileSelectorElement = document.createElement 'span'
fileSelectorElement.style.display = 'none'
fileSelectorElement.click = showFileChooserDialog.bind this, callback
return fileSelectorElement
# Exposed for iframe.
window.createMenu = createMenu
window.createFileSelectorElement = createFileSelectorElement

View File

@@ -3,8 +3,11 @@ ipc = require 'ipc'
remote = require 'remote'
# Window object returned by "window.open".
class FakeWindow
class BrowserWindowProxy
constructor: (@guestId) ->
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_CLOSED', (guestId) =>
if guestId is @guestId
@closed = true
close: ->
ipc.send 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_CLOSE', @guestId
@@ -15,6 +18,9 @@ class FakeWindow
blur: ->
ipc.send 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_METHOD', @guestId, 'blur'
postMessage: (message, targetOrigin='*') ->
ipc.send 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', @guestId, message, targetOrigin
eval: (args...) ->
ipc.send 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', @guestId, 'executeJavaScript', args...
@@ -26,24 +32,28 @@ unless process.guestInstanceId?
# Make the browser window or guest view emit "new-window" event.
window.open = (url, frameName='', features='') ->
options = {}
for feature in features.split ','
[name, value] = feature.split '='
ints = [ 'x', 'y', 'width', 'height', 'min-width', 'max-width', 'min-height', 'max-height', 'zoom-factor' ]
# Make sure to get rid of excessive whitespace in the property name
for feature in features.split /,\s*/
[name, value] = feature.split /\s*=/
options[name] =
if value is 'yes'
if value is 'yes' or value is '1'
true
else if value is 'no'
else if value is 'no' or value is '0'
false
else
value
options.x ?= options.left
options.y ?= options.top
options.x ?= options.left if options.left
options.y ?= options.top if options.top
options.title ?= name
options.width ?= 800
options.height ?= 600
(options[name] = parseInt(options[name], 10) if options[name]?) for name in ints
guestId = ipc.sendSync 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPEN', url, frameName, options
if guestId
new FakeWindow(guestId)
new BrowserWindowProxy(guestId)
else
console.error 'It is not allowed to open new window from this WebContents'
null
@@ -63,3 +73,10 @@ window.confirm = (message, title='') ->
# But we do not support prompt().
window.prompt = ->
throw new Error('prompt() is and will not be supported in atom-shell.')
window.opener =
postMessage: (message, targetOrigin='*') ->
ipc.send 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPENER_POSTMESSAGE', message, targetOrigin
ipc.on 'ATOM_SHELL_GUEST_WINDOW_POSTMESSAGE', (message, targetOrigin) ->
window.postMessage message, targetOrigin

View File

@@ -186,6 +186,7 @@ registerBrowserPluginElement = ->
@setAttribute 'type', 'application/browser-plugin'
@setAttribute 'id', 'browser-plugin-' + getNextId()
# The <object> node fills in the <webview> container.
@style.display = 'block'
@style.width = '100%'
@style.height = '100%'

View File

@@ -192,6 +192,7 @@ void PrintJobWorker::GetSettingsWithUI(
printing_context_->AskUserForSettings(
document_page_count,
has_selection,
false,
base::Bind(&PrintJobWorker::GetSettingsWithUIDone,
base::Unretained(this)));
}

View File

@@ -155,7 +155,7 @@ void PrintViewManagerBase::OnDidPrintPage(
reinterpret_cast<const unsigned char*>(shared_buf.memory()),
params.data_size);
document->DebugDumpData(bytes, FILE_PATH_LITERAL(".pdf"));
document->DebugDumpData(bytes.get(), FILE_PATH_LITERAL(".pdf"));
}
#endif // !OS_WIN
}

View File

@@ -6,7 +6,7 @@
#include "base/basictypes.h"
#include "base/strings/string16.h"
#include "ui/gfx/size.h"
#include "ui/gfx/geometry/size.h"
PrintMsg_Print_Params::PrintMsg_Print_Params()
: page_size(),

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