Compare commits

...

139 Commits

Author SHA1 Message Date
John Kleinschmidt
0602ca8e9c v1.8.8 2018-08-22 16:34:02 -04:00
Samuel Attard
519a02d8d4 fix: inheritance of webPreferences sub properties 2018-08-22 12:21:53 -05:00
Samuel Attard
8ebd0ce1b1 chore: stop auto releasing from windows CI 2018-08-19 15:42:02 -07:00
trop[bot]
61d9470b7a docs: fix electron.d.ts typings (#14136) 2018-08-16 11:11:35 -07:00
John Kleinschmidt
16e1b2340f Merge pull request #14086 from electron/appveyor-rename-1-8-x
ci: Rename appveyor-override to appveyor (1-8-x)
2018-08-14 09:51:15 -07:00
John Kleinschmidt
f91aa3f37d Rename appveyor-override to appveyor
Make sure we have consistent names on our CI config files.
2018-08-14 09:39:52 -07:00
Jeremy Apthorp
a1a921325d chore: roll libcc
Picks up electron/libchromiumcontent#638
2018-08-08 10:40:28 -07:00
trop[bot]
65533961e2 fix: util.promisify(setTimeout) (#13858) 2018-07-30 13:02:59 +10:00
trop[bot]
77093d540f docs: fix electron.d.ts typings (#13855) 2018-07-30 11:14:27 +10:00
John Kleinschmidt
86438632d7 Merge pull request #13610 from trop-bot/1-8-x-bp-ci--use-visual-studio-2015-for-2-0-x-and-older-1531233806214
Backport (1-8-x) - ci: Use Visual Studio 2015 for 2-0-x and older
2018-07-10 11:40:32 -04:00
John Kleinschmidt
df69c6de2c Use Visual Studio 2015 for 2-0-x 2018-07-10 14:43:32 +00:00
Milan Burda
e68bdbff65 Bump libcc (#13342) 2018-06-22 00:40:22 +10:00
Milan Burda
caa889e270 Add FILE_DIALOG_TREAT_PACKAGE_APP_AS_DIRECTORY to web open file dialog (#13220) (#13276) 2018-06-18 10:34:39 -05:00
Milan Burda
700ea8731f Backport "Allow lookup of videodecoder service to fix HW video decoding on macOS 10.13" (#13274)
https://chromium-review.googlesource.com/677290
2018-06-18 21:35:30 +10:00
John Kleinschmidt
e15e152177 v1.8.7 2018-05-16 14:15:18 -04:00
John Kleinschmidt
8e9bdfc59d Merge pull request #12945 from electron/update-libcc_1-8-x
update libcc submodule reference to electron-1-8-x
2018-05-16 12:46:59 -04:00
Charles Kerr
c96916ef94 update libcc submodule reference to electron-1-8-x
remove appveyor.yml to fix windows CI builds
2018-05-16 12:22:36 -04:00
John Kleinschmidt
959ffff316 Merge pull request #12962 from trop-bot/1-8-x-bp-fix-empty-description-when-only-one-extension-is-given-(getfiletypesfromaccepttype)-1526480225772
Backport (1-8-x) - Fix empty description when only one extension is given (GetFileTypesFromAcceptType)
2018-05-16 11:45:56 -04:00
Milan Burda
66bd8c669d Fix empty description when only one extension is given 2018-05-16 14:17:11 +00:00
Milan Burda
2bb22f776a Fix contents.setSize(options) documentation in web-contents.md (#12922) (#12935) 2018-05-15 08:15:56 -05:00
Charles Kerr
baa12df67b update command-line backlist switches (1.8.x) (#12807)
* update command-line backlist switches

Do a better job of finding edge cases, e.g. network_switch_list.h

**NB: This can't be tropped** because the list is dependent on the libcc version

* update list
2018-05-14 17:14:00 -05:00
Alexey Kuzmin
d8b41482a2 Fix context menu for sandbox devtools (#11933) (#12734) 2018-05-01 17:53:07 -05:00
John Kleinschmidt
43650d4053 v1.8.6 2018-04-26 20:52:48 -04:00
John Kleinschmidt
8c50e14eee v1.8.5 2018-04-26 14:29:27 -04:00
trop[bot]
41eda591c2 revert to more graceful template structure check (#12702) 2018-04-24 13:16:56 -04:00
trop[bot]
2a90b5cbfa Backport (1-8-x) - Fix transparency (#12684)
* Fix transparent window capture. Transparency is preserved and not converted to black pixels anymore

* Add test to make sure aplha channel exists in captured image
2018-04-23 01:16:15 +10:00
John Kleinschmidt
9bb3547809 Merge pull request #12645 from ajmacd/ajm-update-1-8-x
Update libcc on 1-8-x to include two backport fixes.
2018-04-19 13:29:23 -04:00
trop[bot]
9827185d60 Backport (1-8-x) - Correct the default of allowRunningInsecureContent as per docs (#12630)
* Correct the default of allowRunningInsecureContent as per docs

* fix linting

* Update calls to match native_mate API change
2018-04-18 05:55:20 -07:00
Andrew MacDonald
ed3206a0f5 Update libcc on 1-8-x to include two backport fixes.
https://github.com/electron/libchromiumcontent/pull/510
https://github.com/electron/libchromiumcontent/pull/518
2018-04-17 10:58:45 -07:00
trop[bot]
7189fb5bd8 Backport (1-8-x) - Fix event leak on reuse of touchbar item (#12623)
* fix event leak on reuse of touchbar item

* Clean up child touch bar item event listeners and escape item listeners
2018-04-15 11:27:29 -05:00
John Kleinschmidt
44d9720629 Use CircleCI for Mac builds (#12574) 2018-04-09 19:45:21 -05:00
John Kleinschmidt
1607708c33 Add native arm/arm64 mksnapshot for 1-8-x (#12533)
* Add logic to bundle native mksnapshot for arm/arm64

* Update libchromiumcontent to latest

* Add unzip to arm64 docker image
2018-04-06 09:20:55 -04:00
trop[bot]
cc7aa41303 WebFrame.setVisualZoomLevelLimits sets user-agent scale constraints (#12509)
Fixes #11216.
2018-04-03 07:50:57 -05:00
Zhuo Lu
acb9a47d50 Backport #12404 to 1-8-x (#12432)
* Do not block main process for async dialog

Backport #12404

* Reduce code redundancy
2018-03-28 15:23:22 -05:00
Shelley Vohr
8d7b348a70 re-enable null check against menu item accelerators (#12456) 2018-03-28 09:29:15 -04:00
trop[bot]
adcddb8b32 Backport (1-8-x) - update doc for setProgressBar (#12453)
* update doc for setProgressBar

The linter was unable to get `paused` as a possible value for `mode`

* update doc for setProgressBar

Addressing PR feedback
2018-03-28 11:35:38 +11:00
trop[bot]
c94eb28451 net: change mime type deduction in Change URLRequestAsarJob (#12374) 2018-03-20 14:43:06 -05:00
Birunthan Mohanathas
dccc98677b Backport (1-8-x) - Update draggable regions when changing BrowserView (#12371)
* Store InspectableWebContents instead of InspectableWebContentsView in NativeBrowserView

* Rename system_drag_exclude_areas => drag_exclude_rects

* Use NSView convertRect:toView: for BrowserView DragRegionView positioning

* Make BrowserView DragRegionViews children of the WebContents view

Previously they were children of the `InspectableWebContentsView` view,
which caused this assertion to fail:

f993888424/brightray/browser/mac/bry_inspectable_web_contents_view.mm (L162)

* Update draggable regions when changing BrowserView

Fixes #12150.
2018-03-20 14:36:11 -05:00
John Kleinschmidt
295a4f81dd Merge pull request #12355 from electron/node-ci-update
Update CI to use Node 8
2018-03-19 13:06:47 -04:00
John Kleinschmidt
6993ee352d Update CI to use Node 8 2018-03-19 11:43:14 -04:00
John Kleinschmidt
9dfb85dd21 v1.8.4 2018-03-16 14:44:17 -04:00
John Kleinschmidt
cf5e77c39f Merge pull request #12323 from electron/fix-mips64el-1-8-x
Fix release build of mips64el (1.8.x)
2018-03-16 10:19:54 -04:00
Cheng Zhao
9a9b4910e8 Use --as-needed for mips64el
This is required to avoid linking unnecessary system libraries which may
conflict with the ones used in Chromium. As side effect we have to turn
off official build for mips64el.
2018-03-15 20:22:56 +09:00
Cheng Zhao
8200d6cdbf Revert "Compile without nss for mips64el"
This reverts commit 8681dc4a26.
2018-03-15 17:46:28 +09:00
trop[bot]
c26372c0f3 Document BrowserView.{destroy,isDestroyed} (#12298) 2018-03-15 16:40:27 +09:00
Charles Kerr
ac75e00aee Set appropriate defaults for webview options (#12272)
* Fix NIB.

* Fix up tests
2018-03-15 13:56:32 +09:00
trop[bot]
f95e5c71c0 spec: isolate sw file scheme spec storage with temp partition (#12289) 2018-03-15 13:04:16 +09:00
trop[bot]
ffe47c3f50 Backport (1-8-x) - Fix require on network share path (#12286)
* first pass at server/network require fix

* refactor for clarity
2018-03-15 12:26:46 +09:00
John Kleinschmidt
73c2652935 Merge pull request #12279 from trop-bot/1-8-x-bp-switching-all-emails-to-@electronjs.org-domain-1521056443989
Backport (1-8-x) - Switching all emails to `@electronjs.org` domain
2018-03-14 16:34:18 -04:00
Jacob Groundwater
6c7e64cceb Change Contact Emails 2018-03-14 19:40:50 +00:00
Samuel Attard
e2c7b43f25 fix remote setInterval flake (#12266) 2018-03-14 15:41:48 +09:00
Charles Kerr
8144e53bfd Fix window open not showing 1 8 x (#12261)
* Parent's visibility trumps inherited 'show' option

* Add tests

* Remove unnecessary work when merging options

* Use idiomatic ES6 when merging options

* Apply further ES6 bikeshedding

* Use JS that works with 1.8's version of libcc

One liner to replace an object spread with Object.assign()
2018-03-14 13:42:17 +09:00
trop[bot]
891ab8e256 Fixed passing of exception to the system crash handler (#12258) 2018-03-14 12:58:37 +09:00
Aleš Pergl
fe2dfdc24d Use content origin in screen coordinates for calculating popup menu position (#12197) 2018-03-09 12:37:01 -05:00
Cheng Zhao
8efd31ab4d Update libcc to include a patch for mips64el (#12151) 2018-03-07 16:46:17 +09:00
Shelley Vohr
d2adedadd3 properly check checkbox state on callback (#12154) 2018-03-07 14:54:52 +09:00
John Kleinschmidt
1ddf6188f4 v1.8.3 2018-03-05 20:40:10 -05:00
Cheng Zhao
2695a68869 Merge pull request #12117 from electron/update-libcc-1-8-x
Update libcc ref to latest 1-8-x
2018-03-05 19:01:21 +09:00
Cheng Zhao
ba016f3949 Update libcc ref to latest 1-8-x 2018-03-05 16:03:59 +09:00
John Kleinschmidt
c7a5c079f7 Allow CI building on arm64 hardware (#12106)
(cherry picked from commit 73394d335af879c59bd0590cf18f8539cfa8124a)
2018-03-03 16:24:35 -06:00
John Kleinschmidt
c1dad25f33 Merge pull request #12100 from electron/fix-protocol-origin-filtering-1-8
Fix protocol filtering of net.request for 1.8.
2018-03-02 16:37:56 -05:00
Paul Frazee
120bc964c6 Add download from custom protocol test (#11931)
(cherry picked from commit 01a6104727)
2018-03-02 15:36:51 -05:00
Thiago de Arruda
c3da3ae3f0 Fix protocol filtering of net.request
net::URLRequest inherits from base::SupportsUserData, which allows
associating arbitrary data with the request. Use this mechanism as a
condition for filtering requests from custom protocols.

Close #11657

(cherry picked from commit bc76f35691)
2018-03-02 10:30:53 -05:00
Cheng Zhao
d1f1210044 Merge pull request #11677 from loc/use_directx_capturer_win_1_8_x
Use same screen capturer settings for thumbnails as getUserMedia (Chrome 59/1-8-x)
2018-03-01 12:50:29 +09:00
Andy Locascio
c9febc49d1 use same capturer for thumbnails as chrome does screen sharing 2018-03-01 10:38:22 +09:00
Cheng Zhao
87d2571663 Merge pull request #11955 from electron/official_build
Official build for 1.8
2018-02-22 18:59:23 +09:00
Ales Pergl
d94970e81a Updated libchromiumcontent submodule 2018-02-22 07:57:35 +01:00
John Kleinschmidt
acbf1c9f94 Use larger machines 2018-02-21 13:49:55 -05:00
John Kleinschmidt
e14b7d9bc6 Try upping timeout 2018-02-21 09:13:26 -05:00
Ales Pergl
712b5fe0fd Linking with --as-needed triggers internal linker assertion failure on mips64el 2018-02-21 11:33:50 +01:00
Ales Pergl
eedb0b778f The --icf=all flag is not supported on all architectures 2018-02-20 18:28:51 +01:00
Ales Pergl
ed0676e167 GYP seems to be incapable to expand $(AR) 2018-02-20 17:56:34 +01:00
John Kleinschmidt
f39763d7f5 Fix lint 2018-02-20 10:41:17 -05:00
Ales Pergl
5889bbe27c Updated libchromiumcontent submodule 2018-02-20 14:01:24 +01:00
Ales Pergl
ae1a54d33e Don't use variable template as it confuses LTCG 2018-02-17 23:52:17 +01:00
Ales Pergl
71a93aec5d Export V8 symbols from node library 2018-02-17 23:51:45 +01:00
Ales Pergl
ad1929c4b6 Disable executable stack in electron binary 2018-02-16 17:59:25 +01:00
Ales Pergl
6aa0c44f5d Use "official" build LTO settings (Windows) 2018-02-16 16:51:01 +01:00
Ales Pergl
5e0111abc6 Use "official" build LTO settings 2018-02-16 16:47:16 +01:00
Ales Pergl
1860930b7e Download Gold linker plugin 2018-02-16 16:47:15 +01:00
Cheng Zhao
c285bdb2bc Merge pull request #11910 from brenca/fix-11849-1-8-x
Re-add WS_EX_COMPOSITED when GPU acceleration is enabled (1-8-x)
2018-02-14 09:57:47 +09:00
Heilig Benedek
9b44c764dc add WS_EX_COMPOSITED when GPU acceleration is enabled 2018-02-13 16:04:12 +01:00
John Kleinschmidt
75ce746885 Fix copying files (#11904)
Check for license was missing condition
2018-02-12 14:50:53 -05:00
John Kleinschmidt
d0aa740720 Merge pull request #11729 from brenca/osr-gpu-update-1-8-x
Improve OSR API (1-8-x)
2018-02-12 13:12:20 -05:00
John Kleinschmidt
5e8735c968 v1.8.2 2018-02-06 20:29:28 -05:00
Felix Rieseberg
13cb27f7ab 🔧 Fix this, but harder (#11845) 2018-02-06 15:34:41 -06:00
John Kleinschmidt
43bc858c0b Merge pull request #11843 from electron/fix-pre-release-string
Fix PRE_RELEASE_VERSION
2018-02-06 15:21:04 -05:00
Felix Rieseberg
6bc2894bf5 🔧 Fix spacing 2018-02-06 12:02:53 -08:00
Felix Rieseberg
a784804349 🔧 Fix PRE_RELEASE_VERSION 2018-02-06 11:57:56 -08:00
John Kleinschmidt
b3e6597317 Merge pull request #11842 from electron/backport-release-updates
Backport release updates to 1-8-x
2018-02-06 11:57:39 -05:00
John Kleinschmidt
6413a7f0f3 Backport release updates to 1-8-x
Backports #11793 to 1-8-x
2018-02-06 11:22:37 -05:00
John Kleinschmidt
0e9b0fff46 v1.8.2-beta.5 2018-01-31 14:46:12 -07:00
shelley vohr
0b7fd96629 Merge pull request #11784 from electron/case-insensitive-comparison-1-8-x
Do case insensitive comparisons
2018-01-31 13:17:00 -05:00
John Kleinschmidt
03add24cd7 Merge pull request #11777 from electron/parallel-releases-1-8-x
Parallel releases 1-8-x
2018-01-31 13:13:43 -05:00
John Kleinschmidt
36f0a74b17 Allow multiple releases to run at once
Find draft release by draft flag and tag name
2018-01-31 10:54:00 -07:00
Samuel Attard
92f4e5ea7d Do case insensitive comparisons 2018-01-31 10:28:03 -07:00
Cheng Zhao
5aee1cefff Merge pull request #11281 from electron/mips64el
Enable mips64el CI job
2018-01-29 17:08:19 +09:00
Cheng Zhao
7bfb3f4141 docs: Limitations of mips64el builds 2018-01-29 15:33:38 +09:00
Cheng Zhao
cd3f36a968 docs: Update our multi-arches support 2018-01-29 15:30:58 +09:00
Cheng Zhao
8681dc4a26 Compile without nss for mips64el 2018-01-29 15:20:59 +09:00
Cheng Zhao
95c7499775 Update gcc to 4.9 for mips64el target 2018-01-29 15:18:53 +09:00
Cheng Zhao
470b31d1af Enable mips64el CI job 2018-01-29 15:18:53 +09:00
Heilig Benedek
e912091aca Remove web_contents_impl() helper to clarify code and remove unnecessary guard 2018-01-26 10:31:48 +01:00
Heilig Benedek
281e1748ef Move OSR api to OsrWCV to allow api calls to take effect sooner 2018-01-25 14:46:30 +01:00
Heilig Benedek
f15ce53dca Call SetAuthoritativeVsyncInterval on the Compositor directly 2018-01-25 14:45:01 +01:00
Heilig Benedek
d45b8dfe83 Raise maximum OSR framerate to 240 2018-01-25 14:44:19 +01:00
Heilig Benedek
ba933e2998 Don't generate a frame with GPU OSR if IsPainting is false 2018-01-25 14:43:31 +01:00
Heilig Benedek
cb1ee8982d Don't generate a paint when StartPainting is called inside paint cb 2018-01-25 14:42:11 +01:00
Heilig Benedek
290f985571 Use null accelerated widget to avoid showing GPU accelerated OSR surface 2018-01-25 14:40:37 +01:00
Cheng Zhao
08f36c1383 Merge pull request #11710 from brenca/fix-10678-1-8-x
Remove WS_EX_COMPOSITED style from window (1-8-x)
2018-01-24 14:45:11 +09:00
shelley vohr
7659c16b09 update update submodule ref for updated node 8.2.1 (#11707) 2018-01-23 18:13:43 -05:00
Heilig Benedek
daf6dd99a8 Remove WS_EX_COMPOSITED style from window 2018-01-23 23:16:53 +01:00
Heilig Benedek
8d220141a5 fix osr devtools crash introduced during merge (#11673) 2018-01-23 09:34:18 -05:00
John Kleinschmidt
a1f23064e1 v1.8.2-beta.4 2018-01-22 22:19:41 -05:00
Charles Kerr
64ede04002 Merge pull request #11692 from electron/update-to-the-latest-libcc
Use the latest libcc from the electron-1-8-x branch
2018-01-22 18:36:44 -06:00
Aleksei Kuzmin
dab7f7f18d Use the latest libcc from the electron-1-8-x branch 2018-01-22 16:10:59 -08:00
Charles Kerr
9ceef5f1d3 fix 'npm lint' errors 2018-01-22 15:52:43 -06:00
Aleš Pergl
a250089a40 Disallow launching unknown apps via browser client.
CVE-2018-1000006
2018-01-22 15:40:46 -06:00
Charles Kerr
6efa33043a Merge pull request #11629 from brenca/tooltip-fix
Explicitly hide tooltip when the window is deactivated (1-8-x)
2018-01-18 23:40:02 -06:00
Heilig Benedek
445781ce33 don't dereference tooltip_controller if it's null 2018-01-18 20:40:37 +01:00
Heilig Benedek
ec088c7940 add todo comment 2018-01-15 12:14:47 +01:00
Heilig Benedek
71034f8008 lint fix 2018-01-12 18:17:16 +01:00
Heilig Benedek
c9d2b071ab explicitly hide tooltip on window deactivation 2018-01-12 17:48:18 +01:00
Cheng Zhao
d0ca62b173 Merge pull request #11597 from electron/fix-shift-key-shortcut
Update libcc in 1-8-x: Fix Shift not showing in menu for certain accelerators
2018-01-08 21:26:18 +09:00
Cheng Zhao
6982fb6dd0 Update libcc: Fix Shift not showing
Fix the Shift key not showing in menu for certain accelerators like
Control+Shift+F.
2018-01-08 16:16:40 +09:00
Cheng Zhao
be46ba1849 Merge pull request #11574 from electron/1-8-x-update-libcc
update libcc reference for 1-8-x
2018-01-07 16:54:52 +09:00
deepak1556
5eefde63b9 update libcc reference for 1-8-x 2018-01-05 16:46:29 +05:30
Cheng Zhao
2a97f2636a Merge pull request #11499 from electron/1-8-menu-popup-patch
fix: menu.popup should handle options correctly in 1.8.x
2018-01-02 16:21:47 +09:00
Cheng Zhao
ab3811e6dd Merge pull request #11526 from electron/fix-buffer-crash
1-8-x: Fix crash when using crypto module
2017-12-27 21:45:22 +09:00
Cheng Zhao
686dd664de Update node: Fix crash when doing crypto operation 2017-12-27 20:17:41 +09:00
Cheng Zhao
1e5ba47731 spec: Add test for crypto operation 2017-12-27 20:17:41 +09:00
deepak1556
7ef262cab3 fix: menu.popup should handle options correctly 2017-12-21 15:41:07 +05:30
Charles Kerr
19d70e5f1f Merge pull request #11489 from electron/1-8-spellchecker-iframe-patch
fix: manually set spellchecker for sub frames in 1.8.x
2017-12-20 16:12:26 -06:00
deepak1556
d0a9379b37 fix: manually set spellchecker for sub frames 2017-12-21 01:18:13 +05:30
Charles Kerr
0ac7106e6c Merge pull request #11482 from electron/fix-inspect-brk
Fix inspect-brk in 1.8.x
2017-12-20 10:46:39 -06:00
Samuel Attard
f19f125f68 _debugWaitConnect becomes _breakFirstLine. Fixes #11430 2017-12-20 14:18:26 +11:00
Charles Kerr
79385dcb74 Merge pull request #11476 from electron/enable-cfg
Security Improvement: Enable Control Flow Guard on Windows - https://…
2017-12-19 10:52:18 -06:00
Catalin Fratila
a71a20ee32 Security Improvement: Enable Control Flow Guard on Windows - https://docs.microsoft.com/en-us/cpp/build/reference/guard-enable-control-flow-guard 2017-12-19 09:16:44 -06:00
Charles Kerr
99a1161fe4 v1.8.2-beta.3 2017-12-04 17:20:29 -06:00
107 changed files with 13129 additions and 564 deletions

View File

@@ -3,10 +3,10 @@ version: 2
jobs: jobs:
electron-linux-arm: electron-linux-arm:
docker: docker:
- image: electronbuilds/electron:0.0.3 - image: electronbuilds/electron:0.0.7
environment: environment:
TARGET_ARCH: arm TARGET_ARCH: arm
resource_class: xlarge resource_class: 2xlarge
steps: steps:
- checkout - checkout
- run: - run:
@@ -60,10 +60,10 @@ jobs:
fi fi
electron-linux-arm64: electron-linux-arm64:
docker: docker:
- image: electronbuilds/electron:0.0.3 - image: electronbuilds/electron:0.0.7
environment: environment:
TARGET_ARCH: arm64 TARGET_ARCH: arm64
resource_class: xlarge resource_class: 2xlarge
steps: steps:
- checkout - checkout
- run: - run:
@@ -117,7 +117,7 @@ jobs:
fi fi
electron-linux-ia32: electron-linux-ia32:
docker: docker:
- image: electronbuilds/electron:0.0.3 - image: electronbuilds/electron:0.0.7
environment: environment:
TARGET_ARCH: ia32 TARGET_ARCH: ia32
resource_class: xlarge resource_class: xlarge
@@ -174,7 +174,7 @@ jobs:
fi fi
electron-linux-mips64el: electron-linux-mips64el:
docker: docker:
- image: electronbuilds/electron:0.0.3 - image: electronbuilds/electron:0.0.7
environment: environment:
TARGET_ARCH: mips64el TARGET_ARCH: mips64el
resource_class: xlarge resource_class: xlarge
@@ -232,11 +232,11 @@ jobs:
electron-linux-x64: electron-linux-x64:
docker: docker:
- image: electronbuilds/electron:0.0.3 - image: electronbuilds/electron:0.0.7
environment: environment:
TARGET_ARCH: x64 TARGET_ARCH: x64
DISPLAY: ':99.0' DISPLAY: ':99.0'
resource_class: xlarge resource_class: 2xlarge
steps: steps:
- checkout - checkout
- run: - run:
@@ -262,6 +262,206 @@ jobs:
- run: npm run lint - run: npm run lint
- run: - run:
name: Build name: Build
no_output_timeout: 30m
command: |
if [ "$ELECTRON_RELEASE" == "1" ]; then
echo 'Building Electron for release'
script/build.py -c R
else
echo 'Building Electron for debug'
script/build.py -c D
fi
- run:
name: Create distribution
command: |
if [ "$ELECTRON_RELEASE" == "1" ]; then
echo 'Creating Electron release distribution'
script/create-dist.py
else
echo 'Skipping create distribution because build is not for release'
fi
- run:
name: Upload distribution
command: |
if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then
echo 'Uploading Electron release distribution to github releases'
script/upload.py
elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then
echo 'Uploading Electron release distribution to s3'
script/upload.py --upload_to_s3
else
echo 'Skipping upload distribution because build is not for release'
fi
- run:
name: Test
environment:
MOCHA_FILE: junit/test-results.xml
MOCHA_REPORTER: mocha-junit-reporter
command: |
if [ "$ELECTRON_RELEASE" != "1" ]; then
echo 'Testing Electron debug build'
mkdir junit
script/test.py --ci --rebuild_native_modules
else
echo 'Skipping testing on release build'
fi
- run:
name: Verify FFmpeg
command: |
if [ "$ELECTRON_RELEASE" != "1" ]; then
echo 'Verifying ffmpeg on debug build'
script/verify-ffmpeg.py
else
echo 'Skipping verify ffmpeg on release build'
fi
- run:
name: Generate Typescript Definitions
command: npm run create-typescript-definitions
- store_test_results:
path: junit
- store_artifacts:
path: junit
- store_artifacts:
path: out/electron.d.ts
- store_artifacts:
path: out/electron-api.json
electron-osx-x64:
environment:
TARGET_ARCH: x64
macos:
xcode: "9.0"
resource_class: 2xlarge
steps:
- checkout
- run:
name: Reclaim disk space
command: |
df -h
sudo rm -rf /Library/Developer/CoreSimulator
df -h
sysctl -n hw.ncpu
- run:
name: Check for release
command: |
if [ -n "${RUN_RELEASE_BUILD}" ]; then
echo 'release build triggered from api'
echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV
fi
- run:
name: Bootstrap
command: |
if [ "$ELECTRON_RELEASE" == "1" ]; then
echo 'Bootstrapping Electron for release build'
script/bootstrap.py --target_arch=$TARGET_ARCH
else
echo 'Bootstrapping Electron for debug build'
script/bootstrap.py --target_arch=$TARGET_ARCH --dev
fi
- run: npm run lint
- run:
name: Build
no_output_timeout: 30m
command: |
if [ "$ELECTRON_RELEASE" == "1" ]; then
echo 'Building Electron for release'
script/build.py -c R
else
echo 'Building Electron for debug'
script/build.py -c D
fi
- run:
name: Create distribution
command: |
if [ "$ELECTRON_RELEASE" == "1" ]; then
echo 'Creating Electron release distribution'
script/create-dist.py
else
echo 'Skipping create distribution because build is not for release'
fi
- run:
name: Upload distribution
command: |
if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then
echo 'Uploading Electron release distribution to github releases'
script/upload.py
elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then
echo 'Uploading Electron release distribution to s3'
script/upload.py --upload_to_s3
else
echo 'Skipping upload distribution because build is not for release'
fi
- run:
name: Test
environment:
MOCHA_FILE: junit/test-results.xml
MOCHA_REPORTER: mocha-junit-reporter
command: |
if [ "$ELECTRON_RELEASE" != "1" ]; then
echo 'Testing Electron debug build'
mkdir junit
script/test.py --ci --rebuild_native_modules
else
echo 'Skipping testing on release build'
fi
- run:
name: Verify FFmpeg
command: |
if [ "$ELECTRON_RELEASE" != "1" ]; then
echo 'Verifying ffmpeg on debug build'
script/verify-ffmpeg.py
else
echo 'Skipping verify ffmpeg on release build'
fi
- run:
name: Generate Typescript Definitions
command: npm run create-typescript-definitions
- store_test_results:
path: junit
- store_artifacts:
path: junit
- store_artifacts:
path: out/electron.d.ts
- store_artifacts:
path: out/electron-api.json
electron-mas-x64:
environment:
TARGET_ARCH: x64
MAS_BUILD: 1
macos:
xcode: "9.0"
resource_class: 2xlarge
steps:
- checkout
- run:
name: Reclaim disk space
command: |
df -h
sudo rm -rf /Library/Developer/CoreSimulator
df -h
sysctl -n hw.ncpu
- run:
name: Check for release
command: |
if [ -n "${RUN_RELEASE_BUILD}" ]; then
echo 'release build triggered from api'
echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV
fi
- run:
name: Bootstrap
command: |
if [ "$ELECTRON_RELEASE" == "1" ]; then
echo 'Bootstrapping Electron for release build'
script/bootstrap.py --target_arch=$TARGET_ARCH
else
echo 'Bootstrapping Electron for debug build'
script/bootstrap.py --target_arch=$TARGET_ARCH --dev
fi
- run: npm run lint
- run:
name: Build
no_output_timeout: 30m
command: | command: |
if [ "$ELECTRON_RELEASE" == "1" ]; then if [ "$ELECTRON_RELEASE" == "1" ]; then
echo 'Building Electron for release' echo 'Building Electron for release'
@@ -339,3 +539,12 @@ workflows:
build-x64: build-x64:
jobs: jobs:
- electron-linux-x64 - electron-linux-x64
build-mips64el:
jobs:
- electron-linux-mips64el
build-osx-x64:
jobs:
- electron-osx-x64
build-mas-x64:
jobs:
- electron-mas-x64

5
.gitignore vendored
View File

@@ -28,6 +28,7 @@
/external_binaries/ /external_binaries/
/out/ /out/
/vendor/.gclient /vendor/.gclient
/vendor/cross-gcc-4.9.3-n64-loongson-rc5.4
/vendor/debian_jessie_amd64-sysroot/ /vendor/debian_jessie_amd64-sysroot/
/vendor/debian_jessie_arm-sysroot/ /vendor/debian_jessie_arm-sysroot/
/vendor/debian_jessie_arm64-sysroot/ /vendor/debian_jessie_arm64-sysroot/
@@ -36,13 +37,13 @@
/vendor/debian_wheezy_amd64-sysroot/ /vendor/debian_wheezy_amd64-sysroot/
/vendor/debian_wheezy_arm-sysroot/ /vendor/debian_wheezy_arm-sysroot/
/vendor/debian_wheezy_i386-sysroot/ /vendor/debian_wheezy_i386-sysroot/
/vendor/gcc-4.8.3-d197-n64-loongson/
/vendor/readme-gcc483-loongson.txt
/vendor/download/ /vendor/download/
/vendor/llvm-build/ /vendor/llvm-build/
/vendor/llvm/ /vendor/llvm/
/vendor/node/deps/node-inspect/.npmrc /vendor/node/deps/node-inspect/.npmrc
/vendor/npm/ /vendor/npm/
/vendor/python_26/ /vendor/python_26/
/vendor/native_mksnapshot
/vendor/LICENSES.chromium.html
node_modules/ node_modules/
SHASUMS256.txt SHASUMS256.txt

View File

@@ -34,7 +34,7 @@ This Code of Conduct applies both within project spaces and in public spaces whe
## Enforcement ## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at [electron@github.com](mailto:electron@github.com). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at [coc@electronjs.org](mailto:coc@electronjs.org). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.

View File

@@ -4,7 +4,7 @@
This project adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDUCT.md). This project adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDUCT.md).
By participating, you are expected to uphold this code. Please report unacceptable By participating, you are expected to uphold this code. Please report unacceptable
behavior to electron@github.com. behavior to coc@electronjs.org.
The following is a set of guidelines for contributing to Electron. The following is a set of guidelines for contributing to Electron.
These are just guidelines, not rules, use your best judgment and feel free to These are just guidelines, not rules, use your best judgment and feel free to

View File

@@ -7,7 +7,7 @@ ENV HOME=/home
RUN chmod a+rwx /home RUN chmod a+rwx /home
# Install node.js # Install node.js
RUN curl -sL https://deb.nodesource.com/setup_6.x | bash - RUN curl -sL https://deb.nodesource.com/setup_8.x | bash -
RUN apt-get update && apt-get install -y --force-yes nodejs RUN apt-get update && apt-get install -y --force-yes nodejs
# Install wget used by crash reporter # Install wget used by crash reporter

64
Dockerfile.arm64v8 Normal file
View File

@@ -0,0 +1,64 @@
FROM arm64v8/ubuntu:16.04
RUN groupadd --gid 1000 builduser \
&& useradd --uid 1000 --gid builduser --shell /bin/bash --create-home builduser
RUN groupadd --gid 114 jenkins \
&& useradd --uid 110 --gid jenkins --shell /bin/bash --create-home jenkins
# Set up TEMP directory
ENV TEMP=/tmp
RUN chmod a+rwx /tmp
RUN apt-get update && apt-get install -y\
bison \
build-essential \
clang \
curl \
gperf \
git \
libasound2 \
libasound2-dev \
libcap-dev \
libcups2-dev \
libdbus-1-dev \
libgconf-2-4 \
libgconf2-dev \
libgnome-keyring-dev \
libgtk2.0-0 \
libgtk2.0-dev \
libgtk-3-0 \
libgtk-3-dev \
libnotify-dev \
libnss3 \
libnss3-dev \
libx11-xcb-dev \
libxss1 \
libxtst-dev \
libxtst6 \
lsb-release \
locales \
ninja \
python-setuptools \
python-pip \
python-dbusmock \
unzip \
wget \
xvfb
# Install node.js
RUN curl -sL https://deb.nodesource.com/setup_8.x | bash -
RUN apt-get update && apt-get install -y nodejs
# Install crcmod
RUN pip install -U crcmod
ADD tools/xvfb-init.sh /etc/init.d/xvfb
RUN chmod a+x /etc/init.d/xvfb
# Install ninja in /usr/local
RUN cd /usr/local && git clone https://github.com/martine/ninja.git -b v1.5.3
RUN cd /usr/local/ninja && ./configure.py --bootstrap
USER builduser
WORKDIR /home/builduser

View File

@@ -3,7 +3,7 @@ FROM electronbuilds/libchromiumcontent:0.0.4
USER root USER root
# Install node.js # Install node.js
RUN curl -sL https://deb.nodesource.com/setup_6.x | bash - RUN curl -sL https://deb.nodesource.com/setup_8.x | bash -
RUN apt-get update && apt-get install -y --force-yes nodejs RUN apt-get update && apt-get install -y --force-yes nodejs
# Install wget used by crash reporter # Install wget used by crash reporter

36
Jenkinsfile.arm64 Normal file
View File

@@ -0,0 +1,36 @@
pipeline {
agent {
docker {
image 'electronbuilds/arm64v8:0.0.3'
args '--privileged'
}
}
environment {
TARGET_ARCH='arm64'
DISPLAY=':99.0'
MOCHA_TIMEOUT='60000'
}
stages {
stage('Bootstrap') {
steps {
sh 'script/bootstrap.py -v --dev --target_arch=$TARGET_ARCH'
}
}
stage('Build') {
steps {
sh 'script/build.py -c D --ninja-path /usr/local/ninja/ninja'
}
}
stage('Test') {
steps {
sh '/etc/init.d/xvfb start'
sh 'script/test.py --ci'
}
}
}
post {
always {
cleanWs()
}
}
}

View File

@@ -19,7 +19,7 @@ announcements.
This project adheres to the Contributor Covenant This project adheres to the Contributor Covenant
[code of conduct](https://github.com/electron/electron/tree/master/CODE_OF_CONDUCT.md). [code of conduct](https://github.com/electron/electron/tree/master/CODE_OF_CONDUCT.md).
By participating, you are expected to uphold this code. Please report unacceptable By participating, you are expected to uphold this code. Please report unacceptable
behavior to [electron@github.com](mailto:electron@github.com). behavior to [coc@electronjs.org](mailto:coc@electronjs.org).
## Installation ## Installation

View File

@@ -2,7 +2,7 @@
The Electron team and community take security bugs in Electron seriously. We appreciate your efforts to responsibly disclose your findings, and will make every effort to acknowledge your contributions. The Electron team and community take security bugs in Electron seriously. We appreciate your efforts to responsibly disclose your findings, and will make every effort to acknowledge your contributions.
To report a security issue, email [electron@github.com](mailto:electron@github.com) and include the word "SECURITY" in the subject line. To report a security issue, email [security@electronjs.org](mailto:security@electronjs.org) and include the word "SECURITY" in the subject line.
The Electron team will send a response indicating the next steps in handling your report. After the initial reply to your report, the security team will keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance. The Electron team will send a response indicating the next steps in handling your report. After the initial reply to your report, the security team will keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance.

View File

@@ -1,25 +1,58 @@
# appveyor file build_cloud: electron-16
# http://www.appveyor.com/docs/appveyor-yml image: electron-16-vs2015
version: "{build}" build_script:
- ps: >-
os: Visual Studio 2015 if(($env:APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME -split "/")[0] -eq ($env:APPVEYOR_REPO_NAME -split "/")[0]) {
Write-warning "Skipping PR build for branch"; Exit-AppveyorBuild
init: } else {
- git config --global core.autocrlf input Add-Path "$env:ProgramFiles (x86)\Windows Kits\10\Debuggers\x64"
$env:path = "$env:ProgramFiles (x86)\Windows Kits\10\Debuggers\x64;$env:path"
platform: if($env:APPVEYOR_SCHEDULED_BUILD -eq 'True') {
- x86 $env:RUN_RELEASE_BUILD = "1"
- x64 }
$Message = (git log --format=%B -n 1 HEAD) | Out-String
install: if ((Test-Path Env:\RUN_RELEASE_BUILD)) {
- cmd: SET PATH=C:\Program Files (x86)\MSBuild\14.0\bin\;%PATH% $env:ELECTRON_RELEASE = '1'
- cmd: SET PATH=C:\python27;%PATH% Write-Output "release build triggered from api"
- cmd: python script/cibuild }
if ((Test-Path Env:\ELECTRON_RELEASE)) {
branches: Write-Output "Running release build"
only: python script\bootstrap.py --target_arch=$env:TARGET_ARCH
- master python script\build.py -c R
python script\create-dist.py
# disable build and test phases } else {
build: off Write-Output "Running debug build"
test: off python script\bootstrap.py --target_arch=$env:TARGET_ARCH --dev
python script\build.py -c D
}
if ($? -ne 'True') {
throw "Build failed with exit code $?"
} else {
"Build succeeded."
}
Push-AppveyorArtifact out
}
test_script:
- ps: >-
if (Test-Path Env:\ELECTRON_RELEASE) {
Write-Output "Skipping tests for release build"
} else {
Write-Output "Running tests for debug build"
python script\test.py --ci --rebuild_native_modules
if ($LASTEXITCODE -ne '0') {
throw "Tests failed with exit code $LASTEXITCODE"
} else {
Write-Output "Tests succeeded."
}
python script\verify-ffmpeg.py
if ($LASTEXITCODE -ne '0') {
throw "Verify ffmpeg failed with exit code $LASTEXITCODE"
} else {
"Verify ffmpeg succeeded."
}
}
artifacts:
- path: test-results.xml
name: test-results.xml
deploy_script:
- ps: "if (Test-Path Env:\\ELECTRON_RELEASE) {\n if (Test-Path Env:\\RUN_RELEASE_BUILD) {\n Write-Output \"Uploading Electron release distribution to s3\"\n & python script\\upload.py --upload_to_s3\n } else {\n Write-Output \"Uploading Electron release distribution to github releases\"\n & python script\\upload.py\n }\n} else {\n Write-Output \"Skipping upload distribution because build is not for release\"\n}"

View File

@@ -10,7 +10,7 @@
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
extern "C" { extern "C" {
__attribute__((visibility("default"))) __attribute__((visibility("default")))
int AtomMain(int argc, const char* argv[]); int AtomMain(int argc, char* argv[]);
__attribute__((visibility("default"))) __attribute__((visibility("default")))
int AtomInitializeICUandStartNode(int argc, char *argv[]); int AtomInitializeICUandStartNode(int argc, char *argv[]);

View File

@@ -15,11 +15,11 @@
#include "content/public/app/content_main.h" #include "content/public/app/content_main.h"
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
int AtomMain(int argc, const char* argv[]) { int AtomMain(int argc, char* argv[]) {
atom::AtomMainDelegate delegate; atom::AtomMainDelegate delegate;
content::ContentMainParams params(&delegate); content::ContentMainParams params(&delegate);
params.argc = argc; params.argc = argc;
params.argv = argv; params.argv = const_cast<const char**>(argv);
atom::AtomCommandLine::Init(argc, argv); atom::AtomCommandLine::Init(argc, argv);
return content::ContentMain(params); return content::ContentMain(params);
} }

View File

@@ -4,7 +4,8 @@
#include "atom/app/atom_main.h" #include "atom/app/atom_main.h"
#include <stdlib.h> #include <cstdlib>
#include <vector>
#if defined(OS_WIN) #if defined(OS_WIN)
#include <windows.h> // windows.h must be included first #include <windows.h> // windows.h must be included first
@@ -15,9 +16,11 @@
#include <tchar.h> #include <tchar.h>
#include "atom/app/atom_main_delegate.h" #include "atom/app/atom_main_delegate.h"
#include "atom/app/command_line_args.h"
#include "atom/common/crash_reporter/win/crash_service_main.h" #include "atom/common/crash_reporter/win/crash_service_main.h"
#include "base/environment.h" #include "base/environment.h"
#include "base/process/launch.h" #include "base/process/launch.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/windows_version.h" #include "base/win/windows_version.h"
#include "content/public/app/sandbox_helper_win.h" #include "content/public/app/sandbox_helper_win.h"
#include "sandbox/win/src/sandbox_types.h" #include "sandbox/win/src/sandbox_types.h"
@@ -52,18 +55,23 @@ bool IsEnvSet(const char* name) {
#if defined(OS_WIN) #if defined(OS_WIN)
int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) { int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
int argc = 0; struct Arguments {
wchar_t** wargv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); int argc = 0;
wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
bool run_as_node = IsEnvSet(kRunAsNode); ~Arguments() { LocalFree(argv); }
} arguments;
if (!arguments.argv)
return -1;
#ifdef _DEBUG #ifdef _DEBUG
// Don't display assert dialog boxes in CI test runs // Don't display assert dialog boxes in CI test runs
static const auto kCI = "ELECTRON_CI"; static const auto kCI = "ELECTRON_CI";
bool is_ci = IsEnvSet(kCI); bool is_ci = IsEnvSet(kCI);
if (!is_ci) { if (!is_ci) {
for (int i = 0; i < argc; ++i) { for (int i = 0; i < arguments.argc; ++i) {
if (!_wcsicmp(wargv[i], L"--ci")) { if (!_wcsicmp(arguments.argv[i], L"--ci")) {
is_ci = true; is_ci = true;
_putenv_s(kCI, "1"); // set flag for child processes _putenv_s(kCI, "1"); // set flag for child processes
break; break;
@@ -81,44 +89,12 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
} }
#endif #endif
bool run_as_node = IsEnvSet(kRunAsNode);
// Make sure the output is printed to console. // Make sure the output is printed to console.
if (run_as_node || !IsEnvSet("ELECTRON_NO_ATTACH_CONSOLE")) if (run_as_node || !IsEnvSet("ELECTRON_NO_ATTACH_CONSOLE"))
base::RouteStdioToConsole(false); base::RouteStdioToConsole(false);
// Convert argv to to UTF8
char** argv = new char*[argc];
for (int i = 0; i < argc; i++) {
// Compute the size of the required buffer
DWORD size = WideCharToMultiByte(CP_UTF8,
0,
wargv[i],
-1,
NULL,
0,
NULL,
NULL);
if (size == 0) {
// This should never happen.
fprintf(stderr, "Could not convert arguments to utf8.");
exit(1);
}
// Do the actual conversion
argv[i] = new char[size];
DWORD result = WideCharToMultiByte(CP_UTF8,
0,
wargv[i],
-1,
argv[i],
size,
NULL,
NULL);
if (result == 0) {
// This should never happen.
fprintf(stderr, "Could not convert arguments to utf8.");
exit(1);
}
}
#ifndef DEBUG #ifndef DEBUG
// Chromium has its own TLS subsystem which supports automatic destruction // Chromium has its own TLS subsystem which supports automatic destruction
// of thread-local data, and also depends on memory allocation routines // of thread-local data, and also depends on memory allocation routines
@@ -139,14 +115,23 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
#endif #endif
if (run_as_node) { if (run_as_node) {
// Now that argv conversion is done, we can finally start. std::vector<char*> argv(arguments.argc);
std::transform(
arguments.argv, arguments.argv + arguments.argc, argv.begin(),
[](auto& a) { return _strdup(base::WideToUTF8(a).c_str()); });
base::AtExitManager atexit_manager; base::AtExitManager atexit_manager;
base::i18n::InitializeICU(); base::i18n::InitializeICU();
return atom::NodeMain(argc, argv); auto ret = atom::NodeMain(argv.size(), argv.data());
std::for_each(argv.begin(), argv.end(), free);
return ret;
} else if (IsEnvSet("ELECTRON_INTERNAL_CRASH_SERVICE")) { } else if (IsEnvSet("ELECTRON_INTERNAL_CRASH_SERVICE")) {
return crash_service::Main(cmd); return crash_service::Main(cmd);
} }
if (!atom::CheckCommandLineArguments(arguments.argc, arguments.argv))
return -1;
sandbox::SandboxInterfaceInfo sandbox_info = {0}; sandbox::SandboxInterfaceInfo sandbox_info = {0};
content::InitializeSandboxInfo(&sandbox_info); content::InitializeSandboxInfo(&sandbox_info);
atom::AtomMainDelegate delegate; atom::AtomMainDelegate delegate;
@@ -154,33 +139,32 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
content::ContentMainParams params(&delegate); content::ContentMainParams params(&delegate);
params.instance = instance; params.instance = instance;
params.sandbox_info = &sandbox_info; params.sandbox_info = &sandbox_info;
atom::AtomCommandLine::Init(argc, argv); atom::AtomCommandLine::Init(arguments.argc, arguments.argv);
atom::AtomCommandLine::InitW(argc, wargv);
return content::ContentMain(params); return content::ContentMain(params);
} }
#elif defined(OS_LINUX) // defined(OS_WIN) #elif defined(OS_LINUX) // defined(OS_WIN)
int main(int argc, const char* argv[]) { int main(int argc, char* argv[]) {
if (IsEnvSet(kRunAsNode)) { if (IsEnvSet(kRunAsNode)) {
base::i18n::InitializeICU(); base::i18n::InitializeICU();
base::AtExitManager atexit_manager; base::AtExitManager atexit_manager;
return atom::NodeMain(argc, const_cast<char**>(argv)); return atom::NodeMain(argc, argv);
} }
atom::AtomMainDelegate delegate; atom::AtomMainDelegate delegate;
content::ContentMainParams params(&delegate); content::ContentMainParams params(&delegate);
params.argc = argc; params.argc = argc;
params.argv = argv; params.argv = const_cast<const char**>(argv);
atom::AtomCommandLine::Init(argc, argv); atom::AtomCommandLine::Init(argc, argv);
return content::ContentMain(params); return content::ContentMain(params);
} }
#else // defined(OS_LINUX) #else // defined(OS_LINUX)
int main(int argc, const char* argv[]) { int main(int argc, char* argv[]) {
if (IsEnvSet(kRunAsNode)) { if (IsEnvSet(kRunAsNode)) {
return AtomInitializeICUandStartNode(argc, const_cast<char**>(argv)); return AtomInitializeICUandStartNode(argc, argv);
} }
return AtomMain(argc, argv); return AtomMain(argc, argv);

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,17 @@
// Copyright (c) 2018 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_APP_COMMAND_LINE_ARGS_H_
#define ATOM_APP_COMMAND_LINE_ARGS_H_
#include "base/command_line.h"
namespace atom {
bool CheckCommandLineArguments(int argc, base::CommandLine::CharType** argv);
} // namespace atom
#endif // ATOM_APP_COMMAND_LINE_ARGS_H_

View File

@@ -861,11 +861,7 @@ bool App::Relaunch(mate::Arguments* js_args) {
} }
if (!override_argv) { if (!override_argv) {
#if defined(OS_WIN)
const relauncher::StringVector& argv = atom::AtomCommandLine::wargv();
#else
const relauncher::StringVector& argv = atom::AtomCommandLine::argv(); const relauncher::StringVector& argv = atom::AtomCommandLine::argv();
#endif
return relauncher::RelaunchApp(argv); return relauncher::RelaunchApp(argv);
} }

View File

@@ -68,8 +68,8 @@ void BrowserView::Init(v8::Isolate* isolate,
web_contents_.Reset(isolate, web_contents.ToV8()); web_contents_.Reset(isolate, web_contents.ToV8());
api_web_contents_ = web_contents.get(); api_web_contents_ = web_contents.get();
view_.reset(NativeBrowserView::Create( view_.reset(
api_web_contents_->managed_web_contents()->GetView())); NativeBrowserView::Create(api_web_contents_->managed_web_contents()));
InitWith(isolate, wrapper); InitWith(isolate, wrapper);
} }

View File

@@ -60,6 +60,7 @@ void DesktopCapturer::StartHandling(bool capture_window,
// implemetation. This is a known and wontFix issue in webrtc (see: // implemetation. This is a known and wontFix issue in webrtc (see:
// http://code.google.com/p/webrtc/issues/detail?id=3373) // http://code.google.com/p/webrtc/issues/detail?id=3373)
options.set_disable_effects(false); options.set_disable_effects(false);
options.set_allow_directx_capturer(true);
#endif #endif
std::unique_ptr<webrtc::DesktopCapturer> screen_capturer( std::unique_ptr<webrtc::DesktopCapturer> screen_capturer(

View File

@@ -22,22 +22,16 @@ MenuViews::MenuViews(v8::Isolate* isolate, v8::Local<v8::Object> wrapper)
void MenuViews::PopupAt( void MenuViews::PopupAt(
Window* window, int x, int y, int positioning_item, bool async) { Window* window, int x, int y, int positioning_item, bool async) {
NativeWindow* native_window = static_cast<NativeWindow*>(window->window()); auto* native_window = static_cast<NativeWindowViews*>(window->window());
if (!native_window) if (!native_window)
return; return;
content::WebContents* web_contents = native_window->web_contents();
if (!web_contents)
return;
content::RenderWidgetHostView* view = web_contents->GetRenderWidgetHostView();
if (!view)
return;
// (-1, -1) means showing on mouse location. // (-1, -1) means showing on mouse location.
gfx::Point location; gfx::Point location;
if (x == -1 || y == -1) { if (x == -1 || y == -1) {
location = display::Screen::GetScreen()->GetCursorScreenPoint(); location = display::Screen::GetScreen()->GetCursorScreenPoint();
} else { } else {
gfx::Point origin = view->GetViewBounds().origin(); gfx::Point origin = native_window->GetContentBounds().origin();
location = gfx::Point(origin.x() + x, origin.y() + y); location = gfx::Point(origin.x() + x, origin.y() + y);
} }
@@ -55,7 +49,7 @@ void MenuViews::PopupAt(
menu_runners_[window_id] = std::unique_ptr<MenuRunner>(new MenuRunner( menu_runners_[window_id] = std::unique_ptr<MenuRunner>(new MenuRunner(
model(), flags, close_callback)); model(), flags, close_callback));
ignore_result(menu_runners_[window_id]->RunMenuAt( ignore_result(menu_runners_[window_id]->RunMenuAt(
static_cast<NativeWindowViews*>(window->window())->widget(), native_window->widget(),
NULL, NULL,
gfx::Rect(location, gfx::Size()), gfx::Rect(location, gfx::Size()),
views::MENU_ANCHOR_TOPLEFT, views::MENU_ANCHOR_TOPLEFT,

View File

@@ -78,10 +78,6 @@ class Protocol : public mate::TrackableObject<Protocol> {
net::URLRequestJob* MaybeCreateJob( net::URLRequestJob* MaybeCreateJob(
net::URLRequest* request, net::URLRequest* request,
net::NetworkDelegate* network_delegate) const override { net::NetworkDelegate* network_delegate) const override {
if (!request->initiator().has_value()) {
// Don't intercept this request as it was created by `net.request`.
return nullptr;
}
RequestJob* request_job = new RequestJob(request, network_delegate); RequestJob* request_job = new RequestJob(request, network_delegate);
request_job->SetHandlerInfo(isolate_, request_context_.get(), handler_); request_job->SetHandlerInfo(isolate_, request_context_.get(), handler_);
return request_job; return request_job;

View File

@@ -271,6 +271,9 @@ content::ServiceWorkerContext* GetServiceWorkerContext(
void OnCapturePageDone(const base::Callback<void(const gfx::Image&)>& callback, void OnCapturePageDone(const base::Callback<void(const gfx::Image&)>& callback,
const SkBitmap& bitmap, const SkBitmap& bitmap,
content::ReadbackResponse response) { content::ReadbackResponse response) {
// Hack to enable transparency in captured image
// TODO(nitsakh) Remove hack once fixed in chromium
const_cast<SkBitmap&>(bitmap).setAlphaType(kPremul_SkAlphaType);
callback.Run(gfx::Image::CreateFrom1xBitmap(bitmap)); callback.Run(gfx::Image::CreateFrom1xBitmap(bitmap));
} }
@@ -377,8 +380,8 @@ WebContents::WebContents(v8::Isolate* isolate, const mate::Dictionary& options)
options.Get("transparent", &transparent); options.Get("transparent", &transparent);
content::WebContents::CreateParams params(session->browser_context()); content::WebContents::CreateParams params(session->browser_context());
auto* view = new OffScreenWebContentsView( auto* view = new OffScreenWebContentsView(transparent,
transparent, base::Bind(&WebContents::OnPaint, base::Unretained(this))); base::Bind(&WebContents::OnPaint, base::Unretained(this)));
params.view = view; params.view = view;
params.delegate_view = view; params.delegate_view = view;
@@ -1644,10 +1647,10 @@ void WebContents::StartPainting() {
return; return;
#if defined(ENABLE_OSR) #if defined(ENABLE_OSR)
auto* osr_rwhv = static_cast<OffScreenRenderWidgetHostView*>( const auto* wc_impl = static_cast<content::WebContentsImpl*>(web_contents());
web_contents()->GetRenderWidgetHostView()); auto* osr_wcv = static_cast<OffScreenWebContentsView*>(wc_impl->GetView());
if (osr_rwhv) if (osr_wcv)
osr_rwhv->SetPainting(true); osr_wcv->SetPainting(true);
#endif #endif
} }
@@ -1656,10 +1659,10 @@ void WebContents::StopPainting() {
return; return;
#if defined(ENABLE_OSR) #if defined(ENABLE_OSR)
auto* osr_rwhv = static_cast<OffScreenRenderWidgetHostView*>( const auto* wc_impl = static_cast<content::WebContentsImpl*>(web_contents());
web_contents()->GetRenderWidgetHostView()); auto* osr_wcv = static_cast<OffScreenWebContentsView*>(wc_impl->GetView());
if (osr_rwhv) if (osr_wcv)
osr_rwhv->SetPainting(false); osr_wcv->SetPainting(false);
#endif #endif
} }
@@ -1668,9 +1671,10 @@ bool WebContents::IsPainting() const {
return false; return false;
#if defined(ENABLE_OSR) #if defined(ENABLE_OSR)
const auto* osr_rwhv = static_cast<OffScreenRenderWidgetHostView*>( const auto* wc_impl = static_cast<content::WebContentsImpl*>(web_contents());
web_contents()->GetRenderWidgetHostView()); auto* osr_wcv = static_cast<OffScreenWebContentsView*>(wc_impl->GetView());
return osr_rwhv && osr_rwhv->IsPainting();
return osr_wcv && osr_wcv->IsPainting();
#else #else
return false; return false;
#endif #endif
@@ -1681,10 +1685,11 @@ void WebContents::SetFrameRate(int frame_rate) {
return; return;
#if defined(ENABLE_OSR) #if defined(ENABLE_OSR)
auto* osr_rwhv = static_cast<OffScreenRenderWidgetHostView*>( const auto* wc_impl = static_cast<content::WebContentsImpl*>(web_contents());
web_contents()->GetRenderWidgetHostView()); auto* osr_wcv = static_cast<OffScreenWebContentsView*>(wc_impl->GetView());
if (osr_rwhv)
osr_rwhv->SetFrameRate(frame_rate); if (osr_wcv)
osr_wcv->SetFrameRate(frame_rate);
#endif #endif
} }
@@ -1693,9 +1698,10 @@ int WebContents::GetFrameRate() const {
return 0; return 0;
#if defined(ENABLE_OSR) #if defined(ENABLE_OSR)
const auto* osr_rwhv = static_cast<OffScreenRenderWidgetHostView*>( const auto* wc_impl = static_cast<content::WebContentsImpl*>(web_contents());
web_contents()->GetRenderWidgetHostView()); auto* osr_wcv = static_cast<OffScreenWebContentsView*>(wc_impl->GetView());
return osr_rwhv ? osr_rwhv->GetFrameRate() : 0;
return osr_wcv ? osr_wcv->GetFrameRate() : 0;
#else #else
return 0; return 0;
#endif #endif
@@ -1765,6 +1771,14 @@ v8::Local<v8::Value> WebContents::GetWebPreferences(v8::Isolate* isolate) {
return mate::ConvertToV8(isolate, *web_preferences->web_preferences()); return mate::ConvertToV8(isolate, *web_preferences->web_preferences());
} }
v8::Local<v8::Value> WebContents::GetLastWebPreferences(v8::Isolate* isolate) {
WebContentsPreferences* web_preferences =
WebContentsPreferences::FromWebContents(web_contents());
if (!web_preferences)
return v8::Null(isolate);
return mate::ConvertToV8(isolate, *web_preferences->last_web_preferences());
}
v8::Local<v8::Value> WebContents::GetOwnerBrowserWindow() { v8::Local<v8::Value> WebContents::GetOwnerBrowserWindow() {
if (owner_window()) if (owner_window())
return Window::From(isolate(), owner_window()); return Window::From(isolate(), owner_window());
@@ -1911,6 +1925,7 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
.SetMethod("_getZoomFactor", &WebContents::GetZoomFactor) .SetMethod("_getZoomFactor", &WebContents::GetZoomFactor)
.SetMethod("getType", &WebContents::GetType) .SetMethod("getType", &WebContents::GetType)
.SetMethod("getWebPreferences", &WebContents::GetWebPreferences) .SetMethod("getWebPreferences", &WebContents::GetWebPreferences)
.SetMethod("getLastWebPreferences", &WebContents::GetLastWebPreferences)
.SetMethod("getOwnerBrowserWindow", &WebContents::GetOwnerBrowserWindow) .SetMethod("getOwnerBrowserWindow", &WebContents::GetOwnerBrowserWindow)
.SetMethod("hasServiceWorker", &WebContents::HasServiceWorker) .SetMethod("hasServiceWorker", &WebContents::HasServiceWorker)
.SetMethod("unregisterServiceWorker", .SetMethod("unregisterServiceWorker",

View File

@@ -212,6 +212,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
// Returns the web preferences of current WebContents. // Returns the web preferences of current WebContents.
v8::Local<v8::Value> GetWebPreferences(v8::Isolate* isolate); v8::Local<v8::Value> GetWebPreferences(v8::Isolate* isolate);
v8::Local<v8::Value> GetLastWebPreferences(v8::Isolate* isolate);
// Returns the owner window. // Returns the owner window.
v8::Local<v8::Value> GetOwnerBrowserWindow(); v8::Local<v8::Value> GetOwnerBrowserWindow();

View File

@@ -889,6 +889,8 @@ void Window::SetBrowserView(v8::Local<v8::Value> value) {
window_->SetBrowserView(browser_view->view()); window_->SetBrowserView(browser_view->view());
browser_view->web_contents()->SetOwnerWindow(window_.get()); browser_view->web_contents()->SetOwnerWindow(window_.get());
browser_view_.Reset(isolate(), value); browser_view_.Reset(isolate(), value);
window_->UpdateDraggableRegionViews();
} }
} }

View File

@@ -38,6 +38,7 @@
#include "content/public/browser/resource_dispatcher_host.h" #include "content/public/browser/resource_dispatcher_host.h"
#include "content/public/browser/site_instance.h" #include "content/public/browser/site_instance.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
#include "content/public/common/content_paths.h"
#include "content/public/common/content_switches.h" #include "content/public/common/content_switches.h"
#include "content/public/common/url_constants.h" #include "content/public/common/url_constants.h"
#include "content/public/common/web_preferences.h" #include "content/public/common/web_preferences.h"
@@ -243,6 +244,11 @@ void AtomBrowserClient::OverrideSiteInstanceForNavigation(
void AtomBrowserClient::AppendExtraCommandLineSwitches( void AtomBrowserClient::AppendExtraCommandLineSwitches(
base::CommandLine* command_line, base::CommandLine* command_line,
int process_id) { int process_id) {
// Make sure we're about to launch a known executable
base::FilePath child_path;
PathService::Get(content::CHILD_PROCESS_EXE, &child_path);
CHECK(base::MakeAbsoluteFilePath(command_line->GetProgram()) == child_path);
std::string process_type = std::string process_type =
command_line->GetSwitchValueASCII(::switches::kProcessType); command_line->GetSwitchValueASCII(::switches::kProcessType);
if (process_type != ::switches::kRendererProcess) if (process_type != ::switches::kRendererProcess)

View File

@@ -7,14 +7,23 @@
#include "atom/browser/native_browser_view.h" #include "atom/browser/native_browser_view.h"
#include "atom/browser/api/atom_api_web_contents.h" #include "atom/browser/api/atom_api_web_contents.h"
#include "brightray/browser/inspectable_web_contents_view.h" #include "brightray/browser/inspectable_web_contents.h"
namespace atom { namespace atom {
NativeBrowserView::NativeBrowserView( NativeBrowserView::NativeBrowserView(
brightray::InspectableWebContentsView* web_contents_view) brightray::InspectableWebContents* inspectable_web_contents)
: web_contents_view_(web_contents_view) {} : inspectable_web_contents_(inspectable_web_contents) {}
NativeBrowserView::~NativeBrowserView() {} NativeBrowserView::~NativeBrowserView() {}
brightray::InspectableWebContentsView*
NativeBrowserView::GetInspectableWebContentsView() {
return inspectable_web_contents_->GetView();
}
content::WebContents* NativeBrowserView::GetWebContents() {
return inspectable_web_contents_->GetWebContents();
}
} // namespace atom } // namespace atom

View File

@@ -9,9 +9,11 @@
#include "atom/common/draggable_region.h" #include "atom/common/draggable_region.h"
#include "base/macros.h" #include "base/macros.h"
#include "content/public/browser/web_contents.h"
#include "third_party/skia/include/core/SkColor.h" #include "third_party/skia/include/core/SkColor.h"
namespace brightray { namespace brightray {
class InspectableWebContents;
class InspectableWebContentsView; class InspectableWebContentsView;
} }
@@ -31,12 +33,15 @@ class NativeBrowserView {
virtual ~NativeBrowserView(); virtual ~NativeBrowserView();
static NativeBrowserView* Create( static NativeBrowserView* Create(
brightray::InspectableWebContentsView* web_contents_view); brightray::InspectableWebContents* inspectable_web_contents);
brightray::InspectableWebContentsView* GetInspectableWebContentsView() { brightray::InspectableWebContents* GetInspectableWebContents() {
return web_contents_view_; return inspectable_web_contents_;
} }
brightray::InspectableWebContentsView* GetInspectableWebContentsView();
content::WebContents* GetWebContents();
virtual void SetAutoResizeFlags(uint8_t flags) = 0; virtual void SetAutoResizeFlags(uint8_t flags) = 0;
virtual void SetBounds(const gfx::Rect& bounds) = 0; virtual void SetBounds(const gfx::Rect& bounds) = 0;
virtual void SetBackgroundColor(SkColor color) = 0; virtual void SetBackgroundColor(SkColor color) = 0;
@@ -47,9 +52,9 @@ class NativeBrowserView {
protected: protected:
explicit NativeBrowserView( explicit NativeBrowserView(
brightray::InspectableWebContentsView* web_contents_view); brightray::InspectableWebContents* inspectable_web_contents);
brightray::InspectableWebContentsView* web_contents_view_; brightray::InspectableWebContents* inspectable_web_contents_;
private: private:
DISALLOW_COPY_AND_ASSIGN(NativeBrowserView); DISALLOW_COPY_AND_ASSIGN(NativeBrowserView);

View File

@@ -17,12 +17,13 @@ namespace atom {
class NativeBrowserViewMac : public NativeBrowserView { class NativeBrowserViewMac : public NativeBrowserView {
public: public:
explicit NativeBrowserViewMac( explicit NativeBrowserViewMac(
brightray::InspectableWebContentsView* web_contents_view); brightray::InspectableWebContents* inspectable_web_contents);
~NativeBrowserViewMac() override; ~NativeBrowserViewMac() override;
void SetAutoResizeFlags(uint8_t flags) override; void SetAutoResizeFlags(uint8_t flags) override;
void SetBounds(const gfx::Rect& bounds) override; void SetBounds(const gfx::Rect& bounds) override;
void SetBackgroundColor(SkColor color) override; void SetBackgroundColor(SkColor color) override;
void UpdateDraggableRegions( void UpdateDraggableRegions(
const std::vector<gfx::Rect>& system_drag_exclude_areas) override; const std::vector<gfx::Rect>& system_drag_exclude_areas) override;

View File

@@ -4,6 +4,7 @@
#include "atom/browser/native_browser_view_mac.h" #include "atom/browser/native_browser_view_mac.h"
#include "brightray/browser/inspectable_web_contents.h"
#include "brightray/browser/inspectable_web_contents_view.h" #include "brightray/browser/inspectable_web_contents_view.h"
#include "skia/ext/skia_utils_mac.h" #include "skia/ext/skia_utils_mac.h"
#include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect.h"
@@ -156,8 +157,8 @@ const NSAutoresizingMaskOptions kDefaultAutoResizingMask =
namespace atom { namespace atom {
NativeBrowserViewMac::NativeBrowserViewMac( NativeBrowserViewMac::NativeBrowserViewMac(
brightray::InspectableWebContentsView* web_contents_view) brightray::InspectableWebContents* inspectable_web_contents)
: NativeBrowserView(web_contents_view) { : NativeBrowserView(inspectable_web_contents) {
auto* view = GetInspectableWebContentsView()->GetNativeView(); auto* view = GetInspectableWebContentsView()->GetNativeView();
view.autoresizingMask = kDefaultAutoResizingMask; view.autoresizingMask = kDefaultAutoResizingMask;
} }
@@ -193,62 +194,46 @@ void NativeBrowserViewMac::SetBackgroundColor(SkColor color) {
} }
void NativeBrowserViewMac::UpdateDraggableRegions( void NativeBrowserViewMac::UpdateDraggableRegions(
const std::vector<gfx::Rect>& system_drag_exclude_areas) { const std::vector<gfx::Rect>& drag_exclude_rects) {
NSView* webView = GetInspectableWebContentsView()->GetNativeView(); NSView* web_view = GetWebContents()->GetNativeView();
NSView* inspectable_view = GetInspectableWebContentsView()->GetNativeView();
NSView* window_content_view = inspectable_view.superview;
const auto window_content_view_height = NSHeight(window_content_view.bounds);
NSInteger superViewHeight = NSHeight([webView.superview bounds]); // Remove all DragRegionViews that were added last time. Note that we need
NSInteger webViewHeight = NSHeight([webView bounds]); // to copy the `subviews` array to avoid mutation during iteration.
NSInteger webViewWidth = NSWidth([webView bounds]); base::scoped_nsobject<NSArray> subviews([[web_view subviews] copy]);
NSInteger webViewX = NSMinX([webView frame]); for (NSView* subview in subviews.get()) {
NSInteger webViewY = 0; if ([subview isKindOfClass:[DragRegionView class]]) {
// Apple's NSViews have their coordinate system originate at the bottom left,
// meaning that we need to be a bit smarter when it comes to calculating our
// current top offset
if (webViewHeight > superViewHeight) {
webViewY = std::abs(webViewHeight - superViewHeight - (std::abs(NSMinY([webView frame]))));
} else {
webViewY = superViewHeight - NSMaxY([webView frame]);
}
// Remove all DraggableRegionViews that are added last time.
// Note that [webView subviews] returns the view's mutable internal array and
// it should be copied to avoid mutating the original array while enumerating
// it.
base::scoped_nsobject<NSArray> subviews([[webView subviews] copy]);
for (NSView* subview in subviews.get())
if ([subview isKindOfClass:[DragRegionView class]])
[subview removeFromSuperview]; [subview removeFromSuperview];
}
}
// Create one giant NSView that is draggable. // Create one giant NSView that is draggable.
base::scoped_nsobject<NSView> dragRegion( base::scoped_nsobject<NSView> drag_region_view(
[[DragRegionView alloc] initWithFrame:NSZeroRect]); [[DragRegionView alloc] initWithFrame:web_view.bounds]);
[dragRegion setFrame:NSMakeRect(0, [web_view addSubview:drag_region_view];
0,
webViewWidth,
webViewHeight)];
// Then, on top of that, add "exclusion zones" // Then, on top of that, add "exclusion zones"
for (auto iter = system_drag_exclude_areas.begin(); for (const auto& rect : drag_exclude_rects) {
iter != system_drag_exclude_areas.end(); const auto window_content_view_exclude_rect =
++iter) { NSMakeRect(rect.x(), window_content_view_height - rect.bottom(),
base::scoped_nsobject<NSView> controlRegion( rect.width(), rect.height());
[[ExcludeDragRegionView alloc] initWithFrame:NSZeroRect]); const auto drag_region_view_exclude_rect =
[controlRegion setFrame:NSMakeRect(iter->x() - webViewX, [window_content_view convertRect:window_content_view_exclude_rect
webViewHeight - iter->bottom() + webViewY, toView:drag_region_view];
iter->width(),
iter->height())];
[dragRegion addSubview:controlRegion];
}
// Add the DragRegion to the WebView base::scoped_nsobject<NSView> exclude_drag_region_view(
[webView addSubview:dragRegion]; [[ExcludeDragRegionView alloc]
initWithFrame:drag_region_view_exclude_rect]);
[drag_region_view addSubview:exclude_drag_region_view];
}
} }
// static // static
NativeBrowserView* NativeBrowserView::Create( NativeBrowserView* NativeBrowserView::Create(
brightray::InspectableWebContentsView* web_contents_view) { brightray::InspectableWebContents* inspectable_web_contents) {
return new NativeBrowserViewMac(web_contents_view); return new NativeBrowserViewMac(inspectable_web_contents);
} }
} // namespace atom } // namespace atom

View File

@@ -12,8 +12,8 @@
namespace atom { namespace atom {
NativeBrowserViewViews::NativeBrowserViewViews( NativeBrowserViewViews::NativeBrowserViewViews(
brightray::InspectableWebContentsView* web_contents_view) brightray::InspectableWebContents* inspectable_web_contents)
: NativeBrowserView(web_contents_view) {} : NativeBrowserView(inspectable_web_contents) {}
NativeBrowserViewViews::~NativeBrowserViewViews() {} NativeBrowserViewViews::~NativeBrowserViewViews() {}
@@ -29,8 +29,8 @@ void NativeBrowserViewViews::SetBackgroundColor(SkColor color) {
// static // static
NativeBrowserView* NativeBrowserView::Create( NativeBrowserView* NativeBrowserView::Create(
brightray::InspectableWebContentsView* web_contents_view) { brightray::InspectableWebContents* inspectable_web_contents) {
return new NativeBrowserViewViews(web_contents_view); return new NativeBrowserViewViews(inspectable_web_contents);
} }
} // namespace atom } // namespace atom

View File

@@ -12,7 +12,7 @@ namespace atom {
class NativeBrowserViewViews : public NativeBrowserView { class NativeBrowserViewViews : public NativeBrowserView {
public: public:
explicit NativeBrowserViewViews( explicit NativeBrowserViewViews(
brightray::InspectableWebContentsView* web_contents_view); brightray::InspectableWebContents* inspectable_web_contents);
~NativeBrowserViewViews() override; ~NativeBrowserViewViews() override;
uint8_t GetAutoResizeFlags() { return auto_resize_flags_; } uint8_t GetAutoResizeFlags() { return auto_resize_flags_; }

View File

@@ -237,6 +237,8 @@ class NativeWindow : public base::SupportsUserData,
const std::vector<base::string16>& labels) {} const std::vector<base::string16>& labels) {}
virtual void HideAutofillPopup(content::RenderFrameHost* frame_host) {} virtual void HideAutofillPopup(content::RenderFrameHost* frame_host) {}
virtual void UpdateDraggableRegionViews() {}
// Public API used by platform-dependent delegates and observers to send UI // Public API used by platform-dependent delegates and observers to send UI
// related notifications. // related notifications.
void NotifyWindowClosed(); void NotifyWindowClosed();

View File

@@ -126,7 +126,7 @@ class NativeWindowMac : public NativeWindow,
content::RenderViewHost* new_host) override; content::RenderViewHost* new_host) override;
// Refresh the DraggableRegion views. // Refresh the DraggableRegion views.
void UpdateDraggableRegionViews() { void UpdateDraggableRegionViews() override {
UpdateDraggableRegionViews(draggable_regions_); UpdateDraggableRegionViews(draggable_regions_);
} }

View File

@@ -1932,25 +1932,20 @@ void NativeWindowMac::UpdateDraggableRegionViews(
// Draggable regions is implemented by having the whole web view draggable // Draggable regions is implemented by having the whole web view draggable
// (mouseDownCanMoveWindow) and overlaying regions that are not draggable. // (mouseDownCanMoveWindow) and overlaying regions that are not draggable.
std::vector<gfx::Rect> system_drag_exclude_areas = std::vector<gfx::Rect> drag_exclude_rects =
CalculateNonDraggableRegions(regions, webViewWidth, webViewHeight); CalculateNonDraggableRegions(regions, webViewWidth, webViewHeight);
if (browser_view_) { if (browser_view_) {
browser_view_->UpdateDraggableRegions(system_drag_exclude_areas); browser_view_->UpdateDraggableRegions(drag_exclude_rects);
} }
// Create and add a ControlRegionView for each region that needs to be // Create and add a ControlRegionView for each region that needs to be
// excluded from the dragging. // excluded from the dragging.
for (std::vector<gfx::Rect>::const_iterator iter = for (const auto& rect : drag_exclude_rects) {
system_drag_exclude_areas.begin();
iter != system_drag_exclude_areas.end();
++iter) {
base::scoped_nsobject<NSView> controlRegion( base::scoped_nsobject<NSView> controlRegion(
[[ControlRegionView alloc] initWithFrame:NSZeroRect]); [[ControlRegionView alloc] initWithFrame:NSZeroRect]);
[controlRegion setFrame:NSMakeRect(iter->x(), [controlRegion setFrame:NSMakeRect(rect.x(), webViewHeight - rect.bottom(),
webViewHeight - iter->bottom(), rect.width(), rect.height())];
iter->width(),
iter->height())];
[webView addSubview:controlRegion]; [webView addSubview:controlRegion];
} }

View File

@@ -53,6 +53,7 @@
#include "atom/browser/ui/views/win_frame_view.h" #include "atom/browser/ui/views/win_frame_view.h"
#include "atom/browser/ui/win/atom_desktop_native_widget_aura.h" #include "atom/browser/ui/win/atom_desktop_native_widget_aura.h"
#include "atom/browser/ui/win/atom_desktop_window_tree_host_win.h" #include "atom/browser/ui/win/atom_desktop_window_tree_host_win.h"
#include "content/public/browser/gpu_data_manager.h"
#include "skia/ext/skia_utils_win.h" #include "skia/ext/skia_utils_win.h"
#include "ui/base/win/shell.h" #include "ui/base/win/shell.h"
#include "ui/display/display.h" #include "ui/display/display.h"
@@ -297,9 +298,12 @@ NativeWindowViews::NativeWindowViews(
::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, frame_style); ::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, frame_style);
} }
bool hardware_accelerated =
content::GpuDataManager::GetInstance()->HardwareAccelerationEnabled();
LONG ex_style = ::GetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE); LONG ex_style = ::GetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE);
// Window without thick frame has to have WS_EX_COMPOSITED style. // Window without thick frame has to have WS_EX_COMPOSITED style when GPU
if (!thick_frame_) // acceleration is enabled.
if (!thick_frame_ && hardware_accelerated)
ex_style |= WS_EX_COMPOSITED; ex_style |= WS_EX_COMPOSITED;
if (window_type == "toolbar") if (window_type == "toolbar")
ex_style |= WS_EX_TOOLWINDOW; ex_style |= WS_EX_TOOLWINDOW;
@@ -1363,22 +1367,26 @@ void NativeWindowViews::ShowAutofillPopup(
const gfx::RectF& bounds, const gfx::RectF& bounds,
const std::vector<base::string16>& values, const std::vector<base::string16>& values,
const std::vector<base::string16>& labels) { const std::vector<base::string16>& labels) {
const auto* web_preferences =
WebContentsPreferences::FromWebContents(web_contents)->web_preferences();
bool is_offsceen = false; bool is_offsceen = false;
web_preferences->GetBoolean("offscreen", &is_offsceen);
int guest_instance_id = 0;
web_preferences->GetInteger(options::kGuestInstanceID, &guest_instance_id);
bool is_embedder_offscreen = false; bool is_embedder_offscreen = false;
if (guest_instance_id) {
auto manager = WebViewManager::GetWebViewManager(web_contents); auto* web_contents_preferences =
if (manager) { WebContentsPreferences::FromWebContents(web_contents);
auto embedder = manager->GetEmbedder(guest_instance_id); if (web_contents_preferences) {
if (embedder) { const auto* web_preferences = web_contents_preferences->web_preferences();
is_embedder_offscreen = WebContentsPreferences::IsPreferenceEnabled(
"offscreen", embedder); web_preferences->GetBoolean("offscreen", &is_offsceen);
int guest_instance_id = 0;
web_preferences->GetInteger(options::kGuestInstanceID, &guest_instance_id);
if (guest_instance_id) {
auto manager = WebViewManager::GetWebViewManager(web_contents);
if (manager) {
auto embedder = manager->GetEmbedder(guest_instance_id);
if (embedder) {
is_embedder_offscreen = WebContentsPreferences::IsPreferenceEnabled(
"offscreen", embedder);
}
} }
} }
} }

View File

@@ -245,10 +245,21 @@ void URLRequestAsarJob::FetchMetaInfo(const base::FilePath& file_path,
meta_info->file_size = file_info.size; meta_info->file_size = file_info.size;
meta_info->is_directory = file_info.is_directory; meta_info->is_directory = file_info.is_directory;
} }
// On Windows GetMimeTypeFromFile() goes to the registry. Thus it should be
// done in WorkerPool. // We use GetWellKnownMimeTypeFromExtension() to ensure that configurations
meta_info->mime_type_result = // that may have been set by other programs on a user's machine don't affect
net::GetMimeTypeFromFile(file_path, &meta_info->mime_type); // the mime type returned (in particular, JS should always be
// (application/javascript). See https://crbug.com/797712. Using an accurate
// mime type is necessary at least for modules and sw, which enforce strict
// mime type requirements.
// TODO(deepak1556): Revert this when sw support is removed for file scheme.
base::FilePath::StringType file_extension = file_path.Extension();
if (file_extension.empty()) {
meta_info->mime_type_result = false;
} else {
meta_info->mime_type_result = net::GetWellKnownMimeTypeFromExtension(
file_extension.substr(1), &meta_info->mime_type);
}
} }
void URLRequestAsarJob::DidFetchMetaInfo(const FileMetaInfo* meta_info) { void URLRequestAsarJob::DidFetchMetaInfo(const FileMetaInfo* meta_info) {

View File

@@ -7,6 +7,7 @@
#include <string> #include <string>
#include "atom/browser/api/atom_api_url_request.h" #include "atom/browser/api/atom_api_url_request.h"
#include "atom/browser/atom_browser_context.h" #include "atom/browser/atom_browser_context.h"
#include "atom/browser/net/atom_url_request_job_factory.h"
#include "base/callback.h" #include "base/callback.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "net/base/elements_upload_data_stream.h" #include "net/base/elements_upload_data_stream.h"
@@ -120,6 +121,9 @@ void AtomURLRequest::DoInitialize(
request_->set_method(method); request_->set_method(method);
// Do not send cookies from the cookie store. // Do not send cookies from the cookie store.
DoSetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES); DoSetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES);
// Set a flag to stop custom protocol from intercepting this request.
request_->SetUserData(DisableProtocolInterceptFlagKey(),
base::WrapUnique(new base::SupportsUserData::Data()));
} }
void AtomURLRequest::DoTerminate() { void AtomURLRequest::DoTerminate() {

View File

@@ -15,8 +15,18 @@ using content::BrowserThread;
namespace atom { namespace atom {
namespace {
int disable_protocol_intercept_flag_key = 0;
} // namespace
typedef net::URLRequestJobFactory::ProtocolHandler ProtocolHandler; typedef net::URLRequestJobFactory::ProtocolHandler ProtocolHandler;
const void* DisableProtocolInterceptFlagKey() {
return &disable_protocol_intercept_flag_key;
}
AtomURLRequestJobFactory::AtomURLRequestJobFactory() {} AtomURLRequestJobFactory::AtomURLRequestJobFactory() {}
AtomURLRequestJobFactory::~AtomURLRequestJobFactory() { AtomURLRequestJobFactory::~AtomURLRequestJobFactory() {
@@ -93,6 +103,8 @@ net::URLRequestJob* AtomURLRequestJobFactory::MaybeCreateJobWithProtocolHandler(
auto it = protocol_handler_map_.find(scheme); auto it = protocol_handler_map_.find(scheme);
if (it == protocol_handler_map_.end()) if (it == protocol_handler_map_.end())
return nullptr; return nullptr;
if (request->GetUserData(DisableProtocolInterceptFlagKey()))
return nullptr;
return it->second->MaybeCreateJob(request, network_delegate); return it->second->MaybeCreateJob(request, network_delegate);
} }

View File

@@ -16,6 +16,8 @@
namespace atom { namespace atom {
const void* DisableProtocolInterceptFlagKey();
class AtomURLRequestJobFactory : public net::URLRequestJobFactory { class AtomURLRequestJobFactory : public net::URLRequestJobFactory {
public: public:
AtomURLRequestJobFactory(); AtomURLRequestJobFactory();

View File

@@ -42,7 +42,7 @@ void NodeDebugger::Start() {
// the debugger on the first line // the debugger on the first line
if (options.wait_for_connect()) { if (options.wait_for_connect()) {
mate::Dictionary process(env_->isolate(), env_->process_object()); mate::Dictionary process(env_->isolate(), env_->process_object());
process.Set("_debugWaitConnect", true); process.Set("_breakFirstLine", true);
} }
inspector->Start(platform_.get(), nullptr, options); inspector->Start(platform_.get(), nullptr, options);

View File

@@ -124,7 +124,7 @@ class AtomCopyFrameGenerator {
} }
void GenerateCopyFrame(const gfx::Rect& damage_rect) { void GenerateCopyFrame(const gfx::Rect& damage_rect) {
if (!view_->render_widget_host()) if (!view_->render_widget_host() || !view_->IsPainting())
return; return;
std::unique_ptr<cc::CopyOutputRequest> request = std::unique_ptr<cc::CopyOutputRequest> request =
@@ -255,6 +255,8 @@ class AtomBeginFrameTimer : public cc::DelayBasedTimeSourceClient {
OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView( OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
bool transparent, bool transparent,
bool painting,
int frame_rate,
const OnPaintCallback& callback, const OnPaintCallback& callback,
content::RenderWidgetHost* host, content::RenderWidgetHost* host,
OffScreenRenderWidgetHostView* parent_host_view, OffScreenRenderWidgetHostView* parent_host_view,
@@ -268,17 +270,18 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
transparent_(transparent), transparent_(transparent),
callback_(callback), callback_(callback),
parent_callback_(nullptr), parent_callback_(nullptr),
frame_rate_(60), frame_rate_(frame_rate),
frame_rate_threshold_us_(0), frame_rate_threshold_us_(0),
last_time_(base::Time::Now()), last_time_(base::Time::Now()),
scale_factor_(kDefaultScaleFactor), scale_factor_(kDefaultScaleFactor),
size_(native_window->GetSize()), size_(native_window->GetSize()),
painting_(true), painting_(painting),
is_showing_(!render_widget_host_->is_hidden()), is_showing_(!render_widget_host_->is_hidden()),
is_destroyed_(false), is_destroyed_(false),
popup_position_(gfx::Rect()), popup_position_(gfx::Rect()),
hold_resize_(false), hold_resize_(false),
pending_resize_(false), pending_resize_(false),
paint_callback_running_(false),
renderer_compositor_frame_sink_(nullptr), renderer_compositor_frame_sink_(nullptr),
background_color_(SkColor()), background_color_(SkColor()),
weak_ptr_factory_(this) { weak_ptr_factory_(this) {
@@ -303,7 +306,7 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
new ui::Compositor(context_factory_private->AllocateFrameSinkId(), new ui::Compositor(context_factory_private->AllocateFrameSinkId(),
content::GetContextFactory(), context_factory_private, content::GetContextFactory(), context_factory_private,
base::ThreadTaskRunnerHandle::Get())); base::ThreadTaskRunnerHandle::Get()));
compositor_->SetAcceleratedWidget(native_window_->GetAcceleratedWidget()); compositor_->SetAcceleratedWidget(gfx::kNullAcceleratedWidget);
compositor_->SetRootLayer(root_layer_.get()); compositor_->SetRootLayer(root_layer_.get());
#endif #endif
GetCompositor()->SetDelegate(this); GetCompositor()->SetDelegate(this);
@@ -738,6 +741,8 @@ content::RenderWidgetHostViewBase*
return new OffScreenRenderWidgetHostView( return new OffScreenRenderWidgetHostView(
transparent_, transparent_,
true,
embedder_host_view->GetFrameRate(),
callback_, callback_,
render_widget_host, render_widget_host,
embedder_host_view, embedder_host_view,
@@ -930,7 +935,7 @@ bool OffScreenRenderWidgetHostView::IsAutoResizeEnabled() const {
void OffScreenRenderWidgetHostView::SetNeedsBeginFrames( void OffScreenRenderWidgetHostView::SetNeedsBeginFrames(
bool needs_begin_frames) { bool needs_begin_frames) {
SetupFrameRate(false); SetupFrameRate(true);
begin_frame_timer_->SetActive(needs_begin_frames); begin_frame_timer_->SetActive(needs_begin_frames);
@@ -1004,7 +1009,9 @@ void OffScreenRenderWidgetHostView::OnPaint(
} }
damage.Intersect(GetViewBounds()); damage.Intersect(GetViewBounds());
paint_callback_running_ = true;
callback_.Run(damage, bitmap); callback_.Run(damage, bitmap);
paint_callback_running_ = false;
for (size_t i = 0; i < damages.size(); i++) { for (size_t i = 0; i < damages.size(); i++) {
CopyBitmapTo(bitmap, originals[i], damages[i]); CopyBitmapTo(bitmap, originals[i], damages[i]);
@@ -1151,7 +1158,7 @@ void OffScreenRenderWidgetHostView::SetPainting(bool painting) {
painting_ = painting; painting_ = painting;
if (software_output_device_) { if (software_output_device_) {
software_output_device_->SetActive(painting_, true); software_output_device_->SetActive(painting_, !paint_callback_running_);
} }
} }
@@ -1168,16 +1175,16 @@ void OffScreenRenderWidgetHostView::SetFrameRate(int frame_rate) {
} else { } else {
if (frame_rate <= 0) if (frame_rate <= 0)
frame_rate = 1; frame_rate = 1;
if (frame_rate > 60) if (frame_rate > 240)
frame_rate = 60; frame_rate = 240;
frame_rate_ = frame_rate; frame_rate_ = frame_rate;
} }
SetupFrameRate(true);
for (auto guest_host_view : guest_host_views_) for (auto guest_host_view : guest_host_views_)
guest_host_view->SetFrameRate(frame_rate); guest_host_view->SetFrameRate(frame_rate);
SetupFrameRate(true);
} }
int OffScreenRenderWidgetHostView::GetFrameRate() const { int OffScreenRenderWidgetHostView::GetFrameRate() const {
@@ -1205,7 +1212,7 @@ void OffScreenRenderWidgetHostView::SetupFrameRate(bool force) {
frame_rate_threshold_us_ = 1000000 / frame_rate_; frame_rate_threshold_us_ = 1000000 / frame_rate_;
GetCompositor()->vsync_manager()->SetAuthoritativeVSyncInterval( GetCompositor()->SetAuthoritativeVSyncInterval(
base::TimeDelta::FromMicroseconds(frame_rate_threshold_us_)); base::TimeDelta::FromMicroseconds(frame_rate_threshold_us_));
if (copy_frame_generator_.get()) { if (copy_frame_generator_.get()) {

View File

@@ -74,6 +74,8 @@ class OffScreenRenderWidgetHostView
public OffscreenViewProxyObserver { public OffscreenViewProxyObserver {
public: public:
OffScreenRenderWidgetHostView(bool transparent, OffScreenRenderWidgetHostView(bool transparent,
bool painting,
int frame_rate,
const OnPaintCallback& callback, const OnPaintCallback& callback,
content::RenderWidgetHost* render_widget_host, content::RenderWidgetHost* render_widget_host,
OffScreenRenderWidgetHostView* parent_host_view, OffScreenRenderWidgetHostView* parent_host_view,
@@ -314,6 +316,8 @@ class OffScreenRenderWidgetHostView
bool hold_resize_; bool hold_resize_;
bool pending_resize_; bool pending_resize_;
bool paint_callback_running_;
std::unique_ptr<ui::Layer> root_layer_; std::unique_ptr<ui::Layer> root_layer_;
std::unique_ptr<ui::Compositor> compositor_; std::unique_ptr<ui::Compositor> compositor_;
std::unique_ptr<content::DelegatedFrameHost> delegated_frame_host_; std::unique_ptr<content::DelegatedFrameHost> delegated_frame_host_;

View File

@@ -15,6 +15,8 @@ namespace atom {
OffScreenWebContentsView::OffScreenWebContentsView( OffScreenWebContentsView::OffScreenWebContentsView(
bool transparent, const OnPaintCallback& callback) bool transparent, const OnPaintCallback& callback)
: transparent_(transparent), : transparent_(transparent),
painting_(true),
frame_rate_(60),
callback_(callback), callback_(callback),
web_contents_(nullptr) { web_contents_(nullptr) {
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
@@ -103,6 +105,8 @@ content::RenderWidgetHostViewBase*
auto relay = NativeWindowRelay::FromWebContents(web_contents_); auto relay = NativeWindowRelay::FromWebContents(web_contents_);
return new OffScreenRenderWidgetHostView( return new OffScreenRenderWidgetHostView(
transparent_, transparent_,
painting_,
GetFrameRate(),
callback_, callback_,
render_widget_host, render_widget_host,
nullptr, nullptr,
@@ -125,6 +129,8 @@ content::RenderWidgetHostViewBase*
return new OffScreenRenderWidgetHostView( return new OffScreenRenderWidgetHostView(
transparent_, transparent_,
true,
view->GetFrameRate(),
callback_, callback_,
render_widget_host, render_widget_host,
view, view,
@@ -202,6 +208,42 @@ void OffScreenWebContentsView::UpdateDragCursor(
blink::WebDragOperation operation) { blink::WebDragOperation operation) {
} }
void OffScreenWebContentsView::SetPainting(bool painting) {
auto* view = GetView();
if (view != nullptr) {
view->SetPainting(painting);
} else {
painting_ = painting;
}
}
bool OffScreenWebContentsView::IsPainting() const {
auto* view = GetView();
if (view != nullptr) {
return view->IsPainting();
} else {
return painting_;
}
}
void OffScreenWebContentsView::SetFrameRate(int frame_rate) {
auto* view = GetView();
if (view != nullptr) {
view->SetFrameRate(frame_rate);
} else {
frame_rate_ = frame_rate;
}
}
int OffScreenWebContentsView::GetFrameRate() const {
auto* view = GetView();
if (view != nullptr) {
return view->GetFrameRate();
} else {
return frame_rate_;
}
}
OffScreenRenderWidgetHostView* OffScreenWebContentsView::GetView() const { OffScreenRenderWidgetHostView* OffScreenWebContentsView::GetView() const {
if (web_contents_) { if (web_contents_) {
return static_cast<OffScreenRenderWidgetHostView*>( return static_cast<OffScreenRenderWidgetHostView*>(

View File

@@ -69,6 +69,11 @@ class OffScreenWebContentsView : public content::WebContentsView,
content::RenderWidgetHostImpl* source_rwh) override; content::RenderWidgetHostImpl* source_rwh) override;
void UpdateDragCursor(blink::WebDragOperation operation) override; void UpdateDragCursor(blink::WebDragOperation operation) override;
void SetPainting(bool painting);
bool IsPainting() const;
void SetFrameRate(int frame_rate);
int GetFrameRate() const;
private: private:
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
void PlatformCreate(); void PlatformCreate();
@@ -78,6 +83,8 @@ class OffScreenWebContentsView : public content::WebContentsView,
OffScreenRenderWidgetHostView* GetView() const; OffScreenRenderWidgetHostView* GetView() const;
const bool transparent_; const bool transparent_;
bool painting_;
int frame_rate_;
OnPaintCallback callback_; OnPaintCallback callback_;
// Weak refs. // Weak refs.

View File

@@ -140,11 +140,7 @@ bool RelaunchAppWithHelper(const base::FilePath& helper,
} }
int RelauncherMain(const content::MainFunctionParams& main_parameters) { int RelauncherMain(const content::MainFunctionParams& main_parameters) {
#if defined(OS_WIN)
const StringVector& argv = atom::AtomCommandLine::wargv();
#else
const StringVector& argv = atom::AtomCommandLine::argv(); const StringVector& argv = atom::AtomCommandLine::argv();
#endif
if (argv.size() < 4 || argv[1] != internal::kRelauncherTypeArg) { if (argv.size() < 4 || argv[1] != internal::kRelauncherTypeArg) {
LOG(ERROR) << "relauncher process invoked with unexpected arguments"; LOG(ERROR) << "relauncher process invoked with unexpected arguments";

View File

@@ -17,9 +17,9 @@
<key>CFBundleIconFile</key> <key>CFBundleIconFile</key>
<string>electron.icns</string> <string>electron.icns</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>1.8.2</string> <string>1.8.8</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>1.8.2</string> <string>1.8.8</string>
<key>LSApplicationCategoryType</key> <key>LSApplicationCategoryType</key>
<string>public.app-category.developer-tools</string> <string>public.app-category.developer-tools</string>
<key>LSMinimumSystemVersion</key> <key>LSMinimumSystemVersion</key>

View File

@@ -56,8 +56,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,8,2,2 FILEVERSION 1,8,8,0
PRODUCTVERSION 1,8,2,2 PRODUCTVERSION 1,8,8,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@@ -74,12 +74,12 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "GitHub, Inc." VALUE "CompanyName", "GitHub, Inc."
VALUE "FileDescription", "Electron" VALUE "FileDescription", "Electron"
VALUE "FileVersion", "1.8.2" VALUE "FileVersion", "1.8.8"
VALUE "InternalName", "electron.exe" VALUE "InternalName", "electron.exe"
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
VALUE "OriginalFilename", "electron.exe" VALUE "OriginalFilename", "electron.exe"
VALUE "ProductName", "Electron" VALUE "ProductName", "Electron"
VALUE "ProductVersion", "1.8.2" VALUE "ProductVersion", "1.8.8"
VALUE "SquirrelAwareVersion", "1" VALUE "SquirrelAwareVersion", "1"
END END
END END

View File

@@ -154,6 +154,18 @@ bool ShowOpenDialog(const DialogSettings& settings,
return true; return true;
} }
void OpenDialogCompletion(int chosen, NSOpenPanel* dialog,
const DialogSettings& settings,
const OpenDialogCallback& callback) {
if (chosen == NSFileHandlingPanelCancelButton) {
callback.Run(false, std::vector<base::FilePath>());
} else {
std::vector<base::FilePath> paths;
ReadDialogPaths(dialog, &paths);
callback.Run(true, paths);
}
}
void ShowOpenDialog(const DialogSettings& settings, void ShowOpenDialog(const DialogSettings& settings,
const OpenDialogCallback& c) { const OpenDialogCallback& c) {
NSOpenPanel* dialog = [NSOpenPanel openPanel]; NSOpenPanel* dialog = [NSOpenPanel openPanel];
@@ -167,25 +179,14 @@ void ShowOpenDialog(const DialogSettings& settings,
if (!settings.parent_window || !settings.parent_window->GetNativeWindow() || if (!settings.parent_window || !settings.parent_window->GetNativeWindow() ||
settings.force_detached) { settings.force_detached) {
int chosen = [dialog runModal]; [dialog beginWithCompletionHandler:^(NSInteger chosen) {
if (chosen == NSFileHandlingPanelCancelButton) { OpenDialogCompletion(chosen, dialog, settings, callback);
callback.Run(false, std::vector<base::FilePath>()); }];
} else {
std::vector<base::FilePath> paths;
ReadDialogPaths(dialog, &paths);
callback.Run(true, paths);
}
} else { } else {
NSWindow* window = settings.parent_window->GetNativeWindow(); NSWindow* window = settings.parent_window->GetNativeWindow();
[dialog beginSheetModalForWindow:window [dialog beginSheetModalForWindow:window
completionHandler:^(NSInteger chosen) { completionHandler:^(NSInteger chosen) {
if (chosen == NSFileHandlingPanelCancelButton) { OpenDialogCompletion(chosen, dialog, settings, callback);
callback.Run(false, std::vector<base::FilePath>());
} else {
std::vector<base::FilePath> paths;
ReadDialogPaths(dialog, &paths);
callback.Run(true, paths);
}
}]; }];
} }
} }
@@ -205,6 +206,17 @@ bool ShowSaveDialog(const DialogSettings& settings,
return true; return true;
} }
void SaveDialogCompletion(int chosen, NSSavePanel* dialog,
const DialogSettings& settings,
const SaveDialogCallback& callback) {
if (chosen == NSFileHandlingPanelCancelButton) {
callback.Run(false, base::FilePath());
} else {
std::string path = base::SysNSStringToUTF8([[dialog URL] path]);
callback.Run(true, base::FilePath(path));
}
}
void ShowSaveDialog(const DialogSettings& settings, void ShowSaveDialog(const DialogSettings& settings,
const SaveDialogCallback& c) { const SaveDialogCallback& c) {
NSSavePanel* dialog = [NSSavePanel savePanel]; NSSavePanel* dialog = [NSSavePanel savePanel];
@@ -216,23 +228,14 @@ void ShowSaveDialog(const DialogSettings& settings,
if (!settings.parent_window || !settings.parent_window->GetNativeWindow() || if (!settings.parent_window || !settings.parent_window->GetNativeWindow() ||
settings.force_detached) { settings.force_detached) {
int chosen = [dialog runModal]; [dialog beginWithCompletionHandler:^(NSInteger chosen) {
if (chosen == NSFileHandlingPanelCancelButton) { SaveDialogCompletion(chosen, dialog, settings, callback);
callback.Run(false, base::FilePath()); }];
} else {
std::string path = base::SysNSStringToUTF8([[dialog URL] path]);
callback.Run(true, base::FilePath(path));
}
} else { } else {
NSWindow* window = settings.parent_window->GetNativeWindow(); NSWindow* window = settings.parent_window->GetNativeWindow();
[dialog beginSheetModalForWindow:window [dialog beginSheetModalForWindow:window
completionHandler:^(NSInteger chosen) { completionHandler:^(NSInteger chosen) {
if (chosen == NSFileHandlingPanelCancelButton) { SaveDialogCompletion(chosen, dialog, settings, callback);
callback.Run(false, base::FilePath());
} else {
std::string path = base::SysNSStringToUTF8([[dialog URL] path]);
callback.Run(true, base::FilePath(path));
}
}]; }];
} }
} }

View File

@@ -188,7 +188,7 @@ void ShowMessageBox(NativeWindow* parent_window,
if (!parent_window || !parent_window->GetNativeWindow() || if (!parent_window || !parent_window->GetNativeWindow() ||
parent_window->is_offscreen_dummy()) { parent_window->is_offscreen_dummy()) {
int ret = [[alert autorelease] runModal]; int ret = [[alert autorelease] runModal];
callback.Run(ret, false); callback.Run(ret, alert.suppressionButton.state == NSOnState);
} else { } else {
ModalDelegate* delegate = [[ModalDelegate alloc] initWithCallback:callback ModalDelegate* delegate = [[ModalDelegate alloc] initWithCallback:callback
andAlert:alert andAlert:alert

View File

@@ -3,12 +3,16 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "atom/browser/ui/win/atom_desktop_native_widget_aura.h" #include "atom/browser/ui/win/atom_desktop_native_widget_aura.h"
#include "ui/views/corewm/tooltip_controller.h"
#include "ui/wm/public/tooltip_client.h"
namespace atom { namespace atom {
AtomDesktopNativeWidgetAura::AtomDesktopNativeWidgetAura( AtomDesktopNativeWidgetAura::AtomDesktopNativeWidgetAura(
views::internal::NativeWidgetDelegate* delegate) views::internal::NativeWidgetDelegate* delegate)
: views::DesktopNativeWidgetAura(delegate) { : views::DesktopNativeWidgetAura(delegate) {
// This is to enable the override of OnWindowActivated
aura::client::SetActivationChangeObserver(GetNativeWindow(), this);
} }
void AtomDesktopNativeWidgetAura::Activate() { void AtomDesktopNativeWidgetAura::Activate() {
@@ -19,4 +23,23 @@ void AtomDesktopNativeWidgetAura::Activate() {
views::DesktopNativeWidgetAura::Activate(); views::DesktopNativeWidgetAura::Activate();
} }
void AtomDesktopNativeWidgetAura::OnWindowActivated(
aura::client::ActivationChangeObserver::ActivationReason reason,
aura::Window* gained_active,
aura::Window* lost_active) {
views::DesktopNativeWidgetAura::OnWindowActivated(
reason, gained_active, lost_active);
if (lost_active != nullptr) {
auto* tooltip_controller = static_cast<views::corewm::TooltipController*>(
aura::client::GetTooltipClient(lost_active->GetRootWindow()));
// This will cause the tooltip to be hidden when a window is deactivated,
// as it should be.
// TODO(brenca): Remove this fix when the chromium issue is fixed.
// crbug.com/724538
if (tooltip_controller != nullptr)
tooltip_controller->OnCancelMode(nullptr);
}
}
} // namespace atom } // namespace atom

View File

@@ -19,6 +19,10 @@ class AtomDesktopNativeWidgetAura : public views::DesktopNativeWidgetAura {
void Activate() override; void Activate() override;
private: private:
void OnWindowActivated(
aura::client::ActivationChangeObserver::ActivationReason reason,
aura::Window* gained_active,
aura::Window* lost_active) override;
DISALLOW_COPY_AND_ASSIGN(AtomDesktopNativeWidgetAura); DISALLOW_COPY_AND_ASSIGN(AtomDesktopNativeWidgetAura);
}; };

View File

@@ -47,6 +47,35 @@ WebContentsPreferences::WebContentsPreferences(
web_contents->SetUserData(UserDataKey(), this); web_contents->SetUserData(UserDataKey(), this);
instances_.push_back(this); instances_.push_back(this);
// Set WebPreferences defaults onto the JS object
SetDefaultBoolIfUndefined("plugins", false);
SetDefaultBoolIfUndefined(options::kExperimentalFeatures, false);
SetDefaultBoolIfUndefined(options::kExperimentalCanvasFeatures, false);
bool node = SetDefaultBoolIfUndefined(options::kNodeIntegration, true);
SetDefaultBoolIfUndefined(options::kNodeIntegrationInWorker, false);
SetDefaultBoolIfUndefined(options::kWebviewTag, node);
SetDefaultBoolIfUndefined("sandbox", false);
SetDefaultBoolIfUndefined("nativeWindowOpen", false);
SetDefaultBoolIfUndefined(options::kContextIsolation, false);
SetDefaultBoolIfUndefined("javascript", true);
SetDefaultBoolIfUndefined("images", true);
SetDefaultBoolIfUndefined("textAreasAreResizable", true);
SetDefaultBoolIfUndefined("webgl", true);
bool webSecurity = true;
SetDefaultBoolIfUndefined("webSecurity", webSecurity);
// If webSecurity was explicity set to false, let's inherit that into
// insecureContent
if (web_preferences.Get("webSecurity", &webSecurity) && !webSecurity) {
SetDefaultBoolIfUndefined("allowRunningInsecureContent", true);
} else {
SetDefaultBoolIfUndefined("allowRunningInsecureContent", false);
}
#if defined(OS_MACOSX)
SetDefaultBoolIfUndefined(options::kScrollBounce, false);
#endif
SetDefaultBoolIfUndefined("offscreen", false);
last_web_preferences_.MergeDictionary(&web_preferences_);
} }
WebContentsPreferences::~WebContentsPreferences() { WebContentsPreferences::~WebContentsPreferences() {
@@ -55,6 +84,16 @@ WebContentsPreferences::~WebContentsPreferences() {
instances_.end()); instances_.end());
} }
bool WebContentsPreferences::SetDefaultBoolIfUndefined(const std::string key,
bool val) {
bool existing;
if (!web_preferences_.GetBoolean(key, &existing)) {
web_preferences_.SetBoolean(key, val);
return val;
}
return existing;
}
void WebContentsPreferences::Merge(const base::DictionaryValue& extend) { void WebContentsPreferences::Merge(const base::DictionaryValue& extend) {
web_preferences_.MergeDictionary(&extend); web_preferences_.MergeDictionary(&extend);
} }
@@ -79,6 +118,12 @@ void WebContentsPreferences::AppendExtraCommandLineSwitches(
base::DictionaryValue& web_preferences = self->web_preferences_; base::DictionaryValue& web_preferences = self->web_preferences_;
// We are appending args to a webContents so let's save the current state
// of our preferences object so that during the lifetime of the WebContents
// we can fetch the options used to initally configure the WebContents
self->last_web_preferences_.Clear();
self->last_web_preferences_.MergeDictionary(&web_preferences);
bool b; bool b;
// Check if plugins are enabled. // Check if plugins are enabled.
if (web_preferences.GetBoolean("plugins", &b) && b) if (web_preferences.GetBoolean("plugins", &b) && b)

View File

@@ -57,6 +57,9 @@ class WebContentsPreferences
// Returns the web preferences. // Returns the web preferences.
base::DictionaryValue* web_preferences() { return &web_preferences_; } base::DictionaryValue* web_preferences() { return &web_preferences_; }
base::DictionaryValue* last_web_preferences() {
return &last_web_preferences_;
}
private: private:
friend class content::WebContentsUserData<WebContentsPreferences>; friend class content::WebContentsUserData<WebContentsPreferences>;
@@ -65,6 +68,10 @@ class WebContentsPreferences
content::WebContents* web_contents_; content::WebContents* web_contents_;
base::DictionaryValue web_preferences_; base::DictionaryValue web_preferences_;
base::DictionaryValue last_web_preferences_;
// Set preference value to given bool if user did not provide value
bool SetDefaultBoolIfUndefined(const std::string key, bool val);
// Get preferences value as integer possibly coercing it from a string // Get preferences value as integer possibly coercing it from a string
bool GetInteger(const std::string& attributeName, int* intValue); bool GetInteger(const std::string& attributeName, int* intValue);

View File

@@ -156,10 +156,10 @@ file_dialog::Filters GetFileTypesFromAcceptType(
filters.push_back(file_dialog::Filter()); filters.push_back(file_dialog::Filter());
if (valid_type_count > 1 || if (valid_type_count > 1 || (valid_type_count == 1 && description.empty()))
(valid_type_count == 1 && description.empty() && extensions.size() > 1))
description = "Custom Files"; description = "Custom Files";
DCHECK(!description.empty());
filters[0].first = description; filters[0].first = description;
for (const auto& extension : extensions) { for (const auto& extension : extensions) {
@@ -215,6 +215,7 @@ void WebDialogHelper::RunFileChooser(
flags |= file_dialog::FILE_DIALOG_MULTI_SELECTIONS; flags |= file_dialog::FILE_DIALOG_MULTI_SELECTIONS;
case content::FileChooserParams::Open: case content::FileChooserParams::Open:
flags |= file_dialog::FILE_DIALOG_OPEN_FILE; flags |= file_dialog::FILE_DIALOG_OPEN_FILE;
flags |= file_dialog::FILE_DIALOG_TREAT_PACKAGE_APP_AS_DIRECTORY;
break; break;
case content::FileChooserParams::UploadFolder: case content::FileChooserParams::UploadFolder:
flags |= file_dialog::FILE_DIALOG_OPEN_DIRECTORY; flags |= file_dialog::FILE_DIALOG_OPEN_DIRECTORY;

View File

@@ -10,31 +10,22 @@
namespace atom { namespace atom {
// static // static
std::vector<std::string> AtomCommandLine::argv_; base::CommandLine::StringVector AtomCommandLine::argv_;
#if defined(OS_WIN)
// static
std::vector<std::wstring> AtomCommandLine::wargv_;
#endif
// static // static
void AtomCommandLine::Init(int argc, const char* const* argv) { void AtomCommandLine::Init(int argc, base::CommandLine::CharType** argv) {
DCHECK(argv_.empty());
// NOTE: uv_setup_args does nothing on Windows, so we don't need to call it.
// Otherwise we'd have to convert the arguments from UTF16.
#if !defined(OS_WIN)
// Hack around with the argv pointer. Used for process.title = "blah" // Hack around with the argv pointer. Used for process.title = "blah"
char** new_argv = uv_setup_args(argc, const_cast<char**>(argv)); argv = uv_setup_args(argc, argv);
for (int i = 0; i < argc; ++i) {
argv_.push_back(new_argv[i]);
}
}
#if defined(OS_WIN)
// static
void AtomCommandLine::InitW(int argc, const wchar_t* const* argv) {
for (int i = 0; i < argc; ++i) {
wargv_.push_back(argv[i]);
}
}
#endif #endif
argv_.assign(argv, argv + argc);
}
#if defined(OS_LINUX) #if defined(OS_LINUX)
// static // static
void AtomCommandLine::InitializeFromCommandLine() { void AtomCommandLine::InitializeFromCommandLine() {

View File

@@ -8,6 +8,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "base/command_line.h"
#include "base/macros.h" #include "base/macros.h"
#include "build/build_config.h" #include "build/build_config.h"
@@ -16,13 +17,9 @@ namespace atom {
// Singleton to remember the original "argc" and "argv". // Singleton to remember the original "argc" and "argv".
class AtomCommandLine { class AtomCommandLine {
public: public:
static void Init(int argc, const char* const* argv); static const base::CommandLine::StringVector& argv() { return argv_; }
static std::vector<std::string> argv() { return argv_; }
#if defined(OS_WIN) static void Init(int argc, base::CommandLine::CharType** argv);
static void InitW(int argc, const wchar_t* const* argv);
static std::vector<std::wstring> wargv() { return wargv_; }
#endif
#if defined(OS_LINUX) #if defined(OS_LINUX)
// On Linux the command line has to be read from base::CommandLine since // On Linux the command line has to be read from base::CommandLine since
@@ -31,11 +28,7 @@ class AtomCommandLine {
#endif #endif
private: private:
static std::vector<std::string> argv_; static base::CommandLine::StringVector argv_;
#if defined(OS_WIN)
static std::vector<std::wstring> wargv_;
#endif
DISALLOW_IMPLICIT_CONSTRUCTORS(AtomCommandLine); DISALLOW_IMPLICIT_CONSTRUCTORS(AtomCommandLine);
}; };

View File

@@ -7,22 +7,24 @@
#define ATOM_MAJOR_VERSION 1 #define ATOM_MAJOR_VERSION 1
#define ATOM_MINOR_VERSION 8 #define ATOM_MINOR_VERSION 8
#define ATOM_PATCH_VERSION 2 #define ATOM_PATCH_VERSION 8
#define ATOM_PRE_RELEASE_VERSION -beta.2 // #define ATOM_PRE_RELEASE_VERSION
#ifndef ATOM_PRE_RELEASE_VERSION
# define ATOM_PRE_RELEASE_VERSION ""
#endif
#ifndef ATOM_STRINGIFY #ifndef ATOM_STRINGIFY
#define ATOM_STRINGIFY(n) ATOM_STRINGIFY_HELPER(n) #define ATOM_STRINGIFY(n) ATOM_STRINGIFY_HELPER(n)
#define ATOM_STRINGIFY_HELPER(n) #n #define ATOM_STRINGIFY_HELPER(n) #n
#endif #endif
# define ATOM_VERSION_STRING ATOM_STRINGIFY(ATOM_MAJOR_VERSION) "." \ #ifndef ATOM_PRE_RELEASE_VERSION
#define ATOM_VERSION_STRING ATOM_STRINGIFY(ATOM_MAJOR_VERSION) "." \
ATOM_STRINGIFY(ATOM_MINOR_VERSION) "." \
ATOM_STRINGIFY(ATOM_PATCH_VERSION)
#else
#define ATOM_VERSION_STRING ATOM_STRINGIFY(ATOM_MAJOR_VERSION) "." \
ATOM_STRINGIFY(ATOM_MINOR_VERSION) "." \ ATOM_STRINGIFY(ATOM_MINOR_VERSION) "." \
ATOM_STRINGIFY(ATOM_PATCH_VERSION) \ ATOM_STRINGIFY(ATOM_PATCH_VERSION) \
ATOM_STRINGIFY(ATOM_PRE_RELEASE_VERSION) ATOM_STRINGIFY(ATOM_PRE_RELEASE_VERSION)
#endif
#define ATOM_VERSION "v" ATOM_VERSION_STRING #define ATOM_VERSION "v" ATOM_VERSION_STRING

View File

@@ -209,7 +209,10 @@ void CrashReporterWin::SetUploadParameters() {
int CrashReporterWin::CrashForException(EXCEPTION_POINTERS* info) { int CrashReporterWin::CrashForException(EXCEPTION_POINTERS* info) {
if (breakpad_) { if (breakpad_) {
breakpad_->WriteMinidumpForException(info); breakpad_->WriteMinidumpForException(info);
TerminateProcessWithoutDump(); if (skip_system_crash_handler_)
TerminateProcessWithoutDump();
else
RaiseFailFastException(info->ExceptionRecord, info->ContextRecord, 0);
} }
return EXCEPTION_CONTINUE_SEARCH; return EXCEPTION_CONTINUE_SEARCH;
} }
@@ -229,7 +232,7 @@ bool CrashReporterWin::MinidumpCallback(const wchar_t* dump_path,
MDRawAssertionInfo* assertion, MDRawAssertionInfo* assertion,
bool succeeded) { bool succeeded) {
CrashReporterWin* self = static_cast<CrashReporterWin*>(context); CrashReporterWin* self = static_cast<CrashReporterWin*>(context);
if (succeeded && !self->skip_system_crash_handler_) if (succeeded && self->skip_system_crash_handler_)
return true; return true;
else else
return false; return false;

View File

@@ -4,6 +4,7 @@
#include "atom/common/node_bindings.h" #include "atom/common/node_bindings.h"
#include <algorithm>
#include <string> #include <string>
#include <vector> #include <vector>
@@ -17,6 +18,7 @@
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/path_service.h" #include "base/path_service.h"
#include "base/run_loop.h" #include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h" #include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
@@ -150,7 +152,14 @@ void NodeBindings::Initialize() {
node::Environment* NodeBindings::CreateEnvironment( node::Environment* NodeBindings::CreateEnvironment(
v8::Handle<v8::Context> context) { v8::Handle<v8::Context> context) {
#if defined(OS_WIN)
auto& atom_args = AtomCommandLine::argv();
std::vector<std::string> args(atom_args.size());
std::transform(atom_args.cbegin(), atom_args.cend(), args.begin(),
[](auto& a) { return base::WideToUTF8(a); });
#else
auto args = AtomCommandLine::argv(); auto args = AtomCommandLine::argv();
#endif
// Feed node the path to initialization script. // Feed node the path to initialization script.
base::FilePath::StringType process_type; base::FilePath::StringType process_type;
@@ -170,8 +179,7 @@ node::Environment* NodeBindings::CreateEnvironment(
resources_path.Append(FILE_PATH_LITERAL("electron.asar")) resources_path.Append(FILE_PATH_LITERAL("electron.asar"))
.Append(process_type) .Append(process_type)
.Append(FILE_PATH_LITERAL("init.js")); .Append(FILE_PATH_LITERAL("init.js"));
std::string script_path_str = script_path.AsUTF8Unsafe(); args.insert(args.begin() + 1, script_path.AsUTF8Unsafe());
args.insert(args.begin() + 1, script_path_str.c_str());
std::unique_ptr<const char*[]> c_argv = StringVectorToArgArray(args); std::unique_ptr<const char*[]> c_argv = StringVectorToArgArray(args);
node::Environment* env = node::CreateEnvironment( node::Environment* env = node::CreateEnvironment(

View File

@@ -13,6 +13,7 @@
#include "atom/renderer/api/atom_api_spell_check_client.h" #include "atom/renderer/api/atom_api_spell_check_client.h"
#include "base/memory/memory_pressure_listener.h" #include "base/memory/memory_pressure_listener.h"
#include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_frame_visitor.h"
#include "content/public/renderer/render_view.h" #include "content/public/renderer/render_view.h"
#include "native_mate/dictionary.h" #include "native_mate/dictionary.h"
#include "native_mate/object_template_builder.h" #include "native_mate/object_template_builder.h"
@@ -58,6 +59,30 @@ class ScriptExecutionCallback : public blink::WebScriptExecutionCallback {
DISALLOW_COPY_AND_ASSIGN(ScriptExecutionCallback); DISALLOW_COPY_AND_ASSIGN(ScriptExecutionCallback);
}; };
class FrameSpellChecker : public content::RenderFrameVisitor {
public:
explicit FrameSpellChecker(SpellCheckClient* spell_check_client,
content::RenderFrame* main_frame)
: spell_check_client_(spell_check_client), main_frame_(main_frame) {}
~FrameSpellChecker() override {
spell_check_client_ = nullptr;
main_frame_ = nullptr;
}
bool Visit(content::RenderFrame* render_frame) override {
auto view = render_frame->GetRenderView();
if (view->GetMainRenderFrame() == main_frame_ ||
(render_frame->IsMainFrame() && render_frame == main_frame_)) {
render_frame->GetWebFrame()->SetTextCheckClient(spell_check_client_);
}
return true;
}
private:
SpellCheckClient* spell_check_client_;
content::RenderFrame* main_frame_;
DISALLOW_COPY_AND_ASSIGN(FrameSpellChecker);
};
} // namespace } // namespace
WebFrame::WebFrame(v8::Isolate* isolate) WebFrame::WebFrame(v8::Isolate* isolate)
@@ -101,6 +126,7 @@ double WebFrame::GetZoomFactor() const {
void WebFrame::SetVisualZoomLevelLimits(double min_level, double max_level) { void WebFrame::SetVisualZoomLevelLimits(double min_level, double max_level) {
web_frame_->View()->SetDefaultPageScaleLimits(min_level, max_level); web_frame_->View()->SetDefaultPageScaleLimits(min_level, max_level);
web_frame_->View()->SetIgnoreViewportTagScaleLimits(true);
} }
void WebFrame::SetLayoutZoomLevelLimits(double min_level, double max_level) { void WebFrame::SetLayoutZoomLevelLimits(double min_level, double max_level) {
@@ -139,10 +165,15 @@ void WebFrame::SetSpellCheckProvider(mate::Arguments* args,
return; return;
} }
spell_check_client_.reset(new SpellCheckClient( std::unique_ptr<SpellCheckClient> client(new SpellCheckClient(
language, auto_spell_correct_turned_on, args->isolate(), provider)); language, auto_spell_correct_turned_on, args->isolate(), provider));
// Set spellchecker for all live frames in the same process or
// in the sandbox mode for all live sub frames to this WebFrame.
FrameSpellChecker spell_checker(
client.get(), content::RenderFrame::FromWebFrame(web_frame_));
content::RenderFrame::ForEach(&spell_checker);
spell_check_client_.swap(client);
web_frame_->View()->SetSpellCheckClient(spell_check_client_.get()); web_frame_->View()->SetSpellCheckClient(spell_check_client_.get());
web_frame_->SetTextCheckClient(spell_check_client_.get());
} }
void WebFrame::RegisterURLSchemeAsSecure(const std::string& scheme) { void WebFrame::RegisterURLSchemeAsSecure(const std::string& scheme) {

View File

@@ -38,7 +38,6 @@ namespace {
const std::string kIpcKey = "ipcNative"; const std::string kIpcKey = "ipcNative";
const std::string kModuleCacheKey = "native-module-cache"; const std::string kModuleCacheKey = "native-module-cache";
v8::Local<v8::Object> GetModuleCache(v8::Isolate* isolate) { v8::Local<v8::Object> GetModuleCache(v8::Isolate* isolate) {
mate::Dictionary global(isolate, isolate->GetCurrentContext()->Global()); mate::Dictionary global(isolate, isolate->GetCurrentContext()->Global());
v8::Local<v8::Value> cache; v8::Local<v8::Value> cache;
@@ -158,8 +157,6 @@ void AtomSandboxedRendererClient::DidCreateScriptContext(
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
std::string preload_script = command_line->GetSwitchValueASCII( std::string preload_script = command_line->GetSwitchValueASCII(
switches::kPreloadScript); switches::kPreloadScript);
if (preload_script.empty())
return;
auto isolate = context->GetIsolate(); auto isolate = context->GetIsolate();
v8::HandleScope handle_scope(isolate); v8::HandleScope handle_scope(isolate);

View File

@@ -228,10 +228,8 @@
'msvs_settings': { 'msvs_settings': {
'VCCLCompilerTool': { 'VCCLCompilerTool': {
'RuntimeLibrary': '2', # /MD (nondebug DLL) 'RuntimeLibrary': '2', # /MD (nondebug DLL)
# 1, optimizeMinSpace, Minimize Size (/O1) 'Optimization': '2', # /O2
'Optimization': '1', 'WholeProgramOptimization': 'true', # /GL
# 2, favorSize - Favor small code (/Os)
'FavorSizeOrSpeed': '2',
# See http://msdn.microsoft.com/en-us/library/47238hez(VS.71).aspx # See http://msdn.microsoft.com/en-us/library/47238hez(VS.71).aspx
'InlineFunctionExpansion': '2', # 2 = max 'InlineFunctionExpansion': '2', # 2 = max
# See http://msdn.microsoft.com/en-us/library/2kxx5t2c(v=vs.80).aspx # See http://msdn.microsoft.com/en-us/library/2kxx5t2c(v=vs.80).aspx
@@ -241,11 +239,24 @@
# perform FPO regardless, so we must explicitly disable. # perform FPO regardless, so we must explicitly disable.
# We still want the false setting above to avoid having # We still want the false setting above to avoid having
# "/Oy /Oy-" and warnings about overriding. # "/Oy /Oy-" and warnings about overriding.
'AdditionalOptions': ['/Oy-'], 'AdditionalOptions': ['/Oy-', '/d2guard4'],
},
'VCLibrarianTool': {
'LinkTimeCodeGeneration': 'true', # /LTCG
}, },
'VCLinkerTool': { 'VCLinkerTool': {
# Control Flow Guard is a security feature in Windows
# 8.1 and higher designed to prevent exploitation of
# indirect calls in executables.
# Control Flow Guard is enabled using the /d2guard4
# compiler setting in combination with the /guard:cf
# linker setting.
'AdditionalOptions': ['/guard:cf'],
# Turn off incremental linking to save binary size. # Turn off incremental linking to save binary size.
'LinkIncremental': '1', # /INCREMENTAL:NO 'LinkIncremental': '1', # /INCREMENTAL:NO
'LinkTimeCodeGeneration': '1', # /LTCG
'OptimizeReferences': 2, # /OPT:REF
'EnableCOMDATFolding': 2, # /OPT:ICF
}, },
}, },
'conditions': [ 'conditions': [
@@ -270,6 +281,18 @@
'-Wl,--gc-sections', '-Wl,--gc-sections',
], ],
}], # OS=="linux" }], # OS=="linux"
['OS=="linux" and target_arch in ["ia32", "x64", "arm64"]', {
'cflags': [
'-flto',
],
'ldflags': [
'-flto',
'-fuse-ld=gold',
'-Wl,-plugin-opt,O1',
'-Wl,-plugin-opt,-function-sections',
'-Wl,--icf=all',
],
}],
], ],
}, # Release_Base }, # Release_Base
'conditions': [ 'conditions': [

View File

@@ -174,7 +174,7 @@ void DesktopNotificationController::AnimateAll() {
if (SystemParametersInfo(SPI_GETWORKAREA, 0, &work_area, 0)) { if (SystemParametersInfo(SPI_GETWORKAREA, 0, &work_area, 0)) {
ScreenMetrics metrics; ScreenMetrics metrics;
POINT origin = { work_area.right, POINT origin = { work_area.right,
work_area.bottom - metrics.Y(toast_margin_<int>) }; work_area.bottom - metrics.Y(toast_margin_) };
auto hdwp = auto hdwp =
BeginDeferWindowPos(static_cast<int>(instances_.size())); BeginDeferWindowPos(static_cast<int>(instances_.size()));
@@ -231,7 +231,7 @@ void DesktopNotificationController::AnimateAll() {
// Set new toast positions // Set new toast positions
if (!instances_.empty()) { if (!instances_.empty()) {
ScreenMetrics metrics; ScreenMetrics metrics;
auto margin = metrics.Y(toast_margin_<int>); auto margin = metrics.Y(toast_margin_);
int target_pos = 0; int target_pos = 0;
for (auto&& inst : instances_) { for (auto&& inst : instances_) {
@@ -305,7 +305,7 @@ void DesktopNotificationController::CreateToast(NotificationLink&& data) {
auto toast = Toast::Get(item.hwnd); auto toast = Toast::Get(item.hwnd);
toast_pos = toast->GetVerticalPosition() + toast_pos = toast->GetVerticalPosition() +
toast->GetHeight() + toast->GetHeight() +
scr.Y(toast_margin_<int>); scr.Y(toast_margin_);
} }
instances_.push_back({ hwnd, move(data) }); instances_.push_back({ hwnd, move(data) });

View File

@@ -36,8 +36,7 @@ class DesktopNotificationController {
TimerID_Animate = 1 TimerID_Animate = 1
}; };
template<typename T> static constexpr int toast_margin_ = 20;
static constexpr T toast_margin_ = 20;
// Wrapper around `NotificationData` which makes sure that // Wrapper around `NotificationData` which makes sure that
// the `controller` member is cleared when the controller object // the `controller` member is cleared when the controller object

View File

@@ -140,6 +140,12 @@
'<(libchromiumcontent_src_dir)/v8', '<(libchromiumcontent_src_dir)/v8',
'<(libchromiumcontent_src_dir)/v8/include', '<(libchromiumcontent_src_dir)/v8/include',
], ],
'defines': [
# Export V8 symbols from node.dll / libnode.so
'BUILDING_V8_SHARED',
'BUILDING_V8_PLATFORM_SHARED',
'BUILDING_V8_BASE_SHARED',
],
'conditions': [ 'conditions': [
['OS=="mac" and libchromiumcontent_component==0', { ['OS=="mac" and libchromiumcontent_component==0', {
# -all_load is the "whole-archive" on macOS. # -all_load is the "whole-archive" on macOS.

View File

@@ -73,6 +73,16 @@ A `Integer` representing the unique ID of the view.
Objects created with `new BrowserView` have the following instance methods: Objects created with `new BrowserView` have the following instance methods:
#### `view.destroy()`
Force closing the view, the `unload` and `beforeunload` events won't be emitted
for the web page. After you're done with a view, call this function in order to
free memory and other resources as soon as possible.
#### `view.isDestroyed()`
Returns `Boolean` - Whether the view is destroyed.
#### `view.setAutoResize(options)` _Experimental_ #### `view.setAutoResize(options)` _Experimental_
* `options` Object * `options` Object

View File

@@ -1174,7 +1174,7 @@ menu bar.
* `progress` Double * `progress` Double
* `options` Object (optional) * `options` Object (optional)
* `mode` String _Windows_ - Mode for the progress bar. Can be `none`, `normal`, `indeterminate`, `error`, or `paused`. * `mode` String _Windows_ - Mode for the progress bar. Can be `none`, `normal`, `indeterminate`, `error` or `paused`.
Sets progress value in progress bar. Valid range is [0, 1.0]. Sets progress value in progress bar. Valid range is [0, 1.0].
@@ -1191,7 +1191,7 @@ mode set (but with a value within the valid range), `normal` will be assumed.
#### `win.setOverlayIcon(overlay, description)` _Windows_ #### `win.setOverlayIcon(overlay, description)` _Windows_
* `overlay` [NativeImage](native-image.md) - the icon to display on the bottom * `overlay` [NativeImage](native-image.md) | null - the icon to display on the bottom
right corner of the taskbar icon. If this parameter is `null`, the overlay is right corner of the taskbar icon. If this parameter is `null`, the overlay is
cleared cleared
* `description` String - a description that will be provided to Accessibility * `description` String - a description that will be provided to Accessibility

View File

@@ -194,7 +194,7 @@ Sets the `image` associated with this tray icon.
#### `tray.setPressedImage(image)` _macOS_ #### `tray.setPressedImage(image)` _macOS_
* `image` [NativeImage](native-image.md) * `image` ([NativeImage](native-image.md) | String)
Sets the `image` associated with this tray icon when pressed on macOS. Sets the `image` associated with this tray icon when pressed on macOS.

View File

@@ -1291,11 +1291,17 @@ Shows pop-up dictionary that searches the selected word on the page.
Set the size of the page. This is only supported for `<webview>` guest contents. Set the size of the page. This is only supported for `<webview>` guest contents.
* `options` Object * `options` Object
* `normal` Object (optional) - Normal size of the page. This can be used in * `enableAutoSize` Boolean (optional) - true to make the webview container automatically
combination with the [`disableguestresize`](web-view-tag.md#disableguestresize) resize within the bounds specified by the attributes normal, min and max.
* `normal` [Size](structures/size.md) (optional) - Normal size of the page. This can be used in
combination with the [`disableguestresize`](webview-tag.md#disableguestresize)
attribute to manually resize the webview guest contents.
* `min` [Size](structures/size.md) (optional) - Minimum size of the page. This can be used in
combination with the [`disableguestresize`](webview-tag.md#disableguestresize)
attribute to manually resize the webview guest contents.
* `max` [Size](structures/size.md) (optional) - Maximium size of the page. This can be used in
combination with the [`disableguestresize`](webview-tag.md#disableguestresize)
attribute to manually resize the webview guest contents. attribute to manually resize the webview guest contents.
* `width` Integer
* `height` Integer
#### `contents.isOffscreen()` #### `contents.isOffscreen()`

View File

@@ -150,6 +150,7 @@ this limitation.
Returns `Object`: Returns `Object`:
* `images` [MemoryUsageDetails](structures/memory-usage-details.md) * `images` [MemoryUsageDetails](structures/memory-usage-details.md)
* `scripts` [MemoryUsageDetails](structures/memory-usage-details.md)
* `cssStyleSheets` [MemoryUsageDetails](structures/memory-usage-details.md) * `cssStyleSheets` [MemoryUsageDetails](structures/memory-usage-details.md)
* `xslStyleSheets` [MemoryUsageDetails](structures/memory-usage-details.md) * `xslStyleSheets` [MemoryUsageDetails](structures/memory-usage-details.md)
* `fonts` [MemoryUsageDetails](structures/memory-usage-details.md) * `fonts` [MemoryUsageDetails](structures/memory-usage-details.md)

View File

@@ -17,15 +17,27 @@ Please note, the `ARM` version of Windows is not supported for now.
### Linux ### Linux
The prebuilt `ia32` (`i686`) and `x64` (`amd64`) binaries of Electron are built on The prebuilt binaries of Electron are built for Debian Jessie, but whether the
Ubuntu 12.04, the `arm` binary is built against ARM v7 with hard-float ABI and prebuilt binary can run on a distribution depends on whether the distribution
NEON for Debian Wheezy. includes the libraries that Electron is linked to on the building platform, so
only Debian Jessie is guaranteed to work, but following platforms are also
Whether the prebuilt binary can run on a distribution depends on whether the verified to be able to run the prebuilt binaries of Electron:
distribution includes the libraries that Electron is linked to on the building
platform, so only Ubuntu 12.04 is guaranteed to work, but following platforms
are also verified to be able to run the prebuilt binaries of Electron:
* Ubuntu 12.04 and later * Ubuntu 12.04 and later
* Fedora 21 * Fedora 21
* Debian 8 * Debian 8 and later
Electorn provides prebuilt binaries for following CPU architectures:
* `ia32` (`i686`)
* `x64` (`amd64`)
* `armv7l`
* `arm64`
* `mips64el`
The `arm` binary is built against ARM v7 with hard-float ABI and NEON, and it is
not guaranteed to run on all ARM platforms.
The `mips64el` binary is built with toolchains provided by Loongson, and it is
not guaranteed to run on all MIPS64 platforms. And currently all certificate
related APIs are not working on `mips64el` builds.

View File

@@ -4,7 +4,7 @@
'product_name%': 'Electron', 'product_name%': 'Electron',
'company_name%': 'GitHub, Inc', 'company_name%': 'GitHub, Inc',
'company_abbr%': 'github', 'company_abbr%': 'github',
'version%': '1.8.2-beta.2', 'version%': '1.8.8',
'js2c_input_dir': '<(SHARED_INTERMEDIATE_DIR)/js2c', 'js2c_input_dir': '<(SHARED_INTERMEDIATE_DIR)/js2c',
}, },
'includes': [ 'includes': [
@@ -217,6 +217,11 @@
], ],
}, },
], ],
'link_settings': {
'ldflags': [
'-Wl,-z,noexecstack',
],
},
}], # OS=="linux" }], # OS=="linux"
], ],
}, # target <(project_name) }, # target <(project_name)

View File

@@ -98,6 +98,8 @@
'atom/app/atom_main_delegate.cc', 'atom/app/atom_main_delegate.cc',
'atom/app/atom_main_delegate.h', 'atom/app/atom_main_delegate.h',
'atom/app/atom_main_delegate_mac.mm', 'atom/app/atom_main_delegate_mac.mm',
'atom/app/command_line_args.cc',
'atom/app/command_line_args.h',
'atom/app/node_main.cc', 'atom/app/node_main.cc',
'atom/app/node_main.h', 'atom/app/node_main.h',
'atom/app/uv_task_runner.cc', 'atom/app/uv_task_runner.cc',

View File

@@ -24,7 +24,7 @@ Menu.prototype._init = function () {
getAcceleratorForCommandId: (id, useDefaultAccelerator) => { getAcceleratorForCommandId: (id, useDefaultAccelerator) => {
const command = this.commandsMap[id] const command = this.commandsMap[id]
if (!command) return if (!command) return
if (command.accelerator) return command.accelerator if (command.accelerator != null) return command.accelerator
if (useDefaultAccelerator) return command.getDefaultRoleAccelerator() if (useDefaultAccelerator) return command.getDefaultRoleAccelerator()
}, },
getIconForCommandId: id => this.commandsMap[id] ? this.commandsMap[id].icon : undefined, getIconForCommandId: id => this.commandsMap[id] ? this.commandsMap[id].icon : undefined,
@@ -44,20 +44,23 @@ Menu.prototype._init = function () {
} }
Menu.prototype.popup = function (window, x, y, positioningItem) { Menu.prototype.popup = function (window, x, y, positioningItem) {
let asyncPopup let asyncPopup, opts
let [newX, newY, newPosition, newWindow] = [x, y, positioningItem, window] let [newX, newY, newPosition, newWindow] = [x, y, positioningItem, window]
// menu.popup(x, y, positioningItem) // menu.popup(x, y, positioningItem)
if (!window) { if (window != null && !(window instanceof BrowserWindow)) {
// shift over values [newPosition, newY, newX, newWindow] = [y, x, window, null]
if (typeof window !== 'object' || window.constructor !== BrowserWindow) {
[newPosition, newY, newX, newWindow] = [y, x, window, null]
}
} }
// menu.popup({})
if (window != null && window.constructor === Object) {
opts = window
// menu.popup(window, {}) // menu.popup(window, {})
if (x && typeof x === 'object') { } else if (x && typeof x === 'object') {
const opts = x opts = x
}
if (opts) {
newX = opts.x newX = opts.x
newY = opts.y newY = opts.y
newPosition = opts.positioningItem newPosition = opts.positioningItem
@@ -65,13 +68,28 @@ Menu.prototype.popup = function (window, x, y, positioningItem) {
} }
// set defaults // set defaults
if (typeof x !== 'number') newX = -1 if (typeof newX !== 'number') newX = -1
if (typeof y !== 'number') newY = -1 if (typeof newY !== 'number') newY = -1
if (typeof positioningItem !== 'number') newPosition = -1 if (typeof newPosition !== 'number') newPosition = -1
if (!window) newWindow = BrowserWindow.getFocusedWindow()
if (typeof asyncPopup !== 'boolean') asyncPopup = false if (typeof asyncPopup !== 'boolean') asyncPopup = false
if (!newWindow || (newWindow && newWindow.constructor !== BrowserWindow)) {
newWindow = BrowserWindow.getFocusedWindow()
// No window focused?
if (!newWindow) {
const browserWindows = BrowserWindow.getAllWindows()
if (browserWindows && browserWindows.length > 0) {
newWindow = browserWindows[0]
} else {
throw new Error(`Cannot open Menu without a BrowserWindow present`)
}
}
}
this.popupAt(newWindow, newX, newY, newPosition, asyncPopup) this.popupAt(newWindow, newX, newY, newPosition, asyncPopup)
return { browserWindow: newWindow, x: newX, y: newY, position: newPosition, async: asyncPopup }
} }
Menu.prototype.closePopup = function (window) { Menu.prototype.closePopup = function (window) {
@@ -149,7 +167,7 @@ Menu.setApplicationMenu = function (menu) {
} }
Menu.buildFromTemplate = function (template) { Menu.buildFromTemplate = function (template) {
if (!(template instanceof Array)) { if (!Array.isArray(template)) {
throw new TypeError('Invalid template for Menu') throw new TypeError('Invalid template for Menu')
} }

View File

@@ -118,6 +118,18 @@ class TouchBar extends EventEmitter {
window.removeListener('closed', removeListeners) window.removeListener('closed', removeListeners)
window._touchBar = null window._touchBar = null
delete this.windowListeners[id] delete this.windowListeners[id]
const unregisterItems = (items) => {
for (const item of items) {
item.removeListener('change', this.changeListener)
if (item.child instanceof TouchBar) {
unregisterItems(item.child.ordereredItems)
}
}
}
unregisterItems(this.ordereredItems)
if (this.escapeItem) {
this.escapeItem.removeListener('change', this.changeListener)
}
} }
window.once('closed', removeListeners) window.once('closed', removeListeners)
this.windowListeners[id] = removeListeners this.windowListeners[id] = removeListeners

View File

@@ -156,7 +156,7 @@ const createGuest = function (embedder, params) {
// Forward internal web contents event to embedder to handle // Forward internal web contents event to embedder to handle
// native window.open setup // native window.open setup
guest.on('-add-new-contents', (...args) => { guest.on('-add-new-contents', (...args) => {
if (guest.getWebPreferences().nativeWindowOpen === true) { if (guest.getLastWebPreferences().nativeWindowOpen === true) {
const embedder = getEmbedder(guestInstanceId) const embedder = getEmbedder(guestInstanceId)
if (embedder != null) { if (embedder != null) {
embedder.emit('-add-new-contents', ...args) embedder.emit('-add-new-contents', ...args)
@@ -164,7 +164,7 @@ const createGuest = function (embedder, params) {
} }
}) })
guest.on('-web-contents-created', (...args) => { guest.on('-web-contents-created', (...args) => {
if (guest.getWebPreferences().nativeWindowOpen === true) { if (guest.getLastWebPreferences().nativeWindowOpen === true) {
const embedder = getEmbedder(guestInstanceId) const embedder = getEmbedder(guestInstanceId)
if (embedder != null) { if (embedder != null) {
embedder.emit('-web-contents-created', ...args) embedder.emit('-web-contents-created', ...args)

View File

@@ -26,11 +26,11 @@ const mergeOptions = function (child, parent, visited) {
visited.add(parent) visited.add(parent)
for (const key in parent) { for (const key in parent) {
if (!hasProp.call(parent, key)) continue if (!hasProp.call(parent, key)) continue
if (key in child) continue if (key in child && key !== 'webPreferences') continue
const value = parent[key] const value = parent[key]
if (typeof value === 'object') { if (typeof value === 'object') {
child[key] = mergeOptions({}, value, visited) child[key] = mergeOptions(child[key] || {}, value, visited)
} else { } else {
child[key] = value child[key] = value
} }
@@ -46,16 +46,24 @@ const mergeBrowserWindowOptions = function (embedder, options) {
options.webPreferences = {} options.webPreferences = {}
} }
if (embedder.browserWindowOptions != null) { if (embedder.browserWindowOptions != null) {
let parentOptions = embedder.browserWindowOptions
// if parent's visibility is available, that overrides 'show' flag (#12125)
const win = BrowserWindow.fromWebContents(embedder.webContents)
if (win != null) {
parentOptions = Object.assign({}, embedder.browserWindowOptions, {show: win.isVisible()})
}
// Inherit the original options if it is a BrowserWindow. // Inherit the original options if it is a BrowserWindow.
mergeOptions(options, embedder.browserWindowOptions) mergeOptions(options, parentOptions)
} else { } else {
// Or only inherit webPreferences if it is a webview. // Or only inherit webPreferences if it is a webview.
mergeOptions(options.webPreferences, embedder.getWebPreferences()) mergeOptions(options.webPreferences, embedder.getLastWebPreferences())
} }
// Inherit certain option values from parent window // Inherit certain option values from parent window
for (const [name, value] of inheritedWebPreferences) { for (const [name, value] of inheritedWebPreferences) {
if (embedder.getWebPreferences()[name] === value) { if (embedder.getLastWebPreferences()[name] === value) {
options.webPreferences[name] = value options.webPreferences[name] = value
} }
} }
@@ -168,8 +176,8 @@ const getGuestWindow = function (guestContents) {
// The W3C does not have anything on this, but from my understanding of the // The W3C does not have anything on this, but from my understanding of the
// security model of |window.opener|, this should be fine. // security model of |window.opener|, this should be fine.
const canAccessWindow = function (sender, target) { const canAccessWindow = function (sender, target) {
return (target.getWebPreferences().openerId === sender.id) || return (target.getLastWebPreferences().openerId === sender.id) ||
(sender.getWebPreferences().nodeIntegration === true) || (sender.getLastWebPreferences().nodeIntegration === true) ||
isSameOrigin(sender.getURL(), target.getURL()) isSameOrigin(sender.getURL(), target.getURL())
} }

View File

@@ -1,4 +1,5 @@
const timers = require('timers') const timers = require('timers')
const util = require('util')
process.atomBinding = require('./atom-binding-setup')(process.binding, process.type) process.atomBinding = require('./atom-binding-setup')(process.binding, process.type)
@@ -8,11 +9,21 @@ process.atomBinding = require('./atom-binding-setup')(process.binding, process.t
// which would delay the callbacks for arbitrary long time. So we should // which would delay the callbacks for arbitrary long time. So we should
// initiatively activate the uv loop once setImmediate and process.nextTick is // initiatively activate the uv loop once setImmediate and process.nextTick is
// called. // called.
var wrapWithActivateUvLoop = function (func) { const wrapWithActivateUvLoop = function (func) {
return function () { return wrap(func, function (func) {
process.activateUvLoop() return function () {
return func.apply(this, arguments) process.activateUvLoop()
return func.apply(this, arguments)
}
})
}
function wrap (func, wrapper) {
const wrapped = wrapper(func)
if (func[util.promisify.custom]) {
wrapped[util.promisify.custom] = wrapper(func[util.promisify.custom])
} }
return wrapped
} }
process.nextTick = wrapWithActivateUvLoop(process.nextTick) process.nextTick = wrapWithActivateUvLoop(process.nextTick)

View File

@@ -121,7 +121,18 @@ if (nodeIntegration === 'true') {
// Set the __filename to the path of html file if it is file: protocol. // Set the __filename to the path of html file if it is file: protocol.
if (window.location.protocol === 'file:') { if (window.location.protocol === 'file:') {
var pathname = process.platform === 'win32' && window.location.pathname[0] === '/' ? window.location.pathname.substr(1) : window.location.pathname const location = window.location
let pathname = location.pathname
if (process.platform === 'win32') {
if (pathname[0] === '/') pathname = pathname.substr(1)
const isWindowsNetworkSharePath = location.hostname.length > 0 && globalPaths[0].startsWith('\\')
if (isWindowsNetworkSharePath) {
pathname = `//${location.host}/${pathname}`
}
}
global.__filename = path.normalize(decodeURIComponent(pathname)) global.__filename = path.normalize(decodeURIComponent(pathname))
global.__dirname = path.dirname(global.__filename) global.__dirname = path.dirname(global.__filename)

View File

@@ -32,8 +32,6 @@ const preloadModules = new Map([
['timers', require('timers')] ['timers', require('timers')]
]) ])
const preloadSrc = fs.readFileSync(preloadPath).toString()
// Pass different process object to the preload script(which should not have // Pass different process object to the preload script(which should not have
// access to things like `process.atomBinding`). // access to things like `process.atomBinding`).
const preloadProcess = new events.EventEmitter() const preloadProcess = new events.EventEmitter()
@@ -54,6 +52,11 @@ function preloadRequire (module) {
throw new Error('module not found') throw new Error('module not found')
} }
if (window.location.protocol === 'chrome-devtools:') {
// Override some inspector APIs.
require('../renderer/inspector')
}
// Wrap the script into a function executed in global scope. It won't have // Wrap the script into a function executed in global scope. It won't have
// access to the current scope, so we'll expose a few objects as arguments: // access to the current scope, so we'll expose a few objects as arguments:
// //
@@ -73,13 +76,16 @@ function preloadRequire (module) {
// and any `require('electron')` calls in `preload.js` will work as expected // and any `require('electron')` calls in `preload.js` will work as expected
// since browserify won't try to include `electron` in the bundle, falling back // since browserify won't try to include `electron` in the bundle, falling back
// to the `preloadRequire` function above. // to the `preloadRequire` function above.
const preloadWrapperSrc = `(function(require, process, Buffer, global, setImmediate) { if (preloadPath) {
${preloadSrc} const preloadSrc = fs.readFileSync(preloadPath).toString()
})` const preloadWrapperSrc = `(function(require, process, Buffer, global, setImmediate) {
${preloadSrc}
})`
// eval in window scope: // eval in window scope:
// http://www.ecma-international.org/ecma-262/5.1/#sec-10.4.2 // http://www.ecma-international.org/ecma-262/5.1/#sec-10.4.2
const geval = eval const geval = eval
const preloadFn = geval(preloadWrapperSrc) const preloadFn = geval(preloadWrapperSrc)
const {setImmediate} = require('timers') const {setImmediate} = require('timers')
preloadFn(preloadRequire, preloadProcess, Buffer, global, setImmediate) preloadFn(preloadRequire, preloadProcess, Buffer, global, setImmediate)
}

10156
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{ {
"name": "electron", "name": "electron",
"version": "1.8.2-beta.2", "version": "1.8.8",
"repository": "https://github.com/electron/electron", "repository": "https://github.com/electron/electron",
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS", "description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
"devDependencies": { "devDependencies": {
@@ -12,7 +12,7 @@
"dugite": "^1.45.0", "dugite": "^1.45.0",
"electabul": "~0.0.4", "electabul": "~0.0.4",
"electron-docs-linter": "^2.3.4", "electron-docs-linter": "^2.3.4",
"electron-typescript-definitions": "^1.2.11", "electron-typescript-definitions": "~1.2.11",
"github": "^9.2.0", "github": "^9.2.0",
"husky": "^0.14.3", "husky": "^0.14.3",
"minimist": "^1.2.0", "minimist": "^1.2.0",

View File

@@ -40,6 +40,9 @@ def main():
if args.target_arch == 'mips64el': if args.target_arch == 'mips64el':
download_mips64el_toolchain() download_mips64el_toolchain()
if args.target_arch.startswith('arm'):
download_native_mksnapshot(args.target_arch)
# Redirect to use local libchromiumcontent build. # Redirect to use local libchromiumcontent build.
if args.build_release_libcc or args.build_debug_libcc: if args.build_release_libcc or args.build_debug_libcc:
build_libchromiumcontent(args.verbose, args.target_arch, defines, build_libchromiumcontent(args.verbose, args.target_arch, defines,
@@ -218,6 +221,15 @@ def download_mips64el_toolchain():
subprocess.check_call(['tar', '-xf', tar_name, '-C', VENDOR_DIR]) subprocess.check_call(['tar', '-xf', tar_name, '-C', VENDOR_DIR])
os.remove(tar_name) os.remove(tar_name)
def download_native_mksnapshot(arch):
if not os.path.exists(os.path.join(VENDOR_DIR,
'native_mksnapshot')):
zip_name = 'native-mksnapshot.zip'
url = '{0}/linux/{1}/{2}/{3}'.format(BASE_URL, arch,
get_libchromiumcontent_commit(), zip_name)
download(zip_name, url, os.path.join(SOURCE_ROOT, zip_name))
subprocess.call(['unzip', zip_name, '-d', VENDOR_DIR])
os.remove(zip_name)
def create_chrome_version_h(): def create_chrome_version_h():
version_file = os.path.join(VENDOR_DIR, 'libchromiumcontent', 'VERSION') version_file = os.path.join(VENDOR_DIR, 'libchromiumcontent', 'VERSION')

View File

@@ -28,6 +28,8 @@ def main():
ninja += '.exe' ninja += '.exe'
args = parse_args() args = parse_args()
if args.ninja_path:
ninja = args.ninja_path
if args.libcc: if args.libcc:
if ('D' not in args.configuration if ('D' not in args.configuration
or not os.path.exists(GCLIENT_DONE) or not os.path.exists(GCLIENT_DONE)
@@ -67,6 +69,9 @@ def parse_args():
'-d --debug_libchromiumcontent.' '-d --debug_libchromiumcontent.'
), ),
action='store_true', default=False) action='store_true', default=False)
parser.add_argument('--ninja-path',
help='Path of ninja command to use.',
required=False)
return parser.parse_args() return parser.parse_args()

View File

@@ -1,7 +1,6 @@
const assert = require('assert') const assert = require('assert')
const request = require('request') const request = require('request')
const buildAppVeyorURL = 'https://windows-ci.electronjs.org/api/builds' const buildAppVeyorURL = 'https://windows-ci.electronjs.org/api/builds'
const jenkinsServer = 'https://mac-ci.electronjs.org'
const circleCIJobs = [ const circleCIJobs = [
'electron-linux-arm', 'electron-linux-arm',
@@ -11,11 +10,6 @@ const circleCIJobs = [
'electron-linux-x64' 'electron-linux-x64'
] ]
const jenkinsJobs = [
'electron-mas-x64-release',
'electron-osx-x64-release'
]
async function makeRequest (requestOptions, parseResponse) { async function makeRequest (requestOptions, parseResponse) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
request(requestOptions, (err, res, body) => { request(requestOptions, (err, res, body) => {
@@ -32,7 +26,7 @@ async function makeRequest (requestOptions, parseResponse) {
} else { } else {
console.log('Error: ', `(status ${res.statusCode})`, err || res.body, requestOptions) console.log('Error: ', `(status ${res.statusCode})`, err || res.body, requestOptions)
} }
reject() reject(err)
} }
}) })
}) })
@@ -111,68 +105,6 @@ function buildCircleCI (targetBranch, ghRelease, job) {
} }
} }
async function buildJenkins (targetBranch, ghRelease, job) {
assert(process.env.JENKINS_AUTH_TOKEN, 'JENKINS_AUTH_TOKEN not found in environment')
assert(process.env.JENKINS_BUILD_TOKEN, 'JENKINS_BUILD_TOKEN not found in environment')
let jenkinsCrumb = await getJenkinsCrumb()
if (job) {
assert(jenkinsJobs.includes(job), `Unknown CI job name: ${job}.`)
callJenkinsBuild(job, jenkinsCrumb, targetBranch, ghRelease)
} else {
jenkinsJobs.forEach((job) => {
callJenkinsBuild(job, jenkinsCrumb, targetBranch, ghRelease)
})
}
}
async function callJenkins (path, requestParameters, requestHeaders) {
let requestOptions = {
url: `${jenkinsServer}/${path}`,
auth: {
user: 'build',
pass: process.env.JENKINS_AUTH_TOKEN
},
qs: requestParameters
}
if (requestHeaders) {
requestOptions.headers = requestHeaders
}
let jenkinsResponse = await makeRequest(requestOptions).catch(err => {
console.log(`Error calling Jenkins:`, err)
})
return jenkinsResponse
}
async function callJenkinsBuild (job, jenkinsCrumb, targetBranch, ghRelease) {
console.log(`Triggering Jenkins to run build job: ${job} on branch: ${targetBranch} with release flag.`)
let jenkinsParams = {
token: process.env.JENKINS_BUILD_TOKEN,
BRANCH: targetBranch
}
if (!ghRelease) {
jenkinsParams.RUN_RELEASE_BUILD = 1
}
await callJenkins(`job/${job}/buildWithParameters`, jenkinsParams, jenkinsCrumb)
.catch(err => {
console.log(`Error calling Jenkins build`, err)
})
let buildUrl = `${jenkinsServer}/job/${job}/lastBuild/`
console.log(`Jenkins build request successful. Check build status at ${buildUrl}.`)
}
async function getJenkinsCrumb () {
let crumbResponse = await callJenkins('crumbIssuer/api/xml', {
xpath: 'concat(//crumbRequestField,":",//crumb)'
}).catch(err => {
console.log(`Error getting jenkins crumb:`, err)
})
let crumbDetails = crumbResponse.split(':')
let crumbHeader = {}
crumbHeader[crumbDetails[0]] = crumbDetails[1]
return crumbHeader
}
function runRelease (targetBranch, options) { function runRelease (targetBranch, options) {
if (options.ci) { if (options.ci) {
switch (options.ci) { switch (options.ci) {
@@ -184,26 +116,21 @@ function runRelease (targetBranch, options) {
buildAppVeyor(targetBranch, options.ghRelease) buildAppVeyor(targetBranch, options.ghRelease)
break break
} }
case 'Jenkins': {
buildJenkins(targetBranch, options.ghRelease, options.job)
break
}
} }
} else { } else {
buildCircleCI(targetBranch, options.ghRelease, options.job) buildCircleCI(targetBranch, options.ghRelease, options.job)
buildAppVeyor(targetBranch, options.ghRelease) buildAppVeyor(targetBranch, options.ghRelease)
buildJenkins(targetBranch, options.ghRelease, options.job)
} }
} }
module.exports = runRelease module.exports = runRelease
if (require.main === module) { if (require.main === module) {
const args = require('minimist')(process.argv.slice(2)) const args = require('minimist')(process.argv.slice(2), { boolean: 'ghRelease' })
const targetBranch = args._[0] const targetBranch = args._[0]
if (args._.length < 1) { if (args._.length < 1) {
console.log(`Trigger CI to build release builds of electron. console.log(`Trigger CI to build release builds of electron.
Usage: ci-release-build.js [--job=CI_JOB_NAME] [--ci=CircleCI|AppVeyor|Jenkins] [--ghRelease] TARGET_BRANCH Usage: ci-release-build.js [--job=CI_JOB_NAME] [--ci=CircleCI|AppVeyor] [--ghRelease] TARGET_BRANCH
`) `)
process.exit(0) process.exit(0)
} }

View File

@@ -24,6 +24,7 @@ DIST_DIR = os.path.join(SOURCE_ROOT, 'dist')
OUT_DIR = os.path.join(SOURCE_ROOT, 'out', 'R') OUT_DIR = os.path.join(SOURCE_ROOT, 'out', 'R')
CHROMIUM_DIR = os.path.join(SOURCE_ROOT, 'vendor', 'download', CHROMIUM_DIR = os.path.join(SOURCE_ROOT, 'vendor', 'download',
'libchromiumcontent', 'static_library') 'libchromiumcontent', 'static_library')
NATIVE_MKSNAPSHOT_DIR = os.path.join(SOURCE_ROOT, 'vendor', 'native_mksnapshot')
PROJECT_NAME = electron_gyp()['project_name%'] PROJECT_NAME = electron_gyp()['project_name%']
PRODUCT_NAME = electron_gyp()['product_name%'] PRODUCT_NAME = electron_gyp()['product_name%']
@@ -138,7 +139,6 @@ def copy_chrome_binary(binary):
shutil.copyfile(src, dest) shutil.copyfile(src, dest)
os.chmod(dest, os.stat(dest).st_mode | stat.S_IEXEC) os.chmod(dest, os.stat(dest).st_mode | stat.S_IEXEC)
def copy_vcruntime_binaries(): def copy_vcruntime_binaries():
with _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, with _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,
r"SOFTWARE\Microsoft\VisualStudio\14.0\Setup\VC", 0, r"SOFTWARE\Microsoft\VisualStudio\14.0\Setup\VC", 0,
@@ -215,7 +215,7 @@ def strip_binary(binary_path):
elif get_target_arch() == 'arm64': elif get_target_arch() == 'arm64':
strip = 'aarch64-linux-gnu-strip' strip = 'aarch64-linux-gnu-strip'
elif get_target_arch() == 'mips64el': elif get_target_arch() == 'mips64el':
strip = 'mips64el-redhat-linux-strip' strip = 'mips64el-loongson-linux-strip'
else: else:
strip = 'strip' strip = 'strip'
execute([strip, binary_path], env=build_env()) execute([strip, binary_path], env=build_env())
@@ -257,17 +257,39 @@ def create_dist_zip():
def create_chrome_binary_zip(binary, version): def create_chrome_binary_zip(binary, version):
dist_name = get_zip_name(binary, version) file_suffix = ''
create_native_mksnapshot = False
if binary == 'mksnapshot':
arch = get_target_arch()
if arch.startswith('arm'):
# if the arch is arm/arm64 the mksnapshot executable is an x64 binary,
# so name it as such.
file_suffix = 'x64'
create_native_mksnapshot = True
dist_name = get_zip_name(binary, version, file_suffix)
zip_file = os.path.join(SOURCE_ROOT, 'dist', dist_name) zip_file = os.path.join(SOURCE_ROOT, 'dist', dist_name)
files = ['LICENSE', 'LICENSES.chromium.html']
if PLATFORM == 'win32':
files += [binary + '.exe']
else:
files += [binary]
with scoped_cwd(DIST_DIR): with scoped_cwd(DIST_DIR):
files = ['LICENSE', 'LICENSES.chromium.html']
if PLATFORM == 'win32':
files += [binary + '.exe']
else:
files += [binary]
make_zip(zip_file, files, []) make_zip(zip_file, files, [])
if create_native_mksnapshot == True:
# Create a zip with the native version of the mksnapshot binary.
src = os.path.join(NATIVE_MKSNAPSHOT_DIR, binary)
dest = os.path.join(DIST_DIR, binary)
# Copy file and keep the executable bit.
shutil.copyfile(src, dest)
os.chmod(dest, os.stat(dest).st_mode | stat.S_IEXEC)
dist_name = get_zip_name(binary, version)
zip_file = os.path.join(SOURCE_ROOT, 'dist', dist_name)
with scoped_cwd(DIST_DIR):
make_zip(zip_file, files, [])
def create_ffmpeg_zip(): def create_ffmpeg_zip():
dist_name = get_zip_name('ffmpeg', ELECTRON_VERSION) dist_name = get_zip_name('ffmpeg', ELECTRON_VERSION)

View File

@@ -8,8 +8,8 @@ import sys
# URL to the mips64el sysroot image. # URL to the mips64el sysroot image.
MIPS64EL_SYSROOT_URL = 'https://github.com/electron/debian-sysroot-image-creator/releases/download/v0.5.0/debian_jessie_mips64-sysroot.tar.bz2' MIPS64EL_SYSROOT_URL = 'https://github.com/electron/debian-sysroot-image-creator/releases/download/v0.5.0/debian_jessie_mips64-sysroot.tar.bz2'
# URL to the mips64el toolchain. # URL to the mips64el toolchain.
MIPS64EL_GCC = 'gcc-4.8.3-d197-n64-loongson' MIPS64EL_GCC = 'cross-gcc-4.9.3-n64-loongson-rc5.4'
MIPS64EL_GCC_URL = 'http://ftp.loongnix.org/toolchain/gcc/release/' + MIPS64EL_GCC + '.tar.gz' MIPS64EL_GCC_URL = 'https://github.com/electron/debian-sysroot-image-creator/releases/download/v0.5.0/' + MIPS64EL_GCC + '.tar.gz'
BASE_URL = os.getenv('LIBCHROMIUMCONTENT_MIRROR') or \ BASE_URL = os.getenv('LIBCHROMIUMCONTENT_MIRROR') or \
'https://s3.amazonaws.com/github-janky-artifacts/libchromiumcontent' 'https://s3.amazonaws.com/github-janky-artifacts/libchromiumcontent'
@@ -93,11 +93,11 @@ def build_env():
VENDOR_DIR = os.path.join(SOURCE_ROOT, 'vendor') VENDOR_DIR = os.path.join(SOURCE_ROOT, 'vendor')
gcc_dir = os.path.join(VENDOR_DIR, MIPS64EL_GCC) gcc_dir = os.path.join(VENDOR_DIR, MIPS64EL_GCC)
ldlib_dirs = [ ldlib_dirs = [
gcc_dir + '/usr/x86_64-unknown-linux-gnu/mips64el-redhat-linux/lib', gcc_dir + '/usr/x86_64-unknown-linux-gnu/mips64el-loongson-linux/lib',
gcc_dir + '/usr/lib64', gcc_dir + '/usr/lib64',
gcc_dir + '/usr/mips64el-redhat-linux/lib64', gcc_dir + '/usr/mips64el-loongson-linux/lib64',
gcc_dir + '/usr/mips64el-redhat-linux/sysroot/lib64', gcc_dir + '/usr/mips64el-loongson-linux/sysroot/lib64',
gcc_dir + '/usr/mips64el-redhat-linux/sysroot/usr/lib64', gcc_dir + '/usr/mips64el-loongson-linux/sysroot/usr/lib64',
] ]
env['LD_LIBRARY_PATH'] = os.pathsep.join(ldlib_dirs) env['LD_LIBRARY_PATH'] = os.pathsep.join(ldlib_dirs)
env['PATH'] = os.pathsep.join([gcc_dir + '/usr/bin', env['PATH']]) env['PATH'] = os.pathsep.join([gcc_dir + '/usr/bin', env['PATH']])

View File

@@ -11,6 +11,7 @@ const GitHub = require('github')
const pass = '\u2713'.green const pass = '\u2713'.green
const path = require('path') const path = require('path')
const pkg = require('../package.json') const pkg = require('../package.json')
const readline = require('readline')
const versionType = args._[0] const versionType = args._[0]
// TODO (future) automatically determine version based on conventional commits // TODO (future) automatically determine version based on conventional commits
@@ -45,18 +46,23 @@ async function createReleaseBranch () {
} }
} }
function getNewVersion () { function getNewVersion (dryRun) {
console.log(`Bumping for new "${versionType}" version.`) console.log(`Bumping for new "${versionType}" version.`)
let bumpScript = path.join(__dirname, 'bump-version.py') let bumpScript = path.join(__dirname, 'bump-version.py')
let scriptArgs = [bumpScript, `--bump ${versionType}`] let scriptArgs = [bumpScript, `--bump ${versionType}`]
if (args.stable) { if (args.stable) {
scriptArgs.push('--stable') scriptArgs.push('--stable')
} }
if (dryRun) {
scriptArgs.push('--dry-run')
}
try { try {
let bumpVersion = execSync(scriptArgs.join(' '), {encoding: 'UTF-8'}) let bumpVersion = execSync(scriptArgs.join(' '), {encoding: 'UTF-8'})
bumpVersion = bumpVersion.substr(bumpVersion.indexOf(':') + 1).trim() bumpVersion = bumpVersion.substr(bumpVersion.indexOf(':') + 1).trim()
let newVersion = `v${bumpVersion}` let newVersion = `v${bumpVersion}`
console.log(`${pass} Successfully bumped version to ${newVersion}`) if (!dryRun) {
console.log(`${pass} Successfully bumped version to ${newVersion}`)
}
return newVersion return newVersion
} catch (err) { } catch (err) {
console.log(`${fail} Could not bump version, error was:`, err) console.log(`${fail} Could not bump version, error was:`, err)
@@ -119,23 +125,25 @@ async function createRelease (branchToTarget, isBeta) {
.catch(err => { .catch(err => {
console.log('$fail} Could not get releases. Error was', err) console.log('$fail} Could not get releases. Error was', err)
}) })
let drafts = releases.data.filter(release => release.draft) let drafts = releases.data.filter(release => release.draft &&
release.tag_name === newVersion)
if (drafts.length > 0) { if (drafts.length > 0) {
console.log(`${fail} Aborting because draft release for console.log(`${fail} Aborting because draft release for
${drafts[0].tag_name} already exists.`) ${drafts[0].tag_name} already exists.`)
process.exit(1) process.exit(1)
} }
console.log(`${pass} A draft release does not exist; creating one.`) console.log(`${pass} A draft release does not exist; creating one.`)
githubOpts.body = releaseNotes
githubOpts.draft = true githubOpts.draft = true
githubOpts.name = `electron ${newVersion}` githubOpts.name = `electron ${newVersion}`
if (isBeta) { if (isBeta) {
githubOpts.body = `Note: This is a beta release. Please file new issues ` + githubOpts.body = `Note: This is a beta release. Please file new issues ` +
`for any bugs you find in it.\n \n This release is published to npm ` + `for any bugs you find in it.\n \n This release is published to npm ` +
`under the beta tag and can be installed via npm install electron@beta, ` + `under the beta tag and can be installed via npm install electron@beta, ` +
`or npm i electron@${newVersion.substr(1)}.` `or npm i electron@${newVersion.substr(1)}.\n \n ${releaseNotes}`
githubOpts.name = `${githubOpts.name}` githubOpts.name = `${githubOpts.name}`
githubOpts.prerelease = true githubOpts.prerelease = true
} else {
githubOpts.body = releaseNotes
} }
githubOpts.tag_name = newVersion githubOpts.tag_name = newVersion
githubOpts.target_commitish = branchToTarget githubOpts.target_commitish = branchToTarget
@@ -165,12 +173,37 @@ async function runReleaseBuilds () {
}) })
} }
async function verifyNewVersion () {
let newVersion = await getNewVersion(true)
let response = await promptForVersion(newVersion)
if (response.match(/^y/i)) {
console.log(`${pass} Starting release of ${newVersion}`)
} else {
console.log(`${fail} Aborting release of ${newVersion}`)
process.exit()
}
}
async function promptForVersion (version) {
return new Promise((resolve, reject) => {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
})
rl.question(`Do you want to create the release ${version.green} (y/N)? `, (answer) => {
rl.close()
resolve(answer)
})
})
}
async function prepareRelease (isBeta, notesOnly) { async function prepareRelease (isBeta, notesOnly) {
let currentBranch = await getCurrentBranch(gitDir) let currentBranch = await getCurrentBranch(gitDir)
if (notesOnly) { if (notesOnly) {
let releaseNotes = await getReleaseNotes(currentBranch) let releaseNotes = await getReleaseNotes(currentBranch)
console.log(`Draft release notes are: ${releaseNotes}`) console.log(`Draft release notes are: ${releaseNotes}`)
} else { } else {
await verifyNewVersion()
await createReleaseBranch() await createReleaseBranch()
await createRelease(currentBranch, isBeta) await createRelease(currentBranch, isBeta)
await pushRelease() await pushRelease()

View File

@@ -21,7 +21,8 @@ const files = [
'index.js', 'index.js',
'install.js', 'install.js',
'package.json', 'package.json',
'README.md' 'README.md',
'LICENSE'
] ]
const jsonFields = [ const jsonFields = [
@@ -49,9 +50,10 @@ new Promise((resolve, reject) => {
tempDir = dirPath tempDir = dirPath
// copy files from `/npm` to temp directory // copy files from `/npm` to temp directory
files.forEach((name) => { files.forEach((name) => {
const noThirdSegment = name === 'README.md' || name === 'LICENSE'
fs.writeFileSync( fs.writeFileSync(
path.join(tempDir, name), path.join(tempDir, name),
fs.readFileSync(path.join(__dirname, '..', name === 'README.md' ? '' : 'npm', name)) fs.readFileSync(path.join(__dirname, '..', noThirdSegment ? '' : 'npm', name))
) )
}) })
// copy from root package.json to temp/package.json // copy from root package.json to temp/package.json

View File

@@ -31,21 +31,18 @@ async function getDraftRelease (version, skipValidation) {
let drafts let drafts
let versionToCheck let versionToCheck
if (version) { if (version) {
drafts = releaseInfo.data
.filter(release => release.tag_name === version)
versionToCheck = version versionToCheck = version
} else { } else {
drafts = releaseInfo.data
.filter(release => release.draft)
versionToCheck = pkgVersion versionToCheck = pkgVersion
} }
drafts = releaseInfo.data
.filter(release => release.tag_name === versionToCheck &&
release.draft === true)
const draft = drafts[0] const draft = drafts[0]
if (!skipValidation) { if (!skipValidation) {
failureCount = 0 failureCount = 0
check(drafts.length === 1, 'one draft exists', true) check(drafts.length === 1, 'one draft exists', true)
check(draft.tag_name === versionToCheck, `draft release version matches local package.json (${versionToCheck})`) if (versionToCheck.indexOf('beta') > -1) {
if (versionToCheck.indexOf('beta')) {
check(draft.prerelease, 'draft is a prerelease') check(draft.prerelease, 'draft is a prerelease')
} }
check(draft.body.length > 50 && !draft.body.includes('(placeholder)'), 'draft has release notes') check(draft.body.length > 50 && !draft.body.includes('(placeholder)'), 'draft has release notes')
@@ -54,8 +51,8 @@ async function getDraftRelease (version, skipValidation) {
return draft return draft
} }
async function validateReleaseAssets (release) { async function validateReleaseAssets (release, validatingRelease) {
const requiredAssets = assetsForVersion(release.tag_name).sort() const requiredAssets = assetsForVersion(release.tag_name, validatingRelease).sort()
const extantAssets = release.assets.map(asset => asset.name).sort() const extantAssets = release.assets.map(asset => asset.name).sort()
const downloadUrls = release.assets.map(asset => asset.browser_download_url).sort() const downloadUrls = release.assets.map(asset => asset.browser_download_url).sort()
@@ -87,7 +84,7 @@ function check (condition, statement, exitIfFail = false) {
} }
} }
function assetsForVersion (version) { function assetsForVersion (version, validatingRelease) {
const patterns = [ const patterns = [
`electron-${version}-darwin-x64-dsym.zip`, `electron-${version}-darwin-x64-dsym.zip`,
`electron-${version}-darwin-x64-symbols.zip`, `electron-${version}-darwin-x64-symbols.zip`,
@@ -123,9 +120,11 @@ function assetsForVersion (version) {
`ffmpeg-${version}-linux-x64.zip`, `ffmpeg-${version}-linux-x64.zip`,
`ffmpeg-${version}-mas-x64.zip`, `ffmpeg-${version}-mas-x64.zip`,
`ffmpeg-${version}-win32-ia32.zip`, `ffmpeg-${version}-win32-ia32.zip`,
`ffmpeg-${version}-win32-x64.zip`, `ffmpeg-${version}-win32-x64.zip`
`SHASUMS256.txt`
] ]
if (!validatingRelease) {
patterns.push('SHASUMS256.txt')
}
return patterns return patterns
} }
@@ -215,7 +214,7 @@ async function uploadShasumFile (filePath, fileName, release) {
filePath, filePath,
name: fileName name: fileName
} }
return await github.repos.uploadAsset(githubOpts) return github.repos.uploadAsset(githubOpts)
.catch(err => { .catch(err => {
console.log(`${fail} Error uploading ${filePath} to GitHub:`, err) console.log(`${fail} Error uploading ${filePath} to GitHub:`, err)
process.exit(1) process.exit(1)
@@ -250,7 +249,7 @@ async function publishRelease (release) {
tag_name: release.tag_name, tag_name: release.tag_name,
draft: false draft: false
} }
return await github.repos.editRelease(githubOpts) return github.repos.editRelease(githubOpts)
.catch(err => { .catch(err => {
console.log(`${fail} Error publishing release:`, err) console.log(`${fail} Error publishing release:`, err)
process.exit(1) process.exit(1)
@@ -259,9 +258,14 @@ async function publishRelease (release) {
async function makeRelease (releaseToValidate) { async function makeRelease (releaseToValidate) {
if (releaseToValidate) { if (releaseToValidate) {
console.log(`Validating release ${args.validateRelease}`) if (releaseToValidate === true) {
let release = await getDraftRelease(args.validateRelease) releaseToValidate = pkgVersion
await validateReleaseAssets(release) } else {
console.log('Release to validate !=== true')
}
console.log(`Validating release ${releaseToValidate}`)
let release = await getDraftRelease(releaseToValidate)
await validateReleaseAssets(release, true)
} else { } else {
checkVersion() checkVersion()
let draftRelease = await getDraftRelease() let draftRelease = await getDraftRelease()
@@ -447,7 +451,7 @@ async function cleanupReleaseBranch () {
await callGit(['branch', '-D', 'release'], errorMessage, successMessage) await callGit(['branch', '-D', 'release'], errorMessage, successMessage)
errorMessage = `Could not delete remote release branch.` errorMessage = `Could not delete remote release branch.`
successMessage = `Successfully deleted remote release branch.` successMessage = `Successfully deleted remote release branch.`
return await callGit(['push', 'origin', ':release'], errorMessage, successMessage) return callGit(['push', 'origin', ':release'], errorMessage, successMessage)
} }
async function callGit (args, errorMessage, successMessage) { async function callGit (args, errorMessage, successMessage) {

View File

@@ -24,6 +24,7 @@ STAMP_FILE="${LLVM_DIR}/../llvm-build/cr_build_revision"
LLVM_REPO_URL=${LLVM_URL:-https://llvm.org/svn/llvm-project} LLVM_REPO_URL=${LLVM_URL:-https://llvm.org/svn/llvm-project}
CDS_URL=https://commondatastorage.googleapis.com/chromium-browser-clang CDS_URL=https://commondatastorage.googleapis.com/chromium-browser-clang
S3_URL=https://s3.amazonaws.com/gh-contractor-zcbenz/clang
# Die if any command dies, error on undefined variable expansions. # Die if any command dies, error on undefined variable expansions.
@@ -45,32 +46,48 @@ rm -f "${STAMP_FILE}"
# Check if there's a prebuilt binary and if so just fetch that. That's faster, # Check if there's a prebuilt binary and if so just fetch that. That's faster,
# and goma relies on having matching binary hashes on client and server too. # and goma relies on having matching binary hashes on client and server too.
CDS_FILE="clang-${PACKAGE_VERSION}.tgz"
CDS_OUT_DIR=$(mktemp -d -t clang_download.XXXXXX)
CDS_OUTPUT="${CDS_OUT_DIR}/${CDS_FILE}"
if [ "${OS}" = "Linux" ]; then
CDS_FULL_URL="${CDS_URL}/Linux_x64/${CDS_FILE}"
elif [ "${OS}" = "Darwin" ]; then
CDS_FULL_URL="${CDS_URL}/Mac/${CDS_FILE}"
fi
echo Trying to download prebuilt clang echo Trying to download prebuilt clang
if which curl > /dev/null; then rm -rf "${LLVM_BUILD_DIR}"
curl -L --fail "${CDS_FULL_URL}" -o "${CDS_OUTPUT}" || \ mkdir -p "${LLVM_BUILD_DIR}"
rm -rf "${CDS_OUT_DIR}"
elif which wget > /dev/null; then CDS_FILES=("clang-${PACKAGE_VERSION}.tgz")
wget "${CDS_FULL_URL}" -O "${CDS_OUTPUT}" || rm -rf "${CDS_OUT_DIR}" CDS_OUT_DIR=$(mktemp -d -t clang_download.XXXXXX)
else if [ "${OS}" = "Linux" ]; then
echo "Neither curl nor wget found. Please install one of these." ARCH="$(uname -m)"
exit 1 if [ "${ARCH}" = "aarch64" ]; then
fi CDS_URL="${S3_URL}"
if [ -f "${CDS_OUTPUT}" ]; then CDS_SUBDIR="arm64"
rm -rf "${LLVM_BUILD_DIR}" else
mkdir -p "${LLVM_BUILD_DIR}" CDS_FILES+=("llvmgold-${PACKAGE_VERSION}.tgz")
tar -xzf "${CDS_OUTPUT}" -C "${LLVM_BUILD_DIR}" CDS_SUBDIR="Linux_x64"
echo clang "${PACKAGE_VERSION}" unpacked fi
echo "${PACKAGE_VERSION}" > "${STAMP_FILE}" elif [ "${OS}" = "Darwin" ]; then
rm -rf "${CDS_OUT_DIR}" CDS_SUBDIR="Mac"
exit 0
else
echo Did not find prebuilt clang "${PACKAGE_VERSION}", building
fi fi
for CDS_FILE in "${CDS_FILES[@]}"
do
CDS_OUTPUT="${CDS_OUT_DIR}/${CDS_FILE}"
CDS_FULL_URL="${CDS_URL}/${CDS_SUBDIR}/${CDS_FILE}"
if which curl > /dev/null; then
curl -L --fail "${CDS_FULL_URL}" -o "${CDS_OUTPUT}" || \
rm -rf "${CDS_OUT_DIR}"
elif which wget > /dev/null; then
wget "${CDS_FULL_URL}" -O "${CDS_OUTPUT}" || rm -rf "${CDS_OUT_DIR}"
else
echo "Neither curl nor wget found. Please install one of these."
exit 1
fi
if [ -f "${CDS_OUTPUT}" ]; then
tar -xzf "${CDS_OUTPUT}" -C "${LLVM_BUILD_DIR}"
else
echo Did not find prebuilt clang "${PACKAGE_VERSION}"
exit 1
fi
done
echo clang "${PACKAGE_VERSION}" unpacked
echo "${PACKAGE_VERSION}" > "${STAMP_FILE}"
rm -rf "${CDS_OUT_DIR}"
exit 0

View File

@@ -85,12 +85,16 @@ def main():
upload_electron(github, release, os.path.join(DIST_DIR, ffmpeg), upload_electron(github, release, os.path.join(DIST_DIR, ffmpeg),
args.upload_to_s3) args.upload_to_s3)
# Upload chromedriver and mksnapshot for minor version update. chromedriver = get_zip_name('chromedriver', ELECTRON_VERSION)
if parse_version(args.version)[2] == '0': upload_electron(github, release, os.path.join(DIST_DIR, chromedriver),
chromedriver = get_zip_name('chromedriver', ELECTRON_VERSION) args.upload_to_s3)
upload_electron(github, release, os.path.join(DIST_DIR, chromedriver), mksnapshot = get_zip_name('mksnapshot', ELECTRON_VERSION)
args.upload_to_s3) upload_electron(github, release, os.path.join(DIST_DIR, mksnapshot),
mksnapshot = get_zip_name('mksnapshot', ELECTRON_VERSION) args.upload_to_s3)
if get_target_arch().startswith('arm'):
# Upload the x64 binary for arm/arm64 mksnapshot
mksnapshot = get_zip_name('mksnapshot', ELECTRON_VERSION, 'x64')
upload_electron(github, release, os.path.join(DIST_DIR, mksnapshot), upload_electron(github, release, os.path.join(DIST_DIR, mksnapshot),
args.upload_to_s3) args.upload_to_s3)
@@ -179,7 +183,7 @@ def get_text_with_editor(name):
def create_or_get_release_draft(github, releases, tag, tag_exists): def create_or_get_release_draft(github, releases, tag, tag_exists):
# Search for existing draft. # Search for existing draft.
for release in releases: for release in releases:
if release['draft']: if release['draft'] and release['tag_name'] == tag:
return release return release
if tag_exists: if tag_exists:

View File

@@ -531,6 +531,54 @@ describe('app module', () => {
}) })
}) })
describe('app launch through uri', () => {
before(function () {
if (process.platform !== 'win32') {
this.skip()
}
})
it('does not launch for blacklisted argument', function (done) {
const appPath = path.join(__dirname, 'fixtures', 'api', 'quit-app')
// App should exit with non 123 code.
const first = ChildProcess.spawn(remote.process.execPath, [appPath, 'electron-test://?', '--no-sandbox', '--gpu-launcher=cmd.exe /c start calc'])
first.once('exit', (code) => {
assert.notEqual(code, 123)
done()
})
})
it('launches successfully for multiple uris in cmd args', function (done) {
const appPath = path.join(__dirname, 'fixtures', 'api', 'quit-app')
// App should exit with code 123.
const first = ChildProcess.spawn(remote.process.execPath, [appPath, 'http://electronjs.org', 'electron-test://testdata'])
first.once('exit', (code) => {
assert.equal(code, 123)
done()
})
})
it('does not launch for encoded space', function (done) {
const appPath = path.join(__dirname, 'fixtures', 'api', 'quit-app')
// App should exit with non 123 code.
const first = ChildProcess.spawn(remote.process.execPath, [appPath, 'electron-test://?', '--no-sandbox', '--gpu-launcher%20"cmd.exe /c start calc'])
first.once('exit', (code) => {
assert.notEqual(code, 123)
done()
})
})
it('launches successfully for argnames similar to blacklisted ones', function (done) {
const appPath = path.join(__dirname, 'fixtures', 'api', 'quit-app')
// inspect is blacklisted, but inspector should work, and app launch should succeed
const first = ChildProcess.spawn(remote.process.execPath, [appPath, 'electron-test://?', '--inspector'])
first.once('exit', (code) => {
assert.equal(code, 123)
done()
})
})
})
describe('getFileIcon() API', () => { describe('getFileIcon() API', () => {
const iconPath = path.join(__dirname, 'fixtures/assets/icon.ico') const iconPath = path.join(__dirname, 'fixtures/assets/icon.ico')
const sizes = { const sizes = {

View File

@@ -30,6 +30,22 @@ describe('BrowserView module', () => {
return closeWindow(w).then(() => { w = null }) return closeWindow(w).then(() => { w = null })
}) })
describe('BrowserView.destroy()', () => {
it('does not throw', () => {
view = new BrowserView()
view.destroy()
})
})
describe('BrowserView.isDestroyed()', () => {
it('returns correct value', () => {
view = new BrowserView()
assert.ok(!view.isDestroyed())
view.destroy()
assert.ok(view.isDestroyed())
})
})
describe('BrowserView.setBackgroundColor()', () => { describe('BrowserView.setBackgroundColor()', () => {
it('does not throw for valid args', () => { it('does not throw for valid args', () => {
view = new BrowserView() view = new BrowserView()

View File

@@ -421,6 +421,29 @@ describe('BrowserWindow module', () => {
done() done()
}) })
}) })
it('preserves transparency', (done) => {
w.close()
const width = 400
const height = 400
w = new BrowserWindow({
show: false,
width: width,
height: height,
transparent: true
})
w.loadURL('data:text/html,<html><body background-color: rgba(255,255,255,0)></body></html>')
w.once('ready-to-show', () => {
w.show()
w.capturePage((image) => {
let imgBuffer = image.toPNG()
// Check 25th byte in the PNG
// Values can be 0,2,3,4, or 6. We want 6, which is RGB + Alpha
assert.equal(imgBuffer[25], 6)
done()
})
})
})
}) })
describe('BrowserWindow.setSize(width, height)', () => { describe('BrowserWindow.setSize(width, height)', () => {
@@ -2861,7 +2884,7 @@ describe('BrowserWindow module', () => {
}) })
it('enables context isolation on child windows', (done) => { it('enables context isolation on child windows', (done) => {
app.once('browser-window-created', (event, window) => { app.once('browser-window-created', (event, window) => {
assert.equal(window.webContents.getWebPreferences().contextIsolation, true) assert.equal(window.webContents.getLastWebPreferences().contextIsolation, true)
done() done()
}) })
w.loadURL(`file://${fixtures}/pages/window-open.html`) w.loadURL(`file://${fixtures}/pages/window-open.html`)

View File

@@ -279,14 +279,26 @@ describe('Menu module', () => {
}) })
afterEach(() => { afterEach(() => {
menu.closePopup()
menu.closePopup(w)
return closeWindow(w).then(() => { w = null }) return closeWindow(w).then(() => { w = null })
}) })
describe('when called with async: true', () => { it('returns immediately', () => {
it('returns immediately', () => { const { browserWindow, x, y, async } = menu.popup(w, {x: 100, y: 101, async: true})
menu.popup(w, {x: 100, y: 100, async: true})
menu.closePopup(w) assert.equal(browserWindow, w)
}) assert.equal(x, 100)
assert.equal(y, 101)
assert.equal(async, true)
})
it('works without a given BrowserWindow and options', () => {
const { browserWindow, x, y } = menu.popup({x: 100, y: 101, async: true})
assert.equal(browserWindow.constructor.name, 'BrowserWindow')
assert.equal(x, 100)
assert.equal(y, 101)
}) })
}) })

View File

@@ -271,7 +271,8 @@ describe('session module', () => {
}) })
describe('DownloadItem', () => { describe('DownloadItem', () => {
const mockPDF = new Buffer(1024 * 1024 * 5) const mockPDF = Buffer.alloc(1024 * 1024 * 5)
const protocolName = 'custom-dl'
let contentDisposition = 'inline; filename="mock.pdf"' let contentDisposition = 'inline; filename="mock.pdf"'
const downloadFilePath = path.join(fixtures, 'mock.pdf') const downloadFilePath = path.join(fixtures, 'mock.pdf')
const downloadServer = http.createServer((req, res) => { const downloadServer = http.createServer((req, res) => {
@@ -286,11 +287,15 @@ describe('session module', () => {
}) })
const assertDownload = (event, state, url, mimeType, const assertDownload = (event, state, url, mimeType,
receivedBytes, totalBytes, disposition, receivedBytes, totalBytes, disposition,
filename, port, savePath) => { filename, port, savePath, isCustom) => {
assert.equal(state, 'completed') assert.equal(state, 'completed')
assert.equal(filename, 'mock.pdf') assert.equal(filename, 'mock.pdf')
assert.equal(savePath, path.join(__dirname, 'fixtures', 'mock.pdf')) assert.equal(savePath, path.join(__dirname, 'fixtures', 'mock.pdf'))
assert.equal(url, `http://127.0.0.1:${port}/`) if (isCustom) {
assert.equal(url, `${protocolName}://item`)
} else {
assert.equal(url, `http://127.0.0.1:${port}/`)
}
assert.equal(mimeType, 'application/pdf') assert.equal(mimeType, 'application/pdf')
assert.equal(receivedBytes, mockPDF.length) assert.equal(receivedBytes, mockPDF.length)
assert.equal(totalBytes, mockPDF.length) assert.equal(totalBytes, mockPDF.length)
@@ -315,6 +320,30 @@ describe('session module', () => {
}) })
}) })
it('can download from custom protocols using WebContents.downloadURL', (done) => {
const protocol = session.defaultSession.protocol
downloadServer.listen(0, '127.0.0.1', () => {
const port = downloadServer.address().port
const handler = (ignoredError, callback) => {
callback({url: `${url}:${port}`})
}
protocol.registerHttpProtocol(protocolName, handler, (error) => {
if (error) return done(error)
ipcRenderer.sendSync('set-download-option', false, false)
w.webContents.downloadURL(`${protocolName}://item`)
ipcRenderer.once('download-done', (event, state, url,
mimeType, receivedBytes,
totalBytes, disposition,
filename, savePath) => {
assertDownload(event, state, url, mimeType, receivedBytes,
totalBytes, disposition, filename, port, savePath,
true)
done()
})
})
})
})
it('can download using WebView.downloadURL', (done) => { it('can download using WebView.downloadURL', (done) => {
downloadServer.listen(0, '127.0.0.1', () => { downloadServer.listen(0, '127.0.0.1', () => {
const port = downloadServer.address().port const port = downloadServer.address().port

View File

@@ -115,7 +115,12 @@ describe('chromium feature', () => {
describe('navigator.serviceWorker', () => { describe('navigator.serviceWorker', () => {
it('should register for file scheme', (done) => { it('should register for file scheme', (done) => {
w = new BrowserWindow({ show: false }) w = new BrowserWindow({
show: false,
webPreferences: {
partition: 'sw-file-scheme-spec'
}
})
w.webContents.on('ipc-message', (event, args) => { w.webContents.on('ipc-message', (event, args) => {
if (args[0] === 'reload') { if (args[0] === 'reload') {
w.webContents.reload() w.webContents.reload()
@@ -123,7 +128,7 @@ describe('chromium feature', () => {
done(`unexpected error : ${args[1]}`) done(`unexpected error : ${args[1]}`)
} else if (args[0] === 'response') { } else if (args[0] === 'response') {
assert.equal(args[1], 'Hello from serviceWorker!') assert.equal(args[1], 'Hello from serviceWorker!')
session.defaultSession.clearStorageData({ session.fromPartition('sw-file-scheme-spec').clearStorageData({
storages: ['serviceworkers'] storages: ['serviceworkers']
}, () => done()) }, () => done())
} }
@@ -208,6 +213,26 @@ describe('chromium feature', () => {
b = window.open(`file://${fixtures}/pages/window-open-size.html`, '', 'show=no') b = window.open(`file://${fixtures}/pages/window-open-size.html`, '', 'show=no')
}) })
for (const show of [true, false]) {
it(`inherits parent visibility over parent {show=${show}} option`, (done) => {
const w = new BrowserWindow({show})
// toggle visibility
if (show) {
w.hide()
} else {
w.show()
}
w.webContents.once('new-window', (e, url, frameName, disposition, options) => {
assert.equal(options.show, w.isVisible())
w.close()
done()
})
w.loadURL(`file://${fixtures}/pages/window-open.html`)
})
}
it('disables node integration when it is disabled on the parent window', (done) => { it('disables node integration when it is disabled on the parent window', (done) => {
let b let b
listener = (event) => { listener = (event) => {
@@ -228,6 +253,26 @@ describe('chromium feature', () => {
b = window.open(windowUrl, '', 'nodeIntegration=no,show=no') b = window.open(windowUrl, '', 'nodeIntegration=no,show=no')
}) })
it('disables webviewTag when node integration is disabled on the parent window', (done) => {
let b
listener = (event) => {
assert.equal(event.data.isWebViewUndefined, true)
b.close()
done()
}
window.addEventListener('message', listener)
const windowUrl = require('url').format({
pathname: `${fixtures}/pages/window-opener-no-web-view-tag.html`,
protocol: 'file',
query: {
p: `${fixtures}/pages/window-opener-web-view.html`
},
slashes: true
})
b = window.open(windowUrl, '', 'nodeIntegration=no,show=no')
})
it('disables node integration when it is disabled on the parent window for chrome devtools URLs', (done) => { it('disables node integration when it is disabled on the parent window for chrome devtools URLs', (done) => {
let b let b
app.once('web-contents-created', (event, contents) => { app.once('web-contents-created', (event, contents) => {
@@ -247,7 +292,7 @@ describe('chromium feature', () => {
app.once('web-contents-created', (event, contents) => { app.once('web-contents-created', (event, contents) => {
contents.once('did-finish-load', () => { contents.once('did-finish-load', () => {
app.once('browser-window-created', (event, window) => { app.once('browser-window-created', (event, window) => {
const preferences = window.webContents.getWebPreferences() const preferences = window.webContents.getLastWebPreferences()
assert.equal(preferences.javascript, false) assert.equal(preferences.javascript, false)
window.destroy() window.destroy()
b.close() b.close()
@@ -469,7 +514,7 @@ describe('chromium feature', () => {
done() done()
} }
window.addEventListener('message', listener) window.addEventListener('message', listener)
w = window.open(url, '', 'show=no') w = window.open(url, '', 'show=no,nodeIntegration=no')
}) })
it('works when origin matches', (done) => { it('works when origin matches', (done) => {
@@ -478,7 +523,7 @@ describe('chromium feature', () => {
done() done()
} }
window.addEventListener('message', listener) window.addEventListener('message', listener)
w = window.open(`file://${fixtures}/pages/window-opener-location.html`, '', 'show=no') w = window.open(`file://${fixtures}/pages/window-opener-location.html`, '', 'show=no,nodeIntegration=no')
}) })
it('works when origin does not match opener but has node integration', (done) => { it('works when origin does not match opener but has node integration', (done) => {

View File

@@ -0,0 +1,15 @@
<html>
<body>
<script type="text/javascript" charset="utf-8">
var windowUrl = decodeURIComponent(window.location.search.substring(3))
var opened = window.open('file://' + windowUrl, '', 'webviewTag=yes,show=no')
window.addEventListener('message', function (event) {
try {
opened.close()
} finally {
window.opener.postMessage(event.data, '*')
}
})
</script>
</body>
</html>

View File

@@ -0,0 +1,9 @@
<html>
<body>
<script type="text/javascript" charset="utf-8">
window.onload = () => {
window.opener.postMessage({isWebViewUndefined: typeof WebView === 'undefined'}, '*')
}
</script>
</body>
</html>

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