Compare commits

...

117 Commits

Author SHA1 Message Date
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
97 changed files with 12954 additions and 511 deletions

View File

@@ -3,10 +3,10 @@ version: 2
jobs:
electron-linux-arm:
docker:
- image: electronbuilds/electron:0.0.3
- image: electronbuilds/electron:0.0.7
environment:
TARGET_ARCH: arm
resource_class: xlarge
resource_class: 2xlarge
steps:
- checkout
- run:
@@ -60,10 +60,10 @@ jobs:
fi
electron-linux-arm64:
docker:
- image: electronbuilds/electron:0.0.3
- image: electronbuilds/electron:0.0.7
environment:
TARGET_ARCH: arm64
resource_class: xlarge
resource_class: 2xlarge
steps:
- checkout
- run:
@@ -117,7 +117,7 @@ jobs:
fi
electron-linux-ia32:
docker:
- image: electronbuilds/electron:0.0.3
- image: electronbuilds/electron:0.0.7
environment:
TARGET_ARCH: ia32
resource_class: xlarge
@@ -174,7 +174,7 @@ jobs:
fi
electron-linux-mips64el:
docker:
- image: electronbuilds/electron:0.0.3
- image: electronbuilds/electron:0.0.7
environment:
TARGET_ARCH: mips64el
resource_class: xlarge
@@ -232,11 +232,11 @@ jobs:
electron-linux-x64:
docker:
- image: electronbuilds/electron:0.0.3
- image: electronbuilds/electron:0.0.7
environment:
TARGET_ARCH: x64
DISPLAY: ':99.0'
resource_class: xlarge
resource_class: 2xlarge
steps:
- checkout
- run:
@@ -262,6 +262,206 @@ jobs:
- 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-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: |
if [ "$ELECTRON_RELEASE" == "1" ]; then
echo 'Building Electron for release'
@@ -339,3 +539,12 @@ workflows:
build-x64:
jobs:
- 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/
/out/
/vendor/.gclient
/vendor/cross-gcc-4.9.3-n64-loongson-rc5.4
/vendor/debian_jessie_amd64-sysroot/
/vendor/debian_jessie_arm-sysroot/
/vendor/debian_jessie_arm64-sysroot/
@@ -36,13 +37,13 @@
/vendor/debian_wheezy_amd64-sysroot/
/vendor/debian_wheezy_arm-sysroot/
/vendor/debian_wheezy_i386-sysroot/
/vendor/gcc-4.8.3-d197-n64-loongson/
/vendor/readme-gcc483-loongson.txt
/vendor/download/
/vendor/llvm-build/
/vendor/llvm/
/vendor/node/deps/node-inspect/.npmrc
/vendor/npm/
/vendor/python_26/
/vendor/native_mksnapshot
/vendor/LICENSES.chromium.html
node_modules/
SHASUMS256.txt

View File

@@ -34,7 +34,7 @@ This Code of Conduct applies both within project spaces and in public spaces whe
## 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.

View File

@@ -4,7 +4,7 @@
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
behavior to electron@github.com.
behavior to coc@electronjs.org.
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

View File

@@ -7,7 +7,7 @@ ENV HOME=/home
RUN chmod a+rwx /home
# 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
# 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
# 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
# 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
[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
behavior to [electron@github.com](mailto:electron@github.com).
behavior to [coc@electronjs.org](mailto:coc@electronjs.org).
## 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.
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.

View File

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

View File

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

View File

@@ -4,7 +4,8 @@
#include "atom/app/atom_main.h"
#include <stdlib.h>
#include <cstdlib>
#include <vector>
#if defined(OS_WIN)
#include <windows.h> // windows.h must be included first
@@ -15,9 +16,11 @@
#include <tchar.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 "base/environment.h"
#include "base/process/launch.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/windows_version.h"
#include "content/public/app/sandbox_helper_win.h"
#include "sandbox/win/src/sandbox_types.h"
@@ -52,18 +55,23 @@ bool IsEnvSet(const char* name) {
#if defined(OS_WIN)
int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
int argc = 0;
wchar_t** wargv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
struct Arguments {
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
// Don't display assert dialog boxes in CI test runs
static const auto kCI = "ELECTRON_CI";
bool is_ci = IsEnvSet(kCI);
if (!is_ci) {
for (int i = 0; i < argc; ++i) {
if (!_wcsicmp(wargv[i], L"--ci")) {
for (int i = 0; i < arguments.argc; ++i) {
if (!_wcsicmp(arguments.argv[i], L"--ci")) {
is_ci = true;
_putenv_s(kCI, "1"); // set flag for child processes
break;
@@ -81,44 +89,12 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
}
#endif
bool run_as_node = IsEnvSet(kRunAsNode);
// Make sure the output is printed to console.
if (run_as_node || !IsEnvSet("ELECTRON_NO_ATTACH_CONSOLE"))
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
// Chromium has its own TLS subsystem which supports automatic destruction
// 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
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::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")) {
return crash_service::Main(cmd);
}
if (!atom::CheckCommandLineArguments(arguments.argc, arguments.argv))
return -1;
sandbox::SandboxInterfaceInfo sandbox_info = {0};
content::InitializeSandboxInfo(&sandbox_info);
atom::AtomMainDelegate delegate;
@@ -154,33 +139,32 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
content::ContentMainParams params(&delegate);
params.instance = instance;
params.sandbox_info = &sandbox_info;
atom::AtomCommandLine::Init(argc, argv);
atom::AtomCommandLine::InitW(argc, wargv);
atom::AtomCommandLine::Init(arguments.argc, arguments.argv);
return content::ContentMain(params);
}
#elif defined(OS_LINUX) // defined(OS_WIN)
int main(int argc, const char* argv[]) {
int main(int argc, char* argv[]) {
if (IsEnvSet(kRunAsNode)) {
base::i18n::InitializeICU();
base::AtExitManager atexit_manager;
return atom::NodeMain(argc, const_cast<char**>(argv));
return atom::NodeMain(argc, argv);
}
atom::AtomMainDelegate delegate;
content::ContentMainParams params(&delegate);
params.argc = argc;
params.argv = argv;
params.argv = const_cast<const char**>(argv);
atom::AtomCommandLine::Init(argc, argv);
return content::ContentMain(params);
}
#else // defined(OS_LINUX)
int main(int argc, const char* argv[]) {
int main(int argc, char* argv[]) {
if (IsEnvSet(kRunAsNode)) {
return AtomInitializeICUandStartNode(argc, const_cast<char**>(argv));
return AtomInitializeICUandStartNode(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 defined(OS_WIN)
const relauncher::StringVector& argv = atom::AtomCommandLine::wargv();
#else
const relauncher::StringVector& argv = atom::AtomCommandLine::argv();
#endif
return relauncher::RelaunchApp(argv);
}

View File

@@ -68,8 +68,8 @@ void BrowserView::Init(v8::Isolate* isolate,
web_contents_.Reset(isolate, web_contents.ToV8());
api_web_contents_ = web_contents.get();
view_.reset(NativeBrowserView::Create(
api_web_contents_->managed_web_contents()->GetView()));
view_.reset(
NativeBrowserView::Create(api_web_contents_->managed_web_contents()));
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:
// http://code.google.com/p/webrtc/issues/detail?id=3373)
options.set_disable_effects(false);
options.set_allow_directx_capturer(true);
#endif
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(
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)
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.
gfx::Point location;
if (x == -1 || y == -1) {
location = display::Screen::GetScreen()->GetCursorScreenPoint();
} else {
gfx::Point origin = view->GetViewBounds().origin();
gfx::Point origin = native_window->GetContentBounds().origin();
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(
model(), flags, close_callback));
ignore_result(menu_runners_[window_id]->RunMenuAt(
static_cast<NativeWindowViews*>(window->window())->widget(),
native_window->widget(),
NULL,
gfx::Rect(location, gfx::Size()),
views::MENU_ANCHOR_TOPLEFT,

View File

@@ -78,10 +78,6 @@ class Protocol : public mate::TrackableObject<Protocol> {
net::URLRequestJob* MaybeCreateJob(
net::URLRequest* request,
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);
request_job->SetHandlerInfo(isolate_, request_context_.get(), handler_);
return request_job;

View File

@@ -271,6 +271,9 @@ content::ServiceWorkerContext* GetServiceWorkerContext(
void OnCapturePageDone(const base::Callback<void(const gfx::Image&)>& callback,
const SkBitmap& bitmap,
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));
}
@@ -377,8 +380,8 @@ WebContents::WebContents(v8::Isolate* isolate, const mate::Dictionary& options)
options.Get("transparent", &transparent);
content::WebContents::CreateParams params(session->browser_context());
auto* view = new OffScreenWebContentsView(
transparent, base::Bind(&WebContents::OnPaint, base::Unretained(this)));
auto* view = new OffScreenWebContentsView(transparent,
base::Bind(&WebContents::OnPaint, base::Unretained(this)));
params.view = view;
params.delegate_view = view;
@@ -1644,10 +1647,10 @@ void WebContents::StartPainting() {
return;
#if defined(ENABLE_OSR)
auto* osr_rwhv = static_cast<OffScreenRenderWidgetHostView*>(
web_contents()->GetRenderWidgetHostView());
if (osr_rwhv)
osr_rwhv->SetPainting(true);
const auto* wc_impl = static_cast<content::WebContentsImpl*>(web_contents());
auto* osr_wcv = static_cast<OffScreenWebContentsView*>(wc_impl->GetView());
if (osr_wcv)
osr_wcv->SetPainting(true);
#endif
}
@@ -1656,10 +1659,10 @@ void WebContents::StopPainting() {
return;
#if defined(ENABLE_OSR)
auto* osr_rwhv = static_cast<OffScreenRenderWidgetHostView*>(
web_contents()->GetRenderWidgetHostView());
if (osr_rwhv)
osr_rwhv->SetPainting(false);
const auto* wc_impl = static_cast<content::WebContentsImpl*>(web_contents());
auto* osr_wcv = static_cast<OffScreenWebContentsView*>(wc_impl->GetView());
if (osr_wcv)
osr_wcv->SetPainting(false);
#endif
}
@@ -1668,9 +1671,10 @@ bool WebContents::IsPainting() const {
return false;
#if defined(ENABLE_OSR)
const auto* osr_rwhv = static_cast<OffScreenRenderWidgetHostView*>(
web_contents()->GetRenderWidgetHostView());
return osr_rwhv && osr_rwhv->IsPainting();
const auto* wc_impl = static_cast<content::WebContentsImpl*>(web_contents());
auto* osr_wcv = static_cast<OffScreenWebContentsView*>(wc_impl->GetView());
return osr_wcv && osr_wcv->IsPainting();
#else
return false;
#endif
@@ -1681,10 +1685,11 @@ void WebContents::SetFrameRate(int frame_rate) {
return;
#if defined(ENABLE_OSR)
auto* osr_rwhv = static_cast<OffScreenRenderWidgetHostView*>(
web_contents()->GetRenderWidgetHostView());
if (osr_rwhv)
osr_rwhv->SetFrameRate(frame_rate);
const auto* wc_impl = static_cast<content::WebContentsImpl*>(web_contents());
auto* osr_wcv = static_cast<OffScreenWebContentsView*>(wc_impl->GetView());
if (osr_wcv)
osr_wcv->SetFrameRate(frame_rate);
#endif
}
@@ -1693,9 +1698,10 @@ int WebContents::GetFrameRate() const {
return 0;
#if defined(ENABLE_OSR)
const auto* osr_rwhv = static_cast<OffScreenRenderWidgetHostView*>(
web_contents()->GetRenderWidgetHostView());
return osr_rwhv ? osr_rwhv->GetFrameRate() : 0;
const auto* wc_impl = static_cast<content::WebContentsImpl*>(web_contents());
auto* osr_wcv = static_cast<OffScreenWebContentsView*>(wc_impl->GetView());
return osr_wcv ? osr_wcv->GetFrameRate() : 0;
#else
return 0;
#endif
@@ -1765,6 +1771,14 @@ v8::Local<v8::Value> WebContents::GetWebPreferences(v8::Isolate* isolate) {
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() {
if (owner_window())
return Window::From(isolate(), owner_window());
@@ -1911,6 +1925,7 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
.SetMethod("_getZoomFactor", &WebContents::GetZoomFactor)
.SetMethod("getType", &WebContents::GetType)
.SetMethod("getWebPreferences", &WebContents::GetWebPreferences)
.SetMethod("getLastWebPreferences", &WebContents::GetLastWebPreferences)
.SetMethod("getOwnerBrowserWindow", &WebContents::GetOwnerBrowserWindow)
.SetMethod("hasServiceWorker", &WebContents::HasServiceWorker)
.SetMethod("unregisterServiceWorker",

View File

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

View File

@@ -889,6 +889,8 @@ void Window::SetBrowserView(v8::Local<v8::Value> value) {
window_->SetBrowserView(browser_view->view());
browser_view->web_contents()->SetOwnerWindow(window_.get());
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/site_instance.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/url_constants.h"
#include "content/public/common/web_preferences.h"
@@ -243,6 +244,11 @@ void AtomBrowserClient::OverrideSiteInstanceForNavigation(
void AtomBrowserClient::AppendExtraCommandLineSwitches(
base::CommandLine* command_line,
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 =
command_line->GetSwitchValueASCII(::switches::kProcessType);
if (process_type != ::switches::kRendererProcess)

View File

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

View File

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

View File

@@ -17,12 +17,13 @@ namespace atom {
class NativeBrowserViewMac : public NativeBrowserView {
public:
explicit NativeBrowserViewMac(
brightray::InspectableWebContentsView* web_contents_view);
brightray::InspectableWebContents* inspectable_web_contents);
~NativeBrowserViewMac() override;
void SetAutoResizeFlags(uint8_t flags) override;
void SetBounds(const gfx::Rect& bounds) override;
void SetBackgroundColor(SkColor color) override;
void UpdateDraggableRegions(
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 "brightray/browser/inspectable_web_contents.h"
#include "brightray/browser/inspectable_web_contents_view.h"
#include "skia/ext/skia_utils_mac.h"
#include "ui/gfx/geometry/rect.h"
@@ -156,8 +157,8 @@ const NSAutoresizingMaskOptions kDefaultAutoResizingMask =
namespace atom {
NativeBrowserViewMac::NativeBrowserViewMac(
brightray::InspectableWebContentsView* web_contents_view)
: NativeBrowserView(web_contents_view) {
brightray::InspectableWebContents* inspectable_web_contents)
: NativeBrowserView(inspectable_web_contents) {
auto* view = GetInspectableWebContentsView()->GetNativeView();
view.autoresizingMask = kDefaultAutoResizingMask;
}
@@ -193,62 +194,46 @@ void NativeBrowserViewMac::SetBackgroundColor(SkColor color) {
}
void NativeBrowserViewMac::UpdateDraggableRegions(
const std::vector<gfx::Rect>& system_drag_exclude_areas) {
NSView* webView = GetInspectableWebContentsView()->GetNativeView();
const std::vector<gfx::Rect>& drag_exclude_rects) {
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]);
NSInteger webViewHeight = NSHeight([webView bounds]);
NSInteger webViewWidth = NSWidth([webView bounds]);
NSInteger webViewX = NSMinX([webView frame]);
NSInteger webViewY = 0;
// 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]])
// Remove all DragRegionViews that were added last time. Note that we need
// to copy the `subviews` array to avoid mutation during iteration.
base::scoped_nsobject<NSArray> subviews([[web_view subviews] copy]);
for (NSView* subview in subviews.get()) {
if ([subview isKindOfClass:[DragRegionView class]]) {
[subview removeFromSuperview];
}
}
// Create one giant NSView that is draggable.
base::scoped_nsobject<NSView> dragRegion(
[[DragRegionView alloc] initWithFrame:NSZeroRect]);
[dragRegion setFrame:NSMakeRect(0,
0,
webViewWidth,
webViewHeight)];
base::scoped_nsobject<NSView> drag_region_view(
[[DragRegionView alloc] initWithFrame:web_view.bounds]);
[web_view addSubview:drag_region_view];
// Then, on top of that, add "exclusion zones"
for (auto iter = system_drag_exclude_areas.begin();
iter != system_drag_exclude_areas.end();
++iter) {
base::scoped_nsobject<NSView> controlRegion(
[[ExcludeDragRegionView alloc] initWithFrame:NSZeroRect]);
[controlRegion setFrame:NSMakeRect(iter->x() - webViewX,
webViewHeight - iter->bottom() + webViewY,
iter->width(),
iter->height())];
[dragRegion addSubview:controlRegion];
}
for (const auto& rect : drag_exclude_rects) {
const auto window_content_view_exclude_rect =
NSMakeRect(rect.x(), window_content_view_height - rect.bottom(),
rect.width(), rect.height());
const auto drag_region_view_exclude_rect =
[window_content_view convertRect:window_content_view_exclude_rect
toView:drag_region_view];
// Add the DragRegion to the WebView
[webView addSubview:dragRegion];
base::scoped_nsobject<NSView> exclude_drag_region_view(
[[ExcludeDragRegionView alloc]
initWithFrame:drag_region_view_exclude_rect]);
[drag_region_view addSubview:exclude_drag_region_view];
}
}
// static
NativeBrowserView* NativeBrowserView::Create(
brightray::InspectableWebContentsView* web_contents_view) {
return new NativeBrowserViewMac(web_contents_view);
brightray::InspectableWebContents* inspectable_web_contents) {
return new NativeBrowserViewMac(inspectable_web_contents);
}
} // namespace atom

View File

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

View File

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

View File

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

View File

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

View File

@@ -1932,25 +1932,20 @@ void NativeWindowMac::UpdateDraggableRegionViews(
// Draggable regions is implemented by having the whole web view 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);
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
// excluded from the dragging.
for (std::vector<gfx::Rect>::const_iterator iter =
system_drag_exclude_areas.begin();
iter != system_drag_exclude_areas.end();
++iter) {
for (const auto& rect : drag_exclude_rects) {
base::scoped_nsobject<NSView> controlRegion(
[[ControlRegionView alloc] initWithFrame:NSZeroRect]);
[controlRegion setFrame:NSMakeRect(iter->x(),
webViewHeight - iter->bottom(),
iter->width(),
iter->height())];
[controlRegion setFrame:NSMakeRect(rect.x(), webViewHeight - rect.bottom(),
rect.width(), rect.height())];
[webView addSubview:controlRegion];
}

View File

@@ -53,6 +53,7 @@
#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_window_tree_host_win.h"
#include "content/public/browser/gpu_data_manager.h"
#include "skia/ext/skia_utils_win.h"
#include "ui/base/win/shell.h"
#include "ui/display/display.h"
@@ -297,9 +298,12 @@ NativeWindowViews::NativeWindowViews(
::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, frame_style);
}
bool hardware_accelerated =
content::GpuDataManager::GetInstance()->HardwareAccelerationEnabled();
LONG ex_style = ::GetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE);
// Window without thick frame has to have WS_EX_COMPOSITED style.
if (!thick_frame_)
// Window without thick frame has to have WS_EX_COMPOSITED style when GPU
// acceleration is enabled.
if (!thick_frame_ && hardware_accelerated)
ex_style |= WS_EX_COMPOSITED;
if (window_type == "toolbar")
ex_style |= WS_EX_TOOLWINDOW;
@@ -1363,22 +1367,26 @@ void NativeWindowViews::ShowAutofillPopup(
const gfx::RectF& bounds,
const std::vector<base::string16>& values,
const std::vector<base::string16>& labels) {
const auto* web_preferences =
WebContentsPreferences::FromWebContents(web_contents)->web_preferences();
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;
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);
auto* web_contents_preferences =
WebContentsPreferences::FromWebContents(web_contents);
if (web_contents_preferences) {
const auto* web_preferences = web_contents_preferences->web_preferences();
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->is_directory = file_info.is_directory;
}
// On Windows GetMimeTypeFromFile() goes to the registry. Thus it should be
// done in WorkerPool.
meta_info->mime_type_result =
net::GetMimeTypeFromFile(file_path, &meta_info->mime_type);
// We use GetWellKnownMimeTypeFromExtension() to ensure that configurations
// that may have been set by other programs on a user's machine don't affect
// 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) {

View File

@@ -7,6 +7,7 @@
#include <string>
#include "atom/browser/api/atom_api_url_request.h"
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/net/atom_url_request_job_factory.h"
#include "base/callback.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/elements_upload_data_stream.h"
@@ -120,6 +121,9 @@ void AtomURLRequest::DoInitialize(
request_->set_method(method);
// Do not send cookies from the cookie store.
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() {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -15,6 +15,8 @@ namespace atom {
OffScreenWebContentsView::OffScreenWebContentsView(
bool transparent, const OnPaintCallback& callback)
: transparent_(transparent),
painting_(true),
frame_rate_(60),
callback_(callback),
web_contents_(nullptr) {
#if defined(OS_MACOSX)
@@ -103,6 +105,8 @@ content::RenderWidgetHostViewBase*
auto relay = NativeWindowRelay::FromWebContents(web_contents_);
return new OffScreenRenderWidgetHostView(
transparent_,
painting_,
GetFrameRate(),
callback_,
render_widget_host,
nullptr,
@@ -125,6 +129,8 @@ content::RenderWidgetHostViewBase*
return new OffScreenRenderWidgetHostView(
transparent_,
true,
view->GetFrameRate(),
callback_,
render_widget_host,
view,
@@ -202,6 +208,42 @@ void OffScreenWebContentsView::UpdateDragCursor(
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 {
if (web_contents_) {
return static_cast<OffScreenRenderWidgetHostView*>(

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -3,12 +3,16 @@
// found in the LICENSE file.
#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 {
AtomDesktopNativeWidgetAura::AtomDesktopNativeWidgetAura(
views::internal::NativeWidgetDelegate* delegate)
: views::DesktopNativeWidgetAura(delegate) {
// This is to enable the override of OnWindowActivated
aura::client::SetActivationChangeObserver(GetNativeWindow(), this);
}
void AtomDesktopNativeWidgetAura::Activate() {
@@ -19,4 +23,23 @@ void AtomDesktopNativeWidgetAura::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

View File

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

View File

@@ -47,6 +47,35 @@ WebContentsPreferences::WebContentsPreferences(
web_contents->SetUserData(UserDataKey(), 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() {
@@ -55,6 +84,16 @@ WebContentsPreferences::~WebContentsPreferences() {
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) {
web_preferences_.MergeDictionary(&extend);
}
@@ -79,6 +118,12 @@ void WebContentsPreferences::AppendExtraCommandLineSwitches(
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;
// Check if plugins are enabled.
if (web_preferences.GetBoolean("plugins", &b) && b)

View File

@@ -57,6 +57,9 @@ class WebContentsPreferences
// Returns the web preferences.
base::DictionaryValue* web_preferences() { return &web_preferences_; }
base::DictionaryValue* last_web_preferences() {
return &last_web_preferences_;
}
private:
friend class content::WebContentsUserData<WebContentsPreferences>;
@@ -65,6 +68,10 @@ class WebContentsPreferences
content::WebContents* web_contents_;
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
bool GetInteger(const std::string& attributeName, int* intValue);

View File

@@ -10,31 +10,22 @@
namespace atom {
// static
std::vector<std::string> AtomCommandLine::argv_;
#if defined(OS_WIN)
// static
std::vector<std::wstring> AtomCommandLine::wargv_;
#endif
base::CommandLine::StringVector AtomCommandLine::argv_;
// 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"
char** new_argv = uv_setup_args(argc, const_cast<char**>(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]);
}
}
argv = uv_setup_args(argc, argv);
#endif
argv_.assign(argv, argv + argc);
}
#if defined(OS_LINUX)
// static
void AtomCommandLine::InitializeFromCommandLine() {

View File

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

View File

@@ -7,22 +7,24 @@
#define ATOM_MAJOR_VERSION 1
#define ATOM_MINOR_VERSION 8
#define ATOM_PATCH_VERSION 2
#define ATOM_PRE_RELEASE_VERSION -beta.2
#ifndef ATOM_PRE_RELEASE_VERSION
# define ATOM_PRE_RELEASE_VERSION ""
#endif
#define ATOM_PATCH_VERSION 6
// #define ATOM_PRE_RELEASE_VERSION
#ifndef ATOM_STRINGIFY
#define ATOM_STRINGIFY(n) ATOM_STRINGIFY_HELPER(n)
#define ATOM_STRINGIFY_HELPER(n) #n
#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_PATCH_VERSION) \
ATOM_STRINGIFY(ATOM_PRE_RELEASE_VERSION)
#endif
#define ATOM_VERSION "v" ATOM_VERSION_STRING

View File

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

View File

@@ -4,6 +4,7 @@
#include "atom/common/node_bindings.h"
#include <algorithm>
#include <string>
#include <vector>
@@ -17,6 +18,7 @@
#include "base/files/file_path.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
#include "content/public/browser/browser_thread.h"
@@ -150,7 +152,14 @@ void NodeBindings::Initialize() {
node::Environment* NodeBindings::CreateEnvironment(
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();
#endif
// Feed node the path to initialization script.
base::FilePath::StringType process_type;
@@ -170,8 +179,7 @@ node::Environment* NodeBindings::CreateEnvironment(
resources_path.Append(FILE_PATH_LITERAL("electron.asar"))
.Append(process_type)
.Append(FILE_PATH_LITERAL("init.js"));
std::string script_path_str = script_path.AsUTF8Unsafe();
args.insert(args.begin() + 1, script_path_str.c_str());
args.insert(args.begin() + 1, script_path.AsUTF8Unsafe());
std::unique_ptr<const char*[]> c_argv = StringVectorToArgArray(args);
node::Environment* env = node::CreateEnvironment(

View File

@@ -13,6 +13,7 @@
#include "atom/renderer/api/atom_api_spell_check_client.h"
#include "base/memory/memory_pressure_listener.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_frame_visitor.h"
#include "content/public/renderer/render_view.h"
#include "native_mate/dictionary.h"
#include "native_mate/object_template_builder.h"
@@ -58,6 +59,30 @@ class ScriptExecutionCallback : public blink::WebScriptExecutionCallback {
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
WebFrame::WebFrame(v8::Isolate* isolate)
@@ -101,6 +126,7 @@ double WebFrame::GetZoomFactor() const {
void WebFrame::SetVisualZoomLevelLimits(double min_level, double max_level) {
web_frame_->View()->SetDefaultPageScaleLimits(min_level, max_level);
web_frame_->View()->SetIgnoreViewportTagScaleLimits(true);
}
void WebFrame::SetLayoutZoomLevelLimits(double min_level, double max_level) {
@@ -139,10 +165,15 @@ void WebFrame::SetSpellCheckProvider(mate::Arguments* args,
return;
}
spell_check_client_.reset(new SpellCheckClient(
std::unique_ptr<SpellCheckClient> client(new SpellCheckClient(
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_->SetTextCheckClient(spell_check_client_.get());
}
void WebFrame::RegisterURLSchemeAsSecure(const std::string& scheme) {

View File

@@ -228,10 +228,8 @@
'msvs_settings': {
'VCCLCompilerTool': {
'RuntimeLibrary': '2', # /MD (nondebug DLL)
# 1, optimizeMinSpace, Minimize Size (/O1)
'Optimization': '1',
# 2, favorSize - Favor small code (/Os)
'FavorSizeOrSpeed': '2',
'Optimization': '2', # /O2
'WholeProgramOptimization': 'true', # /GL
# See http://msdn.microsoft.com/en-us/library/47238hez(VS.71).aspx
'InlineFunctionExpansion': '2', # 2 = max
# 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.
# We still want the false setting above to avoid having
# "/Oy /Oy-" and warnings about overriding.
'AdditionalOptions': ['/Oy-'],
'AdditionalOptions': ['/Oy-', '/d2guard4'],
},
'VCLibrarianTool': {
'LinkTimeCodeGeneration': 'true', # /LTCG
},
'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.
'LinkIncremental': '1', # /INCREMENTAL:NO
'LinkTimeCodeGeneration': '1', # /LTCG
'OptimizeReferences': 2, # /OPT:REF
'EnableCOMDATFolding': 2, # /OPT:ICF
},
},
'conditions': [
@@ -270,6 +281,18 @@
'-Wl,--gc-sections',
],
}], # 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
'conditions': [

View File

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

View File

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

View File

@@ -140,6 +140,12 @@
'<(libchromiumcontent_src_dir)/v8',
'<(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': [
['OS=="mac" and libchromiumcontent_component==0', {
# -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:
#### `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_
* `options` Object

View File

@@ -1174,7 +1174,7 @@ menu bar.
* `progress` Double
* `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].

View File

@@ -17,15 +17,27 @@ Please note, the `ARM` version of Windows is not supported for now.
### Linux
The prebuilt `ia32` (`i686`) and `x64` (`amd64`) binaries of Electron are built on
Ubuntu 12.04, the `arm` binary is built against ARM v7 with hard-float ABI and
NEON for Debian Wheezy.
Whether the prebuilt binary can run on a distribution depends on whether the
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:
The prebuilt binaries of Electron are built for Debian Jessie, but whether the
prebuilt binary can run on a distribution depends on whether the distribution
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
verified to be able to run the prebuilt binaries of Electron:
* Ubuntu 12.04 and later
* 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',
'company_name%': 'GitHub, Inc',
'company_abbr%': 'github',
'version%': '1.8.2-beta.2',
'version%': '1.8.6',
'js2c_input_dir': '<(SHARED_INTERMEDIATE_DIR)/js2c',
},
'includes': [
@@ -217,6 +217,11 @@
],
},
],
'link_settings': {
'ldflags': [
'-Wl,-z,noexecstack',
],
},
}], # OS=="linux"
],
}, # target <(project_name)

View File

@@ -98,6 +98,8 @@
'atom/app/atom_main_delegate.cc',
'atom/app/atom_main_delegate.h',
'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.h',
'atom/app/uv_task_runner.cc',

View File

@@ -24,7 +24,7 @@ Menu.prototype._init = function () {
getAcceleratorForCommandId: (id, useDefaultAccelerator) => {
const command = this.commandsMap[id]
if (!command) return
if (command.accelerator) return command.accelerator
if (command.accelerator != null) return command.accelerator
if (useDefaultAccelerator) return command.getDefaultRoleAccelerator()
},
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) {
let asyncPopup
let asyncPopup, opts
let [newX, newY, newPosition, newWindow] = [x, y, positioningItem, window]
// menu.popup(x, y, positioningItem)
if (!window) {
// shift over values
if (typeof window !== 'object' || window.constructor !== BrowserWindow) {
[newPosition, newY, newX, newWindow] = [y, x, window, null]
}
if (window != null && !(window instanceof BrowserWindow)) {
[newPosition, newY, newX, newWindow] = [y, x, window, null]
}
// menu.popup({})
if (window != null && window.constructor === Object) {
opts = window
// menu.popup(window, {})
if (x && typeof x === 'object') {
const opts = x
} else if (x && typeof x === 'object') {
opts = x
}
if (opts) {
newX = opts.x
newY = opts.y
newPosition = opts.positioningItem
@@ -65,13 +68,28 @@ Menu.prototype.popup = function (window, x, y, positioningItem) {
}
// set defaults
if (typeof x !== 'number') newX = -1
if (typeof y !== 'number') newY = -1
if (typeof positioningItem !== 'number') newPosition = -1
if (!window) newWindow = BrowserWindow.getFocusedWindow()
if (typeof newX !== 'number') newX = -1
if (typeof newY !== 'number') newY = -1
if (typeof newPosition !== 'number') newPosition = -1
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)
return { browserWindow: newWindow, x: newX, y: newY, position: newPosition, async: asyncPopup }
}
Menu.prototype.closePopup = function (window) {
@@ -149,7 +167,7 @@ Menu.setApplicationMenu = function (menu) {
}
Menu.buildFromTemplate = function (template) {
if (!(template instanceof Array)) {
if (!Array.isArray(template)) {
throw new TypeError('Invalid template for Menu')
}

View File

@@ -118,6 +118,18 @@ class TouchBar extends EventEmitter {
window.removeListener('closed', removeListeners)
window._touchBar = null
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)
this.windowListeners[id] = removeListeners

View File

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

View File

@@ -46,16 +46,24 @@ const mergeBrowserWindowOptions = function (embedder, options) {
options.webPreferences = {}
}
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.
mergeOptions(options, embedder.browserWindowOptions)
mergeOptions(options, parentOptions)
} else {
// 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
for (const [name, value] of inheritedWebPreferences) {
if (embedder.getWebPreferences()[name] === value) {
if (embedder.getLastWebPreferences()[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
// security model of |window.opener|, this should be fine.
const canAccessWindow = function (sender, target) {
return (target.getWebPreferences().openerId === sender.id) ||
(sender.getWebPreferences().nodeIntegration === true) ||
return (target.getLastWebPreferences().openerId === sender.id) ||
(sender.getLastWebPreferences().nodeIntegration === true) ||
isSameOrigin(sender.getURL(), target.getURL())
}

View File

@@ -121,7 +121,18 @@ if (nodeIntegration === 'true') {
// Set the __filename to the path of html file if it is file: protocol.
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.__dirname = path.dirname(global.__filename)

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

View File

@@ -40,6 +40,9 @@ def main():
if args.target_arch == 'mips64el':
download_mips64el_toolchain()
if args.target_arch.startswith('arm'):
download_native_mksnapshot(args.target_arch)
# Redirect to use local libchromiumcontent build.
if args.build_release_libcc or args.build_debug_libcc:
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])
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():
version_file = os.path.join(VENDOR_DIR, 'libchromiumcontent', 'VERSION')

View File

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

View File

@@ -1,7 +1,6 @@
const assert = require('assert')
const request = require('request')
const buildAppVeyorURL = 'https://windows-ci.electronjs.org/api/builds'
const jenkinsServer = 'https://mac-ci.electronjs.org'
const circleCIJobs = [
'electron-linux-arm',
@@ -11,11 +10,6 @@ const circleCIJobs = [
'electron-linux-x64'
]
const jenkinsJobs = [
'electron-mas-x64-release',
'electron-osx-x64-release'
]
async function makeRequest (requestOptions, parseResponse) {
return new Promise((resolve, reject) => {
request(requestOptions, (err, res, body) => {
@@ -32,7 +26,7 @@ async function makeRequest (requestOptions, parseResponse) {
} else {
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) {
if (options.ci) {
switch (options.ci) {
@@ -184,26 +116,21 @@ function runRelease (targetBranch, options) {
buildAppVeyor(targetBranch, options.ghRelease)
break
}
case 'Jenkins': {
buildJenkins(targetBranch, options.ghRelease, options.job)
break
}
}
} else {
buildCircleCI(targetBranch, options.ghRelease, options.job)
buildAppVeyor(targetBranch, options.ghRelease)
buildJenkins(targetBranch, options.ghRelease, options.job)
}
}
module.exports = runRelease
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]
if (args._.length < 1) {
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)
}

View File

@@ -24,6 +24,7 @@ DIST_DIR = os.path.join(SOURCE_ROOT, 'dist')
OUT_DIR = os.path.join(SOURCE_ROOT, 'out', 'R')
CHROMIUM_DIR = os.path.join(SOURCE_ROOT, 'vendor', 'download',
'libchromiumcontent', 'static_library')
NATIVE_MKSNAPSHOT_DIR = os.path.join(SOURCE_ROOT, 'vendor', 'native_mksnapshot')
PROJECT_NAME = electron_gyp()['project_name%']
PRODUCT_NAME = electron_gyp()['product_name%']
@@ -138,7 +139,6 @@ def copy_chrome_binary(binary):
shutil.copyfile(src, dest)
os.chmod(dest, os.stat(dest).st_mode | stat.S_IEXEC)
def copy_vcruntime_binaries():
with _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,
r"SOFTWARE\Microsoft\VisualStudio\14.0\Setup\VC", 0,
@@ -215,7 +215,7 @@ def strip_binary(binary_path):
elif get_target_arch() == 'arm64':
strip = 'aarch64-linux-gnu-strip'
elif get_target_arch() == 'mips64el':
strip = 'mips64el-redhat-linux-strip'
strip = 'mips64el-loongson-linux-strip'
else:
strip = 'strip'
execute([strip, binary_path], env=build_env())
@@ -257,17 +257,39 @@ def create_dist_zip():
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)
files = ['LICENSE', 'LICENSES.chromium.html']
if PLATFORM == 'win32':
files += [binary + '.exe']
else:
files += [binary]
with scoped_cwd(DIST_DIR):
files = ['LICENSE', 'LICENSES.chromium.html']
if PLATFORM == 'win32':
files += [binary + '.exe']
else:
files += [binary]
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():
dist_name = get_zip_name('ffmpeg', ELECTRON_VERSION)

View File

@@ -8,8 +8,8 @@ import sys
# 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'
# URL to the mips64el toolchain.
MIPS64EL_GCC = 'gcc-4.8.3-d197-n64-loongson'
MIPS64EL_GCC_URL = 'http://ftp.loongnix.org/toolchain/gcc/release/' + MIPS64EL_GCC + '.tar.gz'
MIPS64EL_GCC = 'cross-gcc-4.9.3-n64-loongson-rc5.4'
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 \
'https://s3.amazonaws.com/github-janky-artifacts/libchromiumcontent'
@@ -93,11 +93,11 @@ def build_env():
VENDOR_DIR = os.path.join(SOURCE_ROOT, 'vendor')
gcc_dir = os.path.join(VENDOR_DIR, MIPS64EL_GCC)
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/mips64el-redhat-linux/lib64',
gcc_dir + '/usr/mips64el-redhat-linux/sysroot/lib64',
gcc_dir + '/usr/mips64el-redhat-linux/sysroot/usr/lib64',
gcc_dir + '/usr/mips64el-loongson-linux/lib64',
gcc_dir + '/usr/mips64el-loongson-linux/sysroot/lib64',
gcc_dir + '/usr/mips64el-loongson-linux/sysroot/usr/lib64',
]
env['LD_LIBRARY_PATH'] = os.pathsep.join(ldlib_dirs)
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 path = require('path')
const pkg = require('../package.json')
const readline = require('readline')
const versionType = args._[0]
// 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.`)
let bumpScript = path.join(__dirname, 'bump-version.py')
let scriptArgs = [bumpScript, `--bump ${versionType}`]
if (args.stable) {
scriptArgs.push('--stable')
}
if (dryRun) {
scriptArgs.push('--dry-run')
}
try {
let bumpVersion = execSync(scriptArgs.join(' '), {encoding: 'UTF-8'})
bumpVersion = bumpVersion.substr(bumpVersion.indexOf(':') + 1).trim()
let newVersion = `v${bumpVersion}`
console.log(`${pass} Successfully bumped version to ${newVersion}`)
if (!dryRun) {
console.log(`${pass} Successfully bumped version to ${newVersion}`)
}
return newVersion
} catch (err) {
console.log(`${fail} Could not bump version, error was:`, err)
@@ -119,23 +125,25 @@ async function createRelease (branchToTarget, isBeta) {
.catch(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) {
console.log(`${fail} Aborting because draft release for
${drafts[0].tag_name} already exists.`)
process.exit(1)
}
console.log(`${pass} A draft release does not exist; creating one.`)
githubOpts.body = releaseNotes
githubOpts.draft = true
githubOpts.name = `electron ${newVersion}`
if (isBeta) {
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 ` +
`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.prerelease = true
} else {
githubOpts.body = releaseNotes
}
githubOpts.tag_name = newVersion
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) {
let currentBranch = await getCurrentBranch(gitDir)
if (notesOnly) {
let releaseNotes = await getReleaseNotes(currentBranch)
console.log(`Draft release notes are: ${releaseNotes}`)
} else {
await verifyNewVersion()
await createReleaseBranch()
await createRelease(currentBranch, isBeta)
await pushRelease()

View File

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

View File

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

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}
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.
@@ -45,32 +46,48 @@ rm -f "${STAMP_FILE}"
# 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.
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
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
rm -rf "${LLVM_BUILD_DIR}"
mkdir -p "${LLVM_BUILD_DIR}"
tar -xzf "${CDS_OUTPUT}" -C "${LLVM_BUILD_DIR}"
echo clang "${PACKAGE_VERSION}" unpacked
echo "${PACKAGE_VERSION}" > "${STAMP_FILE}"
rm -rf "${CDS_OUT_DIR}"
exit 0
else
echo Did not find prebuilt clang "${PACKAGE_VERSION}", building
rm -rf "${LLVM_BUILD_DIR}"
mkdir -p "${LLVM_BUILD_DIR}"
CDS_FILES=("clang-${PACKAGE_VERSION}.tgz")
CDS_OUT_DIR=$(mktemp -d -t clang_download.XXXXXX)
if [ "${OS}" = "Linux" ]; then
ARCH="$(uname -m)"
if [ "${ARCH}" = "aarch64" ]; then
CDS_URL="${S3_URL}"
CDS_SUBDIR="arm64"
else
CDS_FILES+=("llvmgold-${PACKAGE_VERSION}.tgz")
CDS_SUBDIR="Linux_x64"
fi
elif [ "${OS}" = "Darwin" ]; then
CDS_SUBDIR="Mac"
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),
args.upload_to_s3)
# Upload chromedriver and mksnapshot for minor version update.
if parse_version(args.version)[2] == '0':
chromedriver = get_zip_name('chromedriver', ELECTRON_VERSION)
upload_electron(github, release, os.path.join(DIST_DIR, chromedriver),
args.upload_to_s3)
mksnapshot = get_zip_name('mksnapshot', ELECTRON_VERSION)
chromedriver = get_zip_name('chromedriver', ELECTRON_VERSION)
upload_electron(github, release, os.path.join(DIST_DIR, chromedriver),
args.upload_to_s3)
mksnapshot = get_zip_name('mksnapshot', ELECTRON_VERSION)
upload_electron(github, release, os.path.join(DIST_DIR, mksnapshot),
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),
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):
# Search for existing draft.
for release in releases:
if release['draft']:
if release['draft'] and release['tag_name'] == tag:
return release
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', () => {
const iconPath = path.join(__dirname, 'fixtures/assets/icon.ico')
const sizes = {

View File

@@ -30,6 +30,22 @@ describe('BrowserView module', () => {
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()', () => {
it('does not throw for valid args', () => {
view = new BrowserView()

View File

@@ -421,6 +421,29 @@ describe('BrowserWindow module', () => {
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)', () => {
@@ -2861,7 +2884,7 @@ describe('BrowserWindow module', () => {
})
it('enables context isolation on child windows', (done) => {
app.once('browser-window-created', (event, window) => {
assert.equal(window.webContents.getWebPreferences().contextIsolation, true)
assert.equal(window.webContents.getLastWebPreferences().contextIsolation, true)
done()
})
w.loadURL(`file://${fixtures}/pages/window-open.html`)

View File

@@ -279,14 +279,26 @@ describe('Menu module', () => {
})
afterEach(() => {
menu.closePopup()
menu.closePopup(w)
return closeWindow(w).then(() => { w = null })
})
describe('when called with async: true', () => {
it('returns immediately', () => {
menu.popup(w, {x: 100, y: 100, async: true})
menu.closePopup(w)
})
it('returns immediately', () => {
const { browserWindow, x, y, async } = menu.popup(w, {x: 100, y: 101, async: true})
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', () => {
const mockPDF = new Buffer(1024 * 1024 * 5)
const mockPDF = Buffer.alloc(1024 * 1024 * 5)
const protocolName = 'custom-dl'
let contentDisposition = 'inline; filename="mock.pdf"'
const downloadFilePath = path.join(fixtures, 'mock.pdf')
const downloadServer = http.createServer((req, res) => {
@@ -286,11 +287,15 @@ describe('session module', () => {
})
const assertDownload = (event, state, url, mimeType,
receivedBytes, totalBytes, disposition,
filename, port, savePath) => {
filename, port, savePath, isCustom) => {
assert.equal(state, 'completed')
assert.equal(filename, '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(receivedBytes, 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) => {
downloadServer.listen(0, '127.0.0.1', () => {
const port = downloadServer.address().port

View File

@@ -115,7 +115,12 @@ describe('chromium feature', () => {
describe('navigator.serviceWorker', () => {
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) => {
if (args[0] === 'reload') {
w.webContents.reload()
@@ -123,7 +128,7 @@ describe('chromium feature', () => {
done(`unexpected error : ${args[1]}`)
} else if (args[0] === 'response') {
assert.equal(args[1], 'Hello from serviceWorker!')
session.defaultSession.clearStorageData({
session.fromPartition('sw-file-scheme-spec').clearStorageData({
storages: ['serviceworkers']
}, () => done())
}
@@ -208,6 +213,26 @@ describe('chromium feature', () => {
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) => {
let b
listener = (event) => {
@@ -228,6 +253,26 @@ describe('chromium feature', () => {
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) => {
let b
app.once('web-contents-created', (event, contents) => {
@@ -247,7 +292,7 @@ describe('chromium feature', () => {
app.once('web-contents-created', (event, contents) => {
contents.once('did-finish-load', () => {
app.once('browser-window-created', (event, window) => {
const preferences = window.webContents.getWebPreferences()
const preferences = window.webContents.getLastWebPreferences()
assert.equal(preferences.javascript, false)
window.destroy()
b.close()
@@ -469,7 +514,7 @@ describe('chromium feature', () => {
done()
}
window.addEventListener('message', listener)
w = window.open(url, '', 'show=no')
w = window.open(url, '', 'show=no,nodeIntegration=no')
})
it('works when origin matches', (done) => {
@@ -478,7 +523,7 @@ describe('chromium feature', () => {
done()
}
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) => {

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>

View File

@@ -30,7 +30,8 @@ describe('modules support', () => {
describe('ffi', () => {
before(function () {
if (!nativeModulesEnabled || process.platform === 'win32') {
if (!nativeModulesEnabled || process.platform === 'win32' ||
process.arch === 'arm64') {
this.skip()
}
})

View File

@@ -207,10 +207,17 @@ describe('node feature', () => {
describe('setInterval called under Chromium event loop in browser process', () => {
it('can be scheduled in time', (done) => {
let clear
let interval
clear = () => {
let interval = null
let clearing = false
const clear = () => {
if (interval === null || clearing) {
return
}
// interval might trigger while clearing (remote is slow sometimes)
clearing = true
remote.getGlobal('clearInterval')(interval)
clearing = false
interval = null
done()
}
interval = remote.getGlobal('setInterval')(clear, 10)
@@ -293,6 +300,20 @@ describe('node feature', () => {
buffer = new Buffer(new Array(4097).join(' '))
assert.equal(buffer.length, 4096)
})
it('does not crash for crypto operations', () => {
const crypto = require('crypto')
const data = 'lG9E+/g4JmRmedDAnihtBD4Dfaha/GFOjd+xUOQI05UtfVX3DjUXvrS98p7kZQwY3LNhdiFo7MY5rGft8yBuDhKuNNag9vRx/44IuClDhdQ='
const key = 'q90K9yBqhWZnAMCMTOJfPQ=='
const cipherText = '{"error_code":114,"error_message":"Tham số không hợp lệ","data":null}'
for (let i = 0; i < 10000; ++i) {
let iv = Buffer.from('0'.repeat(32), 'hex')
let input = Buffer.from(data, 'base64')
let decipher = crypto.createDecipheriv('aes-128-cbc', Buffer.from(key, 'base64'), iv)
let result = Buffer.concat([decipher.update(input), decipher.final()])
assert.equal(cipherText, result)
}
})
})
describe('process.stdout', () => {

View File

@@ -6,7 +6,7 @@
'clang%': 1,
# Path to mips64el toolchain.
'make_mips64_dir%': 'vendor/gcc-4.8.3-d197-n64-loongson/usr',
'make_mips64_dir%': 'vendor/cross-gcc-4.9.3-n64-loongson-rc5.4/usr',
'variables': {
# The minimum macOS SDK version to use.
@@ -104,8 +104,10 @@
# Setup building with clang.
['clang==1', {
'make_global_settings': [
['AR', '<(make_clang_dir)/bin/llvm-ar'],
['CC', '<(make_clang_dir)/bin/clang'],
['CXX', '<(make_clang_dir)/bin/clang++'],
['AR.host', '<(make_clang_dir)/bin/llvm-ar'],
['CC.host', '$(CC)'],
['CXX.host', '$(CXX)'],
],
@@ -138,8 +140,8 @@
['target_arch=="mips64el"', {
'make_global_settings': [
['CC', '<(make_mips64_dir)/bin/mips64el-redhat-linux-gcc'],
['CXX', '<(make_mips64_dir)/bin/mips64el-redhat-linux-g++'],
['CC', '<(make_mips64_dir)/bin/mips64el-loongson-linux-gcc'],
['CXX', '<(make_mips64_dir)/bin/mips64el-loongson-linux-g++'],
['CC.host', '$(CC)'],
['CXX.host', '$(CXX)'],
],

2
vendor/node vendored