Compare commits

..

359 Commits

Author SHA1 Message Date
Electron Bot
4913fc81d1 Bump v3.1.0 2019-01-07 09:57:52 -08:00
trop[bot]
846b43d7bd chore: add additional logging for release upload failures (3-1-x) (#16277) 2019-01-04 12:47:18 -08:00
trop[bot]
d644eb4164 docs: Update reference to xcode 8.3.3 (backport: 3-1-x) (#16271)
* Update reference to xcode

* Update to reflect use of 10.12 SDK
2019-01-04 15:42:37 -05:00
Electron Bot
dc4057bb48 Bump v3.1.0-beta.5 2019-01-04 11:55:02 -08:00
Michelle Tilley
c3867ba6d5 Revert "Bump v3.1.0-beta.5"
This reverts commit aa57be70a0.
2019-01-04 11:52:30 -08:00
Electron Bot
aa57be70a0 Bump v3.1.0-beta.5 2019-01-04 11:08:14 -08:00
Michelle Tilley
9d24d28816 Revert "Bump v3.1.0-beta.5"
This reverts commit 75a21678d7.
2019-01-04 11:04:09 -08:00
Electron Bot
75a21678d7 Bump v3.1.0-beta.5 2019-01-04 10:32:49 -08:00
Jeremy Apthorp
7f0056f683 Merge pull request #16140 from electron/http_auth_prefs_3_1_x
fix: UAF with http auth preferences (3-1-x)
2018-12-20 15:56:28 -08:00
Jeremy Apthorp
02eeef4dc0 fix: ensure that file descriptors 0/1/2 are opened at startup (backport: 3-0-x) (backport: 3-1-x) (#16167)
This fixes an issue where the gpu subprocess was writing messages to a
random pipe or socket. The standard file desciptors are closed in
chromium's subprocesses because of an unfortunate interaction with
libuv's tty handling code leaving them with the FD_CLOEXEC flag.
2018-12-20 15:47:35 -08:00
Andrzej Szombierski
7d8c59deda style: fix lint warnings 2018-12-20 23:00:41 +00:00
Andrzej Szombierski
1e9a75d9f2 fix: ensure that file descriptors 0/1/2 are opened at startup
This fixes an issue where the gpu subprocess was writing messages to a
random pipe or socket. The standard file desciptors are closed in
chromium's subprocesses because of an unfortunate interaction with
libuv's tty handling code leaving them with the FD_CLOEXEC flag.
2018-12-20 23:00:41 +00:00
deepak1556
e7688723f9 fix: UAF with http auth preferences (3-1-x) 2018-12-21 02:40:49 +05:30
trop[bot]
6fb569cc6c fix: extending tracing startRecording API to take a full tracing config (#16159)
This allows memory-infra to be traced correctly.
Fixes #12506.
2018-12-20 08:27:47 -07:00
trop[bot]
349f10d779 chore: release.id => release.data.id (#16134) 2018-12-18 19:53:43 -07:00
Electron Bot
9f6bee704f Bump v3.1.0-beta.4 2018-12-17 12:08:13 -08:00
Michelle Tilley
e6668f60c8 Revert "Bump v3.1.0-beta.4"
This reverts commit 409b58525a.
2018-12-17 12:04:16 -08:00
Electron Bot
409b58525a Bump v3.1.0-beta.4 2018-12-17 11:14:36 -08:00
Shelley Vohr
ea83871cf6 chore: correctly capitalize releaseID (#16107) 2018-12-17 11:08:42 -08:00
Michelle Tilley
53ace2e099 Revert "Bump v3.1.0-beta.4"
This reverts commit 38fc10f068.
2018-12-17 11:06:47 -08:00
Electron Bot
38fc10f068 Bump v3.1.0-beta.4 2018-12-17 10:28:11 -08:00
Roller Bot
03b9f0db58 chore: bump libcc (3-1-x) (#16076)
* chore: bump libcc submodule to 29e02cd4c37777734f97d00b5a538d7c7acfa67a

* chore: bump libcc in DEPS to 29e02cd4c37777734f97d00b5a538d7c7acfa67a
2018-12-17 10:00:52 -05:00
Electron Bot
aea44b9227 Bump v3.1.0-beta.3 2018-12-14 13:08:19 -08:00
Robo
eb9e468bcc fix: remove event monitor before destroying window (#16056) 2018-12-13 15:05:19 -08:00
Roller Bot
936d088210 chore: bump libcc (3-1-x) (#16033)
* chore: bump libcc submodule to e856446abf81a7eaa3e2f7884f0ef837228234fc

* chore: bump libcc in DEPS to e856446abf81a7eaa3e2f7884f0ef837228234fc
2018-12-13 02:04:43 +05:30
trop[bot]
9490a9f9ba fix: allow 2 threads for CreateIoCompletionPort on single-core to prevent busy looping (backport: 3-1-x) (#16011)
* allow 2 threads for CreateIoCompletionPort on single-core

* use base::SysInfo::NumberOfProcessors instead of env var

* CHECK that uv_loop_ has not been used before replacing its iocp
2018-12-11 16:11:47 +09:00
trop[bot]
3c4cd3f662 fix: do not print an error for an expected condition (#15991) (#15998) 2018-12-10 13:17:28 -08:00
Shelley Vohr
15f8d15b1b fix: incorrect view ordering for customButtonsOnHover (#15997) 2018-12-10 12:27:38 -08:00
Shelley Vohr
9f472acf80 chore: expose release id for use in cleanup (#15904) 2018-12-04 08:04:18 -08:00
Electron Bot
0043acf70a Bump v3.1.0-beta.2 2018-12-03 18:35:22 -08:00
Roller Bot
e25f8c1a08 chore: bump libcc (3-1-x) (#15937)
* chore: bump libcc submodule to dfad80d80b265e508c4e583dda3f2860b20128b7

* chore: bump libcc in DEPS to dfad80d80b265e508c4e583dda3f2860b20128b7
2018-12-04 13:30:31 +11:00
Electron Bot
e2be247579 Bump v3.1.0-beta.1 2018-12-02 09:56:52 -08:00
Roller Bot
9de5965bb7 chore: bump libcc (3-1-x) (#15913)
* chore: bump libcc submodule to 99d8f691c3d64704304020f68d46113a1993e281

* chore: bump libcc in DEPS to 99d8f691c3d64704304020f68d46113a1993e281
2018-12-02 09:54:14 -08:00
Shelley Vohr
67af030df7 Revert "Bump v3.1.0-beta.1"
This reverts commit f0b47b2541.
2018-11-30 14:33:27 -08:00
Electron Bot
f0b47b2541 Bump v3.1.0-beta.1 2018-11-30 12:17:44 -08:00
Shelley Vohr
97ffaf058f roll libcc deps for 3-1-x 2018-11-30 12:12:44 -08:00
Shelley Vohr
a4a0eff1e7 Revert "Bump v3.1.0-beta.1"
This reverts commit 1ad67754c0.
2018-11-30 12:11:43 -08:00
Electron Bot
1ad67754c0 Bump v3.1.0-beta.1 2018-11-30 11:54:17 -08:00
Shelley Vohr
8408136082 chore: don't generate full release notes for beta.1 2018-11-30 11:49:58 -08:00
Shelley Vohr
56f7359ed3 update package.json version from beta.0 to stable 2018-11-30 11:43:35 -08:00
trop[bot]
5dc15fc5d9 chore: allow bumping stable => beta (#15907) 2018-11-30 11:17:02 -08:00
Shelley Vohr
17481882d0 Revert "Bump v3.1.0-beta.1"
This reverts commit b23b72f9c3.
2018-11-30 09:46:09 -08:00
Electron Bot
b23b72f9c3 Bump v3.1.0-beta.1 2018-11-29 19:38:53 -08:00
John Kleinschmidt
957ac493e6 ci: clean git before building (#15887) 2018-11-29 10:52:05 -08:00
Shelley Vohr
5ddc2fb6e7 Revert "Bump v3.1.0-beta.1"
This reverts commit 5d05f1c72a.
2018-11-28 16:05:18 -08:00
Shelley Vohr
31d5e9bbe1 Revert "chore: bump libcc (3-1-x) (#15858)"
This reverts commit 386e356ed6.
2018-11-28 15:59:48 -08:00
Roller Bot
386e356ed6 chore: bump libcc (3-1-x) (#15858)
* chore: bump libcc submodule to b3212522d71a4637cc3f7208ad04c819255963b4

* chore: bump libcc in DEPS to b3212522d71a4637cc3f7208ad04c819255963b4
2018-11-28 10:29:14 -08:00
Tom Moor
250a09a43f fix: send NSView* as the response to getNativeWindowHandle() instead of a null handle (#15521) (#15803) 2018-11-28 11:00:37 +09:00
Roller Bot
3ed5a24c72 chore: bump libcc (3-1-x) (#15839)
* chore: bump libcc submodule to ccf1e2dd1dd2e12125dbbdb98b2cc51142cd07b9

* chore: bump libcc in DEPS to ccf1e2dd1dd2e12125dbbdb98b2cc51142cd07b9
2018-11-27 13:13:09 -05:00
Electron Bot
5d05f1c72a Bump v3.1.0-beta.1 2018-11-26 20:36:36 -08:00
Samuel Attard
0fa449f5f4 chore: bump version number in electron.gyp (#15848) 2018-11-27 15:29:05 +11:00
Felix Rieseberg
05ffcbdb3b chore: Bump version number (#15846) 2018-11-26 17:31:25 -08:00
Robo
4abf55801f fix: switch to mojo proxy resolver (3-1-x) (#15813) 2018-11-26 15:38:33 -08:00
Shelley Vohr
d5a6bb665b fix: no longer require submenu for services menuitem (#15672) 2018-11-20 13:18:24 -05:00
Electron Bot
4305657858 Bump v3.0.10 2018-11-19 12:40:54 -08:00
Michelle Tilley
e391b7df69 Revert "Bump v3.0.10"
This reverts commit 82e7bd3f22.
2018-11-19 12:19:50 -08:00
Electron Bot
82e7bd3f22 Bump v3.0.10 2018-11-19 11:04:25 -08:00
trop[bot]
eb30cc2ede docs: limits of nativeWindowOpen (#15754) 2018-11-19 10:36:52 -05:00
John Kleinschmidt
d9efaa946b build: include needed bin files for v8_context_snapshot_generator (#15713) 2018-11-14 11:19:01 -08:00
Roller Bot
3f99cf4f1d chore: bump libcc (3-0-x) (#15690)
* chore: bump libcc submodule to d9e39391cfae447a84e276a402342cf8b4b5bcba
* chore: bump libcc in DEPS to d9e39391cfae447a84e276a402342cf8b4b5bcba
2018-11-13 14:37:32 +01:00
Electron Bot
a0a9d9d159 Bump v3.0.9 2018-11-12 19:18:08 -08:00
Samuel Attard
7165fb181d Revert "Bump v3.0.9"
This reverts commit 67cf0eb9b0.
2018-11-13 14:14:50 +11:00
Electron Bot
67cf0eb9b0 Bump v3.0.9 2018-11-12 13:34:43 -08:00
trop[bot]
e9823f07be fix: NSWindow crash happening on macos 10.9 (#15669) 2018-11-11 13:44:06 -05:00
Roller Bot
c272f5fc56 chore: bump libcc (3-0-x) (#15659)
* chore: bump libcc submodule to 7361dbe5ac927be4276ec7da1d3548c4f22343a0

* chore: bump libcc in DEPS to 7361dbe5ac927be4276ec7da1d3548c4f22343a0
2018-11-10 14:20:31 -05:00
Nitish Sakhawalkar
48ebebcafe fix: Linux empty menu model handling (#15605)
* fix: Linux empty menu model handling

* Update root_view.cc
2018-11-08 08:11:15 -08:00
trop[bot]
ae9f4ef425 chore: add simple set/unset loginitem spec (#15600) 2018-11-06 22:08:44 -08:00
Electron Bot
5c14992e43 Bump v3.0.8 2018-11-05 14:36:14 -08:00
trop[bot]
53b871ecbd fix: use NSURL path for receipt url (#15573) 2018-11-05 13:21:40 -08:00
John Kleinschmidt
ec6fe27fca build: add v8_context_generator to mksnapshot zip (3-0-x) (#15505)
* build: add v8_context_generator to mksnapshot

Starting with 3-0-x, in order to use custom snapshots the v8_context_snapshot_generator binary is also needed.
Also, add tests for mksnapshot.

* Actually run verify-mksnapshot
2018-11-05 13:31:33 -04:00
Nitish Sakhawalkar
8566f8712c fix: Empty menu case (#15553) 2018-11-02 12:32:57 -07:00
Alexey Kuzmin
08ec270b90 docs: fix the "second-instance" event handler signature in the docs (#15546) 2018-11-02 22:18:12 +11:00
trop[bot]
b2822ed800 docs: add Size as an option for pageSize in docs for printToPDF (#15525) 2018-11-01 07:16:08 -07:00
Samuel Attard
6bec85f30c chore: publish to the latest tag correctly when releasing old versions (#15515) (#15520)
Manual backport of #15274 to <= 3-0-x
2018-11-01 07:15:32 -07:00
trop[bot]
6d658b319b fix: explicitly set windowsHide to the old node default (#15514)
Notes: fix Electron not being visible when launching in development mode on node v11
2018-11-01 15:37:06 +11:00
Cheng Zhao
5c853b681c Fix missing remote object error when calling remote function created in preload script (3-0-x) (#15445)
* fix: report wrong context error based on contextId

* fix: destroyed remote renderer warning is now async
2018-11-01 08:55:02 +09:00
Electron Bot
7b0959ed2b Bump v3.0.7 2018-10-31 16:11:44 -07:00
trop[bot]
3e8b854975 docs: add return type for subscribeNotification (#15499) 2018-10-31 09:48:33 -07:00
trop[bot]
fd97fcf6f0 doc: clarify menu item properties not available top-level (#15461) 2018-10-29 16:23:58 -07:00
Heilig Benedek
809534dca0 fix: enable FixAltGraph to fix Ctrl+Alt accelerators on Windows (#15378) 2018-10-30 02:33:44 +11:00
Roller Bot
b2763cad9f chore: bump libcc (3-0-x) (#15420)
* chore: bump libcc submodule to d2c3189f30cfb39f888a917671024733fe5cffcc

* chore: bump libcc in DEPS to d2c3189f30cfb39f888a917671024733fe5cffcc
2018-10-29 10:37:37 -04:00
trop[bot]
b6b9966162 fix: use gio as default linux trash impl (backport: 3-0-x) (#15421)
* fix: use gio as default linux trash impl

* doc: add ELECTRON_TRASH env var
2018-10-26 11:10:35 -07:00
trop[bot]
a41e919b95 doc: correct ipcRenderer sendTo windowId param (#15418) 2018-10-26 08:36:29 -07:00
Heilig Benedek
bdda248194 fix: check for shared memory handle validity before closing, remove DebugDumpData call (#15402) 2018-10-26 09:57:03 -05:00
trop[bot]
41e86efda0 fix: folder open not working in devtools (#15396) 2018-10-25 10:01:29 -07:00
trop[bot]
88b1f7d9c8 fix: set NSResizableWindowMask at init time (#15384) 2018-10-25 15:30:16 +09:00
Electron Bot
dcdbc87ef4 Bump v3.0.6 2018-10-24 15:40:18 -07:00
Alexey Kuzmin
9e03783781 chore: bump libcc (3-0-x) (#15374)
Resolves #15344
2018-10-24 22:40:38 +02:00
John Kleinschmidt
8208296143 Make sure node is set in path 2018-10-24 15:21:43 -04:00
Roller Bot
518467cf4c chore: bump libcc in DEPS to 82816abaad3930c3702cf23489f0506ba13b1529 2018-10-24 07:23:09 -07:00
Roller Bot
648bf54bb3 chore: bump libcc submodule to 82816abaad3930c3702cf23489f0506ba13b1529 2018-10-24 07:23:07 -07:00
trop[bot]
8dce40137c fix: honor dialog.showMessageBox()'s Icon argument on Linux (#15342)
* Don't call gtk_widget_show_all() on popup dialog.

Fixes #15317.

Notes: Fixed incorrect display of some GtkMessageDialog icons.

The issue is caused because GtkMessageDialog contains an icon widget
which is not shown when there's no associated icon. Our call to
`gtk_widget_show_all()` overrides this, showing the uninitialized
icon widget.

This PR fixes the issue by calling `gtk_widget_show()` where needed
and removing use of `gtk_widget_show_all()` in the message dialog.

* use gtk_dialog_set_default_response() for default

* fix: support icons on gtk+ messageboxes.
2018-10-23 12:01:05 -07:00
trop[bot]
dab77256d2 fix: Native window close crash (#15338) 2018-10-23 12:00:39 -07:00
trop[bot]
c7501bd7ca fix: correct reversed logic in NativeWindowMac::SetEnabled (#15324) 2018-10-23 23:22:19 +11:00
trop[bot]
203c47f038 docs: we don't emit an event object for session-created (#15308) 2018-10-21 10:18:08 -07:00
Shelley Vohr
02cd96875d fix: ability to fetch separators by id (#15299) 2018-10-19 21:58:07 -07:00
trop[bot]
9349b0a273 fix: correctly enable and disable windows on Windows and Linux (backport: 3-0-x) (#15255)
* fix: correctly enable and disable windows

* Move has_child_modal_ to NativeWindowViews

* Track modal children as an int instead of a bool

* Use correct types

* Move Increment/DecrementChildModals to NativeWindowViews

* Use parent() in NativeWindowViews

* Add test for not enabling disabled parent when modal child closes
2018-10-19 17:30:55 -07:00
trop[bot]
1c42715e1d spec: increase MAS timeout for login items (#15296) 2018-10-19 16:57:00 -07:00
Alexey Kuzmin
ef4a7e22fd test: asyncawaitify one of sandbox related tests (backport: 3-0-x) (#15281)
* test: asyncawaitify one of sandbox related tests (#15252)

(cherry picked from commit b3f134de06)

* test: backport "openTheWindow" function to "BrowserWindow module" specs
2018-10-19 09:14:36 -07:00
trop[bot]
ead294fe13 fix: trim app name and productName (#15286)
Fixes #15245
2018-10-19 09:13:10 -07:00
trop[bot]
f119e4cc4b chore: make macOS release builds higher priority to skip the queue (#15284)
Release builds should be run before branch builds on our limited macOS
infra.

Refs: https://docs.microsoft.com/en-us/rest/api/vsts/build/builds/queue?view=vsts-rest-4.1#queuepriority
2018-10-19 09:12:21 -07:00
trop[bot]
00489e6106 fix: make release-artifact-cleanup executable (backport: 3-0-x) (#15272)
* fix: make release-artifact-cleanup executable

* fix misc issues in cleanup script
2018-10-18 20:27:53 -07:00
trop[bot]
a7c34b8a0a fix: Convert to lower case in upload symbols script (backport: 3-0-x) (#15261)
* fix: Convert to lower case in upload symbols script

* fix: Convert to lower case in upload symbols script
2018-10-18 19:17:15 -07:00
trop[bot]
906436f31b fix: loading of devtools extensions on startup (backport: 3-0-x) (#15264)
* Fix loading of devtools extensions on startup

The persisted DevTools Extensions were not being loaded correctly at startup. The `addDevToolsExtension` function was not defined when it was being called. An error was being thrown and ignored, so the whole thing would fail silently. I moved the code to load the extensions to the end of the event handler, so now it works.

* fixup: remove trailing spaces to unblock CI

* fixup: add logging when the Electron Enable Logging env var is set

* Fix linter error on undefined srcDirectory

* fixup: catch exception when loading extension

* Revert "fixup: catch exception when loading extension"

This reverts commit 42c2cf95bc.
2018-10-18 19:13:01 -07:00
Electron Bot
b208fcbf0d Bump v3.0.5 2018-10-18 17:03:53 -07:00
Samuel Attard
6899ac9bde Revert "Bump v3.0.5"
This reverts commit 72c033299f.
2018-10-18 23:46:35 +11:00
Electron Bot
72c033299f Bump v3.0.5 2018-10-17 22:56:11 -07:00
Samuel Attard
7fb6b3bda8 Revert "build: enable PIE when compiling Linux builds, fix #14961. (#15152)"
This reverts commit 70d4644742.
2018-10-18 14:09:34 +11:00
Samuel Attard
1d79840025 Revert "build: enable BIND_NOW when compiling Linux builds, fix #15149. (#15153)"
This reverts commit 049381c6ac.
2018-10-18 14:09:19 +11:00
Samuel Attard
07deaaa502 Revert "Bump v3.0.5"
This reverts commit 259f0a62e8.
2018-10-18 14:08:56 +11:00
Electron Bot
259f0a62e8 Bump v3.0.5 2018-10-17 19:33:27 -07:00
Samuel Attard
4f78df9cfa Revert "Bump v3.0.5"
This reverts commit b2be093bd3.
2018-10-18 13:26:20 +11:00
Electron Bot
b2be093bd3 Bump v3.0.5 2018-10-17 10:28:20 -07:00
Roller Bot
4f666bb6ac chore: bump libcc (3-0-x) (#15201)
* chore: bump libcc submodule to c110392d8556a6428679328f9075b3f4fb54aa3c

* chore: bump libcc in DEPS to c110392d8556a6428679328f9075b3f4fb54aa3c
2018-10-18 00:54:31 +11:00
trop[bot]
12f75832b8 add width to webview iframe (#15204) 2018-10-17 11:54:43 +09:00
Cheng Zhao
6f54d58e2a Merge pull request #15192 from electron/window-open-warn-leak-3-0-x
chore: warn memory leak when using nativeWindowOpen with nodeIntegration (3-0-x)
2018-10-17 11:54:21 +09:00
Cheng Zhao
8716f718a9 fix: print warning after DOM is created 2018-10-17 10:42:02 +09:00
Cheng Zhao
714f3ffd29 chore: warn memory leak when using nativeWindowOpen with nodeIntegration 2018-10-16 20:12:53 +09:00
Cheng Zhao
4a5d2117ba fix: do not enable node integration in child window if not enabled (#15108) 2018-10-16 18:10:31 +09:00
Nitish Sakhawalkar
5cb50b0e33 fix: Menu accelerators not working Unity (#15181) 2018-10-16 14:46:51 +11:00
Kevin Lynagh
7283b78aa2 fix: simpleFullscreen window should be on top of other OS X menu bars. (#15183)
If an app has no menu bar (because `app.dock.hide()` has been called),
OS X will still render the menu bar of the previously-focused app.

This commit ensures simpleFullscreen windows will be drawn on top of
that menu bar by setting their level to NSPopUpMenuWindowLevel while
simpleFullscreen mode is active.

Ref: #11468
2018-10-16 13:51:14 +11:00
#DeleteGithub
049381c6ac build: enable BIND_NOW when compiling Linux builds, fix #15149. (#15153)
We've hardened Linux builds by enabling PIE and RELRO,
and should continue to try hardening Linux builds by
enabling BIND_NOW. With both RELRO and BIND_NOW enabled,
we can stop all GOT overwrite attacks. The same hardening
option has been enabled in official Chrome/Chromium
builds since more than five years ago.

This helps to improve the security of a whole range of
applications built upon Electron, including sensetive ones
such as Signal-Desktop.

Signed-off-by: Tom Li <tomli@tomli.me>
2018-10-16 11:44:35 +11:00
Andy Dill
22597474e0 fix: preserve background color through reload (backport: 3-0-x) (#15175)
* fix: preserve background color through reload

* fix: only set backgroundColor on top-level frames
2018-10-15 12:56:05 -07:00
trop[bot]
760def6147 fix: Memory > Profiles > Load in DevTools (#15155) 2018-10-14 10:59:04 -07:00
#DeleteGithub
70d4644742 build: enable PIE when compiling Linux builds, fix #14961. (#15152)
PIE allows an application to utilize the full benefits of ASLR
to prevent itself from exploitations, but it was disabled for
all released versions of Electron (3.0 and prior).

Currently, PIE is already enabled since 9294fac but enabling it
for all released version is still an ongoing work (#14961). This
patch backports PIE to the 3.0.x branch.

Signed-off-by: Tom Li <tomli@tomli.me>
2018-10-14 12:47:55 +11:00
Shelley Vohr
f6b7f547bb fix: natively implement LoginItems methods (#15128)
* fix: natively implement LoginItems methods

* fix flaky spec on MAS builds
2018-10-12 20:50:03 -07:00
trop[bot]
9bb3701f7e spec: re-enable app.getAppMetric API (#15123) 2018-10-12 10:30:56 -07:00
trop[bot]
d7fe65b9bd docs: app.getLoginItemStatus -> app.getLoginItemSettings (#15113) 2018-10-13 01:19:23 +11:00
Charles Kerr
eb8546c8d1 fix: check dbus response for null before use. (#15033)
* fix: backport #15030 to fix #14958 dbus crash

* chore: re-enable power spec tests

* chore: undo changes made to power monitor tests.

The Linux failures on that are gone in master / 4-0-x.  Whatever
resolved it there is unrelated to this PR's changes, so I'm not
going to block this fix on an unrelated issue.
2018-10-11 22:40:22 -07:00
Electron Bot
6719f66d5a Bump v3.0.4 2018-10-10 20:51:33 -07:00
Roller Bot
b78fb5aa93 chore: bump libcc (3-0-x) (#15072)
* chore: bump libcc submodule to 42e375e8b0bf4d7e030237adbb9cf7122d9f3246

* chore: bump libcc in DEPS to 42e375e8b0bf4d7e030237adbb9cf7122d9f3246
2018-10-11 14:42:45 +11:00
Shelley Vohr
502b0b988e fix: handle shortcuts by default if no WebPreferences object exists (#15066) 2018-10-11 13:37:55 +11:00
trop[bot]
3d8af9d279 fix: Lifetime of auth_info_ in login handler (#15044) 2018-10-10 12:59:27 +11:00
trop[bot]
524bb99948 fix: Check minSize constraints before resizing (backport: 3-0-x) (#15038) 2018-10-09 10:52:00 -07:00
trop[bot]
8f743e6fbe Backport of #14648 (#15032) 2018-10-09 09:47:29 -04:00
Electron Bot
6c085cda74 Bump v3.0.3 2018-10-06 16:31:11 -07:00
trop[bot]
73935bc5dd fix: support ASAR in fs.copyFile (#14953) 2018-10-04 09:23:19 +10:00
Cheng Zhao
bf928ee443 fix: use white background for non-OSR renderer by default (#14934) 2018-10-03 13:41:37 +09:00
trop[bot]
ee6de82c08 fix: check guest view's devtools window size (#14928) 2018-10-03 09:31:34 +09:00
trop[bot]
8d362150e0 fix: Disable new fade animation for BrowserViews (#14913) 2018-10-02 13:17:36 +10:00
Shelley Vohr
385b08881e fix: roll node deps for fs event patch (#14864) 2018-09-29 09:17:33 +10:00
trop[bot]
5cd24a4e81 fix: enable key accelerator flags for Windows and Linux (backport: 3-0-x) (#14859)
* Fix Accelerator Flags for Windows and Linux

* Lint fix

* Lint whitespace
2018-09-28 10:01:28 -07:00
Electron Bot
9ab77adc94 Bump v3.0.2 2018-09-27 13:32:27 -07:00
trop[bot]
d808423975 docs: correct key code reqs for accel doc (#14824) 2018-09-27 12:50:14 +10:00
Electron Bot
3979315517 Bump v3.0.1 2018-09-26 17:07:12 -07:00
Shelley Vohr
35cb671529 fix: get background color from GtkMenuBar#menubar (#14812) 2018-09-26 10:03:33 -07:00
Roller Bot
0f291f9d63 chore: bump libcc (3-0-x) (#14809)
* chore: bump libcc submodule to ecc87483bace2bce628bf5d02a73514ffa95f4bf

* chore: bump libcc in DEPS to ecc87483bace2bce628bf5d02a73514ffa95f4bf
2018-09-26 10:02:41 -07:00
trop[bot]
8574a55bd8 fix: inconsistent titleBarStyle on transparent fullscreen (#14790) 2018-09-25 12:03:54 -07:00
trop[bot]
05a429075e docs: clarify allowable background colors for BrowserWindow transparency (backport: 3-0-x) (#14781)
* docs: clarify allowable colors for transparency

* fix alpha value specification
2018-09-24 09:40:00 -07:00
Alexey Kuzmin
7eb1c3fb1b fix: initialize tracing controller before starting platform (3-0-x) (#14503)
* fix: initialize tracing controller before starting platform

* chore: roll node
2018-09-21 10:23:57 -05:00
Samuel Attard
db0384116e fix: actually return appmetrics (#14750)
Fixes #14710
2018-09-21 10:10:37 -05:00
trop[bot]
0f8fb86e1b fix: do not set layer explicitly for frameless window (#14736) 2018-09-20 22:24:44 -07:00
trop[bot]
0c3cfc50a7 Fix second-instance handler signature (#14748) 2018-09-20 21:28:45 -07:00
trop[bot]
8d87dffe01 docs: specify BrowserWindow features passable to window.open (#14702) 2018-09-20 10:47:35 -07:00
John Kleinschmidt
9bb6c9dc99 Merge pull request #14696 from trop-bot/3-0-x-bp-chore--fix-await-in-cleanup-script-1537375163163
chore: fix await in cleanup script (backport: 3-0-x)
2018-09-19 14:26:17 -04:00
Shelley Vohr
e405103880 chore: fix await in cleanup script 2018-09-19 16:39:24 +00:00
Electron Bot
34c202518d Bump v3.0.0 2018-09-18 11:23:25 -07:00
trop[bot]
e5d84e84c2 chore: AFP info for general public (backport: 3-0-x) (#14673)
* migrate AFP info from maintainers

* wording changes

* capitalize headers

* move to docs and delete details

* review changes
2018-09-18 13:16:35 -05:00
Shelley Vohr
18857f494d fix: define ENABLE_PEPPER_FLASH (#14659) 2018-09-18 12:36:25 -05:00
John Kleinschmidt
d417759885 Merge pull request #14652 from electron/no-slack-notify-on-release
ci: Skip VSTS builds on older branches
2018-09-18 10:02:53 -04:00
trop[bot]
46c467a1f6 chore: dont pass --stable through to bump-version.py (#14666)
I want to clean up this "stable" and "beta" code smell eventually but
for now this will unblock the 2.0.x releases.
2018-09-18 23:41:23 +10:00
John Kleinschmidt
0b3b508eca ci: Skip VSTS testing builds on older branches
Also, don't send slack notifications for actual releases
2018-09-17 15:58:14 -04:00
Electron Bot
e3195413aa Bump v3.0.0-beta.13 2018-09-17 10:27:13 -07:00
trop[bot]
96c47ef537 fix: quit properly in simpleFullScreen mode (#14646) 2018-09-17 08:09:26 -07:00
Shelley Vohr
89148bcf8d refactor: deprecation handling apis (#14615) 2018-09-13 21:39:00 -07:00
trop[bot]
7e5815c180 fix: Windows Background color issue (#14592)
Call InvalidateRect for windows after setting the bg color
2018-09-12 17:06:10 -05:00
John Kleinschmidt
f924a16055 ci: don't run gn debug build on older branches (#14584)
* ci: don't run gn debug build on older branches

Older branches that build using gyp do not run both a debug and testing build.

* Actually skip the build if debug
2018-09-12 13:54:23 -07:00
Electron Bot
2a113e512b Bump v3.0.0-beta.12 2018-09-12 13:36:12 -07:00
trop[bot]
02b1069fd8 fix: Invalidate weak ptrs before window Javascript object is destroyed (backport: 3-0-x) (#14591)
* fix: Invalidate weak ptrs before window Javascript object is destroyed

* chore: add regression test for #14513

This test is similar to the original gist at https://gist.github.com/bpasero/a02a645e11f4946dcca1331d0299149d -- the key is to open multiple windows and add an `app.on('browser-window-focus') listener that accesses window.id.

* fix: last commit didn't test the right thing.

The test needs to run in the main process to reproduce the
conditions reported in #14513
2018-09-12 15:22:05 -05:00
Robo
3348e5162f fix: don't terminate existing sessions when opening devtools (#14566) 2018-09-13 00:17:15 +10:00
Electron Bot
64c8c27575 Bump v3.0.0-beta.11 2018-09-12 01:08:37 -07:00
trop[bot]
e76a976347 chore: make large beta numbers work when publishing (#14572) 2018-09-12 18:00:08 +10:00
Robo
8d27657fa5 fix: use render client id to track deleted render process hosts (backport: 3-0-x) (#14557)
* fix: use render client id to track deleted render process hosts

* fix: use webContentsId with contextId together (#13749)
2018-09-11 19:56:20 -07:00
John Kleinschmidt
5e81d8dad9 Merge pull request #14558 from electron/rename-appveyor-3-0-x
ci: Rename appveyor-override.yml to appveyor.yml (3-0-x)
2018-09-11 19:52:47 -04:00
John Kleinschmidt
b23acab456 Rename appveyor-override.yml to appveyor.yml 2018-09-11 19:17:50 -04:00
Cheng Zhao
8950caaa85 fix: read ignoreMenuShortcuts per WebContents (#14538) 2018-09-11 17:52:04 +10:00
Alexey Kuzmin
1b920c25af chore: Revert "fix: re-enable power monitor test (#14496)" (#14508)
This reverts commit d36b14a322.
2018-09-10 23:49:25 +10:00
Shelley Vohr
8fd31a3e07 build: [gn] widevine cdm support behind flag (3-0-x) (#14497) 2018-09-07 22:43:39 -07:00
Electron Bot
893f866c05 Bump v3.0.0-beta.10 2018-09-07 21:36:19 -07:00
Shelley Vohr
d36b14a322 fix: re-enable power monitor test (#14496) 2018-09-07 16:24:52 -07:00
John Kleinschmidt
27a33cc1cf Merge pull request #14494 from electron/fix-focus-3-0-x
fix: notify focus change right away rather not on next tick (3-0-x)
2018-09-07 15:31:26 -04:00
John Kleinschmidt
7835bceabd Update to latest libcc for 3-0-x 2018-09-07 14:37:28 -04:00
Nitish Sakhawalkar
af4f08e030 fix: notify focus change right away rather not on next tick (#14453)
* fix: Notify focus change right away, not on next tick

* fix: emit the JS blur/focus events on next tick to avoid race condition

* address feedback from review

* fix: bind deferred Emit() calls to a WeakPtr

This is so that the deferred Emit() calls will be canceled
if the TopLevelWindow is destroyed.

* chore: remove wip/test code cruft

* fix: make linter happy

* Enable disabled tests

* refactor: cleaner impl of EmitEventSoon()

* Revert "Merge branch 'fix-win-focus' of github.com:electron/electron into fix-win-focus"

This reverts commit 90576806eb, reversing
changes made to 9c13e47779.

* Restore 704722c1, which was removed in error.

We apologise again for the fault in the subtitles. Those responsible for sacking the people who have just been sacked have been sacked.
2018-09-07 14:30:41 -04:00
John Kleinschmidt
03dac078d7 Merge pull request #14488 from electron/manage-webview-webcontents-3-0-x
fix: manually manage WebContents of webview when it is detached (3-0-x)
2018-09-07 12:54:06 -04:00
Cheng Zhao
d3d44bdbc6 fix: manually manage WebContents of webview when it is detached 2018-09-07 15:42:58 +09:00
trop[bot]
a370b6982d Macos Window Title And Accessibility Focus Fix - Override accessibility method in atom_ns_window - Add title attribute in accessibilityAttributeValue (#14486) 2018-09-06 18:55:46 -07:00
trop[bot]
03ef5c25f7 fix: don't use deprecated fstatNoException API (#14484) 2018-09-06 13:09:03 -07:00
Roller Bot
3bc6652833 chore: bump libcc (3-0-x) (#14482)
* chore: bump libcc submodule to 61d71f3f150c3ff5025560dee254a53313bfbaf6

* chore: bump libcc in DEPS to 61d71f3f150c3ff5025560dee254a53313bfbaf6
2018-09-06 11:48:45 -07:00
Shelley Vohr
664371245a backport debugger fix (#14481)
* chore: enable debugger api specs (#14475)

* backport base::Value converters
2018-09-06 10:57:41 -07:00
John Kleinschmidt
08270e6817 docs: Specify VS 15.4.5 for 3-0-x (#14476)
Resolves #12898
2018-09-07 00:45:16 +10:00
Electron Bot
8f74a77a64 Bump v3.0.0-beta.9 2018-09-05 17:46:59 -07:00
Shelley Vohr
85c8ada99a deps: roll node to deprecate statsyncnoexception and lstatsyncnoexception (#14467) 2018-09-05 12:06:06 -07:00
Electron Bot
b15a3ee2be Bump v3.0.0-nightly.20180904 2018-09-04 17:16:17 -07:00
Shelley Vohr
7b043ac554 chore: add release-artifact-cleanup script (#14447) 2018-09-04 11:36:48 -07:00
trop[bot]
89a6f1efbb feat: add getUploadProgress API to the net API (#14446) 2018-09-04 12:26:50 -05:00
trop[bot]
ce592a5705 feat: allow setting window shape (backport: 3-0-x) (#14445)
* feat: allow setting window shape

This binds Widget::SetShape, an API that already exists in Chromium (for
Windows and Linux). It's a more reliable method of having some parts of
your window be "click-through" than the current `setIgnoreMouseEvents`
API, which messes around with the `WS_EX_LAYERED` window style on
Windows, causing strange bugs and incompatibility with hardware
acceleration.

* update docs
2018-09-04 09:22:11 -07:00
trop[bot]
12087b74e8 feat: allow some features during beta (backport: 3-0-x) (#14449)
* feat: allow all nonbreaking changes during beta

Changes the version policy: currently only nonbreaking bug/security
fixes are allowed during beta. This change would allow all nonbreaking
changes, e.g. new features, during beta.

* refactor: clarify criteria for changes during beta

* Update electron-versioning.md
2018-09-04 11:12:30 -05:00
trop[bot]
d365078022 fix: webview.focus() should move page focus to webview (#14428) 2018-09-03 13:26:41 +10:00
trop[bot]
3dbd84c224 docs: add notes on OOPIF webview's behaviors (#14409) 2018-08-31 14:48:38 -07:00
trop[bot]
2e479ff799 fix: use flexbox to style webview (backport: 3-0-x) (#14408)
* fix: use flexbox to style webview

* docs: remove notes on browserplugin based webview
2018-08-31 14:48:08 -07:00
trop[bot]
a341ae450a fix: allow Tray with title only (without icon) on Mac (#14384) 2018-09-01 08:49:56 +12:00
Roller Bot
0aec308681 chore: bump libcc (3-0-x) (#14391)
* chore: bump libcc submodule to dc2e7ebd2867d4329ebe7b6849e89cf3dc0afa8e

* chore: bump libcc in DEPS to dc2e7ebd2867d4329ebe7b6849e89cf3dc0afa8e
2018-08-31 10:38:56 -07:00
Samuel Attard
8e9c5b8338 chore: fix bootstrap script on 3-0-x (#14361) 2018-08-29 09:55:54 -07:00
trop[bot]
6bc1e37156 docs: keyboard listeners no longer work on webview (#14372) 2018-08-29 19:26:33 +09:00
Electron Bot
7da7dd85e3 Bump v3.0.0-beta.8 2018-08-28 23:04:31 -07:00
trop[bot]
ccf8a797dc fix: use OS process handle to clear object registry (#14364)
RenderProcessHost switch can happen between ipc calls when
speculative process are invvolved, which will lead to deletion
of entries on current context. Use OS process handles to
uniquely associate a destruction handler for a render process.
2018-08-28 22:55:42 -07:00
Milan Burda
3301e05f33 fix: don't expose desktopCapturer in sandboxed renderers if the feature is disabled (#14345) 2018-08-28 19:51:07 -05:00
trop[bot]
b1c22ba531 fix: emit focus/blur events for webview (backport: 3-0-x) (#14359)
* fix: emit focus/blur events for webview

* test: webview can emit focus event
2018-08-28 13:38:11 -05:00
trop[bot]
873f39b159 fix: crash when tray is destroyed (#14357)
Release the view of status item before destroying it,
gives chance to perform cleanup on the view.
2018-08-28 13:37:38 -05:00
trop[bot]
11864e9e08 fix: create persistent channel ID store when cookie store is persistent (#14358) 2018-08-28 13:37:09 -05:00
trop[bot]
c8a21dbb92 fix: don't crash on tray.setContextMenu(null) (#14331) 2018-08-27 13:27:41 -07:00
trop[bot]
97058837e7 fix: dont parse arguments after a -- in the inspector (#14333) 2018-08-27 14:44:53 -05:00
trop[bot]
ff539c1d61 fix: don't expose view APIs when not enabled (#14321) 2018-08-27 13:00:19 +09:00
trop[bot]
9237d40e09 fix: issue 10962, crash when open devtool (backport: 3-0-x) (#14303)
* fix: crash when opening devtool (#10962)

* fix: fixed linting issues
2018-08-25 12:23:06 -07:00
Shelley Vohr
4721dc0856 fix: opt into location services once device service has been started (backport: 3-0-x) (#14289)
* fix: opt into location services once device service has been started (#14253)

* fix: opt into location services once device service has been started

* refactor: provide fake location provider to mock geolocation reponses

* chore: add spec for navigator.geolocation api using fake location provider

* fix conflict
2018-08-24 08:23:15 -07:00
Electron Bot
1f7fd985dd Bump v3.0.0-nightly.20180823 2018-08-23 21:23:48 -07:00
Roller Bot
d432e420ae chore: bump libcc (3-0-x) (#14280)
* chore: bump libcc submodule to 7165af0ca9863529f28e493568ae3d105eddcdef

* chore: bump libcc in DEPS to 7165af0ca9863529f28e493568ae3d105eddcdef
2018-08-23 21:12:09 -07:00
trop[bot]
635c3f53d8 fix: add method and referrer properties to app login event (backport: 3-0-x) (#14277)
* refactor: remove brightray/network_delegate.{cc|h}

* refactor: respond to http requests through network delegate
2018-08-23 20:47:16 +09:00
trop[bot]
ba703deee2 Print error when removed webview attribute is used (backport: 3-0-x) (#14274)
* chore: print error when removed webview attribute is used

* docs: document removed webview features
2018-08-23 15:42:08 +09:00
Electron Bot
b03178105d Bump v3.0.0-beta.7 2018-08-22 11:13:36 -07:00
Samuel Attard
ef0a6d9a1c fix: inheritance of webPreferences sub properties 2018-08-22 12:19:11 -05:00
trop[bot]
4c7af6a429 fix: notify request context shutdown on IO before cleanup (#14092) 2018-08-22 08:24:56 -07:00
trop[bot]
d1886c5d22 ci: add better logging around request failures for releasing (#14245) 2018-08-21 13:31:44 -07:00
trop[bot]
c558dc2d7d chore: retry for the meta dumper a few times (#14243) 2018-08-21 13:31:13 -07:00
Electron Bot
be68cfd4ea Bump v3.0.0-nightly.20180821 2018-08-21 12:07:19 -07:00
Samuel Attard
115a15c356 Revert "Bump v3.0.0-nightly.20180821"
This reverts commit d4fb904450.
2018-08-21 11:45:21 -07:00
Electron Bot
d4fb904450 Bump v3.0.0-nightly.20180821 2018-08-21 11:16:44 -07:00
Electron Bot
c7f7bdab8a Bump v3.0.0-beta.6 2018-08-20 11:01:41 -07:00
trop[bot]
de7cb9524a chore: remove autorelease check logic (#14222) 2018-08-20 10:57:01 -07:00
trop[bot]
5d17e48490 fix: enable osr (backport: 3-0-x) (#14219)
* fix: re-enable osr

* fix: add changes from CEF to add MouseWheelPhaseHandler

* fix: re-enable surface synchronization by applying fix from cef

* update method call and enable AsyncWheelEvents var

* fix: make BrowserCompositorMacGetGutterColor behave like chromium

* fix: HANDLE only exists on windows

* fix: pass correct params to mouse_wheel_phase_handler_

* fix variable accessing

* revert: revert the workaround for disableHardwareAcceleration crash

* fix: remove GuestViewCrossProcessFrames from the disabled features list

* revert: remove check from BrowserChildProcessLaunchedAndConnected
2018-08-20 10:45:53 -07:00
trop[bot]
058c03fdab chore: add option to return next version from prepare-release (backport: 3-0-x) (#14217)
* chore: add option to return next version from prepare-release

* shuffle logic
2018-08-20 08:35:34 -07:00
trop[bot]
bd0d6b1a02 chore: match the bump commit exactly, reverts should not count (#14209) 2018-08-19 14:46:17 -07:00
trop[bot]
0783eb9881 fix: #14160 (#14205) 2018-08-19 14:14:05 -07:00
trop[bot]
4e3aa2e061 fix: electron path for postinstall (backport: 3-0-x) (#14197)
* fix #14127 issue caused by #12426

* add ELECTRON_OVERRIDE_DIST_PATH check for install.js
2018-08-19 12:54:39 -07:00
Samuel Attard
92f3d47ab3 Revert "Bump v3.0.0-nightly.20180819"
This reverts commit bf465dc233.
2018-08-18 19:12:01 -07:00
Shelley Vohr
2a7ec7e051 fix: update_electron_gyp regex for nightlies 2018-08-18 19:11:24 -07:00
Electron Bot
bf465dc233 Bump v3.0.0-nightly.20180819 2018-08-19 01:58:59 +00:00
trop[bot]
00cf45609f chore: only prepare release if last commit not a bump (#14193) 2018-08-18 18:37:47 -07:00
Roller Bot
26f4190102 chore: bump libcc (3-0-x) (#14175)
* chore: bump libcc submodule to 92dc0accfae5cd133fa2a6758ae6b3ff4ff7e569

* chore: bump libcc in DEPS to 92dc0accfae5cd133fa2a6758ae6b3ff4ff7e569
2018-08-18 09:36:18 -07:00
Electron Bot
5d6382270a Bump v3.0.0-nightly.20180818 2018-08-18 07:05:22 +00:00
Samuel Attard
2162c996eb Revert "Bump v3.0.0-nightly.20180818"
This reverts commit 2945be4b9b.
2018-08-17 23:54:57 -07:00
Electron Bot
2945be4b9b Bump v3.0.0-nightly.20180818 2018-08-18 06:37:26 +00:00
Samuel Attard
c066a51bfe chore: always target master for nightly release commitish 2018-08-17 23:35:34 -07:00
Samuel Attard
ff7dfe4a11 chore: add logging to prepare-release 2018-08-17 23:25:09 -07:00
Shelley Vohr
6d17663a0b fix: add dist tags for release branches (#14186) (#14187)
* fix: add dist tags for release branches
2018-08-17 19:47:19 -07:00
Samuel Attard
bd4334e2b4 chore: apply patches from master to 3.0 (#14184) 2018-08-17 17:42:46 -07:00
Samuel Attard
0f937c2300 chore: fix beta bumping in 3.0 (#14173) 2018-08-17 13:00:04 -07:00
Shelley Vohr
2ecdf4a0eb chore: update release scripts to support sudowoodo (#14170)
Backports the totality of our release script changes to support sudowoodo. Also backports changes that have been made to a few other release script files in master after 3-0-x was cut with the purpose of keeping them in sync.
2018-08-17 12:01:10 -07:00
Cheng Zhao
44b0245ac4 fix: use OOPIF for webview tag (#13869) (#14156)
* fix: use OOIF for webview tag

* fix: do not call GetNativeView for webview

* fix: OOIPF webview's WebContents is managed by embedder frame

* fix: guest view can not be focused

* fix: clear zoom controller when guest is destroyed

* fix: implement the webview resize event

The webview is no longer a browser plugin with the resize event, use
ResizeObserver instead.

* test: disable failed tests due to OOPIF webview

* fix: embedder can be destroyed earlier than guest

This happens when embedder is manually destroyed.

* fix: don't double attach

* fix: recreate iframe when webview is reattached

* fix: resize event may happen very early

* test: some tests are working after OOPIF webview

* chore: remove unused browser plugin webview code

* fix: get embedder via closure

When the "destroyed" event is emitted, the entry in guestInstances would be
cleared.

* chore: rename browserPluginNode to internalElement

* test: make the visibilityState test more robust

* chore: guestinstance can not work with OOPIF webview

* fix: element could be detached before got response from browser
2018-08-17 08:21:36 -07:00
trop[bot]
c4d6484264 docs: fix electron.d.ts typings (#14138) 2018-08-16 11:11:38 -07:00
Shelley Vohr
ef2ad40bd9 fix: roll node to fix fs.readSync bug (#14118) 2018-08-15 11:42:31 -07:00
trop[bot]
2642e064a2 fix: add a hidden option to disable remote dereferencing (#14113) 2018-08-15 08:44:23 -07:00
trop[bot]
daf23288bc fix: override fs.realpathSync.native and fs.realpath.native (backport: 3-0-x) (#14051)
* fix: override fs.realpathSync.native and fs.realpath.native

* spec: test new native functions
2018-08-13 23:53:34 -07:00
trop[bot]
8eec8e150d Fix flaky sandbox tests (#14056)
Windows apparently has issues running opening two windows at once which is causing flakiness on the mixed sandbox tests.
2018-08-13 15:14:32 -07:00
trop[bot]
2af61cbe95 fix: lint js and docs alongside clang-format (backport: 3-0-x) (#14053)
* fix: lint js and docs alongside clang-format

* chore: change lint scripts to colon format
2018-08-13 14:25:34 -07:00
Shelley Vohr
32ffb0ba17 Bump v3.0.0-beta.5 2018-08-13 08:30:14 -07:00
trop[bot]
69caea38c1 fix: make asarStatsToFsStats nherit from fs.stats (#14041) 2018-08-12 21:13:38 -07:00
Milan Burda
b5bfd9867b Don't pass preloadPath via ELECTRON_BROWSER_SANDBOX_LOAD for security reasons (#13031) (#14026) 2018-08-11 12:53:33 -05:00
John Kleinschmidt
fb2afe8656 Merge pull request #14022 from electron/3-0-x-vs2017-15-4-5
ci: Use vs2017-15.4.5 for 3-0-x on AppVeyor
2018-08-10 17:18:21 -04:00
John Kleinschmidt
c926f3f6dc Use vs2017-15.4.5 for AppVeyor
Update to libcc with VS2017 15.4.5
2018-08-10 14:16:23 -04:00
trop[bot]
5aa247a627 feat: add location url to "Node.js Integration with Remote Content" warning (backport: 3-0-x) (#13976)
* docs: fix typo

* feat: add location url to Node+Remote warning
2018-08-09 20:48:36 -05:00
trop[bot]
67d202eaf6 Fix typos (#14001) 2018-08-09 10:06:10 -05:00
Milan Burda
98033e4f45 Fix process.execPath returning parent process path instead of the helper in sandboxed renderer (#13959) 2018-08-09 09:58:44 -05:00
trop[bot]
3d89185396 fix: ipcRemote.sendSync regression after moving away from JSON for return values (#13997) 2018-08-09 09:24:10 -05:00
John Kleinschmidt
1f430259ce Merge pull request #13975 from electron/roll-libcc-3-0-x
chore: roll libcc
2018-08-08 09:30:46 -04:00
Jeremy Apthorp
ff86cf5f6a chore: roll libcc
Picks up electron/libchromiumcontent#633
2018-08-07 16:21:17 -07:00
John Kleinschmidt
274a53654c Merge pull request #13898 from electron/release-notes-generator
chore: Merge PR #13359 from electron/release-notes-generator
2018-08-06 12:44:39 -04:00
trop[bot]
8f5fafb636 fix: dipToScreenRect / screenToDipRect - window can be null (#13924) 2018-08-03 13:14:52 +10:00
trop[bot]
bfbd4a2540 fix: Improve --enable-features/--disable-features handling (#13923)
As it turns out, we can reinitialize the feature list directly after the
user JS script has been executed instead of much later. This allows
modifications to `--enable-features`/`--disable-features` to work with a
greater set of features.
2018-08-03 13:08:27 +10:00
Charles Kerr
1926eab172 Bump v3.0.0-beta.4 2018-08-01 15:13:06 -05:00
trop[bot]
9818378e2d fix: some APIs modified for ASAR support cannot be util.promisify'ed (#13902) 2018-08-01 16:38:50 +10:00
trop[bot]
ad2d35c7cf memo: Update security docs: will-navigate, new-window (#13887) 2018-08-01 13:25:24 +10:00
trop[bot]
13d3a055fa fix: handle SIGINT and SIGTERM from the Electron CLI helper (#13889)
Fixes #12840
2018-08-01 13:25:04 +10:00
Charles Kerr
07b93d475d simplify package-lock.json diffs from last commit 2018-07-31 17:36:33 -05:00
John Kleinschmidt
c9da2d7669 Merge pull request #13359 from electron/release-notes-generator
build: New release notes generator
2018-07-31 16:07:40 -05:00
trop[bot]
a9a5766804 chore(tests): allow usage of deprecated APIs in tests (#13862) 2018-07-30 15:02:59 +10:00
trop[bot]
a62cb1e84c fix: util.promisify(setTimeout) (#13860) 2018-07-30 15:02:52 +10:00
trop[bot]
2bdb7a5047 fix: window.setVibrancy parameter passing (backport: 3-0-x) (#13863)
* fix: setVibrancy parameter passing

* fix: uses correct parameter types for setVibrancy
2018-07-30 13:02:32 +10:00
trop[bot]
29f70d7e35 memo: First draft: Here be dragons (#13861) 2018-07-30 11:44:43 +10:00
trop[bot]
91af624cb1 docs: fix electron.d.ts typings (#13857) 2018-07-30 11:20:19 +10:00
trop[bot]
b08df88b7c fix: Use --enable-features and --disable-features (#13805)
Unlike Chrome, we were not using the --enable-features and
--disable-features command-line arguments to initialize
`base::FeatureList`.
2018-07-26 08:29:08 -07:00
Birunthan Mohanathas
b659ff2de3 build: Bump libcc to latest (3.0.x) (#13822)
This picks up electron/libchromiumcontent#618.
2018-07-26 08:25:28 -07:00
trop[bot]
3ad6abc5cc fix: check string encoding before creating value (#13818) 2018-07-26 19:35:18 +09:00
Cheng Zhao
a880e0222f fix: pass scrollBounce by command line flag (#13813)
Implement the scrollBounce option by reading the command line flag in
`RenderThreadImpl::IsElasticOverscrollEnabled`, there is no more need
to set NSScrollViewRubberbanding.
2018-07-26 18:38:48 +09:00
Birunthan Mohanathas
95c69e660c build: Bump libcc to latest (3.0.x)
This picks up electron/libchromiumcontent#611 and
electron/libchromiumcontent#599.
2018-07-25 09:54:00 -07:00
trop[bot]
4333020157 fix: create WebContents for webview on request (#13761) 2018-07-21 16:51:31 +09:00
John Kleinschmidt
f4ff97038c Merge pull request #13755 from trop-bot/3-0-x-bp-fix--update-rebuild-test-modules.py-for-node-10-1532100223562
fix: update rebuild-test-modules.py for node 10 (backport: 3-0-x)
2018-07-20 14:45:00 -04:00
John Kleinschmidt
967577c335 fix: update for node 10 2018-07-20 15:23:49 +00:00
John Kleinschmidt
8bd5c1f858 Merge pull request #13734 from electron/backport-13727-3-0-x
fix: use context counter as contextId (backport 3-0-x)
2018-07-20 10:17:18 -04:00
trop[bot]
2955b0168c fix: ensure DirectX capturer is supported. (backport: 3-0-x) (#13738)
* Ensure DirectX capturer is supported.

* Actually try building on Windows.
2018-07-20 14:25:29 +10:00
Cheng Zhao
04b7c77951 fix: use webContentsId with contextId together
After after using `processId-contextCounter` as contextId, it may happen
that contexts in different WebContents sharing the same renderer process
get the same contextId. Using webContentsId as part of key in
ObjectsRegistry can fix this.
2018-07-20 10:53:02 +09:00
Cheng Zhao
136cf389e8 fix: use context counter as contextId (backport 3-0-x)
For sandboxed renderer it may not have a node::Environment in the context,
using a increasing counter as contextId works for all cases.
2018-07-19 11:27:41 -07:00
Zeke Sikelianos
8d9775b0b1 Bump v3.0.0-beta.3 2018-07-17 09:38:50 -07:00
John Kleinschmidt
9237d46dba make sure tests don't run for GitHub releases. (#13701)
Also fix VSTS slack integration and
Update to latest libchromiumcontent

(cherry picked from commit 1c70a1cccd)
2018-07-17 10:57:59 -05:00
John Kleinschmidt
8f8d198c5a Merge pull request #13539 from trop-bot/3-0-x-bp-enable-webview-in-sandbox-renderer-1530547750986
Backport (3-0-x) - Enable webview in sandbox renderer
2018-07-17 10:01:40 -04:00
trop[bot]
fcdbb8c4a7 fix: create a window capturer correctly (backport: 3-0-x) (#13693)
* fix: create a window capturer correctly

We were incorrectly creating two screen capturers instead of a window
capturer

* spec: ensure dc tests pass

* spec: enable all tests after verifying dc tests work
2018-07-17 15:30:33 +10:00
trop[bot]
b49b071a1f fix: remove race condition for executeJavaScript (#13692)
Replaces 'did-finish-load' with 'did-stop-loading' which semantically
maps to the events inside Chromium.  Before I think we were relying
on a natural 99% winnable race condition.

Fixes #13504
2018-07-16 21:22:27 -07:00
trop[bot]
1feb45da29 docs: update second-instance event docs (#13682) 2018-07-16 13:57:58 -07:00
John Kleinschmidt
2c43dbdb25 Merge pull request #13680 from trop-bot/3-0-x-bp-fix-crash-when-opening-devtools-for-frameless-window-1531748442042
Fix crash when opening devtools for frameless window (backport: 3-0-x)
2018-07-16 10:48:37 -04:00
Cheng Zhao
7eff91dde1 spec: openDevTools should not crash for frameless window 2018-07-16 13:40:48 +00:00
Cheng Zhao
780483ff35 fix: use InspectableWebContentsView as content view 2018-07-16 13:40:48 +00:00
trop[bot]
c2f770df02 Update Windows VS2017 requirement (#13665) 2018-07-13 18:17:53 -05:00
John Kleinschmidt
74e6e063d4 Merge pull request #13658 from trop-bot/3-0-x-bp-fix--don't-invoke-callback-after-framesubscriber-is-destroyed-1531475760693
fix: don't invoke callback after FrameSubscriber is destroyed (backport: 3-0-x)
2018-07-13 11:51:07 -04:00
Cheng Zhao
7702cc1090 fix: don't invoke callback after FrameSubscriber is destroyed 2018-07-13 09:56:07 +00:00
trop[bot]
97319e5a3a fix: remember the render_process_id when permission requests occur on the IO thread (#13651)
Fixes #13620
2018-07-13 12:50:57 +10:00
Jeremy Apthorp
041c952574 fix: enable spell checking, which broke in upgrade to ch66
Chromium commit [03563dd163][1] changed the way that the
spellcheck-enabled status was checked, defaulting to false.

Added the first (!) test for spellchecking, too.

Fixes #13608.

[1]: 03563dd163
2018-07-12 13:28:15 -07:00
John Kleinschmidt
6c9b6f9cac Merge pull request #13642 from trop-bot/3-0-x-bp-chore--updates-for-release-process-1531400155960
chore: Updates for release process (backport: 3-0-x)
2018-07-12 09:37:12 -04:00
John Kleinschmidt
c4884da601 Update docs to reflect current process
Also added troubleshooting steps.
2018-07-12 12:56:02 +00:00
John Kleinschmidt
59b05ed661 Fix Appveyor URL 2018-07-12 12:56:02 +00:00
Cheng Zhao
e3204a5ec1 Merge pull request #13637 from electron/fix-remote-3-0-x
fix: guard against double-freeing remote references (3-0-x)
2018-07-12 16:01:52 +09:00
Cheng Zhao
adf49daaac fix double-freeing remote references
After the page does navigations, garbage collection can still happen in
the old context. This commit changes to store references to remote objects
by _pages_, instead of by _WebContents_.
2018-07-12 11:17:26 +09:00
Cheng Zhao
9431677e79 add API to return an unique ID for page 2018-07-12 11:16:13 +09:00
John Kleinschmidt
0141c083d0 Bump v3.0.0-beta.2 2018-07-10 14:12:05 -04:00
John Kleinschmidt
96b2c08293 Merge pull request #13612 from trop-bot/3-0-x-bp-build--updates-to-the-release-process-1531237367452
Backport (3-0-x) - build: Updates to the release process
2018-07-10 13:26:24 -04:00
John Kleinschmidt
d6f2c26b0f Move github release checking to node.js
Our upload script was relying on an old python script to find the GitHub release for uploading.
2018-07-10 15:42:53 +00:00
John Kleinschmidt
d478906f9c Update to run new AppVeyor jobs
AppVeyor builds got split into two jobs, `electron-x64` and `electron-ia32`
2018-07-10 15:42:53 +00:00
trop[bot]
85526c7f21 fix: fallback to FullSizeContentView for frameless window on mac (#13600)
When using `views::Widget` to create window, Chromium will automatically
use a `BridgedContentView` as content view, which however does not
support draggable regions inside it.

By fallback to `FullSizeContentView` we can work around this problem,
with the price of losing the ability to use `views::View` APIs. Since
we don't expect users to use the new `View` APIs in `BrowserWindow`
anyway, it should not be a problem.

This change does not affect users of `TopLevelWindow`, and for users of
`BrowserWindow` there is nothing to lose.

In the long term we should look into how to make draggable regions work
with `BridgedContentView`. The related Chromium code is still being
changed rapidly, we can wait until Chromium migrated its
`NativeAppWindowCocoa` class to use `views::Widget`.
2018-07-10 13:09:46 +09:00
John Kleinschmidt
f6ae438005 Merge pull request #13591 from trop-bot/3-0-x-bp-fix-failed-devtools-tests-due-to-fs.statsyncnoexception-not-working--1531147212282
Backport (3-0-x) - Fix failed devtools tests due to fs.statSyncNoException not working
2018-07-09 14:30:42 -04:00
John Kleinschmidt
5e51e608db Merge pull request #13593 from electron/update-libcc-3-0-x
build: Update to latest libchromiumcontent for 3-0-x
2018-07-09 14:30:08 -04:00
John Kleinschmidt
97248a7a56 Update to latest libchromiumcontent
Use the latest libchromiumcontent for 3-0-x which is built with Visual Studio 2017 15.7.4
2018-07-09 13:20:41 -04:00
Cheng Zhao
8639466c75 update node to fix fs.statSyncNoException 2018-07-09 14:40:18 +00:00
Cheng Zhao
31e2166cea Revert "spec: disable the i18nString test"
This reverts commit 86c79653de.
2018-07-09 14:40:18 +00:00
trop[bot]
c2f4144996 Backport (3-0-x) - Fix devtools not functioning well (#13571)
* implement devtools showItemInFolder message

* add stubs for new devtools messages

* fix: update devtools url

* spec: enable back devtools tests

* spec: disable the i18nString test

It is failed because of fs.statSyncNoException, I'll fix it in another
PR.
2018-07-06 13:19:21 +10:00
Hari Juturu
f63e5ffa65 cache lastwebprefs 2018-07-02 16:09:17 +00:00
Hari Juturu
32e40cb4c3 Enable webview in sandbox renderer Security: Inherit embedder prefs onto webview 2018-07-02 16:09:17 +00:00
John Kleinschmidt
8585372e11 Merge pull request #13517 from trop-bot/3-0-x-bp-fix--tray-setcontextmenu-crash-1530309092727
Backport (3-0-x) - fix: tray setContextMenu crash
2018-07-02 09:13:58 -04:00
John Kleinschmidt
2e2289d701 Merge pull request #13530 from electron/fix-mas-build-3-0-x
Update libcc to fix private APIs in MAS build (3-0-x)
2018-07-02 08:05:56 -04:00
Cheng Zhao
f6229d9489 fix: update libcc to fix private APIs in mas build 2018-07-02 15:21:18 +09:00
Maxine Whitely
bace4890c8 fix: tray setContextMenu crash
Co-authored-by: Zhuo Lu <sethlu@mintkit.net>
Co-authored-by: Kristine Zhang <kzhang@slack-corp.com>
2018-06-29 21:51:38 +00:00
Cheng Zhao
0a3211c387 fix the crash when loading site with jquery (#13476) 2018-06-29 09:42:26 +09:00
John Kleinschmidt
7d27c91400 Remove no longer used files from asset validation (#13372)
Also removed temporary sha value needed for initial 3.0.0-beta.1
2018-06-27 11:12:11 -07:00
trop[bot]
93edf2edd3 Backport (3-0-x) - fix: deprecate properties in app.getAppMetrics() (#13453)
* fix: deprecate properties in app.getAppMetrics()

* address feedback from review

* fix deprecated property location

* simplify test
2018-06-27 19:07:39 +10:00
trop[bot]
ec993214a2 docs: add native_mate to source code directory structure doc (#13457) 2018-06-27 18:28:13 +10:00
Samuel Attard
509120acde Merge pull request #13456 from electron/native-mate-in-electron-3
Native mate in electron 3
2018-06-27 17:45:04 +10:00
Samuel Attard
b472a69279 Revert "Native mate in electron 3 (#13450)" (#13455)
This reverts commit 7f3620bee3.
2018-06-27 17:43:01 +10:00
Samuel Attard
7f3620bee3 Native mate in electron 3 (#13450)
* Initial commit.

* Do not rely on latest base/template_util.

* Enable modifying existing ObjectTemplate.

* Fix compilation error of function_template.

* Add initial Constructor type.

* Fix passing the wrong parameter.

* Make the Constructor accept arbitrary callback.

* Cleanup.

* Constructor should wrap the this pointer.

* Simplify Wrappable API.

* Remove helper typedefs.

* Support function with 7 parameters.

* Enable converting void*.

* Enable setting method in Dictionary.

* Add v8::Handle<v8::String> to converter.

* Make ScopedPersistent do type conversion.

* Add Arguments.Length method.

* Do not wrap an object when it's already wrapped.

* No need to reset wrapper_ when we would run destructor.

* Call object._init if we have one.

* Add object() accessor for Dictionary.

* Add converter for const char*.

* Enable creating empty Dictionary directly.

* Mark Dictionary.Get as const.

* Strictly check for boolean type.

* Add .gitignore.

* Add APIs to match new V8 APIs.

* Bring back ScopedPersistent.SetWeak.

* Some more APIs fixes.

* Reset handle in weak callback.

This doesn't seem to be neccesary, but we had better follow what upstream does.

* Enable converting ScopedPersistent.

* Fix compilation error with node 0.10.

* Fix compilation error of Constructor and ScopedPersistent in node 0.10.

* Use pump to generate source files.

* Add callback converter.

* Make ScopedPersistent's interface consistent with V8.

* Remove unused constructor of Dictionary.

* Add PersistentDictionary.

* Make throwing exception when parsing args easier

* Use NODE_VERSION_AT_LEAST to determine node version

* Don't throw error in Constructor

* Guard against non-constructor call in Constructor::New

* Fix throwing error in constructor

* Fix ignored exception thrown from constructor.

* OVERRIDE => override

* Avoid unnecessary copy in ConvertToV8

* Check internal field before converting

* Remove unneeded helper

* Add AfterInit method for Wrappable

* Add converter for unsigned long

* usigned long is uint64 on Linux

* Don't reset handle before Wrappable is destroyed

It is possible that the user wants to use the V8 object in the destructor.

Fixes atom/atom-shell#1112.

* added std::set converter

* Use Local instead of Handle

* Pass Handle to upper HandleScope when returning a V8 Handle

* Enter context before calling callback

* Allow converting Array

* Remember isolate in Wrappable

* Make isolate() public

* Check for null when converting Wrappable

* Add IsDestroyed method for Wrappable

* Allow specify methods that can be called after object is destroyed

* Use C++11 version of CreateFunctionTemplate

* Remove callback.h

* Remove locker.h

* Add Dictionary::CreateEmpty

* GetNext should have no side effect when failed

* Don't convert Function to Dictionary

* Don't pass callback as const reference

* Add SetHidden for Dictionary

* Use the new SetWeak in Wrappable

* Check whether key exists in Dictionary::Get

* Don't return v8::Maybe for std::vector

* Add Dictionary::Delete

* Do not manually destroy native resources

* isDestroy => isDestroyed

* Fix converter for std::set

* Improve error message for type error

Close atom/electron#4307.

* Clear internal field when Wrapper is destroyed

* basic_types.h => macros.h

* use v8::private symbols as identifiers for object properties

* Make Wrappable a template class

* Leak Wrappable's template

Since it is declared as static variable it will be released
automatically when process exits, which causes crashes in
renderer process because the template will then be released
later than V8 is closed.

This commit simply leaks the template so the crash won't happen,
this leak should be fine since leaking resource on exit is not
a bad thing.

* Handle.ToV8 should return Object

* Add converter for std::map

* Setup v8::MicrotasksScope for callbacks

* Update to API changes of V8 5.2

* CHECK is not needed

* Call the user call Init in Constructor

* Make InitWith virtual

* Turn Wrappable into using FunctionTemplate

* Create objects from InstanceTemplate

* NewOperatorFactory is not used

* Remove the Constructor class

* GetConstructor should init default constructor

* Pass FunctionTemplate in BuildPrototype

* Do not set constructor name in SetConstructor

* Use ToDetailString for processing error message

* Add back empty handle string

* Add README

* create empty handle for null or undefined value

* Support setting read-only property value

* Add Converter<std::map<std::string, T>>::ToV8

* Add CI build through Electron

* Support 5 argument member function

* Use std functions instead of template_util

* Make Wrappable thread safe

* Use gin to manage FunctionTemplate

Sadly there is no way for us to know when V8 is closing, thus it is
impossible for us to clean the FunctionTemplate on exit at the right
time, which is critcal for multi-thread environment.

* add ability to set high memory usage, skipping the second round of GC callbacks

* Fix broken link

* Add a converter for `nullptr_t`

* Upstream Muon changes to avoid crashing

* only mark handle as independent when it's a high memory user

* Remove WrappableBase::GetWrapper() DCHECK

* virtual members need a virtual destructor

* GetWrapper should be const

* Add support for FreeBSD

* Remove usage of MarkIndependent api

https://bugs.chromium.org/p/chromium/issues/detail?id=780749
Use Active/Not Active as indicator whether the Scavenger can drop wrappers

* Address breaking API

* Fix Value::ToDetailString() call

See https://chromium-review.googlesource.com/848782

* Revert "Address breaking API"

This reverts commit e20cf8687e.

* Add mate::Promise

* Update travis settings

Use Node.js 9.7.0 and Xcode 9.3.

* Update appveyor settings

Use Visual Studio 2017.

* Remove mate::TryCatch (#26)

It's not used anywhere. We use v8::TryCatch instead.

* Address breaking API

* Don't copy things on Dictionary::Set

* Remove native_mate/compat.h

* prepare for merging to electron

* remove native_mate submodule

* update paths for native_mate

* move native_mate script to the electron scripts dir

* rename back to expected values

* fix linting
2018-06-27 17:42:20 +10:00
trop[bot]
21d4ef5eab fix: do not expose Node's external strings (#13452) 2018-06-27 11:40:44 +09:00
Samuel Attard
4f6b6b044f fix linting 2018-06-27 10:05:22 +10:00
Samuel Attard
02026279be rename back to expected values 2018-06-27 10:05:15 +10:00
Samuel Attard
6fd1f7ecb1 move native_mate script to the electron scripts dir 2018-06-27 10:05:07 +10:00
Samuel Attard
922cf08ab4 update paths for native_mate 2018-06-27 10:04:58 +10:00
Samuel Attard
7f8cd51f63 remove native_mate submodule 2018-06-27 10:04:51 +10:00
Samuel Attard
31e5b046a4 Merge 'native_mate' into 'electron' 2018-06-27 10:04:04 +10:00
trop[bot]
957f008726 fix: repair fs.statSyncNoException throwing exceptions (#13397) 2018-06-23 17:27:38 +10:00
trop[bot]
2069eb1972 Fix links to webview.md (#13370) 2018-06-22 03:06:54 +10:00
trop[bot]
e57f7edd37 Revert "Drop support of Mac OS 10.9" (#13350)
This reverts commit efa0ec0263.
2018-06-21 09:37:18 +10:00
John Kleinschmidt
df62fb7788 Skip tests for release build 2018-06-20 18:20:04 -04:00
John Kleinschmidt
9b09d103fd Update appveyor for release. 2018-06-20 16:55:16 -04:00
John Kleinschmidt
453edb42b4 Fix linting error 2018-06-20 14:17:17 -04:00
John Kleinschmidt
1b2a85436c Bump v3.0.0-beta.1 2018-06-20 12:52:49 -04:00
John Kleinschmidt
c7d4d2d18f Set to last version released
Need to properly bump version
2018-06-20 12:52:33 -04:00
John Kleinschmidt
d1a0eb3d11 Merge pull request #13339 from trop-bot/3-0-x-bp-fix-linking-error-for-mas-build-1529503586342
Backport (3-0-x) - Fix linking error for MAS build
2018-06-20 11:00:35 -04:00
trop[bot]
a0e37d1383 Backport (3-0-x) - test: Upgrade spec dependencies (#13328)
* package: Update mocha, mocha-junit-reporter

* package: Update graceful-fs, multiparty, q, walkdir

* package: Update basic-auth

* package: Update ws

* package: Update dbus-native

* package: Upgrade yargs

* lock: Run `npm audit fix`

* wrench: Fix websocket API change
2018-06-20 09:24:27 -05:00
trop[bot]
128a03450a Backport (3-0-x) - fix: tls check shouldnt rely on an external service (#13338)
* fix: tls check shouldnt rely on an external service

* fix linting in the tls script'
2018-06-21 00:12:58 +10:00
Cheng Zhao
d34c7396ef fix: link with crashpad_client for MAS build 2018-06-20 14:06:32 +00:00
John Kleinschmidt
cdbd4792e3 Merge pull request #13336 from trop-bot/3-0-x-bp-revert-"fix--drop-support-for-os-x-mavericks-(version-10.9)"-1529497748886
Backport (3-0-x) - Revert "fix: Drop support for OS X Mavericks (version 10.9)"
2018-06-20 09:07:46 -04:00
Samuel Attard
b0f6c3ab65 Revert "fix: Drop support for OS X Mavericks (version 10.9)" 2018-06-20 12:29:14 +00:00
trop[bot]
d2508faea8 Disable node options in node config (#13323) 2018-06-20 17:10:37 +10:00
trop[bot]
9bda7d0b73 set mac protocol to none (#13326) 2018-06-20 17:10:23 +10:00
3018 changed files with 159551 additions and 208730 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +0,0 @@
#!/bin/bash
set -e
mkdir -p ~/.ssh
echo "|1|B3r+7aO0/x90IdefihIjxIoJrrk=|OJddGDfhbuLFc1bUyy84hhIw57M= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
|1|rGlEvW55DtzNZp+pzw9gvyOyKi4=|LLWr+7qlkAlw3YGGVfLHHxB/kR0= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==" >> ~/.ssh/known_hosts

View File

@@ -1,2 +1,3 @@
*
!tools/xvfb-init.sh
!tools/run-electron.sh

View File

@@ -1,6 +1,7 @@
# These env vars are only necessary for creating Electron releases.
# See docs/development/releasing.md
APPVEYOR_CLOUD_TOKEN=
APPVEYOR_TOKEN=
CIRCLE_TOKEN=
ELECTRON_GITHUB_TOKEN=
VSTS_TOKEN=

View File

@@ -1,53 +0,0 @@
{
"extends": "standard",
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint"],
"env": {
"browser": true
},
"rules": {
"semi": ["error", "always"],
"no-var": "error",
"no-unused-vars": "off",
"no-global-assign": "off",
"guard-for-in": "error",
"@typescript-eslint/no-unused-vars": ["error", {
"vars": "all",
"args": "after-used",
"ignoreRestSiblings": true
}],
"prefer-const": ["error", {
"destructuring": "all"
}],
"standard/no-callback-literal": "off",
"node/no-deprecated-api": "off"
},
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module"
},
"overrides": [
{
"files": "*.js",
"rules": {
"@typescript-eslint/no-unused-vars": "off"
}
},
{
"files": "*.ts",
"rules": {
"no-undef": "off",
"no-redeclare": "off",
"@typescript-eslint/no-redeclare": ["error"],
"no-use-before-define": "off"
}
},
{
"files": "*.d.ts",
"rules": {
"no-useless-constructor": "off",
"@typescript-eslint/no-unused-vars": "off"
}
}
]
}

14
.gitattributes vendored
View File

@@ -1,14 +0,0 @@
# `git apply` and friends don't understand CRLF, even on windows. Force those
# files to be checked out with LF endings even if core.autocrlf is true.
*.patch text eol=lf
patches/**/.patches merge=union
# Source code and markdown files should always use LF as line ending.
*.cc text eol=lf
*.mm text eol=lf
*.h text eol=lf
*.js text eol=lf
*.ts text eol=lf
*.py text eol=lf
*.ps1 text eol=lf
*.md text eol=lf

25
.github/CODEOWNERS vendored
View File

@@ -3,16 +3,19 @@
# https://help.github.com/articles/about-codeowners
# https://git-scm.com/docs/gitignore
# Upgrades WG
/patches/ @electron/wg-upgrades
DEPS @electron/wg-upgrades
# Everything that falls through the cracks:
* @electron/reviewers
# Releases WG
/npm/ @electron/wg-releases
/script/release @electron/wg-releases
# filename patterns
*browser_view* @electron/browserview
*notification* @electron/notifications
*pdf* @electron/printing
*printing* @electron/printing
*updater* @electron/updater
# Security WG
/lib/browser/devtools.ts @electron/wg-security
/lib/browser/guest-view-manager.ts @electron/wg-security
/lib/browser/guest-window-proxy.ts @electron/wg-security
/lib/browser/rpc-server.ts @electron/wg-security
# directories
/.github/ @electron/electrocats
/default_app/ @electron/docs
/docs/ @electron/docs
/docs-translations/ @electron/i18n
/npm/ @electron/electrocats

38
.github/ISSUE_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,38 @@
<!--
Thanks for opening an issue! A few things to keep in mind:
- The issue tracker is only for bugs and feature requests.
- Before reporting a bug, please try reproducing your issue against
the latest version of Electron.
- If you need general advice, join our Slack: http://atom-slack.herokuapp.com
-->
* Electron version:
* Operating system:
<!-- If this used to work -->
* Last known working Electron version:
### Expected behavior
<!-- What do you think should happen? -->
### Actual behavior
<!-- What actually happens? -->
### How to reproduce
<!--
Your best chance of getting this bug looked at quickly is to provide a REPOSITORY that can be cloned and run.
You can fork https://github.com/electron/electron-quick-start and include a link to the branch with your changes.
If you provide a URL, please list the commands required to clone/setup/run your repo e.g.
$ git clone $YOUR_URL -b $BRANCH
$ npm install
$ npm start || electron .
-->

32
.github/ISSUE_TEMPLATE/Bug_report.md vendored Normal file
View File

@@ -0,0 +1,32 @@
---
name: Bug report
about: Create a report to help us improve Electron
---
* Electron Version:
* Operating System (Platform and Version):
* Last known working Electron version:
**Expected Behavior**
A clear and concise description of what you expected to happen.
**Actual behavior**
A clear and concise description of what actually happened.
**To Reproduce**
Your best chance of getting this bug looked at quickly is to provide a REPOSITORY that can be cloned and run.
You can fork [electron-quick-start](https://github.com/electron/electron-quick-start) and include a link to the branch with your changes.
If you provide a URL, please list the commands required to clone/setup/run your repo e.g.
```sh
$ git clone $YOUR_URL -b $BRANCH
$ npm install
$ npm start || electron .
```
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Additional Information**
Add any other context about the problem here.

View File

@@ -0,0 +1,17 @@
---
name: Feature request
about: Suggest an idea for Electron
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is.
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@@ -1,77 +0,0 @@
name: Bug Report
description: Report an Electron bug
title: "[Bug]: "
labels: "bug :beetle:"
body:
- type: checkboxes
attributes:
label: Preflight Checklist
description: Please ensure you've completed all of the following.
options:
- label: I have read the [Contributing Guidelines](https://github.com/electron/electron/blob/master/CONTRIBUTING.md) for this project.
required: true
- label: I agree to follow the [Code of Conduct](https://github.com/electron/electron/blob/master/CODE_OF_CONDUCT.md) that this project adheres to.
required: true
- label: I have searched the [issue tracker](https://www.github.com/electron/electron/issues) for a feature request that matches the one I want to file, without success.
required: true
- type: input
attributes:
label: Electron Version
description: What version of Electron are you using?
placeholder: 12.0.0
validations:
required: true
- type: dropdown
attributes:
label: What operating system are you using?
options:
- Windows
- macOS
- Ubuntu
- Other Linux
- Other (specify below)
validations:
required: true
- type: input
attributes:
label: Operating System Version
description: What operating system version are you using? On Windows, click Start button > Settings > System > About. On macOS, click the Apple Menu > About This Mac. On Linux, use lsb_release or uname -a.
placeholder: "e.g. Windows 10 version 1909, macOS Catalina 10.15.7, or Ubuntu 20.04"
validations:
required: true
- type: dropdown
attributes:
label: What arch are you using?
options:
- x64
- ia32
- arm64 (including Apple Silicon)
- Other (specify below)
validations:
required: true
- type: input
attributes:
label: Last Known Working Electron version
description: What is the last version of Electron this worked in, if applicable?
placeholder: 11.0.0
- type: textarea
attributes:
label: Expected Behavior
description: A clear and concise description of what you expected to happen.
validations:
required: true
- type: textarea
attributes:
label: Actual Behavior
description: A clear description of what actually happens.
validations:
required: true
- type: input
attributes:
label: Testcase Gist URL
description: If you can reproduce the issue in a standalone test case, please use [Electron Fiddle](https://github.com/electron/fiddle) to create one and to publish it as a [GitHub gist](https://gist.github.com) and put the gist URL here. This is **the best way** to ensure this issue is triaged quickly.
placeholder: https://gist.github.com/...
- type: textarea
attributes:
label: Additional Information
description: If your problem needs further explanation, or if the issue you're seeing cannot be reproduced in a gist, please add more information here.

View File

@@ -1,40 +0,0 @@
name: Feature Request
description: Suggest an idea for Electron
title: "[Feature Request]: "
labels: "enhancement :sparkles:"
body:
- type: checkboxes
attributes:
label: Preflight Checklist
description: Please ensure you've completed all of the following.
options:
- label: I have read the [Contributing Guidelines](https://github.com/electron/electron/blob/master/CONTRIBUTING.md) for this project.
required: true
- label: I agree to follow the [Code of Conduct](https://github.com/electron/electron/blob/master/CODE_OF_CONDUCT.md) that this project adheres to.
required: true
- label: I have searched the [issue tracker](https://www.github.com/electron/electron/issues) for a feature request that matches the one I want to file, without success.
required: true
- type: textarea
attributes:
label: Problem Description
description: Please add a clear and concise description of the problem you are seeking to solve with this feature request.
validations:
required: true
- type: textarea
attributes:
label: Proposed Solution
description: Describe the solution you'd like in a clear and concise manner.
validations:
required: true
- type: textarea
attributes:
label: Alternatives Considered
description: A clear and concise description of any alternative solutions or features you've considered.
validations:
required: true
- type: textarea
attributes:
label: Additional Information
description: Add any other context about the problem here.
validations:
required: true

View File

@@ -1,30 +0,0 @@
name: Report Mac App Store Private API Rejection
description: Your app was rejected from the Mac App Store for using private API's
title: "[MAS Rejection]: "
body:
- type: checkboxes
attributes:
label: Preflight Checklist
description: Please ensure you've completed all of the following.
options:
- label: I have read the [Contributing Guidelines](https://github.com/electron/electron/blob/master/CONTRIBUTING.md) for this project.
required: true
- label: I agree to follow the [Code of Conduct](https://github.com/electron/electron/blob/master/CODE_OF_CONDUCT.md) that this project adheres to.
required: true
- type: input
attributes:
label: Electron Version
description: What version of Electron are you using?
placeholder: 12.0.0
validations:
required: true
- type: textarea
attributes:
label: Rejection Email
description: Paste the contents of your rejection email here, censoring any private information such as app names.
validations:
required: true
- type: textarea
attributes:
label: Additional Information
description: Add any other context about the problem here.

View File

@@ -1,4 +1,3 @@
#### Description of Change
<!--
Thank you for your Pull Request. Please provide a description above and review
the requirements below.
@@ -6,15 +5,11 @@ the requirements below.
Contributors guide: https://github.com/electron/electron/blob/master/CONTRIBUTING.md
-->
#### Checklist
##### Checklist
<!-- Remove items that do not apply. For completed items, change [ ] to [x]. -->
- [ ] PR description included and stakeholders cc'd
- [ ] `npm test` passes
- [ ] tests are [changed or added](https://github.com/electron/electron/blob/master/docs/development/testing.md)
- [ ] relevant documentation is changed or added
- [ ] [PR release notes](https://github.com/electron/clerk/blob/master/README.md) describe the change in a way relevant to app developers, and are [capitalized, punctuated, and past tense](https://github.com/electron/clerk/blob/master/README.md#examples).
#### Release Notes
Notes: <!-- Please add a one-line description for app developers to read in the release notes, or 'none' if no notes relevant to app developers. Examples and help on special cases: https://github.com/electron/clerk/blob/master/README.md#examples -->
- [ ] commit messages or PR title follow semantic [commit guidelines](https://github.com/electron/electron/blob/master/docs/development/pull-requests.md#commit-message-guidelines)

22
.github/config.yml vendored
View File

@@ -1,8 +1,18 @@
# Configuration for new-issue-welcome - https://github.com/behaviorbot/new-issue-welcome
# Comment to be posted to on first time issues
newIssueWelcomeComment: |
👋 Thanks for opening your first issue here! If you're reporting a 🐞 bug, please make sure you include steps to reproduce it. We get a lot of issues on this repo, so please be patient and we will get back to you as soon as we can.
To help make it easier for us to investigate your issue, please follow the [contributing guidelines](https://github.com/electron/electron/blob/master/CONTRIBUTING.md).
# Configuration for new-pr-welcome - https://github.com/behaviorbot/new-pr-welcome
# Comment to be posted to on PRs from first time contributors in your repository
newPRWelcomeComment: |
💖 Thanks for opening this pull request! 💖
We use [semantic commit messages](https://github.com/electron/electron/blob/master/docs/development/pull-requests.md#commit-message-guidelines) to streamline the release process. Before your pull request can be merged, you should **update your pull request title** to start with a semantic prefix.
We use [semantic commit messages](https://github.com/electron/electron/blob/master/docs/development/pull-requests.md#commit-message-guidelines) to streamline the release process. Before your pull request can be merged, you should **update your pull request title** to start with a semantic prefix, OR prefix at least one of your commit messages.
Examples of commit messages with semantic prefixes:
@@ -26,16 +36,18 @@ newPRWelcomeComment: |
firstPRMergeComment: >
Congrats on merging your first pull request! 🎉🎉🎉
# Users authorized to run manual trop backports
# Configuration for trop - https://github.com/codebytere/trop
watchedProject:
name: Backports
authorizedUsers:
- alexeykuzmin
- ckerr
- codebytere
- deepak1556
- jkleinsc
- loc
- MarshallOfSound
- miniak
- mlaurencin
- nitsakh
- nornagon
- zcbenz

View File

@@ -1,2 +0,0 @@
# Always validate the PR title, and ignore the commits
titleOnly: true

25
.github/stale.yml vendored Normal file
View File

@@ -0,0 +1,25 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 45
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
# Issues with these labels will never be considered stale
exemptLabels:
- fixme/bug
- fixme/crash
- fixme/regression
- fixme/security
- blocked
- blocking-stable
- needs-review
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity and is not currently prioritized. It will be closed
in a week if no further activity occurs :)
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: >
If you still think this issue is relevant, please ping a maintainer or
leave a comment!

53
.gitignore vendored
View File

@@ -16,40 +16,37 @@
*.vcxproj.user
*.xcodeproj
/.idea/
/brightray/brightray.opensdf
/brightray/brightray.sdf
/brightray/brightray.sln
/brightray/brightray.suo
/brightray/brightray.v12.suo
/brightray/brightray.vcxproj*
/brightray/brightray.xcodeproj/
/dist/
/external_binaries/
/out/
/vendor/.gclient
/vendor/debian_jessie_mips64-sysroot/
/vendor/debian_stretch_amd64-sysroot/
/vendor/debian_stretch_arm-sysroot/
/vendor/debian_stretch_arm64-sysroot/
/vendor/debian_stretch_i386-sysroot/
/vendor/gcc-4.8.3-d197-n64-loongson/
/vendor/readme-gcc483-loongson.txt
/vendor/download/
/vendor/llvm-build/
/vendor/llvm/
/vendor/npm/
/vendor/python_26/
/vendor/native_mksnapshot
/vendor/LICENSES.chromium.html
node_modules/
SHASUMS256.txt
**/package-lock.json
**/yarn.lock
compile_commands.json
.envrc
# npm package
/npm/dist
/npm/path.txt
.npmrc
# Generated API definitions
electron-api.json
electron.d.ts
# Spec hash calculation
spec/.hash
# Eslint Cache
.eslintcache*
# Generated native addon files
/spec-main/fixtures/native-addon/echo/build/
# If someone runs tsc this is where stuff will end up
ts-gen
# Used to accelerate CI builds
.depshash
.depshash-target
# Used to accelerate builds after sync
patches/mtime-cache.json
spec/fixtures/logo.png

27
.gitmodules vendored Normal file
View File

@@ -0,0 +1,27 @@
[submodule "vendor/node"]
path = vendor/node
url = https://github.com/electron/node.git
[submodule "vendor/depot_tools"]
path = vendor/depot_tools
url = https://chromium.googlesource.com/chromium/tools/depot_tools.git
[submodule "vendor/breakpad"]
path = vendor/breakpad
url = https://github.com/electron/chromium-breakpad.git
[submodule "vendor/crashpad"]
path = vendor/crashpad
url = https://github.com/electron/crashpad.git
[submodule "vendor/requests"]
path = vendor/requests
url = https://github.com/kennethreitz/requests
[submodule "vendor/boto"]
path = vendor/boto
url = https://github.com/boto/boto.git
[submodule "vendor/pdf_viewer"]
path = vendor/pdf_viewer
url = https://github.com/electron/pdf-viewer.git
[submodule "vendor/gyp"]
path = vendor/gyp
url = https://github.com/electron/gyp
[submodule "vendor/libchromiumcontent"]
path = vendor/libchromiumcontent
url = https://github.com/electron/libchromiumcontent

1
.husky/.gitignore vendored
View File

@@ -1 +0,0 @@
_

View File

@@ -1,4 +0,0 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npm run precommit

View File

@@ -1,4 +0,0 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npm run prepack

View File

@@ -1,6 +0,0 @@
{
"default": false,
"no-trailing-spaces": {
"br_spaces": 0
}
}

View File

@@ -1,26 +0,0 @@
{
"commands-show-output": false,
"first-line-h1": false,
"header-increment": false,
"line-length": {
"code_blocks": false,
"tables": false,
"stern": true,
"line_length": -1
},
"no-bare-urls": false,
"no-blanks-blockquote": false,
"no-duplicate-header": {
"allow_different_nesting": true
},
"no-emphasis-as-header": false,
"no-hard-tabs": {
"code_blocks": false
},
"no-space-in-emphasis": false,
"no-trailing-punctuation": false,
"no-trailing-spaces": {
"br_spaces": 0
},
"single-h1": false
}

34
.travis.yml Normal file
View File

@@ -0,0 +1,34 @@
git:
depth: 10
notifications:
email: false
before_install:
- export BOTO_CONFIG=/dev/null
language: node_js
node_js:
- "4"
os:
- linux
- osx
env:
- TARGET_ARCH=x64
osx_image: xcode7.3
matrix:
include:
- os: linux
env: TARGET_ARCH=arm
- os: linux
env: TARGET_ARCH=ia32
- os: linux
env: TARGET_ARCH=arm64
allow_failures:
- os: osx
script: './script/cibuild'
branches:
only:
- master

1719
BUILD.gn

File diff suppressed because it is too large Load Diff

View File

@@ -1,135 +1,46 @@
# Code of Conduct
# Contributor Covenant Code of Conduct:
As a member project of the OpenJS Foundation, Electron uses [Contributor Covenant v2.0](https://contributor-covenant.org/version/2/0/code_of_conduct) as their code of conduct. The full text is included [below](#contributor-covenant-code-of-conduct) in English, and translations are available from the Contributor Covenant organisation:
## Our Pledge
* [contributor-covenant.org/translations](https://www.contributor-covenant.org/translations)
* [github.com/ContributorCovenant](https://github.com/ContributorCovenant/contributor_covenant/tree/release/content/version/2/0)
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
## Contributor Covenant Code of Conduct
## Our Standards
### Our Pledge
Examples of behavior that contributes to creating a positive environment include:
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
Examples of unacceptable behavior by participants include:
### Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
* Publishing others' private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting
### Enforcement Responsibilities
## Our Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
### Scope
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
### Enforcement
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
[coc@electronjs.org](mailto:coc@electronjs.org).
All complaints will be reviewed and investigated promptly and fairly.
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.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
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.
### Enforcement Guidelines
## Attribution
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
This Code of Conduct is adapted from the [Contributor-Covenant][homepage], version 1.4, available at [https://contributor-covenant.org/version/1/4][version]
#### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
#### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
#### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
#### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
### Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.
[homepage]: https://contributor-covenant.org
[version]: https://contributor-covenant.org/version/1/4/

View File

@@ -20,23 +20,13 @@ Issues are created [here](https://github.com/electron/electron/issues/new).
* [Triaging a Bug Report](https://electronjs.org/docs/development/issues#triaging-a-bug-report)
* [Resolving a Bug Report](https://electronjs.org/docs/development/issues#resolving-a-bug-report)
### Issue Closure
Bug reports will be closed if the issue has been inactive and the latest affected version no longer receives support. At the moment, Electron maintains its three latest major versions, with a new major version being released every 12 weeks. (For more information on Electron's release cadence, see [this blog post](https://electronjs.org/blog/12-week-cadence).)
_If an issue has been closed and you still feel it's relevant, feel free to ping a maintainer or add a comment!_
### Languages
We accept issues in *any* language.
When an issue is posted in a language besides English, it is acceptable and encouraged to post an English-translated copy as a reply.
Anyone may post the translated reply.
In most cases, a quick pass through translation software is sufficient.
Having the original text _as well as_ the translation can help mitigate translation errors.
Responses to posted issues may or may not be in the original language.
**Please note** that using non-English as an attempt to circumvent our [Code of Conduct](https://github.com/electron/electron/blob/master/CODE_OF_CONDUCT.md) will be an immediate, and possibly indefinite, ban from the project.
### Issue Maintenance and Closure
* If an issue is inactive for 45 days (no activity of any kind), it will be
marked for closure with `stale`.
* If after this label is applied, no further activity occurs in the next 7 days,
the issue will be closed.
* If an issue has been closed and you still feel it's relevant, feel free to
ping a maintainer or add a comment!
## [Pull Requests](https://electronjs.org/docs/development/pull-requests)
@@ -47,17 +37,17 @@ dependencies, and tools contained in the `electron/electron` repository.
* [Step 1: Fork](https://electronjs.org/docs/development/pull-requests#step-1-fork)
* [Step 2: Build](https://electronjs.org/docs/development/pull-requests#step-2-build)
* [Step 3: Branch](https://electronjs.org/docs/development/pull-requests#step-3-branch)
* [Making Changes](https://electronjs.org/docs/development/pull-requests#making-changes)
* [The Process of Making Changes](https://electronjs.org/docs/development/pull-requests#the-process-of-making-changes)
* [Step 4: Code](https://electronjs.org/docs/development/pull-requests#step-4-code)
* [Step 5: Commit](https://electronjs.org/docs/development/pull-requests#step-5-commit)
* [Commit message guidelines](https://electronjs.org/docs/development/pull-requests#commit-message-guidelines)
* [Step 6: Rebase](https://electronjs.org/docs/development/pull-requests#step-6-rebase)
* [Step 7: Test](https://electronjs.org/docs/development/pull-requests#step-7-test)
* [Step 8: Push](https://electronjs.org/docs/development/pull-requests#step-8-push)
* [Step 9: Opening the Pull Request](https://electronjs.org/docs/development/pull-requests#step-9-opening-the-pull-request)
* [Step 10: Discuss and Update](https://electronjs.org/docs/development/pull-requests#step-10-discuss-and-update)
* [Step 8: Opening the Pull Request](https://electronjs.org/docs/development/pull-requests#step-8-opening-the-pull-request)
* [Step 9: Discuss and Update](#step-9-discuss-and-update)
* [Approval and Request Changes Workflow](https://electronjs.org/docs/development/pull-requests#approval-and-request-changes-workflow)
* [Step 11: Landing](https://electronjs.org/docs/development/pull-requests#step-11-landing)
* [Step 10: Landing](https://electronjs.org/docs/development/pull-requests#step-10-landing)
* [Continuous Integration Testing](https://electronjs.org/docs/development/pull-requests#continuous-integration-testing)
## Style Guides
@@ -66,5 +56,5 @@ See [Coding Style](https://electronjs.org/docs/development/coding-style) for inf
## Further Reading
For more in-depth guides on developing Electron, see
[/docs/development](/docs/development/README.md)
For more in-depth guides on developing Electron, see
[/docs/development](/docs/development/README.md)

178
DEPS
View File

@@ -1,163 +1,73 @@
gclient_gn_args_file = 'src/build/config/gclient_args.gni'
gclient_gn_args = [
'build_with_chromium',
'checkout_android',
'checkout_android_native_support',
'checkout_libaom',
'checkout_nacl',
'checkout_pgo_profiles',
'checkout_oculus_sdk',
'checkout_openxr',
'checkout_google_benchmark',
'mac_xcode_version',
]
vars = {
'chromium_version':
'93.0.4536.0',
'63.0.3239.150',
'libchromiumcontent_revision':
'29e02cd4c37777734f97d00b5a538d7c7acfa67a',
'node_version':
'v14.17.0',
'nan_version':
'v2.14.2',
'squirrel.mac_version':
'cdc0729c8bf8576bfef18629186e1e9ecf1b0d9f',
'v9.7.0-33-g538a5023af',
'native_mate_revision':
'4cd7d113915de0cc08e9a218be35bff9c7361906',
'pyyaml_version': '3.12',
'chromium_git':
'https://chromium.googlesource.com',
'chromium_git': 'https://chromium.googlesource.com',
'electron_git': 'https://github.com/electron',
'nodejs_git': 'https://github.com/nodejs',
'yaml_git': 'https://github.com/yaml',
'squirrel_git': 'https://github.com/Squirrel',
# KEEP IN SYNC WITH utils.js FILE
'yarn_version': '1.15.2',
# To be able to build clean Chromium from sources.
'apply_patches': True,
# To use an mtime cache for patched files to speed up builds.
'use_mtime_cache': True,
# To allow in-house builds to checkout those manually.
'checkout_chromium': True,
'checkout_node': True,
'checkout_nan': True,
'checkout_pgo_profiles': True,
# It's only needed to parse the native tests configurations.
'checkout_pyyaml': False,
'use_rts': False,
'mac_xcode_version': 'default',
# To allow running hooks without parsing the DEPS tree
'process_deps': True,
'checkout_nacl':
False,
'checkout_libaom':
True,
'checkout_oculus_sdk':
False,
'checkout_openxr':
False,
'build_with_chromium':
True,
'checkout_android':
False,
'checkout_android_native_support':
False,
'checkout_google_benchmark':
False,
'checkout_clang_tidy':
True,
'electron_git':
'https://github.com/electron',
}
deps = {
'src': {
'url': (Var("chromium_git")) + '/chromium/src.git@' + (Var("chromium_version")),
'condition': 'checkout_chromium and process_deps',
},
'src/third_party/nan': {
'url': (Var("nodejs_git")) + '/nan.git@' + (Var("nan_version")),
'condition': 'checkout_nan and process_deps',
},
'src/third_party/electron_node': {
'url': (Var("nodejs_git")) + '/node.git@' + (Var("node_version")),
'condition': 'checkout_node and process_deps',
},
'src/third_party/pyyaml': {
'url': (Var("yaml_git")) + '/pyyaml.git@' + (Var("pyyaml_version")),
'condition': 'checkout_pyyaml and process_deps',
},
'src/third_party/squirrel.mac': {
'url': Var("squirrel_git") + '/Squirrel.Mac.git@' + Var("squirrel.mac_version"),
'condition': 'process_deps',
},
'src/third_party/squirrel.mac/vendor/ReactiveObjC': {
'url': 'https://github.com/ReactiveCocoa/ReactiveObjC.git@74ab5baccc6f7202c8ac69a8d1e152c29dc1ea76',
'condition': 'process_deps'
},
'src/third_party/squirrel.mac/vendor/Mantle': {
'url': 'https://github.com/Mantle/Mantle.git@78d3966b3c331292ea29ec38661b25df0a245948',
'condition': 'process_deps',
}
'src':
(Var("chromium_git")) + '/chromium/src.git@' + (Var("chromium_version")),
'src/libchromiumcontent':
(Var("electron_git")) + '/libchromiumcontent.git@' + (Var("libchromiumcontent_revision")),
'src/third_party/electron_node':
(Var("electron_git")) + '/node.git@' + (Var("node_version")),
'src/third_party/native_mate':
(Var("electron_git")) + '/native-mate.git@' + (Var("native_mate_revision")),
}
pre_deps_hooks = [
{
'name': 'generate_mtime_cache',
'condition': '(checkout_chromium and apply_patches and use_mtime_cache) and process_deps',
'pattern': 'src/electron',
'action': [
'python3',
'src/electron/script/patches-mtime-cache.py',
'generate',
'--cache-file',
'src/electron/patches/mtime-cache.json',
'--patches-config',
'src/electron/patches/config.json',
],
},
]
hooks = [
{
'name': 'patch_chromium',
'condition': '(checkout_chromium and apply_patches) and process_deps',
'pattern': 'src/electron',
'action': [
'python3',
'src/electron/script/apply_all_patches.py',
'src/electron/patches/config.json',
'src/libchromiumcontent/script/apply-patches'
],
'pattern':
'src/libchromiumcontent',
'name':
'patch_chromium'
},
{
'name': 'apply_mtime_cache',
'condition': '(checkout_chromium and apply_patches and use_mtime_cache) and process_deps',
'pattern': 'src/electron',
'action': [
'python3',
'src/electron/script/patches-mtime-cache.py',
'apply',
'--cache-file',
'src/electron/patches/mtime-cache.json',
'src/electron/script/update-external-binaries.py'
],
'pattern':
'src/electron/script/update-external-binaries.py',
'name':
'electron_external_binaries'
},
{
'name': 'electron_npm_deps',
'pattern': 'src/electron/package.json',
'action': [
'python3',
'bash',
'-c',
'import os, subprocess; os.chdir(os.path.join("src", "electron")); subprocess.check_call(["python3", "script/lib/npx.py", "yarn@' + (Var("yarn_version")) + '", "install", "--frozen-lockfile"]);',
# NOTE(nornagon): this ridiculous {{}} stuff is because these strings get
# variable-substituted twice by gclient.
'echo -e "#\\n{{{{\'variables\':{{{{}}}}}}}}" > src/third_party/electron_node/config.gypi',
],
'pattern': 'src/third_party/electron_node',
'name': 'touch_node_config_gypi'
},
{
'action': [
'bash',
'-c',
'cd src/electron; npm install',
],
'pattern': 'src/electron/package.json',
'name': 'electron_npm_deps'
},
]
recursedeps = [
'src',
'src/third_party/squirrel.mac',
'src/libchromiumcontent',
]

24
Dockerfile Normal file
View File

@@ -0,0 +1,24 @@
FROM electronbuilds/libchromiumcontent:0.0.4
USER root
# Set up HOME directory
ENV HOME=/home
RUN chmod a+rwx /home
# Install node.js
RUN curl -sL https://deb.nodesource.com/setup_10.x | bash -
RUN apt-get install -y nodejs
# Install wget used by crash reporter
RUN apt-get install -y wget
# Install python-dbusmock
RUN apt-get install -y python-dbusmock
# Install libnotify
RUN apt-get install -y libnotify-bin
# Add xvfb init script
ADD tools/xvfb-init.sh /etc/init.d/xvfb
RUN chmod a+x /etc/init.d/xvfb

35
Dockerfile.arm64 Normal file
View File

@@ -0,0 +1,35 @@
FROM multiarch/debian-debootstrap:arm64-jessie
RUN apt-get update && apt-get install -y\
bison \
build-essential \
clang \
curl \
gperf \
libasound2 \
libasound2-dev \
libcap-dev \
libcups2-dev \
libdbus-1-dev \
libgconf-2-4 \
libgconf2-dev \
libgnome-keyring-dev \
libgtk-3-0 \
libgtk-3-dev \
libnotify-bin \
libnotify-dev \
libnss3 \
libnss3-dev \
libx11-xcb-dev \
libxss1 \
libxtst-dev \
libxtst6 \
python-dbusmock \
wget \
xvfb
ADD tools/xvfb-init.sh /etc/init.d/xvfb
RUN chmod a+x /etc/init.d/xvfb
ADD tools/run-electron.sh /run-electron.sh
RUN chmod a+x /run-electron.sh
CMD sh /run-electron.sh

63
Dockerfile.arm64v8 Normal file
View File

@@ -0,0 +1,63 @@
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 \
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

36
Dockerfile.armv7 Normal file
View File

@@ -0,0 +1,36 @@
FROM multiarch/debian-debootstrap:armhf-jessie
RUN apt-get update && apt-get install -y\
bison \
build-essential \
clang \
curl \
gperf \
libasound2 \
libasound2-dev \
libcap-dev \
libcups2-dev \
libdbus-1-dev \
libgconf-2-4 \
libgconf2-dev \
libgnome-keyring-dev \
libgtk-3-0 \
libgtk-3-dev \
libnotify-bin \
libnotify-dev \
libnss3 \
libnss3-dev \
libx11-xcb-dev \
libxss1 \
libxtst-dev \
libxtst6 \
python-dbusmock \
git \
wget \
xvfb
ADD tools/xvfb-init.sh /etc/init.d/xvfb
RUN chmod a+x /etc/init.d/xvfb
ADD tools/run-electron.sh /run-electron.sh
RUN chmod a+x /run-electron.sh
CMD sh /run-electron.sh

23
Dockerfile.circleci Normal file
View File

@@ -0,0 +1,23 @@
FROM electronbuilds/libchromiumcontent:0.0.4
USER root
# Install node.js
RUN curl -sL https://deb.nodesource.com/setup_10.x | bash -
RUN apt-get install -y nodejs
# Install wget used by crash reporter
RUN apt-get install -y wget
# Install python-dbusmock
RUN apt-get install -y python-dbusmock
# Install libnotify
RUN apt-get install -y libnotify-bin
# Add xvfb init script
ADD tools/xvfb-init.sh /etc/init.d/xvfb
RUN chmod a+x /etc/init.d/xvfb
USER builduser
WORKDIR /home/builduser

View File

@@ -1 +0,0 @@
15.0.0-nightly.20210609

View File

@@ -1,5 +1,4 @@
Copyright (c) Electron contributors
Copyright (c) 2013-2020 GitHub Inc.
Copyright (c) 2013-2018 GitHub Inc.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the

View File

@@ -1,10 +1,12 @@
[![Electron Logo](https://electronjs.org/images/electron-logo.svg)](https://electronjs.org)
[![CircleCI Build Status](https://circleci.com/gh/electron/electron/tree/master.svg?style=shield)](https://circleci.com/gh/electron/electron/tree/master)
[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/4lggi9dpjc1qob7k/branch/master?svg=true)](https://ci.appveyor.com/project/electron-bot/electron-ljo26/branch/master)
[![Electron Discord Invite](https://img.shields.io/discord/745037351163527189?color=%237289DA&label=chat&logo=discord&logoColor=white)](https://discord.com/invite/electron)
:memo: Available Translations: 🇨🇳 🇧🇷 🇪🇸 🇯🇵 🇷🇺 🇫🇷 🇺🇸 🇩🇪.
[![CircleCI Build Status](https://circleci.com/gh/electron/electron/tree/master.svg?style=shield)](https://circleci.com/gh/electron/electron/tree/master)
[![AppVeyor Build Status](https://windows-ci.electronjs.org/api/projects/status/nilyf07hcef14dvj/branch/master?svg=true)](https://windows-ci.electronjs.org/project/AppVeyor/electron/branch/master)
[![devDependency Status](https://david-dm.org/electron/electron/dev-status.svg)](https://david-dm.org/electron/electron?type=dev)
[![Join the Electron Community on Slack](https://atom-slack.herokuapp.com/badge.svg)](https://atom-slack.herokuapp.com/)
:memo: Available Translations: 🇨🇳 🇹🇼 🇧🇷 🇪🇸 🇰🇷 🇯🇵 🇷🇺 🇫🇷 🇹🇭 🇳🇱 🇹🇷 🇮🇩 🇺🇦 🇨🇿 🇮🇹.
View these docs in other languages at [electron/i18n](https://github.com/electron/i18n/tree/master/content/).
The Electron framework lets you write cross-platform desktop applications
@@ -27,21 +29,19 @@ The preferred method is to install Electron as a development dependency in your
app:
```sh
npm install electron --save-dev
npm install electron --save-dev [--save-exact]
```
For more installation options and troubleshooting tips, see
[installation](docs/tutorial/installation.md). For info on how to manage Electron versions in your apps, see
The `--save-exact` flag is recommended for Electron prior to version 2, as it does not follow semantic
versioning. As of version 2.0.0, Electron follows semver, so you don't need `--save-exact` flag. For info on how to manage Electron versions in your apps, see
[Electron versioning](docs/tutorial/electron-versioning.md).
## Quick start & Electron Fiddle
For more installation options and troubleshooting tips, see
[installation](docs/tutorial/installation.md).
Use [`Electron Fiddle`](https://github.com/electron/fiddle)
to build, run, and package small Electron experiments, to see code examples for all of Electron's APIs, and
to try out different versions of Electron. It's designed to make the start of your journey with
Electron easier.
## Quick start
Alternatively, clone and run the
Clone and run the
[electron/electron-quick-start](https://github.com/electron/electron-quick-start)
repository to see a minimal Electron app in action:
@@ -54,13 +54,12 @@ npm start
## Resources for learning Electron
- [electronjs.org/docs](https://electronjs.org/docs) - All of Electron's documentation
- [electron/fiddle](https://github.com/electron/fiddle) - A tool to build, run, and package small Electron experiments
- [electron/electron-quick-start](https://github.com/electron/electron-quick-start) - A very basic starter Electron app
- [electronjs.org/community#boilerplates](https://electronjs.org/community#boilerplates) - Sample starter apps created by the community
- [electron/simple-samples](https://github.com/electron/simple-samples) - Small applications with ideas for taking them further
- [electron/electron-api-demos](https://github.com/electron/electron-api-demos) - An Electron app that teaches you how to use Electron
- [hokein/electron-sample-apps](https://github.com/hokein/electron-sample-apps) - Small demo apps for the various Electron APIs
- [electronjs.org/docs](https://electronjs.org/docs) - all of Electron's documentation
- [electron/electron-quick-start](https://github.com/electron/electron-quick-start) - a very basic starter Electron app
- [electronjs.org/community#boilerplates](https://electronjs.org/community#boilerplates) - sample starter apps created by the community
- [electron/simple-samples](https://github.com/electron/simple-samples) - small applications with ideas for taking them further
- [electron/electron-api-demos](https://github.com/electron/electron-api-demos) - an Electron app that teaches you how to use Electron
- [hokein/electron-sample-apps](https://github.com/hokein/electron-sample-apps) - small demo apps for the various Electron APIs
## Programmatic usage
@@ -87,10 +86,6 @@ const child = proc.spawn(electron)
Find documentation translations in [electron/i18n](https://github.com/electron/i18n).
## Contributing
If you are interested in reporting/fixing issues and contributing directly to the code base, please see [CONTRIBUTING.md](CONTRIBUTING.md) for more information on what we're looking for and how to get started.
## Community
Info on reporting bugs, getting help, finding third-party tools and sample apps,

View File

@@ -6,12 +6,7 @@ To report a security issue, email [security@electronjs.org](mailto:security@elec
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.
Report security bugs in third-party modules to the person or team maintaining the module. You can also report a vulnerability through the [npm contact form](https://www.npmjs.com/support) by selecting "I'm reporting a security vulnerability".
## The Electron Security Notification Process
For context on Electron's security notification process, please see the [Notifications](https://github.com/electron/governance/blob/master/wg-security/membership-and-notifications.md#notifications) section of the Security WG's [Membership and Notifications](https://github.com/electron/governance/blob/master/wg-security/membership-and-notifications.md) Governance document.
Report security bugs in third-party modules to the person or team maintaining the module. You can also report a vulnerability through the [Node Security Project](https://nodesecurity.io/report).
## Learning More About Security
To learn more about securing an Electron application, please see the [security tutorial](docs/tutorial/security.md).

View File

@@ -1,233 +1,73 @@
# The config expects the following environment variables to be set:
# - "GN_CONFIG" Build type. One of {'testing', 'release'}.
# - "GN_EXTRA_ARGS" Additional gn arguments for a build config,
# e.g. 'target_cpu="x86"' to build for a 32bit platform.
# https://gn.googlesource.com/gn/+/master/docs/reference.md#target_cpu
# Don't forget to set up "NPM_CONFIG_ARCH" and "TARGET_ARCH" accordningly
# if you pass a custom value for 'target_cpu'.
# - "ELECTRON_RELEASE" Set it to '1' upload binaries on success.
# - "NPM_CONFIG_ARCH" E.g. 'x86'. Is used to build native Node.js modules.
# Must match 'target_cpu' passed to "GN_EXTRA_ARGS" and "TARGET_ARCH" value.
# - "TARGET_ARCH" Choose from {'ia32', 'x64', 'arm', 'arm64', 'mips64el'}.
# Is used in some publishing scripts, but does NOT affect the Electron binary.
# Must match 'target_cpu' passed to "GN_EXTRA_ARGS" and "NPM_CONFIG_ARCH" value.
# - "UPLOAD_TO_S3" Set it to '1' upload a release to the S3 bucket.
# Otherwise the release will be uploaded to the Github Releases.
# (The value is only checked if "ELECTRON_RELEASE" is defined.)
#
# The publishing scripts expect access tokens to be defined as env vars,
# but those are not covered here.
#
# AppVeyor docs on variables:
# https://www.appveyor.com/docs/environment-variables/
# https://www.appveyor.com/docs/build-configuration/#secure-variables
# https://www.appveyor.com/docs/build-configuration/#custom-environment-variables
# Uncomment these lines to enable RDP
#on_finish:
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
version: 1.0.{build}
build_cloud: electron-16-core
image: vs2019bt-16.6.2
environment:
GIT_CACHE_PATH: C:\Users\electron\libcc_cache
ELECTRON_OUT_DIR: Default
ELECTRON_ENABLE_STACK_DUMPING: 1
MOCHA_REPORTER: mocha-multi-reporters
MOCHA_MULTI_REPORTERS: mocha-appveyor-reporter, tap
GOMA_FALLBACK_ON_AUTH_FAILURE: true
notifications:
- provider: Webhook
url: https://electron-mission-control.herokuapp.com/rest/appveyor-hook
method: POST
headers:
x-mission-control-secret:
secure: 90BLVPcqhJPG7d24v0q/RRray6W3wDQ8uVQlQjOHaBWkw1i8FoA1lsjr2C/v1dVok+tS2Pi6KxDctPUkwIb4T27u4RhvmcPzQhVpfwVJAG9oNtq+yKN7vzHfg7k/pojEzVdJpQLzeJGcSrZu7VY39Q==
on_build_success: false
on_build_failure: true
on_build_status_changed: false
build_cloud: electron-16
image: electron-16-vs2017-15.4.5
build_script:
- ps: >-
if(($env:APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME -split "/")[0] -eq ($env:APPVEYOR_REPO_NAME -split "/")[0]) {
Write-warning "Skipping PR build for branch"; Exit-AppveyorBuild
} else {
node script/yarn.js install --frozen-lockfile
- ps: >-
echo "Build worker image $env:APPVEYOR_BUILD_WORKER_IMAGE"
$result = node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER --prBranch=$env:APPVEYOR_REPO_BRANCH
Write-Output $result
if ($result.ExitCode -eq 0) {
Write-warning "Skipping build for doc only change"; Exit-AppveyorBuild
}
&"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"
if($env:SKIP_GYP_BUILD -eq "true") {
Write-warning "Skipping debug build for older branch"; Exit-AppveyorBuild
} elseif(($env:APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME -split "/")[0] -eq ($env:APPVEYOR_REPO_NAME -split "/")[0]) {
Write-warning "Skipping PR build for branch"; Exit-AppveyorBuild
} else {
Add-Path "$env:ProgramFiles (x86)\Windows Kits\10\Debuggers\x64"
$env:path = "$env:ProgramFiles (x86)\Windows Kits\10\Debuggers\x64;$env:path"
if($env:APPVEYOR_SCHEDULED_BUILD -eq 'True') {
$env:RUN_RELEASE_BUILD = "1"
}
- echo "Building $env:GN_CONFIG build"
- git config --global core.longpaths true
- cd ..
- mkdir src
- update_depot_tools.bat
- ps: Move-Item $env:APPVEYOR_BUILD_FOLDER -Destination src\electron
- ps: $env:CHROMIUM_BUILDTOOLS_PATH="$pwd\src\buildtools"
- ps: >-
if ($env:GN_CONFIG -ne 'release') {
$env:NINJA_STATUS="[%r processes, %f/%t @ %o/s : %es] "
$Message = (git log --format=%B -n 1 HEAD) | Out-String
if ((Test-Path Env:\RUN_RELEASE_BUILD)) {
$env:ELECTRON_RELEASE = '1'
Write-Output "release build triggered from api"
}
- >-
gclient config
--name "src\electron"
--unmanaged
%GCLIENT_EXTRA_ARGS%
"https://github.com/electron/electron"
- ps: >-
if ($env:GN_CONFIG -eq 'release') {
$env:RUN_GCLIENT_SYNC="true"
if ((Test-Path Env:\ELECTRON_RELEASE)) {
Write-Output "Running release build"
python script\bootstrap.py --target_arch=$env:TARGET_ARCH
python script\build.py -c R
python script\create-dist.py
} else {
cd src\electron
node script\generate-deps-hash.js
$depshash = Get-Content .\.depshash -Raw
$zipfile = "Z:\$depshash.7z"
cd ..\..
if (Test-Path -Path $zipfile) {
# file exists, unzip and then gclient sync
7z x -y $zipfile -mmt=30 -aoa
if (-not (Test-Path -Path "src\buildtools")) {
# the zip file must be corrupt - resync
$env:RUN_GCLIENT_SYNC="true"
if ($env:TARGET_ARCH -ne 'ia32') {
# only save on x64/woa to avoid contention saving
$env:SAVE_GCLIENT_SRC="true"
}
} else {
# update angle
cd src\third_party\angle
git remote set-url origin https://chromium.googlesource.com/angle/angle.git
git fetch
cd ..\..\..
}
} else {
# file does not exist, gclient sync, then zip
$env:RUN_GCLIENT_SYNC="true"
if ($env:TARGET_ARCH -ne 'ia32') {
# only save on x64/woa to avoid contention saving
$env:SAVE_GCLIENT_SRC="true"
}
}
Write-Output "Running debug build"
python script\bootstrap.py --target_arch=$env:TARGET_ARCH --dev
python script\build.py -c D
}
- if "%RUN_GCLIENT_SYNC%"=="true" ( gclient sync --with_branch_heads --with_tags --ignore_locks)
- ps: >-
if ($env:SAVE_GCLIENT_SRC -eq 'true') {
# archive current source for future use
# only run on x64/woa to avoid contention saving
$(7z a $zipfile src -xr!android_webview -xr!electron -xr'!*\.git' -xr!third_party\WebKit\LayoutTests! -xr!third_party\blink\web_tests -xr!third_party\blink\perf_tests -slp -t7z -mmt=30)
if ($LASTEXITCODE -ne 0) {
Write-warning "Could not save source to shared drive; continuing anyway"
}
# build time generation of file gen/angle/angle_commit.h depends on
# third_party/angle/.git
# https://chromium-review.googlesource.com/c/angle/angle/+/2074924
$(7z a $zipfile src\third_party\angle\.git)
if ($LASTEXITCODE -ne 0) {
Write-warning "Failed to add third_party\angle\.git; continuing anyway"
}
}
- ps: >-
if (Test-Path 'env:RAW_GOMA_AUTH') {
$env:GOMA_OAUTH2_CONFIG_FILE = "$pwd\.goma_oauth2_config"
$env:RAW_GOMA_AUTH | Set-Content $env:GOMA_OAUTH2_CONFIG_FILE
}
- git clone https://github.com/electron/build-tools.git
- cd build-tools
- npm install
- mkdir third_party
- ps: >-
node -e "require('./src/utils/goma.js').downloadAndPrepare({ gomaOneForAll: true })"
- ps: $env:GN_GOMA_FILE = node -e "console.log(require('./src/utils/goma.js').gnFilePath)"
- ps: $env:LOCAL_GOMA_DIR = node -e "console.log(require('./src/utils/goma.js').dir)"
- cd ..
- ps: .\src\electron\script\start-goma.ps1 -gomaDir $env:LOCAL_GOMA_DIR
- cd src
- set BUILD_CONFIG_PATH=//electron/build/args/%GN_CONFIG%.gn
- gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") import(\"%GN_GOMA_FILE%\") %GN_EXTRA_ARGS% "
- gn check out/Default //electron:electron_lib
- gn check out/Default //electron:electron_app
- gn check out/Default //electron/shell/common/api:mojo
- if DEFINED GN_GOMA_FILE (ninja -j 300 -C out/Default electron:electron_app) else (ninja -C out/Default electron:electron_app)
- if "%GN_CONFIG%"=="testing" ( python C:\depot_tools\post_build_ninja_summary.py -C out\Default )
- gn gen out/ffmpeg "--args=import(\"//electron/build/args/ffmpeg.gn\") %GN_EXTRA_ARGS%"
- ninja -C out/ffmpeg electron:electron_ffmpeg_zip
- ninja -C out/Default electron:electron_dist_zip
- ninja -C out/Default shell_browser_ui_unittests
- gn desc out/Default v8:run_mksnapshot_default args > out/Default/mksnapshot_args
- ninja -C out/Default electron:electron_mksnapshot_zip
- cd out\Default
- 7z a mksnapshot.zip mksnapshot_args gen\v8\embedded.S
- cd ..\..
- ninja -C out/Default electron:hunspell_dictionaries_zip
- ninja -C out/Default electron:electron_chromedriver_zip
- ninja -C out/Default third_party/electron_node:headers
- python %LOCAL_GOMA_DIR%\goma_ctl.py stat
- python electron/build/profile_toolchain.py --output-json=out/Default/windows_toolchain_profile.json
- appveyor PushArtifact out/Default/windows_toolchain_profile.json
- appveyor PushArtifact out/Default/dist.zip
- appveyor PushArtifact out/Default/shell_browser_ui_unittests.exe
- appveyor PushArtifact out/Default/chromedriver.zip
- appveyor PushArtifact out/ffmpeg/ffmpeg.zip
- 7z a node_headers.zip out\Default\gen\node_headers
- appveyor PushArtifact node_headers.zip
- appveyor PushArtifact out/Default/mksnapshot.zip
- appveyor PushArtifact out/Default/hunspell_dictionaries.zip
- appveyor PushArtifact out/Default/electron.lib
- ps: >-
if ($env:GN_CONFIG -eq 'release') {
# Needed for msdia140.dll on 64-bit windows
$env:Path += ";$pwd\third_party\llvm-build\Release+Asserts\bin"
ninja -C out/Default electron:electron_symbols
}
- ps: >-
if ($env:GN_CONFIG -eq 'release') {
python electron\script\zip-symbols.py
appveyor-retry appveyor PushArtifact out/Default/symbols.zip
if ($? -ne 'True') {
throw "Build failed with exit code $?"
} else {
# It's useful to have pdb files when debugging testing builds that are
# built on CI.
7z a pdb.zip out\Default\*.pdb
appveyor-retry appveyor PushArtifact pdb.zip
"Build succeeded."
}
- python electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.win.%TARGET_ARCH%.manifest
Push-AppveyorArtifact out
}
test_script:
# Workaround for https://github.com/appveyor/ci/issues/2420
- set "PATH=%PATH%;C:\Program Files\Git\mingw64\libexec\git-core"
- ps: >-
if ((-Not (Test-Path Env:\TEST_WOA)) -And (-Not (Test-Path Env:\ELECTRON_RELEASE)) -And ($env:GN_CONFIG -in "testing", "release")) {
$env:RUN_TESTS="true"
}
- ps: >-
if ($env:RUN_TESTS -eq 'true') {
New-Item .\out\Default\gen\node_headers\Release -Type directory
Copy-Item -path .\out\Default\electron.lib -destination .\out\Default\gen\node_headers\Release\node.lib
- ps: >-
if (Test-Path Env:\ELECTRON_RELEASE) {
Write-Output "Skipping tests for release build"
} else {
Write-Output "Running tests for debug build"
python script\test.py --ci --rebuild_native_modules
if ($LASTEXITCODE -ne '0') {
throw "Tests failed with exit code $LASTEXITCODE"
} else {
echo "Skipping tests for $env:GN_CONFIG build"
Write-Output "Tests succeeded."
}
- cd electron
# CalculateNativeWinOcclusion is disabled due to https://bugs.chromium.org/p/chromium/issues/detail?id=1139022
- if "%RUN_TESTS%"=="true" ( echo Running test suite & node script/yarn test -- --trace-uncaught --enable-logging --disable-features=CalculateNativeWinOcclusion )
- cd ..
- if "%RUN_TESTS%"=="true" ( echo Verifying non proprietary ffmpeg & python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg )
- echo "About to verify mksnapshot"
- if "%RUN_TESTS%"=="true" ( echo Verifying mksnapshot & python electron\script\verify-mksnapshot.py --build-dir out\Default --source-root %cd% )
- echo "Done verifying mksnapshot"
- if "%RUN_TESTS%"=="true" ( echo Verifying chromedriver & python electron\script\verify-chromedriver.py --build-dir out\Default --source-root %cd% )
- echo "Done verifying chromedriver"
python script\verify-ffmpeg.py
if ($LASTEXITCODE -ne '0') {
throw "Verify ffmpeg failed with exit code $LASTEXITCODE"
} else {
"Verify ffmpeg succeeded."
}
}
artifacts:
- path: test-results.xml
name: test-results.xml
deploy_script:
- cd electron
- ps: >-
if (Test-Path Env:\ELECTRON_RELEASE) {
if (Test-Path Env:\UPLOAD_TO_S3) {
Write-Output "Uploading Electron release distribution to s3"
& python script\release\uploaders\upload.py --verbose --upload_to_s3
} else {
Write-Output "Uploading Electron release distribution to github releases"
& python script\release\uploaders\upload.py --verbose
}
} elseif (Test-Path Env:\TEST_WOA) {
node script/release/ci-release-build.js --job=electron-woa-testing --ci=VSTS --armTest --appveyorJobId=$env:APPVEYOR_JOB_ID $env:APPVEYOR_REPO_BRANCH
- ps: >-
if (Test-Path Env:\ELECTRON_RELEASE) {
if (Test-Path Env:\RUN_RELEASE_BUILD) {
Write-Output "Uploading Electron release distribution to s3"
& python script\upload.py --upload_to_s3
} else {
Write-Output "Uploading Electron release distribution to github releases"
& python script\upload.py
}
}

View File

@@ -0,0 +1,266 @@
// Copyright (c) 2014 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/app/atom_content_client.h"
#include <string>
#include <vector>
#include "atom/common/atom_version.h"
#include "atom/common/chrome_version.h"
#include "atom/common/options_switches.h"
#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/pepper_plugin_info.h"
#include "content/public/common/user_agent.h"
#include "media/media_features.h"
#include "ppapi/shared_impl/ppapi_permissions.h"
#include "third_party/widevine/cdm/widevine_cdm_common.h"
#include "ui/base/l10n/l10n_util.h"
#include "url/url_constants.h"
#if defined(WIDEVINE_CDM_AVAILABLE)
#include "base/native_library.h"
#include "base/strings/stringprintf.h"
#include "chrome/common/widevine_cdm_constants.h"
#include "content/public/common/cdm_info.h"
#include "media/base/video_codecs.h"
#endif // defined(WIDEVINE_CDM_AVAILABLE)
#if defined(ENABLE_PDF_VIEWER)
#include "atom/common/atom_constants.h"
#include "pdf/pdf.h"
#endif // defined(ENABLE_PDF_VIEWER)
namespace atom {
namespace {
#if defined(WIDEVINE_CDM_AVAILABLE)
bool IsWidevineAvailable(base::FilePath* adapter_path,
base::FilePath* cdm_path,
std::vector<media::VideoCodec>* codecs_supported) {
static enum {
NOT_CHECKED,
FOUND,
NOT_FOUND,
} widevine_cdm_file_check = NOT_CHECKED;
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
*adapter_path = command_line->GetSwitchValuePath(switches::kWidevineCdmPath);
if (!adapter_path->empty()) {
*cdm_path = adapter_path->DirName().AppendASCII(
base::GetNativeLibraryName(kWidevineCdmLibraryName));
if (widevine_cdm_file_check == NOT_CHECKED) {
widevine_cdm_file_check =
(base::PathExists(*adapter_path) && base::PathExists(*cdm_path))
? FOUND
: NOT_FOUND;
}
if (widevine_cdm_file_check == FOUND) {
// Add the supported codecs as if they came from the component manifest.
// This list must match the CDM that is being bundled with Chrome.
codecs_supported->push_back(media::VideoCodec::kCodecVP8);
codecs_supported->push_back(media::VideoCodec::kCodecVP9);
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
codecs_supported->push_back(media::VideoCodec::kCodecH264);
#endif // BUILDFLAG(USE_PROPRIETARY_CODECS)
return true;
}
}
return false;
}
void AddWidevineAdapterFromCommandLine(
base::CommandLine* command_line,
std::vector<content::PepperPluginInfo>* plugins) {
base::FilePath adapter_path;
base::FilePath cdm_path;
std::vector<media::VideoCodec> video_codecs_supported;
if (IsWidevineAvailable(&adapter_path, &cdm_path, &video_codecs_supported)) {
auto cdm_version_string =
command_line->GetSwitchValueASCII(switches::kWidevineCdmVersion);
content::PepperPluginInfo info;
info.is_out_of_process = true;
info.path = adapter_path;
info.name = kWidevineCdmDisplayName;
info.description =
base::StringPrintf("%s (version: %s)", kWidevineCdmDescription,
cdm_version_string.c_str());
info.version = cdm_version_string;
info.permissions = kWidevineCdmPluginPermissions;
content::WebPluginMimeType mime_type(kWidevineCdmPluginMimeType,
kWidevineCdmPluginExtension,
kWidevineCdmPluginMimeTypeDescription);
info.mime_types.push_back(mime_type);
plugins->push_back(info);
}
}
#endif // defined(WIDEVINE_CDM_AVAILABLE)
#if defined(ENABLE_PEPPER_FLASH)
content::PepperPluginInfo CreatePepperFlashInfo(const base::FilePath& path,
const std::string& version) {
content::PepperPluginInfo plugin;
plugin.is_out_of_process = true;
plugin.name = content::kFlashPluginName;
plugin.path = path;
plugin.permissions = ppapi::PERMISSION_ALL_BITS;
std::vector<std::string> flash_version_numbers = base::SplitString(
version, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
if (flash_version_numbers.empty())
flash_version_numbers.push_back("11");
// |SplitString()| puts in an empty string given an empty string. :(
else if (flash_version_numbers[0].empty())
flash_version_numbers[0] = "11";
if (flash_version_numbers.size() < 2)
flash_version_numbers.push_back("2");
if (flash_version_numbers.size() < 3)
flash_version_numbers.push_back("999");
if (flash_version_numbers.size() < 4)
flash_version_numbers.push_back("999");
// E.g., "Shockwave Flash 10.2 r154":
plugin.description = plugin.name + " " + flash_version_numbers[0] + "." +
flash_version_numbers[1] + " r" +
flash_version_numbers[2];
plugin.version = base::JoinString(flash_version_numbers, ".");
content::WebPluginMimeType swf_mime_type(content::kFlashPluginSwfMimeType,
content::kFlashPluginSwfExtension,
content::kFlashPluginSwfDescription);
plugin.mime_types.push_back(swf_mime_type);
content::WebPluginMimeType spl_mime_type(content::kFlashPluginSplMimeType,
content::kFlashPluginSplExtension,
content::kFlashPluginSplDescription);
plugin.mime_types.push_back(spl_mime_type);
return plugin;
}
void AddPepperFlashFromCommandLine(
base::CommandLine* command_line,
std::vector<content::PepperPluginInfo>* plugins) {
base::FilePath flash_path =
command_line->GetSwitchValuePath(switches::kPpapiFlashPath);
if (flash_path.empty())
return;
auto flash_version =
command_line->GetSwitchValueASCII(switches::kPpapiFlashVersion);
plugins->push_back(CreatePepperFlashInfo(flash_path, flash_version));
}
#endif // defined(ENABLE_PEPPER_FLASH)
void ComputeBuiltInPlugins(std::vector<content::PepperPluginInfo>* plugins) {
#if defined(ENABLE_PDF_VIEWER)
content::PepperPluginInfo pdf_info;
pdf_info.is_internal = true;
pdf_info.is_out_of_process = true;
pdf_info.name = "Chromium PDF Viewer";
pdf_info.description = "Portable Document Format";
pdf_info.path = base::FilePath::FromUTF8Unsafe(kPdfPluginPath);
content::WebPluginMimeType pdf_mime_type(kPdfPluginMimeType, "pdf",
"Portable Document Format");
pdf_info.mime_types.push_back(pdf_mime_type);
pdf_info.internal_entry_points.get_interface = chrome_pdf::PPP_GetInterface;
pdf_info.internal_entry_points.initialize_module =
chrome_pdf::PPP_InitializeModule;
pdf_info.internal_entry_points.shutdown_module =
chrome_pdf::PPP_ShutdownModule;
pdf_info.permissions = ppapi::PERMISSION_PRIVATE | ppapi::PERMISSION_DEV;
plugins->push_back(pdf_info);
#endif // defined(ENABLE_PDF_VIEWER)
}
void ConvertStringWithSeparatorToVector(std::vector<std::string>* vec,
const char* separator,
const char* cmd_switch) {
auto* command_line = base::CommandLine::ForCurrentProcess();
auto string_with_separator = command_line->GetSwitchValueASCII(cmd_switch);
if (!string_with_separator.empty())
*vec = base::SplitString(string_with_separator, separator,
base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
}
} // namespace
AtomContentClient::AtomContentClient() {}
AtomContentClient::~AtomContentClient() {}
std::string AtomContentClient::GetProduct() const {
return "Chrome/" CHROME_VERSION_STRING;
}
std::string AtomContentClient::GetUserAgent() const {
return content::BuildUserAgentFromProduct("Chrome/" CHROME_VERSION_STRING
" " ATOM_PRODUCT_NAME
"/" ATOM_VERSION_STRING);
}
base::string16 AtomContentClient::GetLocalizedString(int message_id) const {
return l10n_util::GetStringUTF16(message_id);
}
void AtomContentClient::AddAdditionalSchemes(Schemes* schemes) {
schemes->standard_schemes.push_back("chrome-extension");
std::vector<std::string> splited;
ConvertStringWithSeparatorToVector(&splited, ",",
switches::kRegisterServiceWorkerSchemes);
for (const std::string& scheme : splited)
schemes->service_worker_schemes.push_back(scheme);
schemes->service_worker_schemes.push_back(url::kFileScheme);
ConvertStringWithSeparatorToVector(&splited, ",", switches::kSecureSchemes);
for (const std::string& scheme : splited)
schemes->secure_schemes.push_back(scheme);
}
void AtomContentClient::AddPepperPlugins(
std::vector<content::PepperPluginInfo>* plugins) {
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
#if defined(ENABLE_PEPPER_FLASH)
AddPepperFlashFromCommandLine(command_line, plugins);
#endif // defined(ENABLE_PEPPER_FLASH)
#if defined(WIDEVINE_CDM_AVAILABLE)
AddWidevineAdapterFromCommandLine(command_line, plugins);
#endif // defined(WIDEVINE_CDM_AVAILABLE)
ComputeBuiltInPlugins(plugins);
}
void AtomContentClient::AddContentDecryptionModules(
std::vector<content::CdmInfo>* cdms,
std::vector<media::CdmHostFilePath>* cdm_host_file_paths) {
if (cdms) {
#if defined(WIDEVINE_CDM_AVAILABLE)
base::FilePath adapter_path;
base::FilePath cdm_path;
std::vector<media::VideoCodec> video_codecs_supported;
bool supports_persistent_license = false;
if (IsWidevineAvailable(&adapter_path, &cdm_path,
&video_codecs_supported)) {
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
auto cdm_version_string =
command_line->GetSwitchValueASCII(switches::kWidevineCdmVersion);
// CdmInfo needs |path| to be the actual Widevine library,
// not the adapter, so adjust as necessary. It will be in the
// same directory as the installed adapter.
const base::Version version(cdm_version_string);
DCHECK(version.IsValid());
cdms->push_back(content::CdmInfo(
kWidevineCdmDisplayName, kWidevineCdmGuid, version, cdm_path,
kWidevineCdmFileSystemId, video_codecs_supported,
supports_persistent_license, kWidevineKeySystem, false));
}
#endif // defined(WIDEVINE_CDM_AVAILABLE)
}
}
} // namespace atom

View File

@@ -0,0 +1,39 @@
// Copyright (c) 2014 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_APP_ATOM_CONTENT_CLIENT_H_
#define ATOM_APP_ATOM_CONTENT_CLIENT_H_
#include <set>
#include <string>
#include <vector>
#include "brightray/common/content_client.h"
namespace atom {
class AtomContentClient : public brightray::ContentClient {
public:
AtomContentClient();
~AtomContentClient() override;
protected:
// content::ContentClient:
std::string GetProduct() const override;
std::string GetUserAgent() const override;
base::string16 GetLocalizedString(int message_id) const override;
void AddAdditionalSchemes(Schemes* schemes) override;
void AddPepperPlugins(
std::vector<content::PepperPluginInfo>* plugins) override;
void AddContentDecryptionModules(
std::vector<content::CdmInfo>* cdms,
std::vector<media::CdmHostFilePath>* cdm_host_file_paths) override;
private:
DISALLOW_COPY_AND_ASSIGN(AtomContentClient);
};
} // namespace atom
#endif // ATOM_APP_ATOM_CONTENT_CLIENT_H_

View File

@@ -0,0 +1,22 @@
// Copyright (c) 2013 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_APP_ATOM_LIBRARY_MAIN_H_
#define ATOM_APP_ATOM_LIBRARY_MAIN_H_
#include "build/build_config.h"
#if defined(OS_MACOSX)
extern "C" {
__attribute__((visibility("default"))) int AtomMain(int argc, char* argv[]);
#ifdef ENABLE_RUN_AS_NODE
__attribute__((visibility("default"))) int AtomInitializeICUandStartNode(
int argc,
char* argv[]);
#endif
}
#endif // OS_MACOSX
#endif // ATOM_APP_ATOM_LIBRARY_MAIN_H_

View File

@@ -0,0 +1,38 @@
// Copyright (c) 2013 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/app/atom_library_main.h"
#include "atom/app/atom_main_delegate.h"
#include "atom/app/node_main.h"
#include "atom/common/atom_command_line.h"
#include "base/at_exit.h"
#include "base/i18n/icu_util.h"
#include "base/mac/bundle_locations.h"
#include "base/mac/scoped_nsautorelease_pool.h"
#include "brightray/common/mac/main_application_bundle.h"
#include "content/public/app/content_main.h"
int AtomMain(int argc, char* argv[]) {
atom::AtomMainDelegate delegate;
content::ContentMainParams params(&delegate);
params.argc = argc;
params.argv = const_cast<const char**>(argv);
atom::AtomCommandLine::Init(argc, argv);
return content::ContentMain(params);
}
#ifdef ENABLE_RUN_AS_NODE
int AtomInitializeICUandStartNode(int argc, char* argv[]) {
base::AtExitManager atexit_manager;
base::mac::ScopedNSAutoreleasePool pool;
base::mac::SetOverrideFrameworkBundlePath(
brightray::MainApplicationBundlePath()
.Append("Contents")
.Append("Frameworks")
.Append(ATOM_PRODUCT_NAME " Framework.framework"));
base::i18n::InitializeICU();
return atom::NodeMain(argc, argv);
}
#endif

View File

@@ -0,0 +1,12 @@
#import <Cocoa/Cocoa.h>
int main(int argc, char* argv[]) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSArray* pathComponents = [[[NSBundle mainBundle] bundlePath] pathComponents];
pathComponents = [pathComponents
subarrayWithRange:NSMakeRange(0, [pathComponents count] - 4)];
NSString* path = [NSString pathWithComponents:pathComponents];
[[NSWorkspace sharedWorkspace] launchApplication:path];
[pool drain];
return 0;
}

214
atom/app/atom_main.cc Normal file
View File

@@ -0,0 +1,214 @@
// Copyright (c) 2013 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/app/atom_main.h"
#include <cstdlib>
#include <vector>
#if defined(OS_WIN)
#include <windows.h> // windows.h must be included first
#include <atlbase.h> // ensures that ATL statics like `_AtlWinModule` are initialized (it's an issue in static debug build)
#include <shellapi.h>
#include <shellscalingapi.h>
#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"
#elif defined(OS_LINUX) // defined(OS_WIN)
#include <unistd.h>
#include <cstdio>
#include "atom/app/atom_main_delegate.h" // NOLINT
#include "content/public/app/content_main.h"
#else // defined(OS_LINUX)
#include <unistd.h>
#include <cstdio>
#include "atom/app/atom_library_main.h"
#endif // defined(OS_MACOSX)
#include "atom/app/node_main.h"
#include "atom/common/atom_command_line.h"
#include "base/at_exit.h"
#include "base/i18n/icu_util.h"
namespace {
#ifdef ENABLE_RUN_AS_NODE
const char kRunAsNode[] = "ELECTRON_RUN_AS_NODE";
#endif
#if defined(ENABLE_RUN_AS_NODE) || defined(OS_WIN)
bool IsEnvSet(const char* name) {
#if defined(OS_WIN)
size_t required_size;
getenv_s(&required_size, nullptr, 0, name);
return required_size != 0;
#else
char* indicator = getenv(name);
return indicator && indicator[0] != '\0';
#endif
}
#endif
#if defined(OS_POSIX)
void FixStdioStreams() {
// libuv may mark stdin/stdout/stderr as close-on-exec, which interferes
// with chromium's subprocess spawning. As a workaround, we detect if these
// streams are closed on startup, and reopen them as /dev/null if necessary.
// Otherwise, an unrelated file descriptor will be assigned as stdout/stderr
// which may cause various errors when attempting to write to them.
//
// For details see https://github.com/libuv/libuv/issues/2062
struct stat st;
if (fstat(STDIN_FILENO, &st) < 0 && errno == EBADF)
freopen("/dev/null", "r", stdin);
if (fstat(STDOUT_FILENO, &st) < 0 && errno == EBADF)
freopen("/dev/null", "w", stdout);
if (fstat(STDERR_FILENO, &st) < 0 && errno == EBADF)
freopen("/dev/null", "w", stderr);
}
#endif
} // namespace
#if defined(OS_WIN)
int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
struct Arguments {
int argc = 0;
wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
~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 < arguments.argc; ++i) {
if (!_wcsicmp(arguments.argv[i], L"--ci")) {
is_ci = true;
_putenv_s(kCI, "1"); // set flag for child processes
break;
}
}
}
if (is_ci) {
_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
_CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
_set_error_mode(_OUT_TO_STDERR);
}
#endif
#ifdef ENABLE_RUN_AS_NODE
bool run_as_node = IsEnvSet(kRunAsNode);
#else
bool run_as_node = false;
#endif
// Make sure the output is printed to console.
if (run_as_node || !IsEnvSet("ELECTRON_NO_ATTACH_CONSOLE"))
base::RouteStdioToConsole(false);
#ifndef DEBUG
// Chromium has its own TLS subsystem which supports automatic destruction
// of thread-local data, and also depends on memory allocation routines
// provided by the CRT. The problem is that the auto-destruction mechanism
// uses a hidden feature of the OS loader which calls a callback on thread
// exit, but only after all loaded DLLs have been detached. Since the CRT is
// also a DLL, it happens that by the time Chromium's `OnThreadExit` function
// is called, the heap functions, though still in memory, no longer perform
// their duties, and when Chromium calls `free` on its buffer, it triggers
// an access violation error.
// We work around this problem by invoking Chromium's `OnThreadExit` in time
// from within the CRT's atexit facility, ensuring the heap functions are
// still active. The second invocation from the OS loader will be a no-op.
extern void NTAPI OnThreadExit(PVOID module, DWORD reason, PVOID reserved);
atexit([]() { OnThreadExit(nullptr, DLL_THREAD_DETACH, nullptr); });
#endif
#ifdef ENABLE_RUN_AS_NODE
if (run_as_node) {
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();
auto ret = atom::NodeMain(argv.size(), argv.data());
std::for_each(argv.begin(), argv.end(), free);
return ret;
}
#endif
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;
content::ContentMainParams params(&delegate);
params.instance = instance;
params.sandbox_info = &sandbox_info;
atom::AtomCommandLine::Init(arguments.argc, arguments.argv);
return content::ContentMain(params);
}
#elif defined(OS_LINUX) // defined(OS_WIN)
int main(int argc, char* argv[]) {
#ifdef ENABLE_RUN_AS_NODE
FixStdioStreams();
if (IsEnvSet(kRunAsNode)) {
base::i18n::InitializeICU();
base::AtExitManager atexit_manager;
return atom::NodeMain(argc, argv);
}
#endif
atom::AtomMainDelegate delegate;
content::ContentMainParams params(&delegate);
params.argc = argc;
params.argv = const_cast<const char**>(argv);
atom::AtomCommandLine::Init(argc, argv);
return content::ContentMain(params);
}
#else // defined(OS_LINUX)
int main(int argc, char* argv[]) {
#ifdef ENABLE_RUN_AS_NODE
FixStdioStreams();
if (IsEnvSet(kRunAsNode)) {
return AtomInitializeICUandStartNode(argc, argv);
}
#endif
return AtomMain(argc, argv);
}
#endif // defined(OS_MACOSX)

10
atom/app/atom_main.h Normal file
View File

@@ -0,0 +1,10 @@
// Copyright (c) 2013 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_APP_ATOM_MAIN_H_
#define ATOM_APP_ATOM_MAIN_H_
#include "content/public/app/content_main.h"
#endif // ATOM_APP_ATOM_MAIN_H_

View File

@@ -0,0 +1,211 @@
// Copyright (c) 2013 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/app/atom_main_delegate.h"
#include <iostream>
#include <string>
#include "atom/app/atom_content_client.h"
#include "atom/browser/atom_browser_client.h"
#include "atom/browser/relauncher.h"
#include "atom/common/google_api_key.h"
#include "atom/common/options_switches.h"
#include "atom/renderer/atom_renderer_client.h"
#include "atom/renderer/atom_sandboxed_renderer_client.h"
#include "atom/utility/atom_content_utility_client.h"
#include "base/command_line.h"
#include "base/debug/stack_trace.h"
#include "base/environment.h"
#include "base/logging.h"
#include "chrome/common/chrome_paths.h"
#include "content/public/common/content_switches.h"
#include "ipc/ipc_features.h"
#include "services/service_manager/sandbox/switches.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#if BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
#define IPC_MESSAGE_MACROS_LOG_ENABLED
#include "content/public/common/content_ipc_logging.h"
#define IPC_LOG_TABLE_ADD_ENTRY(msg_id, logger) \
content::RegisterIPCLogger(msg_id, logger)
#include "atom/common/common_message_generator.h"
#endif
namespace atom {
namespace {
const char* kRelauncherProcess = "relauncher";
bool IsBrowserProcess(base::CommandLine* cmd) {
std::string process_type = cmd->GetSwitchValueASCII(::switches::kProcessType);
return process_type.empty();
}
#if defined(OS_WIN)
void InvalidParameterHandler(const wchar_t*,
const wchar_t*,
const wchar_t*,
unsigned int,
uintptr_t) {
// noop.
}
#endif
} // namespace
AtomMainDelegate::AtomMainDelegate() {}
AtomMainDelegate::~AtomMainDelegate() {}
bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
auto* command_line = base::CommandLine::ForCurrentProcess();
logging::LoggingSettings settings;
#if defined(OS_WIN)
// On Windows the terminal returns immediately, so we add a new line to
// prevent output in the same line as the prompt.
if (IsBrowserProcess(command_line))
std::wcout << std::endl;
#if defined(DEBUG)
// Print logging to debug.log on Windows
settings.logging_dest = logging::LOG_TO_ALL;
settings.log_file = L"debug.log";
settings.lock_log = logging::LOCK_LOG_FILE;
settings.delete_old = logging::DELETE_OLD_LOG_FILE;
#else
settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
#endif // defined(DEBUG)
#else // defined(OS_WIN)
settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
#endif // !defined(OS_WIN)
// Only enable logging when --enable-logging is specified.
auto env = base::Environment::Create();
if (!command_line->HasSwitch(::switches::kEnableLogging) &&
!env->HasVar("ELECTRON_ENABLE_LOGGING")) {
settings.logging_dest = logging::LOG_NONE;
logging::SetMinLogLevel(logging::LOG_NUM_SEVERITIES);
}
logging::InitLogging(settings);
// Logging with pid and timestamp.
logging::SetLogItems(true, false, true, false);
// Enable convient stack printing.
#if defined(DEBUG) && defined(OS_LINUX)
bool enable_stack_dumping = true;
#else
bool enable_stack_dumping = env->HasVar("ELECTRON_ENABLE_STACK_DUMPING");
#endif
#if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
// For 32bit ARM enabling stack printing would end up crashing.
// https://github.com/electron/electron/pull/11230#issuecomment-363232482
enable_stack_dumping = false;
#endif
if (enable_stack_dumping)
base::debug::EnableInProcessStackDumping();
chrome::RegisterPathProvider();
#if defined(OS_MACOSX)
SetUpBundleOverrides();
#endif
#if defined(OS_WIN)
// Ignore invalid parameter errors.
_set_invalid_parameter_handler(InvalidParameterHandler);
// Disable the ActiveVerifier, which is used by Chrome to track possible
// bugs, but no use in Electron.
base::win::DisableHandleVerifier();
#endif
return brightray::MainDelegate::BasicStartupComplete(exit_code);
}
void AtomMainDelegate::PreSandboxStartup() {
brightray::MainDelegate::PreSandboxStartup();
auto* command_line = base::CommandLine::ForCurrentProcess();
std::string process_type =
command_line->GetSwitchValueASCII(::switches::kProcessType);
// Only append arguments for browser process.
if (!IsBrowserProcess(command_line))
return;
if (!command_line->HasSwitch(switches::kEnableMixedSandbox)) {
if (command_line->HasSwitch(switches::kEnableSandbox)) {
// Disable setuid sandbox since it is not longer required on
// linux(namespace sandbox is available on most distros).
command_line->AppendSwitch(
service_manager::switches::kDisableSetuidSandbox);
} else {
// Disable renderer sandbox for most of node's functions.
command_line->AppendSwitch(::switches::kNoSandbox);
}
}
// Allow file:// URIs to read other file:// URIs by default.
command_line->AppendSwitch(::switches::kAllowFileAccessFromFiles);
#if defined(OS_MACOSX)
// Enable AVFoundation.
command_line->AppendSwitch("enable-avfoundation");
#endif
}
content::ContentBrowserClient* AtomMainDelegate::CreateContentBrowserClient() {
browser_client_.reset(new AtomBrowserClient);
return browser_client_.get();
}
content::ContentRendererClient*
AtomMainDelegate::CreateContentRendererClient() {
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableSandbox) ||
!base::CommandLine::ForCurrentProcess()->HasSwitch(
::switches::kNoSandbox)) {
renderer_client_.reset(new AtomSandboxedRendererClient);
} else {
renderer_client_.reset(new AtomRendererClient);
}
return renderer_client_.get();
}
content::ContentUtilityClient* AtomMainDelegate::CreateContentUtilityClient() {
utility_client_.reset(new AtomContentUtilityClient);
return utility_client_.get();
}
int AtomMainDelegate::RunProcess(
const std::string& process_type,
const content::MainFunctionParams& main_function_params) {
if (process_type == kRelauncherProcess)
return relauncher::RelauncherMain(main_function_params);
else
return -1;
}
#if defined(OS_MACOSX)
bool AtomMainDelegate::ShouldSendMachPort(const std::string& process_type) {
return process_type != kRelauncherProcess;
}
bool AtomMainDelegate::DelaySandboxInitialization(
const std::string& process_type) {
return process_type == kRelauncherProcess;
}
#endif
std::unique_ptr<brightray::ContentClient>
AtomMainDelegate::CreateContentClient() {
return std::make_unique<AtomContentClient>();
}
} // namespace atom

View File

@@ -0,0 +1,56 @@
// Copyright (c) 2013 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_APP_ATOM_MAIN_DELEGATE_H_
#define ATOM_APP_ATOM_MAIN_DELEGATE_H_
#include <string>
#include "brightray/common/content_client.h"
#include "brightray/common/main_delegate.h"
namespace atom {
class AtomMainDelegate : public brightray::MainDelegate {
public:
AtomMainDelegate();
~AtomMainDelegate() override;
protected:
// content::ContentMainDelegate:
bool BasicStartupComplete(int* exit_code) override;
void PreSandboxStartup() override;
content::ContentBrowserClient* CreateContentBrowserClient() override;
content::ContentRendererClient* CreateContentRendererClient() override;
content::ContentUtilityClient* CreateContentUtilityClient() override;
int RunProcess(
const std::string& process_type,
const content::MainFunctionParams& main_function_params) override;
#if defined(OS_MACOSX)
bool ShouldSendMachPort(const std::string& process_type) override;
bool DelaySandboxInitialization(const std::string& process_type) override;
#endif
// brightray::MainDelegate:
std::unique_ptr<brightray::ContentClient> CreateContentClient() override;
#if defined(OS_MACOSX)
void OverrideChildProcessPath() override;
void OverrideFrameworkBundlePath() override;
#endif
private:
#if defined(OS_MACOSX)
void SetUpBundleOverrides();
#endif
std::unique_ptr<content::ContentBrowserClient> browser_client_;
std::unique_ptr<content::ContentRendererClient> renderer_client_;
std::unique_ptr<content::ContentUtilityClient> utility_client_;
DISALLOW_COPY_AND_ASSIGN(AtomMainDelegate);
};
} // namespace atom
#endif // ATOM_APP_ATOM_MAIN_DELEGATE_H_

View File

@@ -0,0 +1,66 @@
// Copyright (c) 2014 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/app/atom_main_delegate.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/mac/bundle_locations.h"
#include "base/mac/foundation_util.h"
#include "base/mac/scoped_nsautorelease_pool.h"
#include "base/path_service.h"
#include "base/strings/sys_string_conversions.h"
#include "brightray/common/application_info.h"
#include "brightray/common/mac/main_application_bundle.h"
#include "content/public/common/content_paths.h"
namespace atom {
namespace {
base::FilePath GetFrameworksPath() {
return brightray::MainApplicationBundlePath()
.Append("Contents")
.Append("Frameworks");
}
base::FilePath GetHelperAppPath(const base::FilePath& frameworks_path,
const std::string& name) {
return frameworks_path.Append(name + " Helper.app")
.Append("Contents")
.Append("MacOS")
.Append(name + " Helper");
}
} // namespace
void AtomMainDelegate::OverrideFrameworkBundlePath() {
base::mac::SetOverrideFrameworkBundlePath(
GetFrameworksPath().Append(ATOM_PRODUCT_NAME " Framework.framework"));
}
void AtomMainDelegate::OverrideChildProcessPath() {
base::FilePath frameworks_path = GetFrameworksPath();
base::FilePath helper_path =
GetHelperAppPath(frameworks_path, ATOM_PRODUCT_NAME);
if (!base::PathExists(helper_path))
helper_path =
GetHelperAppPath(frameworks_path, brightray::GetApplicationName());
if (!base::PathExists(helper_path))
LOG(FATAL) << "Unable to find helper app";
PathService::Override(content::CHILD_PROCESS_EXE, helper_path);
}
void AtomMainDelegate::SetUpBundleOverrides() {
base::mac::ScopedNSAutoreleasePool pool;
NSBundle* bundle = brightray::MainApplicationBundle();
std::string base_bundle_id =
base::SysNSStringToUTF8([bundle bundleIdentifier]);
NSString* team_id = [bundle objectForInfoDictionaryKey:@"ElectronTeamID"];
if (team_id)
base_bundle_id = base::SysNSStringToUTF8(team_id) + "." + base_bundle_id;
base::mac::SetBaseBundleID(base_bundle_id.c_str());
}
} // namespace atom

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "shell/app/command_line_args.h"
#include "atom/app/command_line_args.h"
namespace {
@@ -33,7 +33,7 @@ bool IsUrlArg(const base::CommandLine::CharType* arg) {
} // namespace
namespace electron {
namespace atom {
bool CheckCommandLineArguments(int argc, base::CommandLine::CharType** argv) {
const base::CommandLine::StringType dashdash(2, '-');
@@ -50,4 +50,4 @@ bool CheckCommandLineArguments(int argc, base::CommandLine::CharType** argv) {
return true;
}
} // namespace electron
} // namespace atom

View File

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

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

@@ -0,0 +1,120 @@
// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifdef ENABLE_RUN_AS_NODE
#include "atom/app/node_main.h"
#include "atom/app/uv_task_runner.h"
#include "atom/browser/javascript_environment.h"
#include "atom/browser/node_debugger.h"
#include "atom/common/api/atom_bindings.h"
#include "atom/common/crash_reporter/crash_reporter.h"
#include "atom/common/native_mate_converters/string16_converter.h"
#include "atom/common/node_bindings.h"
#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/task_scheduler/task_scheduler.h"
#include "base/threading/thread_task_runner_handle.h"
#include "gin/array_buffer.h"
#include "gin/public/isolate_holder.h"
#include "gin/v8_initializer.h"
#include "native_mate/dictionary.h"
#include "atom/common/node_includes.h"
namespace atom {
int NodeMain(int argc, char* argv[]) {
base::CommandLine::Init(argc, argv);
int exit_code = 1;
{
// Feed gin::PerIsolateData with a task runner.
argv = uv_setup_args(argc, argv);
uv_loop_t* loop = uv_default_loop();
scoped_refptr<UvTaskRunner> uv_task_runner(new UvTaskRunner(loop));
base::ThreadTaskRunnerHandle handle(uv_task_runner);
// Initialize feature list.
auto feature_list = std::make_unique<base::FeatureList>();
feature_list->InitializeFromCommandLine("", "");
base::FeatureList::SetInstance(std::move(feature_list));
gin::V8Initializer::LoadV8Snapshot(
gin::V8Initializer::V8SnapshotFileType::kWithAdditionalContext);
gin::V8Initializer::LoadV8Natives();
// V8 requires a task scheduler apparently
base::TaskScheduler::CreateAndStartWithDefaultParams("Electron");
// Initialize gin::IsolateHolder.
JavascriptEnvironment gin_env;
// Explicitly register electron's builtin modules.
NodeBindings::RegisterBuiltinModules();
int exec_argc;
const char** exec_argv;
node::Init(&argc, const_cast<const char**>(argv), &exec_argc, &exec_argv);
node::Environment* env = node::CreateEnvironment(
node::CreateIsolateData(gin_env.isolate(), loop, gin_env.platform()),
gin_env.context(), argc, argv, exec_argc, exec_argv);
// Enable support for v8 inspector.
NodeDebugger node_debugger(env);
node_debugger.Start(gin_env.platform());
mate::Dictionary process(gin_env.isolate(), env->process_object());
#if defined(OS_WIN)
process.SetMethod("log", &AtomBindings::Log);
#endif
process.SetMethod("crash", &AtomBindings::Crash);
// Setup process.crashReporter.start in child node processes
auto reporter = mate::Dictionary::CreateEmpty(gin_env.isolate());
reporter.SetMethod("start", &crash_reporter::CrashReporter::StartInstance);
process.Set("crashReporter", reporter);
node::LoadEnvironment(env);
bool more;
do {
more = uv_run(env->event_loop(), UV_RUN_ONCE);
gin_env.platform()->DrainBackgroundTasks(env->isolate());
if (more == false) {
node::EmitBeforeExit(env);
// Emit `beforeExit` if the loop became alive either after emitting
// event, or after running some callbacks.
more = uv_loop_alive(env->event_loop());
if (uv_run(env->event_loop(), UV_RUN_NOWAIT) != 0)
more = true;
}
} while (more == true);
exit_code = node::EmitExit(env);
node::RunAtExit(env);
gin_env.platform()->DrainBackgroundTasks(env->isolate());
gin_env.platform()->CancelPendingDelayedTasks(env->isolate());
node::FreeEnvironment(env);
}
// According to "src/gin/shell/gin_main.cc":
//
// gin::IsolateHolder waits for tasks running in TaskScheduler in its
// destructor and thus must be destroyed before TaskScheduler starts skipping
// CONTINUE_ON_SHUTDOWN tasks.
base::TaskScheduler::GetInstance()->Shutdown();
v8::V8::Dispose();
return exit_code;
}
} // namespace atom
#endif // ENABLE_RUN_AS_NODE

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

@@ -0,0 +1,18 @@
// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_APP_NODE_MAIN_H_
#define ATOM_APP_NODE_MAIN_H_
#ifdef ENABLE_RUN_AS_NODE
namespace atom {
int NodeMain(int argc, char* argv[]);
} // namespace atom
#endif // ENABLE_RUN_AS_NODE
#endif // ATOM_APP_NODE_MAIN_H_

View File

@@ -3,7 +3,7 @@
<plist version="1.0">
<dict>
<key>CFBundleIdentifier</key>
<string>${ELECTRON_BUNDLE_ID}</string>
<string>${ATOM_BUNDLE_ID}</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundleExecutable</key>

View File

@@ -4,11 +4,11 @@
#include <utility>
#include "shell/app/uv_task_runner.h"
#include "atom/app/uv_task_runner.h"
#include "base/stl_util.h"
namespace electron {
namespace atom {
UvTaskRunner::UvTaskRunner(uv_loop_t* loop) : loop_(loop) {}
@@ -42,13 +42,12 @@ bool UvTaskRunner::PostNonNestableDelayedTask(const base::Location& from_here,
// static
void UvTaskRunner::OnTimeout(uv_timer_t* timer) {
auto& tasks = static_cast<UvTaskRunner*>(timer->data)->tasks_;
const auto iter = tasks.find(timer);
if (iter == std::end(tasks))
UvTaskRunner* self = static_cast<UvTaskRunner*>(timer->data);
if (!ContainsKey(self->tasks_, timer))
return;
std::move(iter->second).Run();
tasks.erase(iter);
std::move(self->tasks_[timer]).Run();
self->tasks_.erase(timer);
uv_timer_stop(timer);
uv_close(reinterpret_cast<uv_handle_t*>(timer), UvTaskRunner::OnClose);
}
@@ -58,4 +57,4 @@ void UvTaskRunner::OnClose(uv_handle_t* handle) {
delete reinterpret_cast<uv_timer_t*>(handle);
}
} // namespace electron
} // namespace atom

View File

@@ -2,17 +2,17 @@
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef SHELL_APP_UV_TASK_RUNNER_H_
#define SHELL_APP_UV_TASK_RUNNER_H_
#ifndef ATOM_APP_UV_TASK_RUNNER_H_
#define ATOM_APP_UV_TASK_RUNNER_H_
#include <map>
#include "base/callback.h"
#include "base/location.h"
#include "base/single_thread_task_runner.h"
#include "uv.h" // NOLINT(build/include_directory)
#include "uv.h" // NOLINT(build/include)
namespace electron {
namespace atom {
// TaskRunner implementation that posts tasks into libuv's default loop.
class UvTaskRunner : public base::SingleThreadTaskRunner {
@@ -40,6 +40,6 @@ class UvTaskRunner : public base::SingleThreadTaskRunner {
DISALLOW_COPY_AND_ASSIGN(UvTaskRunner);
};
} // namespace electron
} // namespace atom
#endif // SHELL_APP_UV_TASK_RUNNER_H_
#endif // ATOM_APP_UV_TASK_RUNNER_H_

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,241 @@
// Copyright (c) 2013 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_API_ATOM_API_APP_H_
#define ATOM_BROWSER_API_ATOM_API_APP_H_
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "atom/browser/api/event_emitter.h"
#include "atom/browser/atom_browser_client.h"
#include "atom/browser/browser.h"
#include "atom/browser/browser_observer.h"
#include "atom/common/native_mate_converters/callback.h"
#include "base/process/process_iterator.h"
#include "base/task/cancelable_task_tracker.h"
#include "chrome/browser/icon_manager.h"
#include "chrome/browser/process_singleton.h"
#include "content/public/browser/browser_child_process_observer.h"
#include "content/public/browser/gpu_data_manager_observer.h"
#include "content/public/browser/render_process_host.h"
#include "native_mate/dictionary.h"
#include "native_mate/handle.h"
#include "net/base/completion_callback.h"
#include "net/ssl/client_cert_identity.h"
#if defined(USE_NSS_CERTS)
#include "chrome/browser/certificate_manager_model.h"
#endif
namespace base {
class FilePath;
}
namespace mate {
class Arguments;
} // namespace mate
namespace atom {
#if defined(OS_WIN)
enum class JumpListResult : int;
#endif
struct ProcessMetric {
int type;
base::ProcessId pid;
std::unique_ptr<base::ProcessMetrics> metrics;
ProcessMetric(int type,
base::ProcessId pid,
std::unique_ptr<base::ProcessMetrics> metrics);
~ProcessMetric();
};
namespace api {
class App : public AtomBrowserClient::Delegate,
public mate::EventEmitter<App>,
public BrowserObserver,
public content::GpuDataManagerObserver,
public content::BrowserChildProcessObserver {
public:
using FileIconCallback =
base::Callback<void(v8::Local<v8::Value>, const gfx::Image&)>;
static mate::Handle<App> Create(v8::Isolate* isolate);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
#if defined(USE_NSS_CERTS)
void OnCertificateManagerModelCreated(
std::unique_ptr<base::DictionaryValue> options,
const net::CompletionCallback& callback,
std::unique_ptr<CertificateManagerModel> model);
#endif
base::FilePath GetAppPath() const;
void RenderProcessReady(content::RenderProcessHost* host);
void RenderProcessDisconnected(base::ProcessId host_pid);
void PreMainMessageLoopRun();
protected:
explicit App(v8::Isolate* isolate);
~App() override;
// BrowserObserver:
void OnBeforeQuit(bool* prevent_default) override;
void OnWillQuit(bool* prevent_default) override;
void OnWindowAllClosed() override;
void OnQuit() override;
void OnOpenFile(bool* prevent_default, const std::string& file_path) override;
void OnOpenURL(const std::string& url) override;
void OnActivate(bool has_visible_windows) override;
void OnWillFinishLaunching() override;
void OnFinishLaunching(const base::DictionaryValue& launch_info) override;
void OnLogin(scoped_refptr<LoginHandler> login_handler,
const base::DictionaryValue& request_details) override;
void OnAccessibilitySupportChanged() override;
void OnPreMainMessageLoopRun() override;
#if defined(OS_MACOSX)
void OnWillContinueUserActivity(bool* prevent_default,
const std::string& type) override;
void OnDidFailToContinueUserActivity(const std::string& type,
const std::string& error) override;
void OnContinueUserActivity(bool* prevent_default,
const std::string& type,
const base::DictionaryValue& user_info) override;
void OnUserActivityWasContinued(
const std::string& type,
const base::DictionaryValue& user_info) override;
void OnUpdateUserActivityState(
bool* prevent_default,
const std::string& type,
const base::DictionaryValue& user_info) override;
void OnNewWindowForTab() override;
#endif
// content::ContentBrowserClient:
void AllowCertificateError(
content::WebContents* web_contents,
int cert_error,
const net::SSLInfo& ssl_info,
const GURL& request_url,
content::ResourceType resource_type,
bool strict_enforcement,
bool expired_previous_decision,
const base::Callback<void(content::CertificateRequestResultType)>&
callback) override;
void SelectClientCertificate(
content::WebContents* web_contents,
net::SSLCertRequestInfo* cert_request_info,
net::ClientCertIdentityList client_certs,
std::unique_ptr<content::ClientCertificateDelegate> delegate) override;
bool CanCreateWindow(content::RenderFrameHost* opener,
const GURL& opener_url,
const GURL& opener_top_level_frame_url,
const GURL& source_origin,
content::mojom::WindowContainerType container_type,
const GURL& target_url,
const content::Referrer& referrer,
const std::string& frame_name,
WindowOpenDisposition disposition,
const blink::mojom::WindowFeatures& features,
const std::vector<std::string>& additional_features,
const scoped_refptr<network::ResourceRequestBody>& body,
bool user_gesture,
bool opener_suppressed,
bool* no_javascript_access) override;
// content::GpuDataManagerObserver:
void OnGpuProcessCrashed(base::TerminationStatus status) override;
// content::BrowserChildProcessObserver:
void BrowserChildProcessLaunchedAndConnected(
const content::ChildProcessData& data) override;
void BrowserChildProcessHostDisconnected(
const content::ChildProcessData& data) override;
void BrowserChildProcessCrashed(const content::ChildProcessData& data,
int exit_code) override;
void BrowserChildProcessKilled(const content::ChildProcessData& data,
int exit_code) override;
private:
void SetAppPath(const base::FilePath& app_path);
void ChildProcessLaunched(int process_type, base::ProcessHandle handle);
void ChildProcessDisconnected(base::ProcessId pid);
// Get/Set the pre-defined path in PathService.
base::FilePath GetPath(mate::Arguments* args, const std::string& name);
void SetPath(mate::Arguments* args,
const std::string& name,
const base::FilePath& path);
void SetDesktopName(const std::string& desktop_name);
std::string GetLocale();
void OnSecondInstance(const base::CommandLine::StringVector& cmd,
const base::FilePath& cwd);
bool HasSingleInstanceLock() const;
bool RequestSingleInstanceLock();
void ReleaseSingleInstanceLock();
bool Relaunch(mate::Arguments* args);
void DisableHardwareAcceleration(mate::Arguments* args);
void DisableDomainBlockingFor3DAPIs(mate::Arguments* args);
bool IsAccessibilitySupportEnabled();
void SetAccessibilitySupportEnabled(bool enabled);
Browser::LoginItemSettings GetLoginItemSettings(mate::Arguments* args);
#if defined(USE_NSS_CERTS)
void ImportCertificate(const base::DictionaryValue& options,
const net::CompletionCallback& callback);
#endif
void GetFileIcon(const base::FilePath& path, mate::Arguments* args);
std::vector<mate::Dictionary> GetAppMetrics(v8::Isolate* isolate);
v8::Local<v8::Value> GetGPUFeatureStatus(v8::Isolate* isolate);
void EnableMixedSandbox(mate::Arguments* args);
#if defined(OS_MACOSX)
bool MoveToApplicationsFolder(mate::Arguments* args);
bool IsInApplicationsFolder();
#endif
#if defined(MAS_BUILD)
base::Callback<void()> StartAccessingSecurityScopedResource(
mate::Arguments* args);
#endif
#if defined(OS_WIN)
// Get the current Jump List settings.
v8::Local<v8::Value> GetJumpListSettings();
// Set or remove a custom Jump List for the application.
JumpListResult SetJumpList(v8::Local<v8::Value> val, mate::Arguments* args);
#endif // defined(OS_WIN)
std::unique_ptr<ProcessSingleton> process_singleton_;
#if defined(USE_NSS_CERTS)
std::unique_ptr<CertificateManagerModel> certificate_manager_model_;
#endif
// Tracks tasks requesting file icons.
base::CancelableTaskTracker cancelable_task_tracker_;
base::FilePath app_path_;
using ProcessMetricMap =
std::unordered_map<base::ProcessId, std::unique_ptr<atom::ProcessMetric>>;
ProcessMetricMap app_metrics_;
DISALLOW_COPY_AND_ASSIGN(App);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_APP_H_

View File

@@ -0,0 +1,63 @@
// Copyright (c) 2013 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_app.h"
#import <Cocoa/Cocoa.h>
#include "base/strings/sys_string_conversions.h"
namespace atom {
namespace api {
// Callback passed to js which will stop accessing the given bookmark.
void OnStopAccessingSecurityScopedResource(NSURL* bookmarkUrl) {
[bookmarkUrl stopAccessingSecurityScopedResource];
[bookmarkUrl release];
}
// Get base64 encoded NSData, create a bookmark for it and start accessing it.
base::Callback<void()> App::StartAccessingSecurityScopedResource(
mate::Arguments* args) {
std::string data;
args->GetNext(&data);
NSString* base64str = base::SysUTF8ToNSString(data);
NSData* bookmarkData =
[[NSData alloc] initWithBase64EncodedString:base64str options:0];
// Create bookmarkUrl from NSData.
BOOL isStale = false;
NSError* error = nil;
NSURL* bookmarkUrl =
[NSURL URLByResolvingBookmarkData:bookmarkData
options:NSURLBookmarkResolutionWithSecurityScope
relativeToURL:nil
bookmarkDataIsStale:&isStale
error:&error];
if (error != nil) {
NSString* err =
[NSString stringWithFormat:@"NSError: %@ %@", error, [error userInfo]];
args->ThrowError(base::SysNSStringToUTF8(err));
}
if (isStale) {
args->ThrowError("bookmarkDataIsStale - try recreating the bookmark");
}
if (error == nil && isStale == false) {
[bookmarkUrl startAccessingSecurityScopedResource];
}
// Stop the NSURL from being GC'd.
[bookmarkUrl retain];
// Return a js callback which will close the bookmark.
return base::Bind(&OnStopAccessingSecurityScopedResource, bookmarkUrl);
}
} // namespace atom
} // namespace api

View File

@@ -0,0 +1,155 @@
// Copyright (c) 2013 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_auto_updater.h"
#include "atom/browser/browser.h"
#include "atom/browser/native_window.h"
#include "atom/browser/window_list.h"
#include "atom/common/api/event_emitter_caller.h"
#include "atom/common/native_mate_converters/callback.h"
#include "atom/common/node_includes.h"
#include "base/time/time.h"
#include "native_mate/dictionary.h"
#include "native_mate/object_template_builder.h"
namespace mate {
template <>
struct Converter<base::Time> {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
const base::Time& val) {
v8::MaybeLocal<v8::Value> date =
v8::Date::New(isolate->GetCurrentContext(), val.ToJsTime());
if (date.IsEmpty())
return v8::Null(isolate);
else
return date.ToLocalChecked();
}
};
} // namespace mate
namespace atom {
namespace api {
AutoUpdater::AutoUpdater(v8::Isolate* isolate) {
auto_updater::AutoUpdater::SetDelegate(this);
Init(isolate);
}
AutoUpdater::~AutoUpdater() {
auto_updater::AutoUpdater::SetDelegate(nullptr);
}
void AutoUpdater::OnError(const std::string& message) {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
auto error = v8::Exception::Error(mate::StringToV8(isolate(), message));
mate::EmitEvent(
isolate(), GetWrapper(), "error",
error->ToObject(isolate()->GetCurrentContext()).ToLocalChecked(),
// Message is also emitted to keep compatibility with old code.
message);
}
void AutoUpdater::OnError(const std::string& message,
const int code,
const std::string& domain) {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
auto error = v8::Exception::Error(mate::StringToV8(isolate(), message));
auto errorObject =
error->ToObject(isolate()->GetCurrentContext()).ToLocalChecked();
// add two new params for better error handling
errorObject->Set(mate::StringToV8(isolate(), "code"),
v8::Integer::New(isolate(), code));
errorObject->Set(mate::StringToV8(isolate(), "domain"),
mate::StringToV8(isolate(), domain));
mate::EmitEvent(isolate(), GetWrapper(), "error", errorObject, message);
}
void AutoUpdater::OnCheckingForUpdate() {
Emit("checking-for-update");
}
void AutoUpdater::OnUpdateAvailable() {
Emit("update-available");
}
void AutoUpdater::OnUpdateNotAvailable() {
Emit("update-not-available");
}
void AutoUpdater::OnUpdateDownloaded(const std::string& release_notes,
const std::string& release_name,
const base::Time& release_date,
const std::string& url) {
Emit("update-downloaded", release_notes, release_name, release_date, url,
// Keep compatibility with old APIs.
base::Bind(&AutoUpdater::QuitAndInstall, base::Unretained(this)));
}
void AutoUpdater::OnWindowAllClosed() {
QuitAndInstall();
}
void AutoUpdater::SetFeedURL(mate::Arguments* args) {
auto_updater::AutoUpdater::SetFeedURL(args);
}
void AutoUpdater::QuitAndInstall() {
Emit("before-quit-for-update");
// If we don't have any window then quitAndInstall immediately.
if (WindowList::IsEmpty()) {
auto_updater::AutoUpdater::QuitAndInstall();
return;
}
// Otherwise do the restart after all windows have been closed.
WindowList::AddObserver(this);
WindowList::CloseAllWindows();
}
// static
mate::Handle<AutoUpdater> AutoUpdater::Create(v8::Isolate* isolate) {
return mate::CreateHandle(isolate, new AutoUpdater(isolate));
}
// static
void AutoUpdater::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "AutoUpdater"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.SetMethod("checkForUpdates", &auto_updater::AutoUpdater::CheckForUpdates)
.SetMethod("getFeedURL", &auto_updater::AutoUpdater::GetFeedURL)
.SetMethod("setFeedURL", &AutoUpdater::SetFeedURL)
.SetMethod("quitAndInstall", &AutoUpdater::QuitAndInstall);
}
} // namespace api
} // namespace atom
namespace {
using atom::api::AutoUpdater;
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary dict(isolate, exports);
dict.Set("autoUpdater", AutoUpdater::Create(isolate));
dict.Set("AutoUpdater", AutoUpdater::GetConstructor(isolate)->GetFunction());
}
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_auto_updater, Initialize)

View File

@@ -0,0 +1,61 @@
// Copyright (c) 2013 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_API_ATOM_API_AUTO_UPDATER_H_
#define ATOM_BROWSER_API_ATOM_API_AUTO_UPDATER_H_
#include <string>
#include "atom/browser/api/event_emitter.h"
#include "atom/browser/auto_updater.h"
#include "atom/browser/window_list_observer.h"
#include "native_mate/arguments.h"
#include "native_mate/handle.h"
namespace atom {
namespace api {
class AutoUpdater : public mate::EventEmitter<AutoUpdater>,
public auto_updater::Delegate,
public WindowListObserver {
public:
static mate::Handle<AutoUpdater> Create(v8::Isolate* isolate);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
protected:
explicit AutoUpdater(v8::Isolate* isolate);
~AutoUpdater() override;
// Delegate implementations.
void OnError(const std::string& error) override;
void OnError(const std::string& message,
const int code,
const std::string& domain) override;
void OnCheckingForUpdate() override;
void OnUpdateAvailable() override;
void OnUpdateNotAvailable() override;
void OnUpdateDownloaded(const std::string& release_notes,
const std::string& release_name,
const base::Time& release_date,
const std::string& update_url) override;
// WindowListObserver:
void OnWindowAllClosed() override;
private:
std::string GetFeedURL();
void SetFeedURL(mate::Arguments* args);
void QuitAndInstall();
DISALLOW_COPY_AND_ASSIGN(AutoUpdater);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_AUTO_UPDATER_H_

View File

@@ -0,0 +1,87 @@
// Copyright (c) 2018 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_box_layout.h"
#include <string>
#include "atom/browser/api/atom_api_view.h"
#include "atom/common/api/constructor.h"
#include "native_mate/dictionary.h"
#include "atom/common/node_includes.h"
namespace mate {
template <>
struct Converter<views::BoxLayout::Orientation> {
static bool FromV8(v8::Isolate* isolate,
v8::Handle<v8::Value> val,
views::BoxLayout::Orientation* out) {
std::string orientation;
if (!ConvertFromV8(isolate, val, &orientation))
return false;
if (orientation == "horizontal")
*out = views::BoxLayout::kHorizontal;
else if (orientation == "vertical")
*out = views::BoxLayout::kVertical;
else
return false;
return true;
}
};
} // namespace mate
namespace atom {
namespace api {
BoxLayout::BoxLayout(views::BoxLayout::Orientation orientation)
: LayoutManager(new views::BoxLayout(orientation)) {}
BoxLayout::~BoxLayout() {}
void BoxLayout::SetFlexForView(mate::Handle<View> view, int flex) {
auto* box_layout = static_cast<views::BoxLayout*>(layout_manager());
box_layout->SetFlexForView(view->view(), flex);
}
// static
mate::WrappableBase* BoxLayout::New(mate::Arguments* args,
views::BoxLayout::Orientation orientation) {
auto* layout = new BoxLayout(orientation);
layout->InitWith(args->isolate(), args->GetThis());
return layout;
}
// static
void BoxLayout::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "BoxLayout"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.SetMethod("setFlexForView", &BoxLayout::SetFlexForView);
}
} // namespace api
} // namespace atom
namespace {
using atom::api::BoxLayout;
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary dict(isolate, exports);
dict.Set("BoxLayout", mate::CreateConstructor<BoxLayout>(
isolate, base::Bind(&BoxLayout::New)));
}
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_box_layout, Initialize)

View File

@@ -0,0 +1,40 @@
// 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_BROWSER_API_ATOM_API_BOX_LAYOUT_H_
#define ATOM_BROWSER_API_ATOM_API_BOX_LAYOUT_H_
#include "atom/browser/api/atom_api_layout_manager.h"
#include "native_mate/handle.h"
#include "ui/views/layout/box_layout.h"
namespace atom {
namespace api {
class View;
class BoxLayout : public LayoutManager {
public:
static mate::WrappableBase* New(mate::Arguments* args,
views::BoxLayout::Orientation orientation);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
void SetFlexForView(mate::Handle<View> view, int flex);
protected:
explicit BoxLayout(views::BoxLayout::Orientation orientation);
~BoxLayout() override;
private:
DISALLOW_COPY_AND_ASSIGN(BoxLayout);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_BOX_LAYOUT_H_

View File

@@ -0,0 +1,164 @@
// Copyright (c) 2017 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_browser_view.h"
#include "atom/browser/api/atom_api_web_contents.h"
#include "atom/browser/browser.h"
#include "atom/browser/native_browser_view.h"
#include "atom/common/color_util.h"
#include "atom/common/native_mate_converters/gfx_converter.h"
#include "atom/common/native_mate_converters/value_converter.h"
#include "atom/common/node_includes.h"
#include "atom/common/options_switches.h"
#include "native_mate/constructor.h"
#include "native_mate/dictionary.h"
#include "ui/gfx/geometry/rect.h"
namespace mate {
template <>
struct Converter<atom::AutoResizeFlags> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
atom::AutoResizeFlags* auto_resize_flags) {
mate::Dictionary params;
if (!ConvertFromV8(isolate, val, &params)) {
return false;
}
uint8_t flags = 0;
bool width = false;
if (params.Get("width", &width) && width) {
flags |= atom::kAutoResizeWidth;
}
bool height = false;
if (params.Get("height", &height) && height) {
flags |= atom::kAutoResizeHeight;
}
*auto_resize_flags = static_cast<atom::AutoResizeFlags>(flags);
return true;
}
};
} // namespace mate
namespace atom {
namespace api {
BrowserView::BrowserView(v8::Isolate* isolate,
v8::Local<v8::Object> wrapper,
const mate::Dictionary& options) {
Init(isolate, wrapper, options);
}
void BrowserView::Init(v8::Isolate* isolate,
v8::Local<v8::Object> wrapper,
const mate::Dictionary& options) {
mate::Dictionary web_preferences = mate::Dictionary::CreateEmpty(isolate);
options.Get(options::kWebPreferences, &web_preferences);
web_preferences.Set("isBrowserView", true);
mate::Handle<class WebContents> web_contents =
WebContents::Create(isolate, web_preferences);
web_contents_.Reset(isolate, web_contents.ToV8());
api_web_contents_ = web_contents.get();
view_.reset(
NativeBrowserView::Create(api_web_contents_->managed_web_contents()));
InitWith(isolate, wrapper);
}
BrowserView::~BrowserView() {
api_web_contents_->DestroyWebContents(true /* async */);
}
// static
mate::WrappableBase* BrowserView::New(mate::Arguments* args) {
if (!Browser::Get()->is_ready()) {
args->ThrowError("Cannot create BrowserView before app is ready");
return nullptr;
}
if (args->Length() > 1) {
args->ThrowError("Too many arguments");
return nullptr;
}
mate::Dictionary options;
if (!(args->Length() == 1 && args->GetNext(&options))) {
options = mate::Dictionary::CreateEmpty(args->isolate());
}
return new BrowserView(args->isolate(), args->GetThis(), options);
}
int32_t BrowserView::ID() const {
return weak_map_id();
}
void BrowserView::SetAutoResize(AutoResizeFlags flags) {
view_->SetAutoResizeFlags(flags);
}
void BrowserView::SetBounds(const gfx::Rect& bounds) {
view_->SetBounds(bounds);
}
void BrowserView::SetBackgroundColor(const std::string& color_name) {
view_->SetBackgroundColor(ParseHexColor(color_name));
}
v8::Local<v8::Value> BrowserView::GetWebContents() {
if (web_contents_.IsEmpty()) {
return v8::Null(isolate());
}
return v8::Local<v8::Value>::New(isolate(), web_contents_);
}
// static
void BrowserView::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "BrowserView"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.MakeDestroyable()
.SetMethod("setAutoResize", &BrowserView::SetAutoResize)
.SetMethod("setBounds", &BrowserView::SetBounds)
.SetMethod("setBackgroundColor", &BrowserView::SetBackgroundColor)
.SetProperty("webContents", &BrowserView::GetWebContents)
.SetProperty("id", &BrowserView::ID);
}
} // namespace api
} // namespace atom
namespace {
using atom::api::BrowserView;
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
v8::Isolate* isolate = context->GetIsolate();
BrowserView::SetConstructor(isolate, base::Bind(&BrowserView::New));
mate::Dictionary browser_view(
isolate, BrowserView::GetConstructor(isolate)->GetFunction());
browser_view.SetMethod("fromId",
&mate::TrackableObject<BrowserView>::FromWeakMapID);
browser_view.SetMethod("getAllViews",
&mate::TrackableObject<BrowserView>::GetAll);
mate::Dictionary dict(isolate, exports);
dict.Set("BrowserView", browser_view);
}
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_browser_view, Initialize)

View File

@@ -0,0 +1,73 @@
// Copyright (c) 2017 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_API_ATOM_API_BROWSER_VIEW_H_
#define ATOM_BROWSER_API_ATOM_API_BROWSER_VIEW_H_
#include <memory>
#include <string>
#include "atom/browser/api/trackable_object.h"
#include "atom/browser/native_browser_view.h"
#include "native_mate/handle.h"
namespace gfx {
class Rect;
}
namespace mate {
class Arguments;
class Dictionary;
} // namespace mate
namespace atom {
class NativeBrowserView;
namespace api {
class WebContents;
class BrowserView : public mate::TrackableObject<BrowserView> {
public:
static mate::WrappableBase* New(mate::Arguments* args);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
WebContents* web_contents() const { return api_web_contents_; }
NativeBrowserView* view() const { return view_.get(); }
int32_t ID() const;
protected:
BrowserView(v8::Isolate* isolate,
v8::Local<v8::Object> wrapper,
const mate::Dictionary& options);
~BrowserView() override;
private:
void Init(v8::Isolate* isolate,
v8::Local<v8::Object> wrapper,
const mate::Dictionary& options);
void SetAutoResize(AutoResizeFlags flags);
void SetBounds(const gfx::Rect& bounds);
void SetBackgroundColor(const std::string& color_name);
v8::Local<v8::Value> GetWebContents();
v8::Global<v8::Value> web_contents_;
class WebContents* api_web_contents_ = nullptr;
std::unique_ptr<NativeBrowserView> view_;
DISALLOW_COPY_AND_ASSIGN(BrowserView);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_BROWSER_VIEW_H_

View File

@@ -0,0 +1,452 @@
// Copyright (c) 2013 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_browser_window.h"
#include "atom/browser/browser.h"
#include "atom/browser/unresponsive_suppressor.h"
#include "atom/browser/web_contents_preferences.h"
#include "atom/browser/window_list.h"
#include "atom/common/api/api_messages.h"
#include "atom/common/api/constructor.h"
#include "atom/common/color_util.h"
#include "atom/common/native_mate_converters/callback.h"
#include "atom/common/native_mate_converters/value_converter.h"
#include "atom/common/options_switches.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "native_mate/dictionary.h"
#include "ui/gl/gpu_switching_manager.h"
#include "atom/common/node_includes.h"
namespace atom {
namespace api {
BrowserWindow::BrowserWindow(v8::Isolate* isolate,
v8::Local<v8::Object> wrapper,
const mate::Dictionary& options)
: TopLevelWindow(isolate, options), weak_factory_(this) {
mate::Handle<class WebContents> web_contents;
// Use options.webPreferences in WebContents.
mate::Dictionary web_preferences = mate::Dictionary::CreateEmpty(isolate);
options.Get(options::kWebPreferences, &web_preferences);
// Copy the backgroundColor to webContents.
v8::Local<v8::Value> value;
if (options.Get(options::kBackgroundColor, &value))
web_preferences.Set(options::kBackgroundColor, value);
v8::Local<v8::Value> transparent;
if (options.Get("transparent", &transparent))
web_preferences.Set("transparent", transparent);
if (options.Get("webContents", &web_contents) && !web_contents.IsEmpty()) {
// Set webPreferences from options if using an existing webContents.
// These preferences will be used when the webContent launches new
// render processes.
auto* existing_preferences =
WebContentsPreferences::From(web_contents->web_contents());
base::DictionaryValue web_preferences_dict;
if (mate::ConvertFromV8(isolate, web_preferences.GetHandle(),
&web_preferences_dict)) {
existing_preferences->dict()->Clear();
existing_preferences->Merge(web_preferences_dict);
}
} else {
// Creates the WebContents used by BrowserWindow.
web_contents = WebContents::Create(isolate, web_preferences);
}
web_contents_.Reset(isolate, web_contents.ToV8());
api_web_contents_ = web_contents.get();
api_web_contents_->AddObserver(this);
Observe(api_web_contents_->web_contents());
// Keep a copy of the options for later use.
mate::Dictionary(isolate, web_contents->GetWrapper())
.Set("browserWindowOptions", options);
// Tell the content module to initialize renderer widget with transparent
// mode.
ui::GpuSwitchingManager::SetTransparent(window()->transparent());
// Associate with BrowserWindow.
web_contents->SetOwnerWindow(window());
auto* host = web_contents->web_contents()->GetRenderViewHost();
if (host)
host->GetWidget()->AddInputEventObserver(this);
InitWith(isolate, wrapper);
#if defined(OS_MACOSX)
if (!window()->has_frame())
OverrideNSWindowContentView(web_contents->managed_web_contents());
#endif
// Init window after everything has been setup.
window()->InitFromOptions(options);
}
BrowserWindow::~BrowserWindow() {
api_web_contents_->RemoveObserver(this);
// Note that the OnWindowClosed will not be called after the destructor runs,
// since the window object is managed by the TopLevelWindow class.
if (web_contents())
Cleanup();
}
void BrowserWindow::OnInputEvent(const blink::WebInputEvent& event) {
switch (event.GetType()) {
case blink::WebInputEvent::kGestureScrollBegin:
case blink::WebInputEvent::kGestureScrollUpdate:
case blink::WebInputEvent::kGestureScrollEnd:
Emit("scroll-touch-edge");
break;
default:
break;
}
}
void BrowserWindow::RenderViewHostChanged(content::RenderViewHost* old_host,
content::RenderViewHost* new_host) {
if (old_host)
old_host->GetWidget()->RemoveInputEventObserver(this);
if (new_host)
new_host->GetWidget()->AddInputEventObserver(this);
}
void BrowserWindow::RenderViewCreated(
content::RenderViewHost* render_view_host) {
if (!window()->transparent())
return;
content::RenderWidgetHostImpl* impl = content::RenderWidgetHostImpl::FromID(
render_view_host->GetProcess()->GetID(),
render_view_host->GetRoutingID());
if (impl)
impl->SetBackgroundOpaque(false);
}
void BrowserWindow::DidFirstVisuallyNonEmptyPaint() {
if (window()->IsVisible())
return;
// When there is a non-empty first paint, resize the RenderWidget to force
// Chromium to draw.
auto* const view = web_contents()->GetRenderWidgetHostView();
view->Show();
view->SetSize(window()->GetContentSize());
// Emit the ReadyToShow event in next tick in case of pending drawing work.
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(
[](base::WeakPtr<BrowserWindow> self) {
if (self)
self->Emit("ready-to-show");
},
GetWeakPtr()));
}
void BrowserWindow::BeforeUnloadDialogCancelled() {
WindowList::WindowCloseCancelled(window());
// Cancel unresponsive event when window close is cancelled.
window_unresponsive_closure_.Cancel();
}
void BrowserWindow::OnRendererUnresponsive(content::RenderProcessHost*) {
// Schedule the unresponsive shortly later, since we may receive the
// responsive event soon. This could happen after the whole application had
// blocked for a while.
// Also notice that when closing this event would be ignored because we have
// explicitly started a close timeout counter. This is on purpose because we
// don't want the unresponsive event to be sent too early when user is closing
// the window.
ScheduleUnresponsiveEvent(50);
}
bool BrowserWindow::OnMessageReceived(const IPC::Message& message,
content::RenderFrameHost* rfh) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(BrowserWindow, message, rfh)
IPC_MESSAGE_HANDLER(AtomFrameHostMsg_UpdateDraggableRegions,
UpdateDraggableRegions)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
void BrowserWindow::OnCloseContents() {
DCHECK(web_contents());
// Close all child windows before closing current window.
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
for (v8::Local<v8::Value> value : child_windows_.Values(isolate())) {
mate::Handle<BrowserWindow> child;
if (mate::ConvertFromV8(isolate(), value, &child) && !child.IsEmpty())
child->window()->CloseImmediately();
}
// When the web contents is gone, close the window immediately, but the
// memory will not be freed until you call delete.
// In this way, it would be safe to manage windows via smart pointers. If you
// want to free memory when the window is closed, you can do deleting by
// overriding the OnWindowClosed method in the observer.
window()->CloseImmediately();
// Do not sent "unresponsive" event after window is closed.
window_unresponsive_closure_.Cancel();
}
void BrowserWindow::OnRendererResponsive() {
window_unresponsive_closure_.Cancel();
Emit("responsive");
}
void BrowserWindow::RequestPreferredWidth(int* width) {
*width = web_contents()->GetPreferredSize().width();
}
void BrowserWindow::OnCloseButtonClicked(bool* prevent_default) {
// When user tries to close the window by clicking the close button, we do
// not close the window immediately, instead we try to close the web page
// first, and when the web page is closed the window will also be closed.
*prevent_default = true;
// Assume the window is not responding if it doesn't cancel the close and is
// not closed in 5s, in this way we can quickly show the unresponsive
// dialog when the window is busy executing some script withouth waiting for
// the unresponsive timeout.
if (window_unresponsive_closure_.IsCancelled())
ScheduleUnresponsiveEvent(5000);
if (!web_contents())
// Already closed by renderer
return;
if (web_contents()->NeedToFireBeforeUnload())
web_contents()->DispatchBeforeUnload();
else
web_contents()->Close();
}
void BrowserWindow::OnWindowClosed() {
Cleanup();
TopLevelWindow::OnWindowClosed();
}
void BrowserWindow::OnWindowBlur() {
web_contents()->StoreFocus();
#if defined(OS_MACOSX)
auto* rwhv = web_contents()->GetRenderWidgetHostView();
if (rwhv)
rwhv->SetActive(false);
#endif
TopLevelWindow::OnWindowBlur();
}
void BrowserWindow::OnWindowFocus() {
web_contents()->RestoreFocus();
#if defined(OS_MACOSX)
auto* rwhv = web_contents()->GetRenderWidgetHostView();
if (rwhv)
rwhv->SetActive(true);
#else
if (!api_web_contents_->IsDevToolsOpened())
web_contents()->Focus();
#endif
TopLevelWindow::OnWindowFocus();
}
void BrowserWindow::OnWindowResize() {
#if defined(OS_MACOSX)
if (!draggable_regions_.empty())
UpdateDraggableRegions(nullptr, draggable_regions_);
#endif
TopLevelWindow::OnWindowResize();
}
void BrowserWindow::OnWindowLeaveFullScreen() {
TopLevelWindow::OnWindowLeaveFullScreen();
#if defined(OS_MACOSX)
if (web_contents()->IsFullscreenForCurrentTab())
web_contents()->ExitFullscreen(true);
#endif
}
void BrowserWindow::Focus() {
if (api_web_contents_->IsOffScreen())
FocusOnWebView();
else
TopLevelWindow::Focus();
}
void BrowserWindow::Blur() {
if (api_web_contents_->IsOffScreen())
BlurWebView();
else
TopLevelWindow::Blur();
}
void BrowserWindow::SetBackgroundColor(const std::string& color_name) {
TopLevelWindow::SetBackgroundColor(color_name);
auto* view = web_contents()->GetRenderWidgetHostView();
if (view)
view->SetBackgroundColor(ParseHexColor(color_name));
}
void BrowserWindow::SetBrowserView(v8::Local<v8::Value> value) {
TopLevelWindow::SetBrowserView(value);
#if defined(OS_MACOSX)
UpdateDraggableRegions(nullptr, draggable_regions_);
#endif
}
void BrowserWindow::SetVibrancy(v8::Isolate* isolate,
v8::Local<v8::Value> value) {
std::string type = mate::V8ToString(value);
auto* render_view_host = web_contents()->GetRenderViewHost();
if (render_view_host) {
auto* impl = content::RenderWidgetHostImpl::FromID(
render_view_host->GetProcess()->GetID(),
render_view_host->GetRoutingID());
if (impl)
impl->SetBackgroundOpaque(type.empty() ? !window_->transparent() : false);
}
TopLevelWindow::SetVibrancy(isolate, value);
}
void BrowserWindow::FocusOnWebView() {
web_contents()->GetRenderViewHost()->GetWidget()->Focus();
}
void BrowserWindow::BlurWebView() {
web_contents()->GetRenderViewHost()->GetWidget()->Blur();
}
bool BrowserWindow::IsWebViewFocused() {
auto* host_view = web_contents()->GetRenderViewHost()->GetWidget()->GetView();
return host_view && host_view->HasFocus();
}
v8::Local<v8::Value> BrowserWindow::GetWebContents(v8::Isolate* isolate) {
if (web_contents_.IsEmpty())
return v8::Null(isolate);
return v8::Local<v8::Value>::New(isolate, web_contents_);
}
// Convert draggable regions in raw format to SkRegion format.
std::unique_ptr<SkRegion> BrowserWindow::DraggableRegionsToSkRegion(
const std::vector<DraggableRegion>& regions) {
auto sk_region = std::make_unique<SkRegion>();
for (const DraggableRegion& region : regions) {
sk_region->op(
region.bounds.x(), region.bounds.y(), region.bounds.right(),
region.bounds.bottom(),
region.draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op);
}
return sk_region;
}
void BrowserWindow::ScheduleUnresponsiveEvent(int ms) {
if (!window_unresponsive_closure_.IsCancelled())
return;
window_unresponsive_closure_.Reset(
base::Bind(&BrowserWindow::NotifyWindowUnresponsive, GetWeakPtr()));
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE, window_unresponsive_closure_.callback(),
base::TimeDelta::FromMilliseconds(ms));
}
void BrowserWindow::NotifyWindowUnresponsive() {
window_unresponsive_closure_.Cancel();
if (!window_->IsClosed() && window_->IsEnabled() &&
!IsUnresponsiveEventSuppressed()) {
Emit("unresponsive");
}
}
void BrowserWindow::Cleanup() {
auto* host = web_contents()->GetRenderViewHost();
if (host)
host->GetWidget()->RemoveInputEventObserver(this);
api_web_contents_->DestroyWebContents(true /* async */);
Observe(nullptr);
}
// static
mate::WrappableBase* BrowserWindow::New(mate::Arguments* args) {
if (!Browser::Get()->is_ready()) {
args->ThrowError("Cannot create BrowserWindow before app is ready");
return nullptr;
}
if (args->Length() > 1) {
args->ThrowError();
return nullptr;
}
mate::Dictionary options;
if (!(args->Length() == 1 && args->GetNext(&options))) {
options = mate::Dictionary::CreateEmpty(args->isolate());
}
return new BrowserWindow(args->isolate(), args->GetThis(), options);
}
// static
void BrowserWindow::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "BrowserWindow"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.SetMethod("focusOnWebView", &BrowserWindow::FocusOnWebView)
.SetMethod("blurWebView", &BrowserWindow::BlurWebView)
.SetMethod("isWebViewFocused", &BrowserWindow::IsWebViewFocused)
.SetProperty("webContents", &BrowserWindow::GetWebContents);
}
// static
v8::Local<v8::Value> BrowserWindow::From(v8::Isolate* isolate,
NativeWindow* native_window) {
auto* existing = TrackableObject::FromWrappedClass(isolate, native_window);
if (existing)
return existing->GetWrapper();
else
return v8::Null(isolate);
}
} // namespace api
} // namespace atom
namespace {
using atom::api::BrowserWindow;
using atom::api::TopLevelWindow;
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary dict(isolate, exports);
dict.Set("BrowserWindow", mate::CreateConstructor<BrowserWindow>(
isolate, base::Bind(&BrowserWindow::New)));
}
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_window, Initialize)

View File

@@ -0,0 +1,126 @@
// Copyright (c) 2013 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_API_ATOM_API_BROWSER_WINDOW_H_
#define ATOM_BROWSER_API_ATOM_API_BROWSER_WINDOW_H_
#include <string>
#include <vector>
#include "atom/browser/api/atom_api_top_level_window.h"
#include "atom/browser/api/atom_api_web_contents.h"
#include "base/cancelable_callback.h"
namespace atom {
namespace api {
class BrowserWindow : public TopLevelWindow,
public content::RenderWidgetHost::InputEventObserver,
public content::WebContentsObserver,
public ExtendedWebContentsObserver {
public:
static mate::WrappableBase* New(mate::Arguments* args);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
// Returns the BrowserWindow object from |native_window|.
static v8::Local<v8::Value> From(v8::Isolate* isolate,
NativeWindow* native_window);
base::WeakPtr<BrowserWindow> GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
protected:
BrowserWindow(v8::Isolate* isolate,
v8::Local<v8::Object> wrapper,
const mate::Dictionary& options);
~BrowserWindow() override;
// content::RenderWidgetHost::InputEventObserver:
void OnInputEvent(const blink::WebInputEvent& event) override;
// content::WebContentsObserver:
void RenderViewHostChanged(content::RenderViewHost* old_host,
content::RenderViewHost* new_host) override;
void RenderViewCreated(content::RenderViewHost* render_view_host) override;
void DidFirstVisuallyNonEmptyPaint() override;
void BeforeUnloadDialogCancelled() override;
void OnRendererUnresponsive(content::RenderProcessHost*) override;
bool OnMessageReceived(const IPC::Message& message,
content::RenderFrameHost* rfh) override;
// ExtendedWebContentsObserver:
void OnCloseContents() override;
void OnRendererResponsive() override;
// NativeWindowObserver:
void RequestPreferredWidth(int* width) override;
void OnCloseButtonClicked(bool* prevent_default) override;
// TopLevelWindow:
void OnWindowClosed() override;
void OnWindowBlur() override;
void OnWindowFocus() override;
void OnWindowResize() override;
void OnWindowLeaveFullScreen() override;
void Focus() override;
void Blur() override;
void SetBackgroundColor(const std::string& color_name) override;
void SetBrowserView(v8::Local<v8::Value> value) override;
void SetVibrancy(v8::Isolate* isolate, v8::Local<v8::Value> value) override;
// BrowserWindow APIs.
void FocusOnWebView();
void BlurWebView();
bool IsWebViewFocused();
v8::Local<v8::Value> GetWebContents(v8::Isolate* isolate);
private:
#if defined(OS_MACOSX)
void OverrideNSWindowContentView(brightray::InspectableWebContents* iwc);
#endif
// Helpers.
// Called when the window needs to update its draggable region.
void UpdateDraggableRegions(content::RenderFrameHost* rfh,
const std::vector<DraggableRegion>& regions);
// Convert draggable regions in raw format to SkRegion format.
std::unique_ptr<SkRegion> DraggableRegionsToSkRegion(
const std::vector<DraggableRegion>& regions);
// Schedule a notification unresponsive event.
void ScheduleUnresponsiveEvent(int ms);
// Dispatch unresponsive event to observers.
void NotifyWindowUnresponsive();
// Cleanup our WebContents observers.
void Cleanup();
// Closure that would be called when window is unresponsive when closing,
// it should be cancelled when we can prove that the window is responsive.
base::CancelableClosure window_unresponsive_closure_;
#if defined(OS_MACOSX)
std::vector<DraggableRegion> draggable_regions_;
#endif
v8::Global<v8::Value> web_contents_;
api::WebContents* api_web_contents_;
base::WeakPtrFactory<BrowserWindow> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(BrowserWindow);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_BROWSER_WINDOW_H_

View File

@@ -0,0 +1,135 @@
// Copyright (c) 2018 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_browser_window.h"
#import <Cocoa/Cocoa.h>
#include "atom/browser/native_browser_view.h"
#include "atom/browser/native_window_mac.h"
#include "atom/common/draggable_region.h"
#include "base/mac/scoped_nsobject.h"
#include "brightray/browser/inspectable_web_contents_view.h"
@interface NSView (WebContentsView)
- (void)setMouseDownCanMoveWindow:(BOOL)can_move;
@end
@interface ControlRegionView : NSView
@end
@implementation ControlRegionView
- (BOOL)mouseDownCanMoveWindow {
return NO;
}
- (NSView*)hitTest:(NSPoint)aPoint {
return nil;
}
@end
namespace atom {
namespace api {
namespace {
// Return a vector of non-draggable regions that fill a window of size
// |width| by |height|, but leave gaps where the window should be draggable.
std::vector<gfx::Rect> CalculateNonDraggableRegions(
std::unique_ptr<SkRegion> draggable,
int width,
int height) {
std::vector<gfx::Rect> result;
SkRegion non_draggable;
non_draggable.op(0, 0, width, height, SkRegion::kUnion_Op);
non_draggable.op(*draggable, SkRegion::kDifference_Op);
for (SkRegion::Iterator it(non_draggable); !it.done(); it.next()) {
result.push_back(gfx::SkIRectToRect(it.rect()));
}
return result;
}
} // namespace
void BrowserWindow::OverrideNSWindowContentView(
brightray::InspectableWebContents* iwc) {
// Make NativeWindow use a NSView as content view.
static_cast<NativeWindowMac*>(window())->OverrideNSWindowContentView();
// Add webview to contentView.
NSView* webView = iwc->GetView()->GetNativeView();
NSView* contentView = [window()->GetNativeWindow() contentView];
[webView setFrame:[contentView bounds]];
// ensure that buttons view is floated to top of view hierarchy
NSArray* subviews = [contentView subviews];
NSView* last = subviews.lastObject;
[contentView addSubview:webView positioned:NSWindowBelow relativeTo:last];
[contentView viewDidMoveToWindow];
}
void BrowserWindow::UpdateDraggableRegions(
content::RenderFrameHost* rfh,
const std::vector<DraggableRegion>& regions) {
if (window_->has_frame())
return;
// All ControlRegionViews should be added as children of the WebContentsView,
// because WebContentsView will be removed and re-added when entering and
// leaving fullscreen mode.
NSView* webView = web_contents()->GetNativeView();
NSInteger webViewWidth = NSWidth([webView bounds]);
NSInteger webViewHeight = NSHeight([webView bounds]);
if ([webView respondsToSelector:@selector(setMouseDownCanMoveWindow:)]) {
[webView setMouseDownCanMoveWindow:YES];
}
// Remove all ControlRegionViews 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:[ControlRegionView class]])
[subview removeFromSuperview];
// Draggable regions is implemented by having the whole web view draggable
// (mouseDownCanMoveWindow) and overlaying regions that are not draggable.
draggable_regions_ = regions;
std::vector<gfx::Rect> drag_exclude_rects;
if (regions.empty()) {
drag_exclude_rects.push_back(gfx::Rect(0, 0, webViewWidth, webViewHeight));
} else {
drag_exclude_rects = CalculateNonDraggableRegions(
DraggableRegionsToSkRegion(regions), webViewWidth, webViewHeight);
}
if (window_->browser_view())
window_->browser_view()->UpdateDraggableRegions(drag_exclude_rects);
// Create and add a ControlRegionView for each region that needs to be
// excluded from the dragging.
for (const auto& rect : drag_exclude_rects) {
base::scoped_nsobject<NSView> controlRegion(
[[ControlRegionView alloc] initWithFrame:NSZeroRect]);
[controlRegion setFrame:NSMakeRect(rect.x(), webViewHeight - rect.bottom(),
rect.width(), rect.height())];
[webView addSubview:controlRegion];
}
// AppKit will not update its cache of mouseDownCanMoveWindow unless something
// changes. Previously we tried adding an NSView and removing it, but for some
// reason it required reposting the mouse-down event, and didn't always work.
// Calling the below seems to be an effective solution.
[[webView window] setMovableByWindowBackground:NO];
[[webView window] setMovableByWindowBackground:YES];
}
} // namespace api
} // namespace atom

View File

@@ -0,0 +1,24 @@
// Copyright (c) 2018 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_browser_window.h"
#include "atom/browser/native_window_views.h"
namespace atom {
namespace api {
void BrowserWindow::UpdateDraggableRegions(
content::RenderFrameHost* rfh,
const std::vector<DraggableRegion>& regions) {
if (window_->has_frame())
return;
static_cast<NativeWindowViews*>(window_.get())
->UpdateDraggableRegions(DraggableRegionsToSkRegion(regions));
}
} // namespace api
} // namespace atom

View File

@@ -0,0 +1,58 @@
// Copyright (c) 2018 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_button.h"
#include "atom/common/api/constructor.h"
#include "native_mate/dictionary.h"
#include "atom/common/node_includes.h"
namespace atom {
namespace api {
Button::Button(views::Button* button) : View(button) {
view()->set_owned_by_client();
}
Button::~Button() {}
void Button::ButtonPressed(views::Button* sender, const ui::Event& event) {
Emit("click");
}
// static
mate::WrappableBase* Button::New(mate::Arguments* args) {
args->ThrowError("Button can not be created directly");
return nullptr;
}
// static
void Button::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "Button"));
}
} // namespace api
} // namespace atom
namespace {
using atom::api::Button;
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary dict(isolate, exports);
dict.Set("Button",
mate::CreateConstructor<Button>(isolate, base::Bind(&Button::New)));
}
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_button, Initialize)

View File

@@ -0,0 +1,38 @@
// 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_BROWSER_API_ATOM_API_BUTTON_H_
#define ATOM_BROWSER_API_ATOM_API_BUTTON_H_
#include "atom/browser/api/atom_api_view.h"
#include "native_mate/handle.h"
#include "ui/views/controls/button/button.h"
namespace atom {
namespace api {
class Button : public View, public views::ButtonListener {
public:
static mate::WrappableBase* New(mate::Arguments* args);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
protected:
explicit Button(views::Button* view);
~Button() override;
// views::ButtonListener:
void ButtonPressed(views::Button* sender, const ui::Event& event) override;
private:
DISALLOW_COPY_AND_ASSIGN(Button);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_BUTTON_H_

View File

@@ -0,0 +1,92 @@
// Copyright (c) 2014 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include <set>
#include <string>
#include "atom/common/native_mate_converters/callback.h"
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "atom/common/native_mate_converters/value_converter.h"
#include "base/bind.h"
#include "base/files/file_util.h"
#include "content/public/browser/tracing_controller.h"
#include "native_mate/dictionary.h"
#include "atom/common/node_includes.h"
using content::TracingController;
namespace mate {
template <>
struct Converter<base::trace_event::TraceConfig> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
base::trace_event::TraceConfig* out) {
// (alexeykuzmin): A combination of "categoryFilter" and "traceOptions"
// has to be checked first because none of the fields
// in the `memory_dump_config` dict below are mandatory
// and we cannot check the config format.
Dictionary options;
if (ConvertFromV8(isolate, val, &options)) {
std::string category_filter, trace_options;
if (options.Get("categoryFilter", &category_filter) &&
options.Get("traceOptions", &trace_options)) {
*out = base::trace_event::TraceConfig(category_filter, trace_options);
return true;
}
}
base::DictionaryValue memory_dump_config;
if (ConvertFromV8(isolate, val, &memory_dump_config)) {
*out = base::trace_event::TraceConfig(memory_dump_config);
return true;
}
return false;
}
};
} // namespace mate
namespace {
using CompletionCallback = base::Callback<void(const base::FilePath&)>;
scoped_refptr<TracingController::TraceDataEndpoint> GetTraceDataEndpoint(
const base::FilePath& path,
const CompletionCallback& callback) {
base::FilePath result_file_path = path;
if (result_file_path.empty() && !base::CreateTemporaryFile(&result_file_path))
LOG(ERROR) << "Creating temporary file failed";
return TracingController::CreateFileEndpoint(
result_file_path, base::Bind(callback, result_file_path));
}
void StopRecording(const base::FilePath& path,
const CompletionCallback& callback) {
TracingController::GetInstance()->StopTracing(
GetTraceDataEndpoint(path, callback));
}
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
auto controller = base::Unretained(TracingController::GetInstance());
mate::Dictionary dict(context->GetIsolate(), exports);
dict.SetMethod("getCategories",
base::Bind(&TracingController::GetCategories, controller));
dict.SetMethod("startRecording",
base::Bind(&TracingController::StartTracing, controller));
dict.SetMethod("stopRecording", &StopRecording);
dict.SetMethod(
"getTraceBufferUsage",
base::Bind(&TracingController::GetTraceBufferUsage, controller));
}
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_content_tracing, Initialize)

View File

@@ -0,0 +1,326 @@
// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_cookies.h"
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/cookie_change_notifier.h"
#include "atom/common/native_mate_converters/callback.h"
#include "atom/common/native_mate_converters/gurl_converter.h"
#include "atom/common/native_mate_converters/value_converter.h"
#include "base/time/time.h"
#include "base/values.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "native_mate/dictionary.h"
#include "native_mate/object_template_builder.h"
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_store.h"
#include "net/cookies/cookie_util.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
using content::BrowserThread;
namespace mate {
template <>
struct Converter<atom::api::Cookies::Error> {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
atom::api::Cookies::Error val) {
if (val == atom::api::Cookies::SUCCESS)
return v8::Null(isolate);
else
return v8::Exception::Error(StringToV8(isolate, "Setting cookie failed"));
}
};
template <>
struct Converter<net::CanonicalCookie> {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
const net::CanonicalCookie& val) {
mate::Dictionary dict(isolate, v8::Object::New(isolate));
dict.Set("name", val.Name());
dict.Set("value", val.Value());
dict.Set("domain", val.Domain());
dict.Set("hostOnly", net::cookie_util::DomainIsHostOnly(val.Domain()));
dict.Set("path", val.Path());
dict.Set("secure", val.IsSecure());
dict.Set("httpOnly", val.IsHttpOnly());
dict.Set("session", !val.IsPersistent());
if (val.IsPersistent())
dict.Set("expirationDate", val.ExpiryDate().ToDoubleT());
return dict.GetHandle();
}
};
template <>
struct Converter<network::mojom::CookieChangeCause> {
static v8::Local<v8::Value> ToV8(
v8::Isolate* isolate,
const network::mojom::CookieChangeCause& val) {
switch (val) {
case network::mojom::CookieChangeCause::INSERTED:
case network::mojom::CookieChangeCause::EXPLICIT:
return mate::StringToV8(isolate, "explicit");
case network::mojom::CookieChangeCause::OVERWRITE:
return mate::StringToV8(isolate, "overwrite");
case network::mojom::CookieChangeCause::EXPIRED:
return mate::StringToV8(isolate, "expired");
case network::mojom::CookieChangeCause::EVICTED:
return mate::StringToV8(isolate, "evicted");
case network::mojom::CookieChangeCause::EXPIRED_OVERWRITE:
return mate::StringToV8(isolate, "expired-overwrite");
default:
return mate::StringToV8(isolate, "unknown");
}
}
};
} // namespace mate
namespace atom {
namespace api {
namespace {
// Returns whether |domain| matches |filter|.
bool MatchesDomain(std::string filter, const std::string& domain) {
// Add a leading '.' character to the filter domain if it doesn't exist.
if (net::cookie_util::DomainIsHostOnly(filter))
filter.insert(0, ".");
std::string sub_domain(domain);
// Strip any leading '.' character from the input cookie domain.
if (!net::cookie_util::DomainIsHostOnly(sub_domain))
sub_domain = sub_domain.substr(1);
// Now check whether the domain argument is a subdomain of the filter domain.
for (sub_domain.insert(0, "."); sub_domain.length() >= filter.length();) {
if (sub_domain == filter)
return true;
const size_t next_dot = sub_domain.find('.', 1); // Skip over leading dot.
sub_domain.erase(0, next_dot);
}
return false;
}
// Returns whether |cookie| matches |filter|.
bool MatchesCookie(const base::DictionaryValue* filter,
const net::CanonicalCookie& cookie) {
std::string str;
bool b;
if (filter->GetString("name", &str) && str != cookie.Name())
return false;
if (filter->GetString("path", &str) && str != cookie.Path())
return false;
if (filter->GetString("domain", &str) && !MatchesDomain(str, cookie.Domain()))
return false;
if (filter->GetBoolean("secure", &b) && b != cookie.IsSecure())
return false;
if (filter->GetBoolean("session", &b) && b != !cookie.IsPersistent())
return false;
return true;
}
// Helper to returns the CookieStore.
inline net::CookieStore* GetCookieStore(
scoped_refptr<net::URLRequestContextGetter> getter) {
return getter->GetURLRequestContext()->cookie_store();
}
// Run |callback| on UI thread.
void RunCallbackInUI(const base::Closure& callback) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback);
}
// Remove cookies from |list| not matching |filter|, and pass it to |callback|.
void FilterCookies(std::unique_ptr<base::DictionaryValue> filter,
const Cookies::GetCallback& callback,
const net::CookieList& list) {
net::CookieList result;
for (const auto& cookie : list) {
if (MatchesCookie(filter.get(), cookie))
result.push_back(cookie);
}
RunCallbackInUI(base::Bind(callback, Cookies::SUCCESS, result));
}
// Receives cookies matching |filter| in IO thread.
void GetCookiesOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
std::unique_ptr<base::DictionaryValue> filter,
const Cookies::GetCallback& callback) {
std::string url;
filter->GetString("url", &url);
auto filtered_callback =
base::Bind(FilterCookies, base::Passed(&filter), callback);
// Empty url will match all url cookies.
if (url.empty())
GetCookieStore(getter)->GetAllCookiesAsync(filtered_callback);
else
GetCookieStore(getter)->GetAllCookiesForURLAsync(GURL(url),
filtered_callback);
}
// Removes cookie with |url| and |name| in IO thread.
void RemoveCookieOnIOThread(scoped_refptr<net::URLRequestContextGetter> getter,
const GURL& url,
const std::string& name,
const base::Closure& callback) {
GetCookieStore(getter)->DeleteCookieAsync(
url, name, base::BindOnce(RunCallbackInUI, callback));
}
// Callback of SetCookie.
void OnSetCookie(const Cookies::SetCallback& callback, bool success) {
RunCallbackInUI(
base::Bind(callback, success ? Cookies::SUCCESS : Cookies::FAILED));
}
// Flushes cookie store in IO thread.
void FlushCookieStoreOnIOThread(
scoped_refptr<net::URLRequestContextGetter> getter,
const base::Closure& callback) {
GetCookieStore(getter)->FlushStore(base::BindOnce(RunCallbackInUI, callback));
}
// Sets cookie with |details| in IO thread.
void SetCookieOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
std::unique_ptr<base::DictionaryValue> details,
const Cookies::SetCallback& callback) {
std::string url, name, value, domain, path;
bool secure = false;
bool http_only = false;
double creation_date;
double expiration_date;
double last_access_date;
details->GetString("url", &url);
details->GetString("name", &name);
details->GetString("value", &value);
details->GetString("domain", &domain);
details->GetString("path", &path);
details->GetBoolean("secure", &secure);
details->GetBoolean("httpOnly", &http_only);
base::Time creation_time;
if (details->GetDouble("creationDate", &creation_date)) {
creation_time = (creation_date == 0)
? base::Time::UnixEpoch()
: base::Time::FromDoubleT(creation_date);
}
base::Time expiration_time;
if (details->GetDouble("expirationDate", &expiration_date)) {
expiration_time = (expiration_date == 0)
? base::Time::UnixEpoch()
: base::Time::FromDoubleT(expiration_date);
}
base::Time last_access_time;
if (details->GetDouble("lastAccessDate", &last_access_date)) {
last_access_time = (last_access_date == 0)
? base::Time::UnixEpoch()
: base::Time::FromDoubleT(last_access_date);
}
std::unique_ptr<net::CanonicalCookie> canonical_cookie(
net::CanonicalCookie::CreateSanitizedCookie(
GURL(url), name, value, domain, path, creation_time, expiration_time,
last_access_time, secure, http_only,
net::CookieSameSite::DEFAULT_MODE, net::COOKIE_PRIORITY_DEFAULT));
auto completion_callback = base::BindOnce(OnSetCookie, callback);
if (!canonical_cookie || !canonical_cookie->IsCanonical()) {
std::move(completion_callback).Run(false);
return;
}
if (url.empty()) {
std::move(completion_callback).Run(false);
return;
}
if (name.empty()) {
std::move(completion_callback).Run(false);
return;
}
GetCookieStore(getter)->SetCanonicalCookieAsync(
std::move(canonical_cookie), secure, http_only,
std::move(completion_callback));
}
} // namespace
Cookies::Cookies(v8::Isolate* isolate, AtomBrowserContext* browser_context)
: browser_context_(browser_context) {
Init(isolate);
cookie_change_subscription_ =
browser_context_->cookie_change_notifier()->RegisterCookieChangeCallback(
base::Bind(&Cookies::OnCookieChanged, base::Unretained(this)));
}
Cookies::~Cookies() {}
void Cookies::Get(const base::DictionaryValue& filter,
const GetCallback& callback) {
std::unique_ptr<base::DictionaryValue> copied(filter.CreateDeepCopy());
auto* getter = browser_context_->GetRequestContext();
content::BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(GetCookiesOnIO, base::RetainedRef(getter),
std::move(copied), callback));
}
void Cookies::Remove(const GURL& url,
const std::string& name,
const base::Closure& callback) {
auto* getter = browser_context_->GetRequestContext();
content::BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(RemoveCookieOnIOThread, base::RetainedRef(getter), url,
name, callback));
}
void Cookies::Set(const base::DictionaryValue& details,
const SetCallback& callback) {
std::unique_ptr<base::DictionaryValue> copied(details.CreateDeepCopy());
auto* getter = browser_context_->GetRequestContext();
content::BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(SetCookieOnIO, base::RetainedRef(getter),
std::move(copied), callback));
}
void Cookies::FlushStore(const base::Closure& callback) {
auto* getter = browser_context_->GetRequestContext();
content::BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(FlushCookieStoreOnIOThread, base::RetainedRef(getter),
callback));
}
void Cookies::OnCookieChanged(const CookieDetails* details) {
Emit("changed", *(details->cookie), details->cause, details->removed);
}
// static
mate::Handle<Cookies> Cookies::Create(v8::Isolate* isolate,
AtomBrowserContext* browser_context) {
return mate::CreateHandle(isolate, new Cookies(isolate, browser_context));
}
// static
void Cookies::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "Cookies"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.SetMethod("get", &Cookies::Get)
.SetMethod("remove", &Cookies::Remove)
.SetMethod("set", &Cookies::Set)
.SetMethod("flushStore", &Cookies::FlushStore);
}
} // namespace api
} // namespace atom

View File

@@ -0,0 +1,73 @@
// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_API_ATOM_API_COOKIES_H_
#define ATOM_BROWSER_API_ATOM_API_COOKIES_H_
#include <string>
#include "atom/browser/api/trackable_object.h"
#include "atom/browser/net/cookie_details.h"
#include "base/callback_list.h"
#include "native_mate/handle.h"
#include "net/cookies/canonical_cookie.h"
namespace base {
class DictionaryValue;
}
namespace net {
class URLRequestContextGetter;
}
namespace atom {
class AtomBrowserContext;
namespace api {
class Cookies : public mate::TrackableObject<Cookies> {
public:
enum Error {
SUCCESS,
FAILED,
};
using GetCallback = base::Callback<void(Error, const net::CookieList&)>;
using SetCallback = base::Callback<void(Error)>;
static mate::Handle<Cookies> Create(v8::Isolate* isolate,
AtomBrowserContext* browser_context);
// mate::TrackableObject:
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
protected:
Cookies(v8::Isolate* isolate, AtomBrowserContext* browser_context);
~Cookies() override;
void Get(const base::DictionaryValue& filter, const GetCallback& callback);
void Remove(const GURL& url,
const std::string& name,
const base::Closure& callback);
void Set(const base::DictionaryValue& details, const SetCallback& callback);
void FlushStore(const base::Closure& callback);
// CookieChangeNotifier subscription:
void OnCookieChanged(const CookieDetails*);
private:
std::unique_ptr<base::CallbackList<void(const CookieDetails*)>::Subscription>
cookie_change_subscription_;
scoped_refptr<AtomBrowserContext> browser_context_;
DISALLOW_COPY_AND_ASSIGN(Cookies);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_COOKIES_H_

View File

@@ -0,0 +1,196 @@
// Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_debugger.h"
#include <string>
#include "atom/common/native_mate_converters/callback.h"
#include "atom/common/native_mate_converters/value_converter.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/web_contents.h"
#include "native_mate/dictionary.h"
#include "atom/common/node_includes.h"
using content::DevToolsAgentHost;
namespace atom {
namespace api {
Debugger::Debugger(v8::Isolate* isolate, content::WebContents* web_contents)
: content::WebContentsObserver(web_contents), web_contents_(web_contents) {
Init(isolate);
}
Debugger::~Debugger() {}
void Debugger::AgentHostClosed(DevToolsAgentHost* agent_host) {
DCHECK(agent_host == agent_host_);
agent_host_ = nullptr;
ClearPendingRequests();
Emit("detach", "target closed");
}
void Debugger::DispatchProtocolMessage(DevToolsAgentHost* agent_host,
const std::string& message) {
DCHECK(agent_host == agent_host_);
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
std::unique_ptr<base::Value> parsed_message = base::JSONReader::Read(message);
if (!parsed_message || !parsed_message->is_dict())
return;
base::DictionaryValue* dict =
static_cast<base::DictionaryValue*>(parsed_message.get());
int id;
if (!dict->GetInteger("id", &id)) {
std::string method;
if (!dict->GetString("method", &method))
return;
base::DictionaryValue* params_value = nullptr;
base::DictionaryValue params;
if (dict->GetDictionary("params", &params_value))
params.Swap(params_value);
Emit("message", method, params);
} else {
auto send_command_callback = pending_requests_[id];
pending_requests_.erase(id);
if (send_command_callback.is_null())
return;
base::DictionaryValue* error_body = nullptr;
base::DictionaryValue error;
if (dict->GetDictionary("error", &error_body))
error.Swap(error_body);
base::DictionaryValue* result_body = nullptr;
base::DictionaryValue result;
if (dict->GetDictionary("result", &result_body))
result.Swap(result_body);
send_command_callback.Run(error, result);
}
}
void Debugger::RenderFrameHostChanged(content::RenderFrameHost* old_rfh,
content::RenderFrameHost* new_rfh) {
if (agent_host_) {
agent_host_->DisconnectWebContents();
auto* web_contents = content::WebContents::FromRenderFrameHost(new_rfh);
agent_host_->ConnectWebContents(web_contents);
}
}
void Debugger::Attach(mate::Arguments* args) {
std::string protocol_version;
args->GetNext(&protocol_version);
if (agent_host_) {
args->ThrowError("Debugger is already attached to the target");
return;
}
if (!protocol_version.empty() &&
!DevToolsAgentHost::IsSupportedProtocolVersion(protocol_version)) {
args->ThrowError("Requested protocol version is not supported");
return;
}
agent_host_ = DevToolsAgentHost::GetOrCreateFor(web_contents_);
if (!agent_host_) {
args->ThrowError("No target available");
return;
}
agent_host_->AttachClient(this);
}
bool Debugger::IsAttached() {
return agent_host_ && agent_host_->IsAttached();
}
void Debugger::Detach() {
if (!agent_host_)
return;
agent_host_->DetachClient(this);
AgentHostClosed(agent_host_.get());
}
void Debugger::SendCommand(mate::Arguments* args) {
if (!agent_host_)
return;
std::string method;
if (!args->GetNext(&method)) {
args->ThrowError();
return;
}
base::DictionaryValue command_params;
args->GetNext(&command_params);
SendCommandCallback callback;
args->GetNext(&callback);
base::DictionaryValue request;
int request_id = ++previous_request_id_;
pending_requests_[request_id] = callback;
request.SetInteger("id", request_id);
request.SetString("method", method);
if (!command_params.empty())
request.Set("params", base::WrapUnique(command_params.DeepCopy()));
std::string json_args;
base::JSONWriter::Write(request, &json_args);
agent_host_->DispatchProtocolMessage(this, json_args);
}
void Debugger::ClearPendingRequests() {
if (pending_requests_.empty())
return;
base::Value error(base::Value::Type::DICTIONARY);
base::Value error_msg("target closed while handling command");
error.SetKey("message", std::move(error_msg));
for (const auto& it : pending_requests_)
it.second.Run(error, base::Value());
}
// static
mate::Handle<Debugger> Debugger::Create(v8::Isolate* isolate,
content::WebContents* web_contents) {
return mate::CreateHandle(isolate, new Debugger(isolate, web_contents));
}
// static
void Debugger::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "Debugger"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.SetMethod("attach", &Debugger::Attach)
.SetMethod("isAttached", &Debugger::IsAttached)
.SetMethod("detach", &Debugger::Detach)
.SetMethod("sendCommand", &Debugger::SendCommand);
}
} // namespace api
} // namespace atom
namespace {
using atom::api::Debugger;
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary(isolate, exports)
.Set("Debugger", Debugger::GetConstructor(isolate)->GetFunction());
}
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_debugger, Initialize);

View File

@@ -0,0 +1,80 @@
// Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_API_ATOM_API_DEBUGGER_H_
#define ATOM_BROWSER_API_ATOM_API_DEBUGGER_H_
#include <map>
#include <string>
#include "atom/browser/api/trackable_object.h"
#include "base/callback.h"
#include "base/values.h"
#include "content/public/browser/devtools_agent_host_client.h"
#include "content/public/browser/web_contents_observer.h"
#include "native_mate/handle.h"
namespace content {
class DevToolsAgentHost;
class WebContents;
} // namespace content
namespace mate {
class Arguments;
}
namespace atom {
namespace api {
class Debugger : public mate::TrackableObject<Debugger>,
public content::DevToolsAgentHostClient,
public content::WebContentsObserver {
public:
using SendCommandCallback =
base::Callback<void(const base::Value&, const base::Value&)>;
static mate::Handle<Debugger> Create(v8::Isolate* isolate,
content::WebContents* web_contents);
// mate::TrackableObject:
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
protected:
Debugger(v8::Isolate* isolate, content::WebContents* web_contents);
~Debugger() override;
// content::DevToolsAgentHostClient:
void AgentHostClosed(content::DevToolsAgentHost* agent_host) override;
void DispatchProtocolMessage(content::DevToolsAgentHost* agent_host,
const std::string& message) override;
// content::WebContentsObserver:
void RenderFrameHostChanged(content::RenderFrameHost* old_rfh,
content::RenderFrameHost* new_rfh) override;
private:
using PendingRequestMap = std::map<int, SendCommandCallback>;
void Attach(mate::Arguments* args);
bool IsAttached();
void Detach();
void SendCommand(mate::Arguments* args);
void ClearPendingRequests();
content::WebContents* web_contents_; // Weak Reference.
scoped_refptr<content::DevToolsAgentHost> agent_host_;
PendingRequestMap pending_requests_;
int previous_request_id_ = 0;
DISALLOW_COPY_AND_ASSIGN(Debugger);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_DEBUGGER_H_

View File

@@ -0,0 +1,207 @@
// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_desktop_capturer.h"
#include <vector>
using base::PlatformThreadRef;
#include "atom/common/api/atom_api_native_image.h"
#include "atom/common/native_mate_converters/gfx_converter.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task_scheduler/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
#include "chrome/browser/media/desktop_media_list.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/desktop_capture.h"
#include "native_mate/dictionary.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h"
#if defined(OS_WIN)
#include "third_party/webrtc/modules/desktop_capture/win/dxgi_duplicator_controller.h"
#include "third_party/webrtc/modules/desktop_capture/win/screen_capturer_win_directx.h"
#include "ui/display/win/display_info.h"
#endif // defined(OS_WIN)
#include "atom/common/node_includes.h"
namespace mate {
template <>
struct Converter<atom::api::DesktopCapturer::Source> {
static v8::Local<v8::Value> ToV8(
v8::Isolate* isolate,
const atom::api::DesktopCapturer::Source& source) {
mate::Dictionary dict(isolate, v8::Object::New(isolate));
content::DesktopMediaID id = source.media_list_source.id;
dict.Set("name", base::UTF16ToUTF8(source.media_list_source.name));
dict.Set("id", id.ToString());
dict.Set("thumbnail",
atom::api::NativeImage::Create(
isolate, gfx::Image(source.media_list_source.thumbnail)));
dict.Set("display_id", source.display_id);
return ConvertToV8(isolate, dict);
}
};
} // namespace mate
namespace {
void EmitFinished(
const std::vector<atom::api::DesktopCapturer::Source>& sources,
atom::api::DesktopCapturer* cap) {
cap->Emit("finished", sources);
}
void StartHandlingTask(bool capture_window,
bool capture_screen,
const gfx::Size& thumbnail_size,
atom::api::DesktopCapturer* cap) {
#if defined(OS_WIN)
if (content::desktop_capture::CreateDesktopCaptureOptions()
.allow_directx_capturer()) {
// DxgiDuplicatorController should be alive in this scope according to
// screen_capturer_win.cc.
auto duplicator = webrtc::DxgiDuplicatorController::Instance();
cap->using_directx_capturer_ =
webrtc::ScreenCapturerWinDirectx::IsSupported();
}
#endif // defined(OS_WIN)
std::unique_ptr<webrtc::DesktopCapturer> screen_capturer(
capture_screen ? content::desktop_capture::CreateScreenCapturer()
: nullptr);
std::unique_ptr<webrtc::DesktopCapturer> window_capturer(
capture_window ? content::desktop_capture::CreateWindowCapturer()
: nullptr);
cap->media_list_.reset(new NativeDesktopMediaList(
std::move(screen_capturer), std::move(window_capturer)));
cap->media_list_->SetThumbnailSize(thumbnail_size);
cap->media_list_->StartUpdating(cap);
}
void OnRefreshFinishedTask(atom::api::DesktopCapturer* cap) {
const auto media_list_sources = cap->media_list_->GetSources();
std::vector<atom::api::DesktopCapturer::Source> sources;
for (const auto& media_list_source : media_list_sources) {
sources.emplace_back(
atom::api::DesktopCapturer::Source{media_list_source, std::string()});
}
#if defined(OS_WIN)
// Gather the same unique screen IDs used by the electron.screen API in order
// to provide an association between it and desktopCapturer/getUserMedia.
// This is only required when using the DirectX capturer, otherwise the IDs
// across the APIs already match.
if (cap->using_directx_capturer_) {
std::vector<std::string> device_names;
// Crucially, this list of device names will be in the same order as
// |media_list_sources|.
webrtc::DxgiDuplicatorController::Instance()->GetDeviceNames(&device_names);
int device_name_index = 0;
for (auto& source : sources) {
if (source.media_list_source.id.type ==
content::DesktopMediaID::TYPE_SCREEN) {
const auto& device_name = device_names[device_name_index++];
std::wstring wide_device_name;
base::UTF8ToWide(device_name.c_str(), device_name.size(),
&wide_device_name);
const int64_t device_id =
display::win::DisplayInfo::DeviceIdFromDeviceName(
wide_device_name.c_str());
source.display_id = base::Int64ToString(device_id);
}
}
}
#elif defined(OS_MACOSX)
// On Mac, the IDs across the APIs match.
for (auto& source : sources) {
if (source.media_list_source.id.type ==
content::DesktopMediaID::TYPE_SCREEN) {
source.display_id = base::Int64ToString(source.media_list_source.id.id);
}
}
#endif // defined(OS_WIN)
// TODO(ajmacd): Add Linux support. The IDs across APIs differ but Chrome only
// supports capturing the entire desktop on Linux. Revisit this if individual
// screen support is added.
content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
base::Bind(EmitFinished, sources, cap));
}
} // namespace
namespace atom {
namespace api {
DesktopCapturer::DesktopCapturer(v8::Isolate* isolate) {
Init(isolate);
capture_thread_ = base::CreateSequencedTaskRunnerWithTraits(
{base::WithBaseSyncPrimitives(), base::MayBlock(),
base::TaskPriority::USER_VISIBLE});
}
DesktopCapturer::~DesktopCapturer() {}
void DesktopCapturer::StartHandling(bool capture_window,
bool capture_screen,
const gfx::Size& thumbnail_size) {
capture_thread_->PostTask(
FROM_HERE, base::BindOnce(StartHandlingTask, capture_window,
capture_screen, thumbnail_size, this));
}
void DesktopCapturer::OnSourceAdded(int index) {}
void DesktopCapturer::OnSourceRemoved(int index) {}
void DesktopCapturer::OnSourceMoved(int old_index, int new_index) {}
void DesktopCapturer::OnSourceNameChanged(int index) {}
void DesktopCapturer::OnSourceThumbnailChanged(int index) {}
bool DesktopCapturer::OnRefreshFinished() {
capture_thread_->PostTask(FROM_HERE,
base::BindOnce(OnRefreshFinishedTask, this));
return false;
}
// static
mate::Handle<DesktopCapturer> DesktopCapturer::Create(v8::Isolate* isolate) {
return mate::CreateHandle(isolate, new DesktopCapturer(isolate));
}
// static
void DesktopCapturer::BuildPrototype(
v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "DesktopCapturer"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.SetMethod("startHandling", &DesktopCapturer::StartHandling);
}
} // namespace api
} // namespace atom
namespace {
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary dict(isolate, exports);
dict.Set("desktopCapturer", atom::api::DesktopCapturer::Create(isolate));
}
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_desktop_capturer, Initialize);

View File

@@ -0,0 +1,64 @@
// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_API_ATOM_API_DESKTOP_CAPTURER_H_
#define ATOM_BROWSER_API_ATOM_API_DESKTOP_CAPTURER_H_
#include <string>
#include "atom/browser/api/event_emitter.h"
#include "chrome/browser/media/desktop_media_list_observer.h"
#include "chrome/browser/media/native_desktop_media_list.h"
#include "native_mate/handle.h"
namespace atom {
namespace api {
class DesktopCapturer : public mate::EventEmitter<DesktopCapturer>,
public DesktopMediaListObserver {
public:
struct Source {
DesktopMediaList::Source media_list_source;
// Will be an empty string if not available.
std::string display_id;
};
static mate::Handle<DesktopCapturer> Create(v8::Isolate* isolate);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
void StartHandling(bool capture_window,
bool capture_screen,
const gfx::Size& thumbnail_size);
std::unique_ptr<DesktopMediaList> media_list_;
#if defined(OS_WIN)
bool using_directx_capturer_ = false;
#endif // defined(OS_WIN)
protected:
explicit DesktopCapturer(v8::Isolate* isolate);
~DesktopCapturer() override;
// DesktopMediaListObserver overrides.
void OnSourceAdded(int index) override;
void OnSourceRemoved(int index) override;
void OnSourceMoved(int old_index, int new_index) override;
void OnSourceNameChanged(int index) override;
void OnSourceThumbnailChanged(int index) override;
bool OnRefreshFinished() override;
private:
scoped_refptr<base::SequencedTaskRunner> capture_thread_;
DISALLOW_COPY_AND_ASSIGN(DesktopCapturer);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_DESKTOP_CAPTURER_H_

View File

@@ -0,0 +1,142 @@
// Copyright (c) 2013 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include <string>
#include <utility>
#include <vector>
#include "atom/browser/api/atom_api_browser_window.h"
#include "atom/browser/native_window.h"
#include "atom/browser/ui/certificate_trust.h"
#include "atom/browser/ui/file_dialog.h"
#include "atom/browser/ui/message_box.h"
#include "atom/common/native_mate_converters/callback.h"
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "atom/common/native_mate_converters/image_converter.h"
#include "atom/common/native_mate_converters/net_converter.h"
#include "native_mate/dictionary.h"
#include "atom/common/node_includes.h"
namespace mate {
template <>
struct Converter<file_dialog::Filter> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
file_dialog::Filter* out) {
mate::Dictionary dict;
if (!ConvertFromV8(isolate, val, &dict))
return false;
if (!dict.Get("name", &(out->first)))
return false;
if (!dict.Get("extensions", &(out->second)))
return false;
return true;
}
};
template <>
struct Converter<file_dialog::DialogSettings> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
file_dialog::DialogSettings* out) {
mate::Dictionary dict;
if (!ConvertFromV8(isolate, val, &dict))
return false;
dict.Get("window", &(out->parent_window));
dict.Get("title", &(out->title));
dict.Get("message", &(out->message));
dict.Get("buttonLabel", &(out->button_label));
dict.Get("nameFieldLabel", &(out->name_field_label));
dict.Get("defaultPath", &(out->default_path));
dict.Get("filters", &(out->filters));
dict.Get("properties", &(out->properties));
dict.Get("showsTagField", &(out->shows_tag_field));
#if defined(MAS_BUILD)
dict.Get("securityScopedBookmarks", &(out->security_scoped_bookmarks));
#endif
return true;
}
};
} // namespace mate
namespace {
void ShowMessageBox(int type,
const std::vector<std::string>& buttons,
int default_id,
int cancel_id,
int options,
const std::string& title,
const std::string& message,
const std::string& detail,
const std::string& checkbox_label,
bool checkbox_checked,
const gfx::ImageSkia& icon,
atom::NativeWindow* window,
mate::Arguments* args) {
v8::Local<v8::Value> peek = args->PeekNext();
atom::MessageBoxCallback callback;
if (mate::Converter<atom::MessageBoxCallback>::FromV8(args->isolate(), peek,
&callback)) {
atom::ShowMessageBox(window, static_cast<atom::MessageBoxType>(type),
buttons, default_id, cancel_id, options, title,
message, detail, checkbox_label, checkbox_checked,
icon, callback);
} else {
int chosen = atom::ShowMessageBox(
window, static_cast<atom::MessageBoxType>(type), buttons, default_id,
cancel_id, options, title, message, detail, icon);
args->Return(chosen);
}
}
void ShowOpenDialog(const file_dialog::DialogSettings& settings,
mate::Arguments* args) {
v8::Local<v8::Value> peek = args->PeekNext();
file_dialog::OpenDialogCallback callback;
if (mate::Converter<file_dialog::OpenDialogCallback>::FromV8(
args->isolate(), peek, &callback)) {
file_dialog::ShowOpenDialog(settings, callback);
} else {
std::vector<base::FilePath> paths;
if (file_dialog::ShowOpenDialog(settings, &paths))
args->Return(paths);
}
}
void ShowSaveDialog(const file_dialog::DialogSettings& settings,
mate::Arguments* args) {
v8::Local<v8::Value> peek = args->PeekNext();
file_dialog::SaveDialogCallback callback;
if (mate::Converter<file_dialog::SaveDialogCallback>::FromV8(
args->isolate(), peek, &callback)) {
file_dialog::ShowSaveDialog(settings, callback);
} else {
base::FilePath path;
if (file_dialog::ShowSaveDialog(settings, &path))
args->Return(path);
}
}
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
mate::Dictionary dict(context->GetIsolate(), exports);
dict.SetMethod("showMessageBox", &ShowMessageBox);
dict.SetMethod("showErrorBox", &atom::ShowErrorBox);
dict.SetMethod("showOpenDialog", &ShowOpenDialog);
dict.SetMethod("showSaveDialog", &ShowSaveDialog);
#if defined(OS_MACOSX) || defined(OS_WIN)
dict.SetMethod("showCertificateTrustDialog",
&certificate_trust::ShowCertificateTrust);
#endif
}
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_dialog, Initialize)

View File

@@ -0,0 +1,241 @@
// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_download_item.h"
#include <map>
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/common/native_mate_converters/callback.h"
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "atom/common/native_mate_converters/gurl_converter.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "native_mate/dictionary.h"
#include "net/base/filename_util.h"
#include "atom/common/node_includes.h"
namespace mate {
template <>
struct Converter<download::DownloadItem::DownloadState> {
static v8::Local<v8::Value> ToV8(
v8::Isolate* isolate,
download::DownloadItem::DownloadState state) {
std::string download_state;
switch (state) {
case download::DownloadItem::IN_PROGRESS:
download_state = "progressing";
break;
case download::DownloadItem::COMPLETE:
download_state = "completed";
break;
case download::DownloadItem::CANCELLED:
download_state = "cancelled";
break;
case download::DownloadItem::INTERRUPTED:
download_state = "interrupted";
break;
default:
break;
}
return ConvertToV8(isolate, download_state);
}
};
} // namespace mate
namespace atom {
namespace api {
namespace {
std::map<uint32_t, v8::Global<v8::Object>> g_download_item_objects;
} // namespace
DownloadItem::DownloadItem(v8::Isolate* isolate,
download::DownloadItem* download_item)
: download_item_(download_item) {
download_item_->AddObserver(this);
Init(isolate);
AttachAsUserData(download_item);
}
DownloadItem::~DownloadItem() {
if (download_item_) {
// Destroyed by either garbage collection or destroy().
download_item_->RemoveObserver(this);
download_item_->Remove();
}
// Remove from the global map.
g_download_item_objects.erase(weak_map_id());
}
void DownloadItem::OnDownloadUpdated(download::DownloadItem* item) {
if (download_item_->IsDone()) {
Emit("done", item->GetState());
// Destroy the item once item is downloaded.
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
GetDestroyClosure());
} else {
Emit("updated", item->GetState());
}
}
void DownloadItem::OnDownloadDestroyed(download::DownloadItem* download_item) {
download_item_ = nullptr;
// Destroy the native class immediately when downloadItem is destroyed.
delete this;
}
void DownloadItem::Pause() {
download_item_->Pause();
}
bool DownloadItem::IsPaused() const {
return download_item_->IsPaused();
}
void DownloadItem::Resume() {
download_item_->Resume();
}
bool DownloadItem::CanResume() const {
return download_item_->CanResume();
}
void DownloadItem::Cancel() {
download_item_->Cancel(true);
}
int64_t DownloadItem::GetReceivedBytes() const {
return download_item_->GetReceivedBytes();
}
int64_t DownloadItem::GetTotalBytes() const {
return download_item_->GetTotalBytes();
}
std::string DownloadItem::GetMimeType() const {
return download_item_->GetMimeType();
}
bool DownloadItem::HasUserGesture() const {
return download_item_->HasUserGesture();
}
std::string DownloadItem::GetFilename() const {
return base::UTF16ToUTF8(
net::GenerateFileName(GetURL(), GetContentDisposition(), std::string(),
download_item_->GetSuggestedFilename(),
GetMimeType(), "download")
.LossyDisplayName());
}
std::string DownloadItem::GetContentDisposition() const {
return download_item_->GetContentDisposition();
}
const GURL& DownloadItem::GetURL() const {
return download_item_->GetURL();
}
const std::vector<GURL>& DownloadItem::GetURLChain() const {
return download_item_->GetUrlChain();
}
download::DownloadItem::DownloadState DownloadItem::GetState() const {
return download_item_->GetState();
}
bool DownloadItem::IsDone() const {
return download_item_->IsDone();
}
void DownloadItem::SetSavePath(const base::FilePath& path) {
save_path_ = path;
}
base::FilePath DownloadItem::GetSavePath() const {
return save_path_;
}
std::string DownloadItem::GetLastModifiedTime() const {
return download_item_->GetLastModifiedTime();
}
std::string DownloadItem::GetETag() const {
return download_item_->GetETag();
}
double DownloadItem::GetStartTime() const {
return download_item_->GetStartTime().ToDoubleT();
}
// static
void DownloadItem::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "DownloadItem"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.MakeDestroyable()
.SetMethod("pause", &DownloadItem::Pause)
.SetMethod("isPaused", &DownloadItem::IsPaused)
.SetMethod("resume", &DownloadItem::Resume)
.SetMethod("canResume", &DownloadItem::CanResume)
.SetMethod("cancel", &DownloadItem::Cancel)
.SetMethod("getReceivedBytes", &DownloadItem::GetReceivedBytes)
.SetMethod("getTotalBytes", &DownloadItem::GetTotalBytes)
.SetMethod("getMimeType", &DownloadItem::GetMimeType)
.SetMethod("hasUserGesture", &DownloadItem::HasUserGesture)
.SetMethod("getFilename", &DownloadItem::GetFilename)
.SetMethod("getContentDisposition", &DownloadItem::GetContentDisposition)
.SetMethod("getURL", &DownloadItem::GetURL)
.SetMethod("getURLChain", &DownloadItem::GetURLChain)
.SetMethod("getState", &DownloadItem::GetState)
.SetMethod("isDone", &DownloadItem::IsDone)
.SetMethod("setSavePath", &DownloadItem::SetSavePath)
.SetMethod("getSavePath", &DownloadItem::GetSavePath)
.SetMethod("getLastModifiedTime", &DownloadItem::GetLastModifiedTime)
.SetMethod("getETag", &DownloadItem::GetETag)
.SetMethod("getStartTime", &DownloadItem::GetStartTime);
}
// static
mate::Handle<DownloadItem> DownloadItem::Create(v8::Isolate* isolate,
download::DownloadItem* item) {
auto* existing = TrackableObject::FromWrappedClass(isolate, item);
if (existing)
return mate::CreateHandle(isolate, static_cast<DownloadItem*>(existing));
auto handle = mate::CreateHandle(isolate, new DownloadItem(isolate, item));
// Reference this object in case it got garbage collected.
g_download_item_objects[handle->weak_map_id()] =
v8::Global<v8::Object>(isolate, handle.ToV8());
return handle;
}
} // namespace api
} // namespace atom
namespace {
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary(isolate, exports)
.Set("DownloadItem",
atom::api::DownloadItem::GetConstructor(isolate)->GetFunction());
}
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_download_item, Initialize);

View File

@@ -0,0 +1,70 @@
// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_API_ATOM_API_DOWNLOAD_ITEM_H_
#define ATOM_BROWSER_API_ATOM_API_DOWNLOAD_ITEM_H_
#include <string>
#include <vector>
#include "atom/browser/api/trackable_object.h"
#include "base/files/file_path.h"
#include "components/download/public/common/download_item.h"
#include "native_mate/handle.h"
#include "url/gurl.h"
namespace atom {
namespace api {
class DownloadItem : public mate::TrackableObject<DownloadItem>,
public download::DownloadItem::Observer {
public:
static mate::Handle<DownloadItem> Create(v8::Isolate* isolate,
download::DownloadItem* item);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
void Pause();
bool IsPaused() const;
void Resume();
bool CanResume() const;
void Cancel();
int64_t GetReceivedBytes() const;
int64_t GetTotalBytes() const;
std::string GetMimeType() const;
bool HasUserGesture() const;
std::string GetFilename() const;
std::string GetContentDisposition() const;
const GURL& GetURL() const;
const std::vector<GURL>& GetURLChain() const;
download::DownloadItem::DownloadState GetState() const;
bool IsDone() const;
void SetSavePath(const base::FilePath& path);
base::FilePath GetSavePath() const;
std::string GetLastModifiedTime() const;
std::string GetETag() const;
double GetStartTime() const;
protected:
DownloadItem(v8::Isolate* isolate, download::DownloadItem* download_item);
~DownloadItem() override;
// Override download::DownloadItem::Observer methods
void OnDownloadUpdated(download::DownloadItem* download) override;
void OnDownloadDestroyed(download::DownloadItem* download) override;
private:
base::FilePath save_path_;
download::DownloadItem* download_item_;
DISALLOW_COPY_AND_ASSIGN(DownloadItem);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_DOWNLOAD_ITEM_H_

View File

@@ -0,0 +1,103 @@
// Copyright (c) 2014 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_global_shortcut.h"
#include <string>
#include "atom/common/native_mate_converters/accelerator_converter.h"
#include "atom/common/native_mate_converters/callback.h"
#include "base/stl_util.h"
#include "native_mate/dictionary.h"
#include "atom/common/node_includes.h"
using extensions::GlobalShortcutListener;
namespace atom {
namespace api {
GlobalShortcut::GlobalShortcut(v8::Isolate* isolate) {
Init(isolate);
}
GlobalShortcut::~GlobalShortcut() {
UnregisterAll();
}
void GlobalShortcut::OnKeyPressed(const ui::Accelerator& accelerator) {
if (accelerator_callback_map_.find(accelerator) ==
accelerator_callback_map_.end()) {
// This should never occur, because if it does, GlobalGlobalShortcutListener
// notifes us with wrong accelerator.
NOTREACHED();
return;
}
accelerator_callback_map_[accelerator].Run();
}
bool GlobalShortcut::Register(const ui::Accelerator& accelerator,
const base::Closure& callback) {
if (!GlobalShortcutListener::GetInstance()->RegisterAccelerator(accelerator,
this)) {
return false;
}
accelerator_callback_map_[accelerator] = callback;
return true;
}
void GlobalShortcut::Unregister(const ui::Accelerator& accelerator) {
if (!ContainsKey(accelerator_callback_map_, accelerator))
return;
accelerator_callback_map_.erase(accelerator);
GlobalShortcutListener::GetInstance()->UnregisterAccelerator(accelerator,
this);
}
bool GlobalShortcut::IsRegistered(const ui::Accelerator& accelerator) {
return ContainsKey(accelerator_callback_map_, accelerator);
}
void GlobalShortcut::UnregisterAll() {
accelerator_callback_map_.clear();
GlobalShortcutListener::GetInstance()->UnregisterAccelerators(this);
}
// static
mate::Handle<GlobalShortcut> GlobalShortcut::Create(v8::Isolate* isolate) {
return mate::CreateHandle(isolate, new GlobalShortcut(isolate));
}
// static
void GlobalShortcut::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "GlobalShortcut"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.SetMethod("register", &GlobalShortcut::Register)
.SetMethod("isRegistered", &GlobalShortcut::IsRegistered)
.SetMethod("unregister", &GlobalShortcut::Unregister)
.SetMethod("unregisterAll", &GlobalShortcut::UnregisterAll);
}
} // namespace api
} // namespace atom
namespace {
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary dict(isolate, exports);
dict.Set("globalShortcut", atom::api::GlobalShortcut::Create(isolate));
}
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_global_shortcut, Initialize)

View File

@@ -0,0 +1,54 @@
// Copyright (c) 2014 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_API_ATOM_API_GLOBAL_SHORTCUT_H_
#define ATOM_BROWSER_API_ATOM_API_GLOBAL_SHORTCUT_H_
#include <map>
#include <string>
#include "atom/browser/api/trackable_object.h"
#include "base/callback.h"
#include "chrome/browser/extensions/global_shortcut_listener.h"
#include "native_mate/handle.h"
#include "ui/base/accelerators/accelerator.h"
namespace atom {
namespace api {
class GlobalShortcut : public extensions::GlobalShortcutListener::Observer,
public mate::TrackableObject<GlobalShortcut> {
public:
static mate::Handle<GlobalShortcut> Create(v8::Isolate* isolate);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
protected:
explicit GlobalShortcut(v8::Isolate* isolate);
~GlobalShortcut() override;
private:
typedef std::map<ui::Accelerator, base::Closure> AcceleratorCallbackMap;
bool Register(const ui::Accelerator& accelerator,
const base::Closure& callback);
bool IsRegistered(const ui::Accelerator& accelerator);
void Unregister(const ui::Accelerator& accelerator);
void UnregisterAll();
// GlobalShortcutListener::Observer implementation.
void OnKeyPressed(const ui::Accelerator& accelerator) override;
AcceleratorCallbackMap accelerator_callback_map_;
DISALLOW_COPY_AND_ASSIGN(GlobalShortcut);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_GLOBAL_SHORTCUT_H_

View File

@@ -0,0 +1,142 @@
// Copyright (c) 2017 Amaplex Software, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_in_app_purchase.h"
#include <string>
#include <utility>
#include <vector>
#include "atom/common/native_mate_converters/callback.h"
#include "native_mate/dictionary.h"
#include "atom/common/node_includes.h"
namespace mate {
template <>
struct Converter<in_app_purchase::Payment> {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
const in_app_purchase::Payment& payment) {
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
dict.SetHidden("simple", true);
dict.Set("productIdentifier", payment.productIdentifier);
dict.Set("quantity", payment.quantity);
return dict.GetHandle();
}
};
template <>
struct Converter<in_app_purchase::Transaction> {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
const in_app_purchase::Transaction& val) {
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
dict.SetHidden("simple", true);
dict.Set("transactionIdentifier", val.transactionIdentifier);
dict.Set("transactionDate", val.transactionDate);
dict.Set("originalTransactionIdentifier",
val.originalTransactionIdentifier);
dict.Set("transactionState", val.transactionState);
dict.Set("errorCode", val.errorCode);
dict.Set("errorMessage", val.errorMessage);
dict.Set("payment", val.payment);
return dict.GetHandle();
}
};
template <>
struct Converter<in_app_purchase::Product> {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
const in_app_purchase::Product& val) {
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
dict.SetHidden("simple", true);
dict.Set("productIdentifier", val.productIdentifier);
dict.Set("localizedDescription", val.localizedDescription);
dict.Set("localizedTitle", val.localizedTitle);
dict.Set("contentVersion", val.localizedTitle);
dict.Set("contentLengths", val.contentLengths);
// Pricing Information
dict.Set("price", val.price);
dict.Set("formattedPrice", val.formattedPrice);
// Downloadable Content Information
dict.Set("isDownloadable", val.downloadable);
return dict.GetHandle();
}
};
} // namespace mate
namespace atom {
namespace api {
#if defined(OS_MACOSX)
// static
mate::Handle<InAppPurchase> InAppPurchase::Create(v8::Isolate* isolate) {
return mate::CreateHandle(isolate, new InAppPurchase(isolate));
}
// static
void InAppPurchase::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "InAppPurchase"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.SetMethod("canMakePayments", &in_app_purchase::CanMakePayments)
.SetMethod("getReceiptURL", &in_app_purchase::GetReceiptURL)
.SetMethod("purchaseProduct", &InAppPurchase::PurchaseProduct)
.SetMethod("finishAllTransactions",
&in_app_purchase::FinishAllTransactions)
.SetMethod("finishTransactionByDate",
&in_app_purchase::FinishTransactionByDate)
.SetMethod("getProducts", &in_app_purchase::GetProducts);
}
InAppPurchase::InAppPurchase(v8::Isolate* isolate) {
Init(isolate);
}
InAppPurchase::~InAppPurchase() {}
void InAppPurchase::PurchaseProduct(const std::string& product_id,
mate::Arguments* args) {
int quantity = 1;
in_app_purchase::InAppPurchaseCallback callback;
args->GetNext(&quantity);
args->GetNext(&callback);
in_app_purchase::PurchaseProduct(product_id, quantity, callback);
}
void InAppPurchase::OnTransactionsUpdated(
const std::vector<in_app_purchase::Transaction>& transactions) {
Emit("transactions-updated", transactions);
}
#endif
} // namespace api
} // namespace atom
namespace {
using atom::api::InAppPurchase;
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
#if defined(OS_MACOSX)
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary dict(isolate, exports);
dict.Set("inAppPurchase", InAppPurchase::Create(isolate));
dict.Set("InAppPurchase",
InAppPurchase::GetConstructor(isolate)->GetFunction());
#endif
}
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_in_app_purchase, Initialize)

View File

@@ -0,0 +1,47 @@
// Copyright (c) 2017 Amaplex Software, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_API_ATOM_API_IN_APP_PURCHASE_H_
#define ATOM_BROWSER_API_ATOM_API_IN_APP_PURCHASE_H_
#include <string>
#include <vector>
#include "atom/browser/api/event_emitter.h"
#include "atom/browser/mac/in_app_purchase.h"
#include "atom/browser/mac/in_app_purchase_observer.h"
#include "atom/browser/mac/in_app_purchase_product.h"
#include "native_mate/handle.h"
namespace atom {
namespace api {
class InAppPurchase : public mate::EventEmitter<InAppPurchase>,
public in_app_purchase::TransactionObserver {
public:
static mate::Handle<InAppPurchase> Create(v8::Isolate* isolate);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
protected:
explicit InAppPurchase(v8::Isolate* isolate);
~InAppPurchase() override;
void PurchaseProduct(const std::string& product_id, mate::Arguments* args);
// TransactionObserver:
void OnTransactionsUpdated(
const std::vector<in_app_purchase::Transaction>& transactions) override;
private:
DISALLOW_COPY_AND_ASSIGN(InAppPurchase);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_IN_APP_PURCHASE_H_

View File

@@ -0,0 +1,58 @@
// Copyright (c) 2018 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_label_button.h"
#include "atom/common/api/constructor.h"
#include "base/strings/utf_string_conversions.h"
#include "native_mate/dictionary.h"
#include "ui/views/controls/button/label_button.h"
#include "atom/common/node_includes.h"
namespace atom {
namespace api {
LabelButton::LabelButton(const std::string& text)
: Button(new views::LabelButton(this, base::UTF8ToUTF16(text))) {}
LabelButton::~LabelButton() {}
// static
mate::WrappableBase* LabelButton::New(mate::Arguments* args,
const std::string& text) {
// Constructor call.
auto* view = new LabelButton(text);
view->InitWith(args->isolate(), args->GetThis());
return view;
}
// static
void LabelButton::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "LabelButton"));
}
} // namespace api
} // namespace atom
namespace {
using atom::api::LabelButton;
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary dict(isolate, exports);
dict.Set("LabelButton", mate::CreateConstructor<LabelButton>(
isolate, base::Bind(&LabelButton::New)));
}
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_label_button, Initialize)

View File

@@ -0,0 +1,36 @@
// 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_BROWSER_API_ATOM_API_LABEL_BUTTON_H_
#define ATOM_BROWSER_API_ATOM_API_LABEL_BUTTON_H_
#include <string>
#include "atom/browser/api/atom_api_button.h"
namespace atom {
namespace api {
class LabelButton : public Button {
public:
static mate::WrappableBase* New(mate::Arguments* args,
const std::string& text);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
protected:
explicit LabelButton(const std::string& text);
~LabelButton() override;
private:
DISALLOW_COPY_AND_ASSIGN(LabelButton);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_LABEL_BUTTON_H_

View File

@@ -0,0 +1,63 @@
// Copyright (c) 2018 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_layout_manager.h"
#include "atom/common/api/constructor.h"
#include "native_mate/dictionary.h"
#include "atom/common/node_includes.h"
namespace atom {
namespace api {
LayoutManager::LayoutManager(views::LayoutManager* layout_manager)
: layout_manager_(layout_manager) {
DCHECK(layout_manager_);
}
LayoutManager::~LayoutManager() {
if (managed_by_us_)
delete layout_manager_;
}
std::unique_ptr<views::LayoutManager> LayoutManager::TakeOver() {
if (!managed_by_us_) // already taken over.
return nullptr;
managed_by_us_ = false;
return std::unique_ptr<views::LayoutManager>(layout_manager_);
}
// static
mate::WrappableBase* LayoutManager::New(mate::Arguments* args) {
args->ThrowError("LayoutManager can not be created directly");
return nullptr;
}
// static
void LayoutManager::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {}
} // namespace api
} // namespace atom
namespace {
using atom::api::LayoutManager;
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary dict(isolate, exports);
dict.Set("LayoutManager", mate::CreateConstructor<LayoutManager>(
isolate, base::Bind(&LayoutManager::New)));
}
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_layout_manager, Initialize)

View File

@@ -0,0 +1,44 @@
// 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_BROWSER_API_ATOM_API_LAYOUT_MANAGER_H_
#define ATOM_BROWSER_API_ATOM_API_LAYOUT_MANAGER_H_
#include <memory>
#include "atom/browser/api/trackable_object.h"
#include "ui/views/layout/layout_manager.h"
namespace atom {
namespace api {
class LayoutManager : public mate::TrackableObject<LayoutManager> {
public:
static mate::WrappableBase* New(mate::Arguments* args);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
// Take over the ownership of the LayoutManager, and leave weak ref here.
std::unique_ptr<views::LayoutManager> TakeOver();
views::LayoutManager* layout_manager() const { return layout_manager_; }
protected:
explicit LayoutManager(views::LayoutManager* layout_manager);
~LayoutManager() override;
private:
bool managed_by_us_ = true;
views::LayoutManager* layout_manager_;
DISALLOW_COPY_AND_ASSIGN(LayoutManager);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_LAYOUT_MANAGER_H_

View File

@@ -0,0 +1,231 @@
// Copyright (c) 2013 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_menu.h"
#include "atom/browser/native_window.h"
#include "atom/common/native_mate_converters/accelerator_converter.h"
#include "atom/common/native_mate_converters/callback.h"
#include "atom/common/native_mate_converters/image_converter.h"
#include "atom/common/native_mate_converters/string16_converter.h"
#include "native_mate/constructor.h"
#include "native_mate/dictionary.h"
#include "native_mate/object_template_builder.h"
#include "atom/common/node_includes.h"
namespace atom {
namespace api {
Menu::Menu(v8::Isolate* isolate, v8::Local<v8::Object> wrapper)
: model_(new AtomMenuModel(this)) {
InitWith(isolate, wrapper);
model_->AddObserver(this);
}
Menu::~Menu() {
if (model_) {
model_->RemoveObserver(this);
}
}
void Menu::AfterInit(v8::Isolate* isolate) {
mate::Dictionary wrappable(isolate, GetWrapper());
mate::Dictionary delegate;
if (!wrappable.Get("delegate", &delegate))
return;
delegate.Get("isCommandIdChecked", &is_checked_);
delegate.Get("isCommandIdEnabled", &is_enabled_);
delegate.Get("isCommandIdVisible", &is_visible_);
delegate.Get("getAcceleratorForCommandId", &get_accelerator_);
delegate.Get("executeCommand", &execute_command_);
delegate.Get("menuWillShow", &menu_will_show_);
}
bool Menu::IsCommandIdChecked(int command_id) const {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
return is_checked_.Run(GetWrapper(), command_id);
}
bool Menu::IsCommandIdEnabled(int command_id) const {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
return is_enabled_.Run(GetWrapper(), command_id);
}
bool Menu::IsCommandIdVisible(int command_id) const {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
return is_visible_.Run(GetWrapper(), command_id);
}
bool Menu::GetAcceleratorForCommandIdWithParams(
int command_id,
bool use_default_accelerator,
ui::Accelerator* accelerator) const {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
v8::Local<v8::Value> val =
get_accelerator_.Run(GetWrapper(), command_id, use_default_accelerator);
return mate::ConvertFromV8(isolate(), val, accelerator);
}
void Menu::ExecuteCommand(int command_id, int flags) {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
execute_command_.Run(GetWrapper(),
mate::internal::CreateEventFromFlags(isolate(), flags),
command_id);
}
void Menu::MenuWillShow(ui::SimpleMenuModel* source) {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
menu_will_show_.Run(GetWrapper());
}
void Menu::InsertItemAt(int index,
int command_id,
const base::string16& label) {
model_->InsertItemAt(index, command_id, label);
}
void Menu::InsertSeparatorAt(int index) {
model_->InsertSeparatorAt(index, ui::NORMAL_SEPARATOR);
}
void Menu::InsertCheckItemAt(int index,
int command_id,
const base::string16& label) {
model_->InsertCheckItemAt(index, command_id, label);
}
void Menu::InsertRadioItemAt(int index,
int command_id,
const base::string16& label,
int group_id) {
model_->InsertRadioItemAt(index, command_id, label, group_id);
}
void Menu::InsertSubMenuAt(int index,
int command_id,
const base::string16& label,
Menu* menu) {
menu->parent_ = this;
model_->InsertSubMenuAt(index, command_id, label, menu->model_.get());
}
void Menu::SetIcon(int index, const gfx::Image& image) {
model_->SetIcon(index, image);
}
void Menu::SetSublabel(int index, const base::string16& sublabel) {
model_->SetSublabel(index, sublabel);
}
void Menu::SetRole(int index, const base::string16& role) {
model_->SetRole(index, role);
}
void Menu::Clear() {
model_->Clear();
}
int Menu::GetIndexOfCommandId(int command_id) {
return model_->GetIndexOfCommandId(command_id);
}
int Menu::GetItemCount() const {
return model_->GetItemCount();
}
int Menu::GetCommandIdAt(int index) const {
return model_->GetCommandIdAt(index);
}
base::string16 Menu::GetLabelAt(int index) const {
return model_->GetLabelAt(index);
}
base::string16 Menu::GetSublabelAt(int index) const {
return model_->GetSublabelAt(index);
}
bool Menu::IsItemCheckedAt(int index) const {
return model_->IsItemCheckedAt(index);
}
bool Menu::IsEnabledAt(int index) const {
return model_->IsEnabledAt(index);
}
bool Menu::IsVisibleAt(int index) const {
return model_->IsVisibleAt(index);
}
void Menu::OnMenuWillClose() {
Emit("menu-will-close");
}
void Menu::OnMenuWillShow() {
Emit("menu-will-show");
}
// static
void Menu::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "Menu"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.MakeDestroyable()
.SetMethod("insertItem", &Menu::InsertItemAt)
.SetMethod("insertCheckItem", &Menu::InsertCheckItemAt)
.SetMethod("insertRadioItem", &Menu::InsertRadioItemAt)
.SetMethod("insertSeparator", &Menu::InsertSeparatorAt)
.SetMethod("insertSubMenu", &Menu::InsertSubMenuAt)
.SetMethod("setIcon", &Menu::SetIcon)
.SetMethod("setSublabel", &Menu::SetSublabel)
.SetMethod("setRole", &Menu::SetRole)
.SetMethod("clear", &Menu::Clear)
.SetMethod("getIndexOfCommandId", &Menu::GetIndexOfCommandId)
.SetMethod("getItemCount", &Menu::GetItemCount)
.SetMethod("getCommandIdAt", &Menu::GetCommandIdAt)
.SetMethod("getLabelAt", &Menu::GetLabelAt)
.SetMethod("getSublabelAt", &Menu::GetSublabelAt)
.SetMethod("isItemCheckedAt", &Menu::IsItemCheckedAt)
.SetMethod("isEnabledAt", &Menu::IsEnabledAt)
.SetMethod("isVisibleAt", &Menu::IsVisibleAt)
.SetMethod("popupAt", &Menu::PopupAt)
.SetMethod("closePopupAt", &Menu::ClosePopupAt);
}
} // namespace api
} // namespace atom
namespace {
using atom::api::Menu;
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
v8::Isolate* isolate = context->GetIsolate();
Menu::SetConstructor(isolate, base::Bind(&Menu::New));
mate::Dictionary dict(isolate, exports);
dict.Set("Menu", Menu::GetConstructor(isolate)->GetFunction());
#if defined(OS_MACOSX)
dict.SetMethod("setApplicationMenu", &Menu::SetApplicationMenu);
dict.SetMethod("sendActionToFirstResponder",
&Menu::SendActionToFirstResponder);
#endif
}
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_menu, Initialize)

View File

@@ -0,0 +1,138 @@
// Copyright (c) 2013 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_API_ATOM_API_MENU_H_
#define ATOM_BROWSER_API_ATOM_API_MENU_H_
#include <memory>
#include <string>
#include "atom/browser/api/atom_api_top_level_window.h"
#include "atom/browser/api/trackable_object.h"
#include "atom/browser/ui/atom_menu_model.h"
#include "base/callback.h"
namespace atom {
namespace api {
class Menu : public mate::TrackableObject<Menu>,
public AtomMenuModel::Delegate,
public AtomMenuModel::Observer {
public:
static mate::WrappableBase* New(mate::Arguments* args);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
#if defined(OS_MACOSX)
// Set the global menubar.
static void SetApplicationMenu(Menu* menu);
// Fake sending an action from the application menu.
static void SendActionToFirstResponder(const std::string& action);
#endif
AtomMenuModel* model() const { return model_.get(); }
protected:
Menu(v8::Isolate* isolate, v8::Local<v8::Object> wrapper);
~Menu() override;
// mate::Wrappable:
void AfterInit(v8::Isolate* isolate) override;
// ui::SimpleMenuModel::Delegate:
bool IsCommandIdChecked(int command_id) const override;
bool IsCommandIdEnabled(int command_id) const override;
bool IsCommandIdVisible(int command_id) const override;
bool GetAcceleratorForCommandIdWithParams(
int command_id,
bool use_default_accelerator,
ui::Accelerator* accelerator) const override;
void ExecuteCommand(int command_id, int event_flags) override;
void MenuWillShow(ui::SimpleMenuModel* source) override;
virtual void PopupAt(TopLevelWindow* window,
int x,
int y,
int positioning_item,
const base::Closure& callback) = 0;
virtual void ClosePopupAt(int32_t window_id) = 0;
std::unique_ptr<AtomMenuModel> model_;
Menu* parent_ = nullptr;
// Observable:
void OnMenuWillClose() override;
void OnMenuWillShow() override;
private:
void InsertItemAt(int index, int command_id, const base::string16& label);
void InsertSeparatorAt(int index);
void InsertCheckItemAt(int index,
int command_id,
const base::string16& label);
void InsertRadioItemAt(int index,
int command_id,
const base::string16& label,
int group_id);
void InsertSubMenuAt(int index,
int command_id,
const base::string16& label,
Menu* menu);
void SetIcon(int index, const gfx::Image& image);
void SetSublabel(int index, const base::string16& sublabel);
void SetRole(int index, const base::string16& role);
void Clear();
int GetIndexOfCommandId(int command_id);
int GetItemCount() const;
int GetCommandIdAt(int index) const;
base::string16 GetLabelAt(int index) const;
base::string16 GetSublabelAt(int index) const;
bool IsItemCheckedAt(int index) const;
bool IsEnabledAt(int index) const;
bool IsVisibleAt(int index) const;
// Stored delegate methods.
base::Callback<bool(v8::Local<v8::Value>, int)> is_checked_;
base::Callback<bool(v8::Local<v8::Value>, int)> is_enabled_;
base::Callback<bool(v8::Local<v8::Value>, int)> is_visible_;
base::Callback<v8::Local<v8::Value>(v8::Local<v8::Value>, int, bool)>
get_accelerator_;
base::Callback<void(v8::Local<v8::Value>, v8::Local<v8::Value>, int)>
execute_command_;
base::Callback<void(v8::Local<v8::Value>)> menu_will_show_;
DISALLOW_COPY_AND_ASSIGN(Menu);
};
} // namespace api
} // namespace atom
namespace mate {
template <>
struct Converter<atom::AtomMenuModel*> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
atom::AtomMenuModel** out) {
// null would be tranfered to NULL.
if (val->IsNull()) {
*out = nullptr;
return true;
}
atom::api::Menu* menu;
if (!Converter<atom::api::Menu*>::FromV8(isolate, val, &menu))
return false;
*out = menu->model();
return true;
}
};
} // namespace mate
#endif // ATOM_BROWSER_API_ATOM_API_MENU_H_

View File

@@ -0,0 +1,58 @@
// Copyright (c) 2013 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_API_ATOM_API_MENU_MAC_H_
#define ATOM_BROWSER_API_ATOM_API_MENU_MAC_H_
#include "atom/browser/api/atom_api_menu.h"
#include <map>
#include <string>
#import "atom/browser/ui/cocoa/atom_menu_controller.h"
using base::scoped_nsobject;
namespace atom {
namespace api {
class MenuMac : public Menu {
protected:
MenuMac(v8::Isolate* isolate, v8::Local<v8::Object> wrapper);
~MenuMac() override;
void PopupAt(TopLevelWindow* window,
int x,
int y,
int positioning_item,
const base::Closure& callback) override;
void PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
int32_t window_id,
int x,
int y,
int positioning_item,
base::Closure callback);
void ClosePopupAt(int32_t window_id) override;
private:
friend class Menu;
void OnClosed(int32_t window_id, base::Closure callback);
scoped_nsobject<AtomMenuController> menu_controller_;
// window ID -> open context menu
std::map<int32_t, scoped_nsobject<AtomMenuController>> popup_controllers_;
base::WeakPtrFactory<MenuMac> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(MenuMac);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_MENU_MAC_H_

View File

@@ -0,0 +1,171 @@
// Copyright (c) 2013 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#import "atom/browser/api/atom_api_menu_mac.h"
#include "atom/browser/native_window.h"
#include "atom/browser/unresponsive_suppressor.h"
#include "base/mac/scoped_sending_event.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/sys_string_conversions.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
#include "atom/common/node_includes.h"
using content::BrowserThread;
namespace {
static scoped_nsobject<NSMenu> applicationMenu_;
} // namespace
namespace atom {
namespace api {
MenuMac::MenuMac(v8::Isolate* isolate, v8::Local<v8::Object> wrapper)
: Menu(isolate, wrapper), weak_factory_(this) {}
MenuMac::~MenuMac() = default;
void MenuMac::PopupAt(TopLevelWindow* window,
int x,
int y,
int positioning_item,
const base::Closure& callback) {
NativeWindow* native_window = window->window();
if (!native_window)
return;
auto popup = base::Bind(&MenuMac::PopupOnUI, weak_factory_.GetWeakPtr(),
native_window->GetWeakPtr(), window->weak_map_id(), x,
y, positioning_item, callback);
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, popup);
}
void MenuMac::PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
int32_t window_id,
int x,
int y,
int positioning_item,
base::Closure callback) {
if (!native_window)
return;
NSWindow* nswindow = native_window->GetNativeWindow();
auto close_callback = base::Bind(
&MenuMac::OnClosed, weak_factory_.GetWeakPtr(), window_id, callback);
popup_controllers_[window_id] = base::scoped_nsobject<AtomMenuController>([
[AtomMenuController alloc] initWithModel:model()
useDefaultAccelerator:NO]);
NSMenu* menu = [popup_controllers_[window_id] menu];
NSView* view = [nswindow contentView];
// Which menu item to show.
NSMenuItem* item = nil;
if (positioning_item < [menu numberOfItems] && positioning_item >= 0)
item = [menu itemAtIndex:positioning_item];
// (-1, -1) means showing on mouse location.
NSPoint position;
if (x == -1 || y == -1) {
position = [view convertPoint:[nswindow mouseLocationOutsideOfEventStream]
fromView:nil];
} else {
position = NSMakePoint(x, [view frame].size.height - y);
}
// If no preferred item is specified, try to show all of the menu items.
if (!positioning_item) {
CGFloat windowBottom = CGRectGetMinY([view window].frame);
CGFloat lowestMenuPoint = windowBottom + position.y - [menu size].height;
CGFloat screenBottom = CGRectGetMinY([view window].screen.frame);
CGFloat distanceFromBottom = lowestMenuPoint - screenBottom;
if (distanceFromBottom < 0)
position.y = position.y - distanceFromBottom + 4;
}
// Place the menu left of cursor if it is overflowing off right of screen.
CGFloat windowLeft = CGRectGetMinX([view window].frame);
CGFloat rightmostMenuPoint = windowLeft + position.x + [menu size].width;
CGFloat screenRight = CGRectGetMaxX([view window].screen.frame);
if (rightmostMenuPoint > screenRight)
position.x = position.x - [menu size].width;
[popup_controllers_[window_id] setCloseCallback:close_callback];
// Make sure events can be pumped while the menu is up.
base::MessageLoop::ScopedNestableTaskAllower allow(
base::MessageLoop::current());
// One of the events that could be pumped is |window.close()|.
// User-initiated event-tracking loops protect against this by
// setting flags in -[CrApplication sendEvent:], but since
// web-content menus are initiated by IPC message the setup has to
// be done manually.
base::mac::ScopedSendingEvent sendingEventScoper;
// Don't emit unresponsive event when showing menu.
atom::UnresponsiveSuppressor suppressor;
[menu popUpMenuPositioningItem:item atLocation:position inView:view];
}
void MenuMac::ClosePopupAt(int32_t window_id) {
auto controller = popup_controllers_.find(window_id);
if (controller != popup_controllers_.end()) {
// Close the controller for the window.
[controller->second cancel];
} else if (window_id == -1) {
// Or just close all opened controllers.
for (auto it = popup_controllers_.begin();
it != popup_controllers_.end();) {
// The iterator is invalidated after the call.
[(it++)->second cancel];
}
}
}
void MenuMac::OnClosed(int32_t window_id, base::Closure callback) {
popup_controllers_.erase(window_id);
callback.Run();
}
// static
void Menu::SetApplicationMenu(Menu* base_menu) {
MenuMac* menu = static_cast<MenuMac*>(base_menu);
base::scoped_nsobject<AtomMenuController> menu_controller([
[AtomMenuController alloc] initWithModel:menu->model_.get()
useDefaultAccelerator:YES]);
NSRunLoop* currentRunLoop = [NSRunLoop currentRunLoop];
[currentRunLoop cancelPerformSelector:@selector(setMainMenu:)
target:NSApp
argument:applicationMenu_];
applicationMenu_.reset([[menu_controller menu] retain]);
[[NSRunLoop currentRunLoop]
performSelector:@selector(setMainMenu:)
target:NSApp
argument:applicationMenu_
order:0
modes:[NSArray arrayWithObject:NSDefaultRunLoopMode]];
// Ensure the menu_controller_ is destroyed after main menu is set.
menu_controller.swap(menu->menu_controller_);
}
// static
void Menu::SendActionToFirstResponder(const std::string& action) {
SEL selector = NSSelectorFromString(base::SysUTF8ToNSString(action));
[NSApp sendAction:selector to:nil from:[NSApp mainMenu]];
}
// static
mate::WrappableBase* Menu::New(mate::Arguments* args) {
return new MenuMac(args->isolate(), args->GetThis());
}
} // namespace api
} // namespace atom

View File

@@ -0,0 +1,82 @@
// Copyright (c) 2014 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_menu_views.h"
#include "atom/browser/native_window_views.h"
#include "atom/browser/unresponsive_suppressor.h"
#include "ui/display/screen.h"
using views::MenuRunner;
namespace atom {
namespace api {
MenuViews::MenuViews(v8::Isolate* isolate, v8::Local<v8::Object> wrapper)
: Menu(isolate, wrapper), weak_factory_(this) {}
MenuViews::~MenuViews() = default;
void MenuViews::PopupAt(TopLevelWindow* window,
int x,
int y,
int positioning_item,
const base::Closure& callback) {
auto* native_window = static_cast<NativeWindowViews*>(window->window());
if (!native_window)
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 = native_window->GetContentBounds().origin();
location = gfx::Point(origin.x() + x, origin.y() + y);
}
int flags = MenuRunner::CONTEXT_MENU | MenuRunner::HAS_MNEMONICS;
// Don't emit unresponsive event when showing menu.
atom::UnresponsiveSuppressor suppressor;
// Show the menu.
int32_t window_id = window->weak_map_id();
auto close_callback = base::Bind(
&MenuViews::OnClosed, weak_factory_.GetWeakPtr(), window_id, callback);
menu_runners_[window_id] =
std::make_unique<MenuRunner>(model(), flags, close_callback);
menu_runners_[window_id]->RunMenuAt(
native_window->widget(), NULL, gfx::Rect(location, gfx::Size()),
views::MENU_ANCHOR_TOPLEFT, ui::MENU_SOURCE_MOUSE);
}
void MenuViews::ClosePopupAt(int32_t window_id) {
auto runner = menu_runners_.find(window_id);
if (runner != menu_runners_.end()) {
// Close the runner for the window.
runner->second->Cancel();
} else if (window_id == -1) {
// Or just close all opened runners.
for (auto it = menu_runners_.begin(); it != menu_runners_.end();) {
// The iterator is invalidated after the call.
(it++)->second->Cancel();
}
}
}
void MenuViews::OnClosed(int32_t window_id, base::Closure callback) {
menu_runners_.erase(window_id);
callback.Run();
}
// static
mate::WrappableBase* Menu::New(mate::Arguments* args) {
return new MenuViews(args->isolate(), args->GetThis());
}
} // namespace api
} // namespace atom

View File

@@ -0,0 +1,47 @@
// Copyright (c) 2014 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_API_ATOM_API_MENU_VIEWS_H_
#define ATOM_BROWSER_API_ATOM_API_MENU_VIEWS_H_
#include <map>
#include "atom/browser/api/atom_api_menu.h"
#include "base/memory/weak_ptr.h"
#include "ui/display/screen.h"
#include "ui/views/controls/menu/menu_runner.h"
namespace atom {
namespace api {
class MenuViews : public Menu {
public:
MenuViews(v8::Isolate* isolate, v8::Local<v8::Object> wrapper);
~MenuViews() override;
protected:
void PopupAt(TopLevelWindow* window,
int x,
int y,
int positioning_item,
const base::Closure& callback) override;
void ClosePopupAt(int32_t window_id) override;
private:
void OnClosed(int32_t window_id, base::Closure callback);
// window ID -> open context menu
std::map<int32_t, std::unique_ptr<views::MenuRunner>> menu_runners_;
base::WeakPtrFactory<MenuViews> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(MenuViews);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_MENU_VIEWS_H_

View File

@@ -0,0 +1,61 @@
// Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_net.h"
#include "atom/browser/api/atom_api_url_request.h"
#include "atom/common/node_includes.h"
#include "native_mate/dictionary.h"
namespace atom {
namespace api {
Net::Net(v8::Isolate* isolate) {
Init(isolate);
}
Net::~Net() {}
// static
v8::Local<v8::Value> Net::Create(v8::Isolate* isolate) {
return mate::CreateHandle(isolate, new Net(isolate)).ToV8();
}
// static
void Net::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "Net"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.SetProperty("URLRequest", &Net::URLRequest);
}
v8::Local<v8::Value> Net::URLRequest(v8::Isolate* isolate) {
return URLRequest::GetConstructor(isolate)->GetFunction();
}
} // namespace api
} // namespace atom
namespace {
using atom::api::Net;
using atom::api::URLRequest;
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
v8::Isolate* isolate = context->GetIsolate();
URLRequest::SetConstructor(isolate, base::Bind(URLRequest::New));
mate::Dictionary dict(isolate, exports);
dict.Set("net", Net::Create(isolate));
dict.Set("Net", Net::GetConstructor(isolate)->GetFunction());
}
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_net, Initialize)

View File

@@ -0,0 +1,35 @@
// Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_API_ATOM_API_NET_H_
#define ATOM_BROWSER_API_ATOM_API_NET_H_
#include "atom/browser/api/event_emitter.h"
namespace atom {
namespace api {
class Net : public mate::EventEmitter<Net> {
public:
static v8::Local<v8::Value> Create(v8::Isolate* isolate);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
v8::Local<v8::Value> URLRequest(v8::Isolate* isolate);
protected:
explicit Net(v8::Isolate* isolate);
~Net() override;
private:
DISALLOW_COPY_AND_ASSIGN(Net);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_NET_H_

View File

@@ -0,0 +1,137 @@
// Copyright (c) 2018 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_net_log.h"
#include <utility>
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/common/native_mate_converters/callback.h"
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "base/command_line.h"
#include "components/net_log/chrome_net_log.h"
#include "content/public/browser/storage_partition.h"
#include "native_mate/dictionary.h"
#include "native_mate/handle.h"
#include "net/url_request/url_request_context_getter.h"
#include "atom/common/node_includes.h"
namespace atom {
namespace api {
NetLog::NetLog(v8::Isolate* isolate, AtomBrowserContext* browser_context)
: browser_context_(browser_context) {
Init(isolate);
net_log_writer_ =
atom::AtomBrowserMainParts::Get()->net_log()->net_export_file_writer();
net_log_writer_->AddObserver(this);
}
NetLog::~NetLog() {
net_log_writer_->RemoveObserver(this);
}
void NetLog::StartLogging(mate::Arguments* args) {
base::FilePath log_path;
if (!args->GetNext(&log_path) || log_path.empty()) {
args->ThrowError("The first parameter must be a valid string");
return;
}
net_log::NetExportFileWriter::URLRequestContextGetterList context_getters = {
browser_context_->GetRequestContext()};
// TODO(deepak1556): Provide more flexibility to this module
// by allowing customizations on the capturing options.
net_log_writer_->StartNetLog(
log_path, net::NetLogCaptureMode::Default(),
net_log::NetExportFileWriter::kNoLimit /* file size limit */,
base::CommandLine::ForCurrentProcess()->GetCommandLineString(),
std::string(), context_getters);
}
std::string NetLog::GetLoggingState() const {
if (!net_log_state_)
return std::string();
const base::Value* current_log_state =
net_log_state_->FindKeyOfType("state", base::Value::Type::STRING);
if (!current_log_state)
return std::string();
return current_log_state->GetString();
}
bool NetLog::IsCurrentlyLogging() const {
const std::string log_state = GetLoggingState();
return (log_state == "STARTING_LOG") || (log_state == "LOGGING");
}
std::string NetLog::GetCurrentlyLoggingPath() const {
// Net log exporter has a default path which will be used
// when no log path is provided, but since we don't allow
// net log capture without user provided file path, this
// check is completely safe.
if (IsCurrentlyLogging()) {
const base::Value* current_log_path =
net_log_state_->FindKeyOfType("file", base::Value::Type::STRING);
if (current_log_path)
return current_log_path->GetString();
}
return std::string();
}
void NetLog::StopLogging(mate::Arguments* args) {
net_log::NetExportFileWriter::FilePathCallback callback;
if (!args->GetNext(&callback)) {
args->ThrowError("Invalid callback function");
return;
}
if (IsCurrentlyLogging()) {
stop_callback_queue_.emplace_back(callback);
net_log_writer_->StopNetLog(nullptr, nullptr);
} else {
callback.Run(base::FilePath());
}
}
void NetLog::OnNewState(const base::DictionaryValue& state) {
net_log_state_ = state.CreateDeepCopy();
if (stop_callback_queue_.empty())
return;
if (GetLoggingState() == "NOT_LOGGING") {
for (auto& callback : stop_callback_queue_) {
if (!callback.is_null())
net_log_writer_->GetFilePathToCompletedLog(callback);
}
stop_callback_queue_.clear();
}
}
// static
mate::Handle<NetLog> NetLog::Create(v8::Isolate* isolate,
AtomBrowserContext* browser_context) {
return mate::CreateHandle(isolate, new NetLog(isolate, browser_context));
}
// static
void NetLog::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "NetLog"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.SetProperty("currentlyLogging", &NetLog::IsCurrentlyLogging)
.SetProperty("currentlyLoggingPath", &NetLog::GetCurrentlyLoggingPath)
.SetMethod("startLogging", &NetLog::StartLogging)
.SetMethod("stopLogging", &NetLog::StopLogging);
}
} // namespace api
} // namespace atom

View File

@@ -0,0 +1,60 @@
// 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_BROWSER_API_ATOM_API_NET_LOG_H_
#define ATOM_BROWSER_API_ATOM_API_NET_LOG_H_
#include <list>
#include <memory>
#include <string>
#include "atom/browser/api/trackable_object.h"
#include "base/callback.h"
#include "base/values.h"
#include "components/net_log/net_export_file_writer.h"
#include "native_mate/handle.h"
namespace atom {
class AtomBrowserContext;
namespace api {
class NetLog : public mate::TrackableObject<NetLog>,
public net_log::NetExportFileWriter::StateObserver {
public:
static mate::Handle<NetLog> Create(v8::Isolate* isolate,
AtomBrowserContext* browser_context);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
void StartLogging(mate::Arguments* args);
std::string GetLoggingState() const;
bool IsCurrentlyLogging() const;
std::string GetCurrentlyLoggingPath() const;
void StopLogging(mate::Arguments* args);
protected:
explicit NetLog(v8::Isolate* isolate, AtomBrowserContext* browser_context);
~NetLog() override;
// net_log::NetExportFileWriter::StateObserver implementation
void OnNewState(const base::DictionaryValue& state) override;
private:
AtomBrowserContext* browser_context_;
net_log::NetExportFileWriter* net_log_writer_;
std::list<net_log::NetExportFileWriter::FilePathCallback>
stop_callback_queue_;
std::unique_ptr<base::DictionaryValue> net_log_state_;
DISALLOW_COPY_AND_ASSIGN(NetLog);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_NET_LOG_H_

View File

@@ -0,0 +1,272 @@
// Copyright (c) 2014 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_notification.h"
#include "atom/browser/api/atom_api_menu.h"
#include "atom/browser/browser.h"
#include "atom/common/native_mate_converters/gfx_converter.h"
#include "atom/common/native_mate_converters/image_converter.h"
#include "atom/common/native_mate_converters/string16_converter.h"
#include "base/guid.h"
#include "base/strings/utf_string_conversions.h"
#include "brightray/browser/browser_client.h"
#include "native_mate/constructor.h"
#include "native_mate/dictionary.h"
#include "native_mate/object_template_builder.h"
#include "url/gurl.h"
// Must be the last in the includes list.
// See https://github.com/electron/electron/issues/10363
#include "atom/common/node_includes.h"
namespace mate {
template <>
struct Converter<brightray::NotificationAction> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
brightray::NotificationAction* out) {
mate::Dictionary dict;
if (!ConvertFromV8(isolate, val, &dict))
return false;
if (!dict.Get("type", &(out->type))) {
return false;
}
dict.Get("text", &(out->text));
return true;
}
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
brightray::NotificationAction val) {
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
dict.Set("text", val.text);
dict.Set("type", val.type);
return dict.GetHandle();
}
};
} // namespace mate
namespace atom {
namespace api {
Notification::Notification(v8::Isolate* isolate,
v8::Local<v8::Object> wrapper,
mate::Arguments* args) {
InitWith(isolate, wrapper);
presenter_ = brightray::BrowserClient::Get()->GetNotificationPresenter();
mate::Dictionary opts;
if (args->GetNext(&opts)) {
opts.Get("title", &title_);
opts.Get("subtitle", &subtitle_);
opts.Get("body", &body_);
has_icon_ = opts.Get("icon", &icon_);
if (has_icon_) {
opts.Get("icon", &icon_path_);
}
opts.Get("silent", &silent_);
opts.Get("replyPlaceholder", &reply_placeholder_);
opts.Get("hasReply", &has_reply_);
opts.Get("actions", &actions_);
opts.Get("sound", &sound_);
opts.Get("closeButtonText", &close_button_text_);
}
}
Notification::~Notification() {
if (notification_)
notification_->set_delegate(nullptr);
}
// static
mate::WrappableBase* Notification::New(mate::Arguments* args) {
if (!Browser::Get()->is_ready()) {
args->ThrowError("Cannot create Notification before app is ready");
return nullptr;
}
return new Notification(args->isolate(), args->GetThis(), args);
}
// Getters
base::string16 Notification::GetTitle() const {
return title_;
}
base::string16 Notification::GetSubtitle() const {
return subtitle_;
}
base::string16 Notification::GetBody() const {
return body_;
}
bool Notification::GetSilent() const {
return silent_;
}
bool Notification::GetHasReply() const {
return has_reply_;
}
base::string16 Notification::GetReplyPlaceholder() const {
return reply_placeholder_;
}
base::string16 Notification::GetSound() const {
return sound_;
}
std::vector<brightray::NotificationAction> Notification::GetActions() const {
return actions_;
}
base::string16 Notification::GetCloseButtonText() const {
return close_button_text_;
}
// Setters
void Notification::SetTitle(const base::string16& new_title) {
title_ = new_title;
}
void Notification::SetSubtitle(const base::string16& new_subtitle) {
subtitle_ = new_subtitle;
}
void Notification::SetBody(const base::string16& new_body) {
body_ = new_body;
}
void Notification::SetSilent(bool new_silent) {
silent_ = new_silent;
}
void Notification::SetHasReply(bool new_has_reply) {
has_reply_ = new_has_reply;
}
void Notification::SetReplyPlaceholder(const base::string16& new_placeholder) {
reply_placeholder_ = new_placeholder;
}
void Notification::SetSound(const base::string16& new_sound) {
sound_ = new_sound;
}
void Notification::SetActions(
const std::vector<brightray::NotificationAction>& actions) {
actions_ = actions;
}
void Notification::SetCloseButtonText(const base::string16& text) {
close_button_text_ = text;
}
void Notification::NotificationAction(int index) {
Emit("action", index);
}
void Notification::NotificationClick() {
Emit("click");
}
void Notification::NotificationReplied(const std::string& reply) {
Emit("reply", reply);
}
void Notification::NotificationDisplayed() {
Emit("show");
}
void Notification::NotificationDestroyed() {}
void Notification::NotificationClosed() {
Emit("close");
}
void Notification::Close() {
if (notification_) {
notification_->Dismiss();
notification_.reset();
}
}
// Showing notifications
void Notification::Show() {
Close();
if (presenter_) {
notification_ = presenter_->CreateNotification(this, base::GenerateGUID());
if (notification_) {
brightray::NotificationOptions options;
options.title = title_;
options.subtitle = subtitle_;
options.msg = body_;
options.icon_url = GURL();
options.icon = icon_.AsBitmap();
options.silent = silent_;
options.has_reply = has_reply_;
options.reply_placeholder = reply_placeholder_;
options.actions = actions_;
options.sound = sound_;
options.close_button_text = close_button_text_;
notification_->Show(options);
}
}
}
bool Notification::IsSupported() {
return !!brightray::BrowserClient::Get()->GetNotificationPresenter();
}
// static
void Notification::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "Notification"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.MakeDestroyable()
.SetMethod("show", &Notification::Show)
.SetMethod("close", &Notification::Close)
.SetProperty("title", &Notification::GetTitle, &Notification::SetTitle)
.SetProperty("subtitle", &Notification::GetSubtitle,
&Notification::SetSubtitle)
.SetProperty("body", &Notification::GetBody, &Notification::SetBody)
.SetProperty("silent", &Notification::GetSilent, &Notification::SetSilent)
.SetProperty("hasReply", &Notification::GetHasReply,
&Notification::SetHasReply)
.SetProperty("replyPlaceholder", &Notification::GetReplyPlaceholder,
&Notification::SetReplyPlaceholder)
.SetProperty("sound", &Notification::GetSound, &Notification::SetSound)
.SetProperty("actions", &Notification::GetActions,
&Notification::SetActions)
.SetProperty("closeButtonText", &Notification::GetCloseButtonText,
&Notification::SetCloseButtonText);
}
} // namespace api
} // namespace atom
namespace {
using atom::api::Notification;
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
v8::Isolate* isolate = context->GetIsolate();
Notification::SetConstructor(isolate, base::Bind(&Notification::New));
mate::Dictionary dict(isolate, exports);
dict.Set("Notification",
Notification::GetConstructor(isolate)->GetFunction());
dict.SetMethod("isSupported", &Notification::IsSupported);
}
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_common_notification, Initialize)

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