mirror of
https://github.com/electron/electron.git
synced 2026-04-10 03:01:51 -04:00
Compare commits
77 Commits
v11.4.7
...
v12.0.0-ni
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
735d8b84f0 | ||
|
|
a65f7f7d42 | ||
|
|
2cfa41e6e0 | ||
|
|
77038b7bda | ||
|
|
4d1dab849f | ||
|
|
0b055b2fb8 | ||
|
|
53aaeb7a16 | ||
|
|
e0a25cb1e3 | ||
|
|
993eab691f | ||
|
|
a200b15600 | ||
|
|
ba55aaa53b | ||
|
|
1ba46a91b6 | ||
|
|
fa7a29e84b | ||
|
|
e5933c6910 | ||
|
|
2091fd7dd9 | ||
|
|
45170fdbd7 | ||
|
|
fbf32f697f | ||
|
|
459a95aaec | ||
|
|
b1d8057ec9 | ||
|
|
87d67a9365 | ||
|
|
9f4a097e03 | ||
|
|
5de7eb3618 | ||
|
|
7f885bd266 | ||
|
|
bc9816b206 | ||
|
|
633e5d8503 | ||
|
|
9b08fbefe5 | ||
|
|
70e3aa0182 | ||
|
|
a3389d017f | ||
|
|
ce86591459 | ||
|
|
7d56ca7360 | ||
|
|
cd455c8b40 | ||
|
|
acf5d487d2 | ||
|
|
dd781c4f63 | ||
|
|
98683190b4 | ||
|
|
1815b95e74 | ||
|
|
a829ae56b2 | ||
|
|
e6fbbf4325 | ||
|
|
f6df79b927 | ||
|
|
5a8046c994 | ||
|
|
ae5776041e | ||
|
|
f7d9d68e14 | ||
|
|
2c5c51afb9 | ||
|
|
860e14c0da | ||
|
|
31322400e7 | ||
|
|
4ad9bcb8b5 | ||
|
|
29c1248e96 | ||
|
|
a6b9f9d8e5 | ||
|
|
d305fe7d30 | ||
|
|
4dc09ea9dc | ||
|
|
4484e95fc8 | ||
|
|
03e60cce8b | ||
|
|
733d56e908 | ||
|
|
43485b8705 | ||
|
|
bda6378685 | ||
|
|
1b6534b326 | ||
|
|
e9e7eee25e | ||
|
|
7e698df8f3 | ||
|
|
e0611d0946 | ||
|
|
184e72fafd | ||
|
|
3745b76da8 | ||
|
|
bf7dbff858 | ||
|
|
7c10f86c6e | ||
|
|
9803e4d526 | ||
|
|
068b464e13 | ||
|
|
a09694ae85 | ||
|
|
e06a1c2746 | ||
|
|
c5320b3951 | ||
|
|
6cc960f214 | ||
|
|
a4b6fce907 | ||
|
|
8f727b3569 | ||
|
|
95073decd3 | ||
|
|
e8ef1ef252 | ||
|
|
075502477e | ||
|
|
97755bbd85 | ||
|
|
bab69ae4d2 | ||
|
|
443540fd13 | ||
|
|
5e1950ceff |
10
.gitattributes
vendored
10
.gitattributes
vendored
@@ -2,3 +2,13 @@
|
||||
# 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
|
||||
|
||||
3
.github/CODEOWNERS
vendored
3
.github/CODEOWNERS
vendored
@@ -10,3 +10,6 @@ DEPS @electron/wg-upgrades
|
||||
# Releases WG
|
||||
/npm/ @electron/wg-releases
|
||||
/script/release @electron/wg-releases
|
||||
|
||||
# Security WG
|
||||
/lib/browser/rpc-server.ts @electron/wg-security
|
||||
|
||||
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -15,7 +15,6 @@ Contributors guide: https://github.com/electron/electron/blob/master/CONTRIBUTIN
|
||||
- [ ] relevant documentation is changed or added
|
||||
- [ ] PR title follows semantic [commit guidelines](https://github.com/electron/electron/blob/master/docs/development/pull-requests.md#commit-message-guidelines)
|
||||
- [ ] [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).
|
||||
- [ ] This is **NOT A BREAKING CHANGE**. Breaking changes may not be merged to master until 11-x-y is branched.
|
||||
|
||||
#### Release Notes
|
||||
|
||||
|
||||
19
BUILD.gn
19
BUILD.gn
@@ -642,6 +642,7 @@ source_set("electron_lib") {
|
||||
"shell/common/extensions/api",
|
||||
"shell/common/extensions/api:extensions_features",
|
||||
"//chrome/browser/resources:component_extension_resources",
|
||||
"//components/update_client:update_client",
|
||||
"//components/zoom",
|
||||
"//extensions/browser",
|
||||
"//extensions/browser:core_api_provider",
|
||||
@@ -1138,22 +1139,24 @@ if (is_mac) {
|
||||
"//components/crash/core/app:run_as_crashpad_handler",
|
||||
]
|
||||
|
||||
ldflags = []
|
||||
|
||||
libs = [
|
||||
"comctl32.lib",
|
||||
"uiautomationcore.lib",
|
||||
"wtsapi32.lib",
|
||||
]
|
||||
|
||||
configs += [ "//build/config/win:windowed" ]
|
||||
|
||||
ldflags = [
|
||||
# Windows 7 doesn't have these DLLs.
|
||||
# TODO: are there other DLLs we need to list here to be win7
|
||||
# compatible?
|
||||
"/DELAYLOAD:api-ms-win-core-winrt-l1-1-0.dll",
|
||||
"/DELAYLOAD:api-ms-win-core-winrt-string-l1-1-0.dll",
|
||||
configs += [
|
||||
"//build/config/win:windowed",
|
||||
"//build/config/win:delayloads",
|
||||
]
|
||||
|
||||
if (target_cpu == "arm64") {
|
||||
configs -= [ "//build/config/win:cfi_linker" ]
|
||||
ldflags += [ "/guard:cf,nolongjmp" ]
|
||||
}
|
||||
|
||||
# This is to support renaming of electron.exe. node-gyp has hard-coded
|
||||
# executable names which it will recognise as node. This module definition
|
||||
# file claims that the electron executable is in fact named "node.exe",
|
||||
|
||||
2
DEPS
2
DEPS
@@ -16,7 +16,7 @@ vars = {
|
||||
'chromium_version':
|
||||
'b04584161e07d4ac110045b7647fa8a81f5f0709',
|
||||
'node_version':
|
||||
'v12.18.3',
|
||||
'v14.9.0',
|
||||
'nan_version':
|
||||
'2c4ee8a32a299eada3cd6e468bbd0a473bfea96d',
|
||||
'squirrel.mac_version':
|
||||
|
||||
@@ -1 +1 @@
|
||||
11.0.0-nightly.20200826
|
||||
12.0.0-nightly.20200918
|
||||
@@ -11,7 +11,6 @@ import find_depot_tools
|
||||
from vs_toolchain import \
|
||||
SetEnvironmentAndGetRuntimeDllDirs, \
|
||||
SetEnvironmentAndGetSDKDir, \
|
||||
GetVisualStudioVersion, \
|
||||
NormalizePath
|
||||
|
||||
sys.path.append("%s/win_toolchain" % find_depot_tools.add_depot_tools_to_path())
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import sys
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
def main(argv):
|
||||
cwd = argv[1]
|
||||
|
||||
@@ -10,10 +10,9 @@ config.output = {
|
||||
filename: path.basename(outPath)
|
||||
};
|
||||
|
||||
const { wrapInitWithProfilingTimeout } = config;
|
||||
delete config.wrapInitWithProfilingTimeout;
|
||||
const { wrapInitWithProfilingTimeout, wrapInitWithTryCatch, ...webpackConfig } = config;
|
||||
|
||||
webpack(config, (err, stats) => {
|
||||
webpack(webpackConfig, (err, stats) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
@@ -21,9 +20,17 @@ webpack(config, (err, stats) => {
|
||||
console.error(stats.toString('normal'));
|
||||
process.exit(1);
|
||||
} else {
|
||||
let contents = fs.readFileSync(outPath, 'utf8');
|
||||
if (wrapInitWithTryCatch) {
|
||||
contents = `try {
|
||||
${contents}
|
||||
} catch (err) {
|
||||
console.error('Electron ${webpackConfig.output.filename} script failed to run');
|
||||
console.error(err);
|
||||
}`;
|
||||
}
|
||||
if (wrapInitWithProfilingTimeout) {
|
||||
const contents = fs.readFileSync(outPath, 'utf8');
|
||||
const newContents = `function ___electron_webpack_init__() {
|
||||
contents = `function ___electron_webpack_init__() {
|
||||
${contents}
|
||||
};
|
||||
if ((globalThis.process || binding.process).argv.includes("--profile-electron-init")) {
|
||||
@@ -31,8 +38,8 @@ if ((globalThis.process || binding.process).argv.includes("--profile-electron-in
|
||||
} else {
|
||||
___electron_webpack_init__();
|
||||
}`;
|
||||
fs.writeFileSync(outPath, newContents);
|
||||
}
|
||||
fs.writeFileSync(outPath, contents);
|
||||
process.exit(0);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -69,7 +69,8 @@ module.exports = ({
|
||||
loadElectronFromAlternateTarget,
|
||||
targetDeletesNodeGlobals,
|
||||
target,
|
||||
wrapInitWithProfilingTimeout
|
||||
wrapInitWithProfilingTimeout,
|
||||
wrapInitWithTryCatch
|
||||
}) => {
|
||||
let entry = path.resolve(electronRoot, 'lib', target, 'init.ts');
|
||||
if (!fs.existsSync(entry)) {
|
||||
@@ -87,6 +88,7 @@ module.exports = ({
|
||||
filename: `${target}.bundle.js`
|
||||
},
|
||||
wrapInitWithProfilingTimeout,
|
||||
wrapInitWithTryCatch,
|
||||
resolve: {
|
||||
alias: {
|
||||
'@electron/internal': path.resolve(electronRoot, 'lib'),
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
module.exports = require('./webpack.config.base')({
|
||||
target: 'isolated_renderer',
|
||||
alwaysHasNode: false
|
||||
alwaysHasNode: false,
|
||||
wrapInitWithTryCatch: true
|
||||
});
|
||||
|
||||
@@ -2,5 +2,6 @@ module.exports = require('./webpack.config.base')({
|
||||
target: 'renderer',
|
||||
alwaysHasNode: true,
|
||||
targetDeletesNodeGlobals: true,
|
||||
wrapInitWithProfilingTimeout: true
|
||||
wrapInitWithProfilingTimeout: true,
|
||||
wrapInitWithTryCatch: true
|
||||
});
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
module.exports = require('./webpack.config.base')({
|
||||
target: 'sandboxed_renderer',
|
||||
alwaysHasNode: false,
|
||||
wrapInitWithProfilingTimeout: true
|
||||
wrapInitWithProfilingTimeout: true,
|
||||
wrapInitWithTryCatch: true
|
||||
});
|
||||
|
||||
@@ -2,5 +2,6 @@ module.exports = require('./webpack.config.base')({
|
||||
target: 'worker',
|
||||
loadElectronFromAlternateTarget: 'renderer',
|
||||
alwaysHasNode: true,
|
||||
targetDeletesNodeGlobals: true
|
||||
targetDeletesNodeGlobals: true,
|
||||
wrapInitWithTryCatch: true
|
||||
});
|
||||
|
||||
@@ -56,7 +56,7 @@ an issue:
|
||||
* [Accessibility](tutorial/accessibility.md)
|
||||
* [Spectron](tutorial/accessibility.md#spectron)
|
||||
* [Devtron](tutorial/accessibility.md#devtron)
|
||||
* [Enabling Accessibility](tutorial/accessibility.md#enabling-accessibility)
|
||||
* [Manually Enabling Accessibility Features](tutorial/accessibility.md#manually-enabling-accessibility-features)
|
||||
* [Testing and Debugging](tutorial/application-debugging.md)
|
||||
* [Debugging the Main Process](tutorial/debugging-main-process.md)
|
||||
* [Debugging the Main Process with Visual Studio Code](tutorial/debugging-main-process-vscode.md)
|
||||
|
||||
@@ -501,7 +501,7 @@ Returns:
|
||||
Emitted when `desktopCapturer.getSources()` is called in the renderer process of `webContents`.
|
||||
Calling `event.preventDefault()` will make it return empty sources.
|
||||
|
||||
### Event: 'remote-require'
|
||||
### Event: 'remote-require' _Deprecated_
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -513,7 +513,7 @@ Emitted when `remote.require()` is called in the renderer process of `webContent
|
||||
Calling `event.preventDefault()` will prevent the module from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
### Event: 'remote-get-global'
|
||||
### Event: 'remote-get-global' _Deprecated_
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -525,7 +525,7 @@ Emitted when `remote.getGlobal()` is called in the renderer process of `webConte
|
||||
Calling `event.preventDefault()` will prevent the global from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
### Event: 'remote-get-builtin'
|
||||
### Event: 'remote-get-builtin' _Deprecated_
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -537,7 +537,7 @@ Emitted when `remote.getBuiltin()` is called in the renderer process of `webCont
|
||||
Calling `event.preventDefault()` will prevent the module from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
### Event: 'remote-get-current-window'
|
||||
### Event: 'remote-get-current-window' _Deprecated_
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -548,7 +548,7 @@ Emitted when `remote.getCurrentWindow()` is called in the renderer process of `w
|
||||
Calling `event.preventDefault()` will prevent the object from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
### Event: 'remote-get-current-web-contents'
|
||||
### Event: 'remote-get-current-web-contents' _Deprecated_
|
||||
|
||||
Returns:
|
||||
|
||||
|
||||
@@ -8,9 +8,6 @@ Process: [Main](../glossary.md#main-process)
|
||||
// In the main process.
|
||||
const { BrowserWindow } = require('electron')
|
||||
|
||||
// Or use `remote` from the renderer process.
|
||||
// const { BrowserWindow } = require('electron').remote
|
||||
|
||||
const win = new BrowserWindow({ width: 800, height: 600 })
|
||||
|
||||
// Load a remote URL
|
||||
|
||||
@@ -59,7 +59,7 @@ The `crashReporter` module has the following methods:
|
||||
* `rateLimit` Boolean (optional) _macOS_ _Windows_ - If true, limit the
|
||||
number of crashes uploaded to 1/hour. Default is `false`.
|
||||
* `compress` Boolean (optional) - If true, crash reports will be compressed
|
||||
and uploaded with `Content-Encoding: gzip`. Default is `false`.
|
||||
and uploaded with `Content-Encoding: gzip`. Default is `true`.
|
||||
* `extra` Record<String, String> (optional) - Extra string key/value
|
||||
annotations that will be sent along with crash reports that are generated
|
||||
in the main process. Only string values are supported. Crashes generated in
|
||||
|
||||
@@ -72,50 +72,6 @@ const constraints = {
|
||||
}
|
||||
```
|
||||
|
||||
This example shows how to capture a video from a [WebContents](web-contents.md)
|
||||
|
||||
```javascript
|
||||
// In the renderer process.
|
||||
const { desktopCapturer, remote } = require('electron')
|
||||
|
||||
desktopCapturer.getMediaSourceIdForWebContents(remote.getCurrentWebContents().id).then(async mediaSourceId => {
|
||||
try {
|
||||
const stream = await navigator.mediaDevices.getUserMedia({
|
||||
audio: {
|
||||
mandatory: {
|
||||
chromeMediaSource: 'tab',
|
||||
chromeMediaSourceId: mediaSourceId
|
||||
}
|
||||
},
|
||||
video: {
|
||||
mandatory: {
|
||||
chromeMediaSource: 'tab',
|
||||
chromeMediaSourceId: mediaSourceId,
|
||||
minWidth: 1280,
|
||||
maxWidth: 1280,
|
||||
minHeight: 720,
|
||||
maxHeight: 720
|
||||
}
|
||||
}
|
||||
})
|
||||
handleStream(stream)
|
||||
} catch (e) {
|
||||
handleError(e)
|
||||
}
|
||||
})
|
||||
|
||||
function handleStream (stream) {
|
||||
const video = document.querySelector('video')
|
||||
video.srcObject = stream
|
||||
video.onloadedmetadata = (e) => video.play()
|
||||
}
|
||||
|
||||
function handleError (e) {
|
||||
console.log(e)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Methods
|
||||
|
||||
The `desktopCapturer` module has the following methods:
|
||||
@@ -138,15 +94,6 @@ Returns `Promise<DesktopCapturerSource[]>` - Resolves with an array of [`Desktop
|
||||
**Note** Capturing the screen contents requires user consent on macOS 10.15 Catalina or higher,
|
||||
which can detected by [`systemPreferences.getMediaAccessStatus`].
|
||||
|
||||
### `desktopCapturer.getMediaSourceIdForWebContents(webContentsId)`
|
||||
|
||||
* `webContentsId` number - Id of the WebContents to get stream of
|
||||
|
||||
Returns `Promise<string>` - Resolves with the identifier of a WebContents stream, this identifier can be
|
||||
used with [`navigator.mediaDevices.getUserMedia`].
|
||||
The identifier is **only valid for 10 seconds**.
|
||||
The identifier may be empty if not requested from a renderer process.
|
||||
|
||||
[`navigator.mediaDevices.getUserMedia`]: https://developer.mozilla.org/en/docs/Web/API/MediaDevices/getUserMedia
|
||||
[`systemPreferences.getMediaAccessStatus`]: system-preferences.md#systempreferencesgetmediaaccessstatusmediatype-macos
|
||||
|
||||
|
||||
@@ -11,14 +11,6 @@ const { dialog } = require('electron')
|
||||
console.log(dialog.showOpenDialog({ properties: ['openFile', 'multiSelections'] }))
|
||||
```
|
||||
|
||||
The Dialog is opened from Electron's main thread. If you want to use the dialog
|
||||
object from a renderer process, remember to access it using the remote:
|
||||
|
||||
```javascript
|
||||
const { dialog } = require('electron').remote
|
||||
console.log(dialog)
|
||||
```
|
||||
|
||||
## Methods
|
||||
|
||||
The `dialog` module has the following methods:
|
||||
|
||||
@@ -74,6 +74,7 @@ The following methods of `chrome.runtime` are supported:
|
||||
|
||||
- `chrome.runtime.getBackgroundPage`
|
||||
- `chrome.runtime.getManifest`
|
||||
- `chrome.runtime.getPlatformInfo`
|
||||
- `chrome.runtime.getURL`
|
||||
- `chrome.runtime.connect`
|
||||
- `chrome.runtime.sendMessage`
|
||||
@@ -102,3 +103,15 @@ The following methods of `chrome.tabs` are supported:
|
||||
> **Note:** In Chrome, passing `-1` as a tab ID signifies the "currently active
|
||||
> tab". Since Electron has no such concept, passing `-1` as a tab ID is not
|
||||
> supported and will raise an error.
|
||||
|
||||
### `chrome.management`
|
||||
|
||||
The following methods of `chrome.management` are supported:
|
||||
|
||||
- `chrome.management.getAll`
|
||||
- `chrome.management.get`
|
||||
- `chrome.management.getSelf`
|
||||
- `chrome.management.getPermissionWarningsById`
|
||||
- `chrome.management.getPermissionWarningsByManifest`
|
||||
- `chrome.management.onEnabled`
|
||||
- `chrome.management.onDisabled`
|
||||
|
||||
@@ -112,13 +112,19 @@ optional parameter can be used to forward mouse move messages to the web page,
|
||||
allowing events such as `mouseleave` to be emitted:
|
||||
|
||||
```javascript
|
||||
const win = require('electron').remote.getCurrentWindow()
|
||||
const { ipcRenderer } = require('electron')
|
||||
const el = document.getElementById('clickThroughElement')
|
||||
el.addEventListener('mouseenter', () => {
|
||||
win.setIgnoreMouseEvents(true, { forward: true })
|
||||
ipcRenderer.send('set-ignore-mouse-events', true, { forward: true })
|
||||
})
|
||||
el.addEventListener('mouseleave', () => {
|
||||
win.setIgnoreMouseEvents(false)
|
||||
ipcRenderer.send('set-ignore-mouse-events', false)
|
||||
})
|
||||
|
||||
// Main process
|
||||
const { ipcMain } = require('electron')
|
||||
ipcMain.on('set-ignore-mouse-events', (event, ...args) => {
|
||||
BrowserWindow.fromWebContents(event.sender).setIgnoreMouseEvents(...args)
|
||||
})
|
||||
```
|
||||
|
||||
|
||||
@@ -141,13 +141,7 @@ can have a submenu.
|
||||
|
||||
## Examples
|
||||
|
||||
The `Menu` class is only available in the main process, but you can also use it
|
||||
in the render process via the [`remote`](remote.md) module.
|
||||
|
||||
### Main process
|
||||
|
||||
An example of creating the application menu in the main process with the
|
||||
simple template API:
|
||||
An example of creating the application menu with the simple template API:
|
||||
|
||||
```javascript
|
||||
const { app, Menu } = require('electron')
|
||||
@@ -257,26 +251,36 @@ Menu.setApplicationMenu(menu)
|
||||
|
||||
### Render process
|
||||
|
||||
Below is an example of creating a menu dynamically in a web page
|
||||
(render process) by using the [`remote`](remote.md) module, and showing it when
|
||||
the user right clicks the page:
|
||||
To create menus initiated by the renderer process, send the required
|
||||
information to the main process using IPC and have the main process display the
|
||||
menu on behalf of the renderer.
|
||||
|
||||
```html
|
||||
<!-- index.html -->
|
||||
<script>
|
||||
const { remote } = require('electron')
|
||||
const { Menu, MenuItem } = remote
|
||||
|
||||
const menu = new Menu()
|
||||
menu.append(new MenuItem({ label: 'MenuItem1', click() { console.log('item 1 clicked') } }))
|
||||
menu.append(new MenuItem({ type: 'separator' }))
|
||||
menu.append(new MenuItem({ label: 'MenuItem2', type: 'checkbox', checked: true }))
|
||||
Below is an example of showing a menu when the user right clicks the page:
|
||||
|
||||
```js
|
||||
// renderer
|
||||
window.addEventListener('contextmenu', (e) => {
|
||||
e.preventDefault()
|
||||
menu.popup({ window: remote.getCurrentWindow() })
|
||||
}, false)
|
||||
</script>
|
||||
ipcRenderer.send('show-context-menu')
|
||||
})
|
||||
|
||||
ipcRenderer.on('context-menu-command', (e, command) => {
|
||||
// ...
|
||||
})
|
||||
|
||||
// main
|
||||
ipcMain.on('show-context-menu', (event) => {
|
||||
const template = [
|
||||
{
|
||||
label: 'Menu Item 1',
|
||||
click: () => { event.sender.send('context-menu-command', 'menu-item-1') }
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{ label: 'Menu Item 2', type: 'checkbox', checked: true }
|
||||
]
|
||||
const menu = Menu.buildFromTemplate(template)
|
||||
menu.popup(BrowserWindow.fromWebContents(event.sender))
|
||||
})
|
||||
```
|
||||
|
||||
## Notes on macOS Application Menu
|
||||
|
||||
@@ -8,19 +8,19 @@ Process: [Main](../glossary.md#main-process)
|
||||
|
||||
The `powerMonitor` module emits the following events:
|
||||
|
||||
### Event: 'suspend'
|
||||
### Event: 'suspend' _macOS_ _Windows_
|
||||
|
||||
Emitted when the system is suspending.
|
||||
|
||||
### Event: 'resume'
|
||||
### Event: 'resume' _macOS_ _Windows_
|
||||
|
||||
Emitted when system is resuming.
|
||||
|
||||
### Event: 'on-ac' _Windows_
|
||||
### Event: 'on-ac' _macOS_ _Windows_
|
||||
|
||||
Emitted when the system changes to AC power.
|
||||
|
||||
### Event: 'on-battery' _Windows_
|
||||
### Event: 'on-battery' _macOS_ _Windows_
|
||||
|
||||
Emitted when system changes to battery power.
|
||||
|
||||
|
||||
@@ -4,6 +4,16 @@
|
||||
|
||||
Process: [Renderer](../glossary.md#renderer-process)
|
||||
|
||||
> ⚠️ WARNING ⚠️
|
||||
> The `remote` module is [deprecated](https://github.com/electron/electron/issues/21408).
|
||||
> Instead of `remote`, use [`ipcRenderer`](ipc-renderer.md) and
|
||||
> [`ipcMain`](ipc-main.md).
|
||||
>
|
||||
> Read more about why the `remote` module is deprecated [here](https://medium.com/@nornagon/electrons-remote-module-considered-harmful-70d69500f31).
|
||||
>
|
||||
> If you still want to use `remote` despite the performance and security
|
||||
> concerns, see [@electron/remote](https://github.com/electron/remote).
|
||||
|
||||
The `remote` module provides a simple way to do inter-process communication
|
||||
(IPC) between the renderer process (web page) and the main process.
|
||||
|
||||
@@ -140,11 +150,32 @@ console.log(app)
|
||||
|
||||
The `remote` module has the following methods:
|
||||
|
||||
### `remote.require(module)`
|
||||
### `remote.getCurrentWindow()`
|
||||
|
||||
* `module` String
|
||||
Returns [`BrowserWindow`](browser-window.md) - The window to which this web page
|
||||
belongs.
|
||||
|
||||
Returns `any` - The object returned by `require(module)` in the main process.
|
||||
**Note:** Do not use `removeAllListeners` on [`BrowserWindow`](browser-window.md).
|
||||
Use of this can remove all [`blur`](https://developer.mozilla.org/en-US/docs/Web/Events/blur)
|
||||
listeners, disable click events on touch bar buttons, and other unintended
|
||||
consequences.
|
||||
|
||||
### `remote.getCurrentWebContents()`
|
||||
|
||||
Returns [`WebContents`](web-contents.md) - The web contents of this web page.
|
||||
|
||||
### `remote.getGlobal(name)`
|
||||
|
||||
* `name` String
|
||||
|
||||
Returns `any` - The global variable of `name` (e.g. `global[name]`) in the main
|
||||
process.
|
||||
|
||||
## Properties
|
||||
|
||||
### `remote.require`
|
||||
|
||||
A `NodeJS.Require` function equivalent to `require(module)` in the main process.
|
||||
Modules specified by their relative path will resolve relative to the entrypoint
|
||||
of the main process.
|
||||
|
||||
@@ -176,28 +207,6 @@ module.exports = 'bar'
|
||||
const foo = require('electron').remote.require('./foo') // bar
|
||||
```
|
||||
|
||||
### `remote.getCurrentWindow()`
|
||||
|
||||
Returns [`BrowserWindow`](browser-window.md) - The window to which this web page
|
||||
belongs.
|
||||
|
||||
**Note:** Do not use `removeAllListeners` on [`BrowserWindow`](browser-window.md).
|
||||
Use of this can remove all [`blur`](https://developer.mozilla.org/en-US/docs/Web/Events/blur)
|
||||
listeners, disable click events on touch bar buttons, and other unintended
|
||||
consequences.
|
||||
|
||||
### `remote.getCurrentWebContents()`
|
||||
|
||||
Returns [`WebContents`](web-contents.md) - The web contents of this web page.
|
||||
|
||||
### `remote.getGlobal(name)`
|
||||
|
||||
* `name` String
|
||||
|
||||
Returns `any` - The global variable of `name` (e.g. `global[name]`) in the main
|
||||
process.
|
||||
|
||||
## Properties
|
||||
|
||||
### `remote.process` _Readonly_
|
||||
|
||||
|
||||
@@ -88,26 +88,17 @@ and preload.js:
|
||||
|
||||
```js
|
||||
// This file is loaded whenever a javascript context is created. It runs in a
|
||||
// private scope that can access a subset of Electron renderer APIs. We must be
|
||||
// careful to not leak any objects into the global scope!
|
||||
const { ipcRenderer, remote } = require('electron')
|
||||
const fs = remote.require('fs')
|
||||
|
||||
// read a configuration file using the `fs` module
|
||||
const buf = fs.readFileSync('allowed-popup-urls.json')
|
||||
const allowedUrls = JSON.parse(buf.toString('utf8'))
|
||||
// private scope that can access a subset of Electron renderer APIs. Without
|
||||
// contextIsolation enabled, it's possible to accidentally leak privileged
|
||||
// globals like ipcRenderer to web content.
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
||||
const defaultWindowOpen = window.open
|
||||
|
||||
function customWindowOpen (url, ...args) {
|
||||
if (allowedUrls.indexOf(url) === -1) {
|
||||
ipcRenderer.sendSync('blocked-popup-notification', location.origin, url)
|
||||
return null
|
||||
}
|
||||
return defaultWindowOpen(url, ...args)
|
||||
window.open = function customWindowOpen (url, ...args) {
|
||||
ipcRenderer.send('report-window-open', location.origin, url, args)
|
||||
return defaultWindowOpen(url + '?from_electron=1', ...args)
|
||||
}
|
||||
|
||||
window.open = customWindowOpen
|
||||
```
|
||||
|
||||
Important things to notice in the preload script:
|
||||
@@ -115,8 +106,6 @@ Important things to notice in the preload script:
|
||||
- Even though the sandboxed renderer doesn't have Node.js running, it still has
|
||||
access to a limited node-like environment: `Buffer`, `process`, `setImmediate`,
|
||||
`clearImmediate` and `require` are available.
|
||||
- The preload script can indirectly access all APIs from the main process through the
|
||||
`remote` and `ipcRenderer` modules.
|
||||
- The preload script must be contained in a single script, but it is possible to have
|
||||
complex preload code composed with multiple modules by using a tool like
|
||||
webpack or browserify. An example of using browserify is below.
|
||||
@@ -144,15 +133,12 @@ following modules:
|
||||
- `desktopCapturer`
|
||||
- `ipcRenderer`
|
||||
- `nativeImage`
|
||||
- `remote`
|
||||
- `webFrame`
|
||||
- `events`
|
||||
- `timers`
|
||||
- `url`
|
||||
|
||||
More may be added as needed to expose more Electron APIs in the sandbox, but any
|
||||
module in the main process can already be used through
|
||||
`electron.remote.require`.
|
||||
More may be added as needed to expose more Electron APIs in the sandbox.
|
||||
|
||||
## Rendering untrusted content
|
||||
|
||||
|
||||
@@ -45,15 +45,27 @@ Returns `Promise<void>`
|
||||
|
||||
Open the given external protocol URL in the desktop's default manner. (For example, mailto: URLs in the user's default mail agent).
|
||||
|
||||
### `shell.moveItemToTrash(fullPath[, deleteOnFail])`
|
||||
### `shell.moveItemToTrash(fullPath[, deleteOnFail])` _Deprecated_
|
||||
|
||||
* `fullPath` String
|
||||
* `deleteOnFail` Boolean (optional) - Whether or not to unilaterally remove the item if the Trash is disabled or unsupported on the volume. _macOS_
|
||||
|
||||
Returns `Boolean` - Whether the item was successfully moved to the trash or otherwise deleted.
|
||||
|
||||
> NOTE: This method is deprecated. Use `shell.trashItem` instead.
|
||||
|
||||
Move the given file to trash and returns a boolean status for the operation.
|
||||
|
||||
### `shell.trashItem(path)`
|
||||
|
||||
* `path` String - path to the item to be moved to the trash.
|
||||
|
||||
Returns `Promise<void>` - Resolves when the operation has been completed.
|
||||
Rejects if there was an error while deleting the requested item.
|
||||
|
||||
This moves a path to the OS-specific trash location (Trash on macOS, Recycle
|
||||
Bin on Windows, and a desktop-environment-specific location on Linux).
|
||||
|
||||
### `shell.beep()`
|
||||
|
||||
Play the beep sound.
|
||||
|
||||
@@ -13,3 +13,5 @@ target's icon.
|
||||
DLL or EXE. Default is 0.
|
||||
* `appUserModelId` String (optional) - The Application User Model ID. Default
|
||||
is empty.
|
||||
* `toastActivatorClsid` String (optional) - The Application Toast Activator CLSID. Needed
|
||||
for participating in Action Center.
|
||||
|
||||
@@ -9,7 +9,7 @@ the [native modules](../tutorial/using-native-node-modules.md)).
|
||||
Electron also provides some extra built-in modules for developing native
|
||||
desktop applications. Some modules are only available in the main process, some
|
||||
are only available in the renderer process (web page), and some can be used in
|
||||
both processes.
|
||||
either process type.
|
||||
|
||||
The basic rule is: if a module is [GUI][gui] or low-level system related, then
|
||||
it should be only available in the main process. You need to be familiar with
|
||||
@@ -29,15 +29,15 @@ app.whenReady().then(() => {
|
||||
```
|
||||
|
||||
The renderer process is no different than a normal web page, except for the
|
||||
extra ability to use node modules:
|
||||
extra ability to use node modules if `nodeIntegration` is enabled:
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<script>
|
||||
const { app } = require('electron').remote
|
||||
console.log(app.getVersion())
|
||||
const fs = require('fs')
|
||||
console.log(fs.readFileSync(__filename, 'utf8'))
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -784,7 +784,7 @@ Returns:
|
||||
Emitted when `desktopCapturer.getSources()` is called in the renderer process.
|
||||
Calling `event.preventDefault()` will make it return empty sources.
|
||||
|
||||
#### Event: 'remote-require'
|
||||
#### Event: 'remote-require' _Deprecated_
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -795,7 +795,7 @@ Emitted when `remote.require()` is called in the renderer process.
|
||||
Calling `event.preventDefault()` will prevent the module from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
#### Event: 'remote-get-global'
|
||||
#### Event: 'remote-get-global' _Deprecated_
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -806,7 +806,7 @@ Emitted when `remote.getGlobal()` is called in the renderer process.
|
||||
Calling `event.preventDefault()` will prevent the global from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
#### Event: 'remote-get-builtin'
|
||||
#### Event: 'remote-get-builtin' _Deprecated_
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -817,7 +817,7 @@ Emitted when `remote.getBuiltin()` is called in the renderer process.
|
||||
Calling `event.preventDefault()` will prevent the module from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
#### Event: 'remote-get-current-window'
|
||||
#### Event: 'remote-get-current-window' _Deprecated_
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -827,7 +827,7 @@ Emitted when `remote.getCurrentWindow()` is called in the renderer process.
|
||||
Calling `event.preventDefault()` will prevent the object from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
#### Event: 'remote-get-current-web-contents'
|
||||
#### Event: 'remote-get-current-web-contents' _Deprecated_
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -1117,6 +1117,10 @@ increment above or below represents zooming 20% larger or smaller to default
|
||||
limits of 300% and 50% of original size, respectively. The formula for this is
|
||||
`scale := 1.2 ^ level`.
|
||||
|
||||
> **NOTE**: The zoom policy at the Chromium level is same-origin, meaning that the
|
||||
> zoom level for a specific domain propagates across all instances of windows with
|
||||
> the same domain. Differentiating the window URLs will make zoom work per-window.
|
||||
|
||||
#### `contents.getZoomLevel()`
|
||||
|
||||
Returns `Number` - the current zoom level.
|
||||
@@ -1296,9 +1300,9 @@ Returns [`PrinterInfo[]`](structures/printer-info.md)
|
||||
* `pagesPerSheet` Number (optional) - The number of pages to print per page sheet.
|
||||
* `collate` Boolean (optional) - Whether the web page should be collated.
|
||||
* `copies` Number (optional) - The number of copies of the web page to print.
|
||||
* `pageRanges` Record<string, number> (optional) - The page range to print.
|
||||
* `from` Number - the start page.
|
||||
* `to` Number - the end page.
|
||||
* `pageRanges` Object[] (optional) - The page range to print. On macOS, only one range is honored.
|
||||
* `from` Number - Index of the first page to print (0-based).
|
||||
* `to` Number - Index of the last page to print (inclusive) (0-based).
|
||||
* `duplexMode` String (optional) - Set the duplex mode of the printed web page. Can be `simplex`, `shortEdge`, or `longEdge`.
|
||||
* `dpi` Record<string, number> (optional)
|
||||
* `horizontal` Number (optional) - The horizontal dpi.
|
||||
@@ -1324,10 +1328,10 @@ Example usage:
|
||||
const options = {
|
||||
silent: true,
|
||||
deviceName: 'My-Printer',
|
||||
pageRanges: {
|
||||
pageRanges: [{
|
||||
from: 0,
|
||||
to: 1
|
||||
}
|
||||
}]
|
||||
}
|
||||
win.webContents.print(options, (success, errorType) => {
|
||||
if (!success) console.log(errorType)
|
||||
@@ -1345,8 +1349,8 @@ win.webContents.print(options, (success, errorType) => {
|
||||
default margin, 1 for no margin, and 2 for minimum margin.
|
||||
* `scaleFactor` Number (optional) - The scale factor of the web page. Can range from 0 to 100.
|
||||
* `pageRanges` Record<string, number> (optional) - The page range to print.
|
||||
* `from` Number - zero-based index of the first page to print.
|
||||
* `to` Number - zero-based index of the last page to print (inclusive).
|
||||
* `from` Number - Index of the first page to print (0-based).
|
||||
* `to` Number - Index of the last page to print (inclusive) (0-based).
|
||||
* `pageSize` String | Size (optional) - Specify page size of the generated PDF. Can be `A3`,
|
||||
`A4`, `A5`, `Legal`, `Letter`, `Tabloid` or an Object containing `height` and `width` in microns.
|
||||
* `printBackground` Boolean (optional) - Whether to print CSS backgrounds.
|
||||
@@ -1453,7 +1457,7 @@ An example of showing devtools in a `<webview>` tag:
|
||||
<webview id="browser" src="https://github.com"></webview>
|
||||
<webview id="devtools" src="about:blank"></webview>
|
||||
<script>
|
||||
const { webContents } = require('electron').remote
|
||||
const { ipcRenderer } = require('electron')
|
||||
const emittedOnce = (element, eventName) => new Promise(resolve => {
|
||||
element.addEventListener(eventName, event => resolve(event), { once: true })
|
||||
})
|
||||
@@ -1462,16 +1466,26 @@ An example of showing devtools in a `<webview>` tag:
|
||||
const browserReady = emittedOnce(browserView, 'dom-ready')
|
||||
const devtoolsReady = emittedOnce(devtoolsView, 'dom-ready')
|
||||
Promise.all([browserReady, devtoolsReady]).then(() => {
|
||||
const browser = webContents.fromId(browserView.getWebContentsId())
|
||||
const devtools = webContents.fromId(devtoolsView.getWebContentsId())
|
||||
browser.setDevToolsWebContents(devtools)
|
||||
browser.openDevTools()
|
||||
const targetId = browserView.getWebContentsId()
|
||||
const devtoolsId = devtoolsView.getWebContentsId()
|
||||
ipcRenderer.send('open-devtools', targetId, devtoolsId)
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```js
|
||||
// Main process
|
||||
const { ipcMain, webContents } = require('electron')
|
||||
ipcMain.on('open-devtools', (event, targetContentsId, devtoolsContentsId) => {
|
||||
const target = webContents.fromId(targetContentsId)
|
||||
const devtools = webContents.fromId(devtoolsContentsId)
|
||||
target.setDevToolsWebContents(devtools)
|
||||
target.openDevTools()
|
||||
})
|
||||
```
|
||||
|
||||
An example of showing devtools in a `BrowserWindow`:
|
||||
|
||||
```js
|
||||
|
||||
@@ -41,6 +41,10 @@ Changes the zoom level to the specified level. The original size is 0 and each
|
||||
increment above or below represents zooming 20% larger or smaller to default
|
||||
limits of 300% and 50% of original size, respectively.
|
||||
|
||||
> **NOTE**: The zoom policy at the Chromium level is same-origin, meaning that the
|
||||
> zoom level for a specific domain propagates across all instances of windows with
|
||||
> the same domain. Differentiating the window URLs will make zoom work per-window.
|
||||
|
||||
### `webFrame.getZoomLevel()`
|
||||
|
||||
Returns `Number` - The current zoom level.
|
||||
|
||||
@@ -137,7 +137,7 @@ This option is disabled by default in the guest page.
|
||||
```
|
||||
|
||||
A `Boolean`. When this attribute is `false` the guest page in `webview` will not have access
|
||||
to the [`remote`](remote.md) module. The remote module is available by default.
|
||||
to the [`remote`](remote.md) module. The remote module is unavailable by default.
|
||||
|
||||
### `plugins`
|
||||
|
||||
@@ -560,9 +560,9 @@ Stops any `findInPage` request for the `webview` with the provided `action`.
|
||||
* `pagesPerSheet` Number (optional) - The number of pages to print per page sheet.
|
||||
* `collate` Boolean (optional) - Whether the web page should be collated.
|
||||
* `copies` Number (optional) - The number of copies of the web page to print.
|
||||
* `pageRanges` Record<string, number> (optional) - The page range to print.
|
||||
* `from` Number - zero-based index of the first page to print.
|
||||
* `to` Number - zero-based index of the last page to print (inclusive).
|
||||
* `pageRanges` Object[] (optional) - The page range to print.
|
||||
* `from` Number - Index of the first page to print (0-based).
|
||||
* `to` Number - Index of the last page to print (inclusive) (0-based).
|
||||
* `duplexMode` String (optional) - Set the duplex mode of the printed web page. Can be `simplex`, `shortEdge`, or `longEdge`.
|
||||
* `dpi` Record<string, number> (optional)
|
||||
* `horizontal` Number (optional) - The horizontal dpi.
|
||||
@@ -587,9 +587,9 @@ Prints `webview`'s web page. Same as `webContents.print([options])`.
|
||||
default margin, 1 for no margin, and 2 for minimum margin.
|
||||
and `width` in microns.
|
||||
* `scaleFactor` Number (optional) - The scale factor of the web page. Can range from 0 to 100.
|
||||
* `pageRanges` Record<string, number> (optional) - The page range to print.
|
||||
* `from` Number - the first page to print.
|
||||
* `to` Number - the last page to print (inclusive).
|
||||
* `pageRanges` Record<string, number> (optional) - The page range to print. On macOS, only the first range is honored.
|
||||
* `from` Number - Index of the first page to print (0-based).
|
||||
* `to` Number - Index of the last page to print (inclusive) (0-based).
|
||||
* `pageSize` String | Size (optional) - Specify page size of the generated PDF. Can be `A3`,
|
||||
`A4`, `A5`, `Legal`, `Letter`, `Tabloid` or an Object containing `height`
|
||||
* `printBackground` Boolean (optional) - Whether to print CSS backgrounds.
|
||||
@@ -648,6 +648,10 @@ increment above or below represents zooming 20% larger or smaller to default
|
||||
limits of 300% and 50% of original size, respectively. The formula for this is
|
||||
`scale := 1.2 ^ level`.
|
||||
|
||||
> **NOTE**: The zoom policy at the Chromium level is same-origin, meaning that the
|
||||
> zoom level for a specific domain propagates across all instances of windows with
|
||||
> the same domain. Differentiating the window URLs will make zoom work per-window.
|
||||
|
||||
### `<webview>.getZoomFactor()`
|
||||
|
||||
Returns `Number` - the current zoom factor.
|
||||
|
||||
@@ -12,6 +12,20 @@ This document uses the following convention to categorize breaking changes:
|
||||
- **Deprecated:** An API was marked as deprecated. The API will continue to function, but will emit a deprecation warning, and will be removed in a future release.
|
||||
- **Removed:** An API or feature was removed, and is no longer supported by Electron.
|
||||
|
||||
## Planned Breaking API Changes (13.0)
|
||||
|
||||
### Removed: `shell.moveItemToTrash()`
|
||||
|
||||
The deprecated synchronous `shell.moveItemToTrash()` API has been removed. Use
|
||||
the asynchronous `shell.trashItem()` instead.
|
||||
|
||||
```js
|
||||
// Removed in Electron 13
|
||||
shell.moveItemToTrash(path)
|
||||
// Replace with
|
||||
shell.trashItem(path).then(/* ... */)
|
||||
```
|
||||
|
||||
## Planned Breaking API Changes (12.0)
|
||||
|
||||
### Default Changed: `contextIsolation` defaults to `true`
|
||||
@@ -50,6 +64,37 @@ If your crash ingestion server does not support compressed payloads, you can
|
||||
turn off compression by specifying `{ compress: false }` in the crash reporter
|
||||
options.
|
||||
|
||||
### Deprecated: `remote` module
|
||||
|
||||
The `remote` module is deprecated in Electron 12, and will be removed in
|
||||
Electron 14. It is replaced by the
|
||||
[`@electron/remote`](https://github.com/electron/remote) module.
|
||||
|
||||
```js
|
||||
// Deprecated in Electron 12:
|
||||
const { BrowserWindow } = require('electron').remote
|
||||
```
|
||||
|
||||
```js
|
||||
// Replace with:
|
||||
const { BrowserWindow } = require('@electron/remote')
|
||||
|
||||
// In the main process:
|
||||
require('@electron/remote/main').initialize()
|
||||
```
|
||||
|
||||
### Deprecated: `shell.moveItemToTrash()`
|
||||
|
||||
The synchronous `shell.moveItemToTrash()` has been replaced by the new,
|
||||
asynchronous `shell.trashItem()`.
|
||||
|
||||
```js
|
||||
// Deprecated in Electron 12
|
||||
shell.moveItemToTrash(path)
|
||||
// Replace with
|
||||
shell.trashItem(path).then(/* ... */)
|
||||
```
|
||||
|
||||
## Planned Breaking API Changes (11.0)
|
||||
|
||||
There are no breaking changes planned for 11.0.
|
||||
|
||||
@@ -4,8 +4,8 @@ These guides are intended for people working on the Electron project itself.
|
||||
For guides on Electron app development, see
|
||||
[/docs/README.md](../README.md#guides-and-tutorials).
|
||||
|
||||
* [Code of Conduct](../../CODE_OF_CONDUCT.md)
|
||||
* [Contributing to Electron](../../CONTRIBUTING.md)
|
||||
* [Code of Conduct](https://github.com/electron/electron/blob/master/CODE_OF_CONDUCT.md)
|
||||
* [Contributing to Electron](https://github.com/electron/electron/blob/master/CONTRIBUTING.md)
|
||||
* [Issues](issues.md)
|
||||
* [Pull Requests](pull-requests.md)
|
||||
* [Documentation Styleguide](coding-style.md#documentation)
|
||||
|
||||
@@ -69,8 +69,7 @@ way of figuring out which is which.
|
||||
### Which Process Should I Attach to?
|
||||
|
||||
Code executed within the main process (that is, code found in or eventually run
|
||||
by your main JavaScript file) as well as code called using the remote
|
||||
(`require('electron').remote`) will run inside the main process, while other
|
||||
by your main JavaScript file) will run inside the main process, while other
|
||||
code will execute inside its respective renderer process.
|
||||
|
||||
You can be attached to multiple programs when you are debugging, but only one
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
const { BrowserWindow, app } = require('electron')
|
||||
const { BrowserWindow, app, screen, ipcMain } = require('electron')
|
||||
|
||||
let mainWindow = null
|
||||
|
||||
ipcMain.handle('get-screen-size', () => {
|
||||
return screen.getPrimaryDisplay().workAreaSize
|
||||
})
|
||||
|
||||
function createWindow () {
|
||||
const windowOptions = {
|
||||
width: 600,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
const { desktopCapturer } = require('electron')
|
||||
const { screen, shell } = require('electron').remote
|
||||
const { desktopCapturer, shell, ipcRenderer } = require('electron')
|
||||
|
||||
const fs = require('fs')
|
||||
const os = require('os')
|
||||
@@ -8,9 +7,9 @@ const path = require('path')
|
||||
const screenshot = document.getElementById('screen-shot')
|
||||
const screenshotMsg = document.getElementById('screenshot-path')
|
||||
|
||||
screenshot.addEventListener('click', (event) => {
|
||||
screenshot.addEventListener('click', async (event) => {
|
||||
screenshotMsg.textContent = 'Gathering screens...'
|
||||
const thumbSize = determineScreenShotSize()
|
||||
const thumbSize = await determineScreenShotSize()
|
||||
const options = { types: ['screen'], thumbnailSize: thumbSize }
|
||||
|
||||
desktopCapturer.getSources(options, (error, sources) => {
|
||||
@@ -33,8 +32,8 @@ screenshot.addEventListener('click', (event) => {
|
||||
})
|
||||
})
|
||||
|
||||
function determineScreenShotSize () {
|
||||
const screenSize = screen.getPrimaryDisplay().workAreaSize
|
||||
async function determineScreenShotSize () {
|
||||
const screenSize = await ipcRenderer.invoke('get-screen-size')
|
||||
const maxDimension = Math.max(screenSize.width, screenSize.height)
|
||||
return {
|
||||
width: maxDimension * window.devicePixelRatio,
|
||||
|
||||
@@ -1,95 +1,95 @@
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow, ipcMain, dialog } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On macOS it is common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
ipcMain.on('open-error-dialog', event => {
|
||||
dialog.showErrorBox('An Error Message', 'Demonstrating an error message.')
|
||||
})
|
||||
|
||||
ipcMain.on('open-information-dialog', event => {
|
||||
const options = {
|
||||
type: 'info',
|
||||
title: 'Information',
|
||||
message: "This is an information dialog. Isn't it nice?",
|
||||
buttons: ['Yes', 'No']
|
||||
}
|
||||
dialog.showMessageBox(options, index => {
|
||||
event.sender.send('information-dialog-selection', index)
|
||||
})
|
||||
})
|
||||
|
||||
ipcMain.on('open-file-dialog', event => {
|
||||
dialog.showOpenDialog(
|
||||
{
|
||||
properties: ['openFile', 'openDirectory']
|
||||
},
|
||||
files => {
|
||||
if (files) {
|
||||
event.sender.send('selected-directory', files)
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
ipcMain.on('save-dialog', event => {
|
||||
const options = {
|
||||
title: 'Save an Image',
|
||||
filters: [{ name: 'Images', extensions: ['jpg', 'png', 'gif'] }]
|
||||
}
|
||||
dialog.showSaveDialog(options, filename => {
|
||||
event.sender.send('saved-file', filename)
|
||||
})
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow, ipcMain, dialog } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On macOS it is common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
ipcMain.on('open-error-dialog', event => {
|
||||
dialog.showErrorBox('An Error Message', 'Demonstrating an error message.')
|
||||
})
|
||||
|
||||
ipcMain.on('open-information-dialog', event => {
|
||||
const options = {
|
||||
type: 'info',
|
||||
title: 'Information',
|
||||
message: "This is an information dialog. Isn't it nice?",
|
||||
buttons: ['Yes', 'No']
|
||||
}
|
||||
dialog.showMessageBox(options, index => {
|
||||
event.sender.send('information-dialog-selection', index)
|
||||
})
|
||||
})
|
||||
|
||||
ipcMain.on('open-file-dialog', event => {
|
||||
dialog.showOpenDialog(
|
||||
{
|
||||
properties: ['openFile', 'openDirectory']
|
||||
},
|
||||
files => {
|
||||
if (files) {
|
||||
event.sender.send('selected-directory', files)
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
ipcMain.on('save-dialog', event => {
|
||||
const options = {
|
||||
title: 'Save an Image',
|
||||
filters: [{ name: 'Images', extensions: ['jpg', 'png', 'gif'] }]
|
||||
}
|
||||
dialog.showSaveDialog(options, filename => {
|
||||
event.sender.send('saved-file', filename)
|
||||
})
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
const { ipcRenderer, shell } = require('electron')
|
||||
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
const errorBtn = document.getElementById('error-dialog')
|
||||
|
||||
errorBtn.addEventListener('click', event => {
|
||||
ipcRenderer.send('open-error-dialog')
|
||||
})
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
const { ipcRenderer, shell } = require('electron')
|
||||
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
const errorBtn = document.getElementById('error-dialog')
|
||||
|
||||
errorBtn.addEventListener('click', event => {
|
||||
ipcRenderer.send('open-error-dialog')
|
||||
})
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -1,70 +1,70 @@
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow, ipcMain, dialog } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On macOS it is common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
ipcMain.on('open-information-dialog', event => {
|
||||
const options = {
|
||||
type: 'info',
|
||||
title: 'Information',
|
||||
message: "This is an information dialog. Isn't it nice?",
|
||||
buttons: ['Yes', 'No']
|
||||
}
|
||||
dialog.showMessageBox(options, index => {
|
||||
event.sender.send('information-dialog-selection', index)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow, ipcMain, dialog } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On macOS it is common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
ipcMain.on('open-information-dialog', event => {
|
||||
const options = {
|
||||
type: 'info',
|
||||
title: 'Information',
|
||||
message: "This is an information dialog. Isn't it nice?",
|
||||
buttons: ['Yes', 'No']
|
||||
}
|
||||
dialog.showMessageBox(options, index => {
|
||||
event.sender.send('information-dialog-selection', index)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
const { ipcRenderer, shell } = require('electron')
|
||||
|
||||
const informationBtn = document.getElementById('information-dialog')
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
informationBtn.addEventListener('click', event => {
|
||||
ipcRenderer.send('open-information-dialog')
|
||||
})
|
||||
|
||||
ipcRenderer.on('information-dialog-selection', (event, index) => {
|
||||
let message = 'You selected '
|
||||
if (index === 0) message += 'yes.'
|
||||
else message += 'no.'
|
||||
document.getElementById('info-selection').innerHTML = message
|
||||
})
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
const { ipcRenderer, shell } = require('electron')
|
||||
|
||||
const informationBtn = document.getElementById('information-dialog')
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
informationBtn.addEventListener('click', event => {
|
||||
ipcRenderer.send('open-information-dialog')
|
||||
})
|
||||
|
||||
ipcRenderer.on('information-dialog-selection', (event, index) => {
|
||||
let message = 'You selected '
|
||||
if (index === 0) message += 'yes.'
|
||||
else message += 'no.'
|
||||
document.getElementById('info-selection').innerHTML = message
|
||||
})
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -1,70 +1,70 @@
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow, ipcMain, dialog } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On macOS it is common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
ipcMain.on('open-file-dialog', event => {
|
||||
dialog.showOpenDialog(
|
||||
{
|
||||
properties: ['openFile', 'openDirectory']
|
||||
},
|
||||
files => {
|
||||
if (files) {
|
||||
event.sender.send('selected-directory', files)
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow, ipcMain, dialog } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On macOS it is common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
ipcMain.on('open-file-dialog', event => {
|
||||
dialog.showOpenDialog(
|
||||
{
|
||||
properties: ['openFile', 'openDirectory']
|
||||
},
|
||||
files => {
|
||||
if (files) {
|
||||
event.sender.send('selected-directory', files)
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
const { ipcRenderer, shell } = require('electron')
|
||||
|
||||
const selectDirBtn = document.getElementById('select-directory')
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
selectDirBtn.addEventListener('click', event => {
|
||||
ipcRenderer.send('open-file-dialog')
|
||||
})
|
||||
|
||||
ipcRenderer.on('selected-directory', (event, path) => {
|
||||
document.getElementById('selected-file').innerHTML = `You selected: ${path}`
|
||||
})
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
})
|
||||
const { ipcRenderer, shell } = require('electron')
|
||||
|
||||
const selectDirBtn = document.getElementById('select-directory')
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
selectDirBtn.addEventListener('click', event => {
|
||||
ipcRenderer.send('open-file-dialog')
|
||||
})
|
||||
|
||||
ipcRenderer.on('selected-directory', (event, path) => {
|
||||
document.getElementById('selected-file').innerHTML = `You selected: ${path}`
|
||||
})
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,66 +1,66 @@
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow, ipcMain, dialog } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On macOS it is common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
ipcMain.on('save-dialog', event => {
|
||||
const options = {
|
||||
title: 'Save an Image',
|
||||
filters: [{ name: 'Images', extensions: ['jpg', 'png', 'gif'] }]
|
||||
}
|
||||
dialog.showSaveDialog(options, filename => {
|
||||
event.sender.send('saved-file', filename)
|
||||
})
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow, ipcMain, dialog } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On macOS it is common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
ipcMain.on('save-dialog', event => {
|
||||
const options = {
|
||||
title: 'Save an Image',
|
||||
filters: [{ name: 'Images', extensions: ['jpg', 'png', 'gif'] }]
|
||||
}
|
||||
dialog.showSaveDialog(options, filename => {
|
||||
event.sender.send('saved-file', filename)
|
||||
})
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
const { ipcRenderer, shell } = require('electron')
|
||||
|
||||
const saveBtn = document.getElementById('save-dialog')
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
saveBtn.addEventListener('click', event => {
|
||||
ipcRenderer.send('save-dialog')
|
||||
})
|
||||
|
||||
ipcRenderer.on('saved-file', (event, path) => {
|
||||
if (!path) path = 'No path'
|
||||
document.getElementById('file-saved').innerHTML = `Path selected: ${path}`
|
||||
})
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
const { ipcRenderer, shell } = require('electron')
|
||||
|
||||
const saveBtn = document.getElementById('save-dialog')
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
saveBtn.addEventListener('click', event => {
|
||||
ipcRenderer.send('save-dialog')
|
||||
})
|
||||
|
||||
ipcRenderer.on('saved-file', (event, path) => {
|
||||
if (!path) path = 'No path'
|
||||
document.getElementById('file-saved').innerHTML = `Path selected: ${path}`
|
||||
})
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -1,56 +1,56 @@
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On macOS it is common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On macOS it is common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
const { shell } = require('electron')
|
||||
const os = require('os')
|
||||
|
||||
const exLinksBtn = document.getElementById('open-ex-links')
|
||||
const fileManagerBtn = document.getElementById('open-file-manager')
|
||||
|
||||
fileManagerBtn.addEventListener('click', (event) => {
|
||||
shell.showItemInFolder(os.homedir())
|
||||
})
|
||||
|
||||
exLinksBtn.addEventListener('click', (event) => {
|
||||
shell.openExternal('https://electronjs.org')
|
||||
const { shell } = require('electron')
|
||||
const os = require('os')
|
||||
|
||||
const exLinksBtn = document.getElementById('open-ex-links')
|
||||
const fileManagerBtn = document.getElementById('open-file-manager')
|
||||
|
||||
fileManagerBtn.addEventListener('click', (event) => {
|
||||
shell.showItemInFolder(os.homedir())
|
||||
})
|
||||
|
||||
exLinksBtn.addEventListener('click', (event) => {
|
||||
shell.openExternal('https://electronjs.org')
|
||||
})
|
||||
|
||||
@@ -1,56 +1,56 @@
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On macOS it is common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On macOS it is common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
const basicNotification = {
|
||||
title: 'Basic Notification',
|
||||
body: 'Short message part'
|
||||
}
|
||||
|
||||
const notification = {
|
||||
title: 'Notification with image',
|
||||
body: 'Short message plus a custom image',
|
||||
icon: 'https://via.placeholder.com/150'
|
||||
}
|
||||
|
||||
const basicNotificationButton = document.getElementById('basic-noti')
|
||||
const notificationButton = document.getElementById('advanced-noti')
|
||||
|
||||
notificationButton.addEventListener('click', () => {
|
||||
const myNotification = new window.Notification(notification.title, notification)
|
||||
|
||||
myNotification.onclick = () => {
|
||||
console.log('Notification clicked')
|
||||
}
|
||||
})
|
||||
|
||||
basicNotificationButton.addEventListener('click', () => {
|
||||
const myNotification = new window.Notification(basicNotification.title, basicNotification)
|
||||
|
||||
myNotification.onclick = () => {
|
||||
console.log('Notification clicked')
|
||||
}
|
||||
})
|
||||
const basicNotification = {
|
||||
title: 'Basic Notification',
|
||||
body: 'Short message part'
|
||||
}
|
||||
|
||||
const notification = {
|
||||
title: 'Notification with image',
|
||||
body: 'Short message plus a custom image',
|
||||
icon: 'https://via.placeholder.com/150'
|
||||
}
|
||||
|
||||
const basicNotificationButton = document.getElementById('basic-noti')
|
||||
const notificationButton = document.getElementById('advanced-noti')
|
||||
|
||||
notificationButton.addEventListener('click', () => {
|
||||
const myNotification = new window.Notification(notification.title, notification)
|
||||
|
||||
myNotification.onclick = () => {
|
||||
console.log('Notification clicked')
|
||||
}
|
||||
})
|
||||
|
||||
basicNotificationButton.addEventListener('click', () => {
|
||||
const myNotification = new window.Notification(basicNotification.title, basicNotification)
|
||||
|
||||
myNotification.onclick = () => {
|
||||
console.log('Notification clicked')
|
||||
}
|
||||
})
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,35 +1,35 @@
|
||||
const { ipcRenderer, shell } = require('electron')
|
||||
|
||||
const trayBtn = document.getElementById('put-in-tray')
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
let trayOn = false
|
||||
|
||||
trayBtn.addEventListener('click', function (event) {
|
||||
if (trayOn) {
|
||||
trayOn = false
|
||||
document.getElementById('tray-countdown').innerHTML = ''
|
||||
ipcRenderer.send('remove-tray')
|
||||
} else {
|
||||
trayOn = true
|
||||
const message = 'Click demo again to remove.'
|
||||
document.getElementById('tray-countdown').innerHTML = message
|
||||
ipcRenderer.send('put-in-tray')
|
||||
}
|
||||
})
|
||||
// Tray removed from context menu on icon
|
||||
ipcRenderer.on('tray-removed', function () {
|
||||
ipcRenderer.send('remove-tray')
|
||||
trayOn = false
|
||||
document.getElementById('tray-countdown').innerHTML = ''
|
||||
})
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
const { ipcRenderer, shell } = require('electron')
|
||||
|
||||
const trayBtn = document.getElementById('put-in-tray')
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
let trayOn = false
|
||||
|
||||
trayBtn.addEventListener('click', function (event) {
|
||||
if (trayOn) {
|
||||
trayOn = false
|
||||
document.getElementById('tray-countdown').innerHTML = ''
|
||||
ipcRenderer.send('remove-tray')
|
||||
} else {
|
||||
trayOn = true
|
||||
const message = 'Click demo again to remove.'
|
||||
document.getElementById('tray-countdown').innerHTML = message
|
||||
ipcRenderer.send('put-in-tray')
|
||||
}
|
||||
})
|
||||
// Tray removed from context menu on icon
|
||||
ipcRenderer.on('tray-removed', function () {
|
||||
ipcRenderer.send('remove-tray')
|
||||
trayOn = false
|
||||
document.getElementById('tray-countdown').innerHTML = ''
|
||||
})
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -1,23 +1,20 @@
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
const { app, BrowserWindow, ipcMain } = require('electron')
|
||||
|
||||
let mainWindow = null
|
||||
ipcMain.on('create-frameless-window', (event, {url}) => {
|
||||
const win = new BrowserWindow({ frame: false })
|
||||
win.loadURL(url)
|
||||
})
|
||||
|
||||
function createWindow () {
|
||||
const windowOptions = {
|
||||
const mainWindow = new BrowserWindow({
|
||||
width: 600,
|
||||
height: 400,
|
||||
title: 'Create a frameless window',
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
}
|
||||
|
||||
mainWindow = new BrowserWindow(windowOptions)
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
mainWindow.on('closed', () => {
|
||||
mainWindow = null
|
||||
})
|
||||
mainWindow.loadFile('index.html')
|
||||
}
|
||||
|
||||
app.whenReady().then(() => {
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
const { BrowserWindow } = require('electron').remote
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
||||
const newWindowBtn = document.getElementById('frameless-window')
|
||||
|
||||
newWindowBtn.addEventListener('click', (event) => {
|
||||
let win = new BrowserWindow({ frame: false })
|
||||
|
||||
win.on('close', () => { win = null })
|
||||
|
||||
win.loadURL('data:text/html,<h2>Hello World!</h2><a id="close" href="javascript:window.close()">Close this Window</a>')
|
||||
win.show()
|
||||
newWindowBtn.addEventListener('click', () => {
|
||||
const url = 'data:text/html,<h2>Hello World!</h2><a id="close" href="javascript:window.close()">Close this Window</a>'
|
||||
ipcRenderer.send('create-frameless-window', { url })
|
||||
})
|
||||
|
||||
@@ -1,56 +1,46 @@
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On macOS it is common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
ipcMain.on('create-frameless-window', (event, {url}) => {
|
||||
const win = new BrowserWindow({ frame: false })
|
||||
win.loadURL(url)
|
||||
})
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
const mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On macOS it is common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
|
||||
@@ -1,25 +1,8 @@
|
||||
const { BrowserWindow } = require('electron').remote
|
||||
const shell = require('electron').shell
|
||||
|
||||
const framelessWindowBtn = document.getElementById('frameless-window')
|
||||
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
framelessWindowBtn.addEventListener('click', (event) => {
|
||||
const modalPath = 'https://electronjs.org'
|
||||
let win = new BrowserWindow({ frame: false })
|
||||
|
||||
win.on('close', () => { win = null })
|
||||
win.loadURL(modalPath)
|
||||
win.show()
|
||||
})
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
})
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
||||
const newWindowBtn = document.getElementById('frameless-window')
|
||||
|
||||
newWindowBtn.addEventListener('click', () => {
|
||||
const url = 'data:text/html,<h2>Hello World!</h2><a id="close" href="javascript:window.close()">Close this Window</a>'
|
||||
ipcRenderer.send('create-frameless-window', { url })
|
||||
})
|
||||
|
||||
@@ -1,56 +1,56 @@
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On macOS it is common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow, ipcMain } = require('electron')
|
||||
|
||||
ipcMain.on('create-demo-window', (event) => {
|
||||
const win = new BrowserWindow({ width: 400, height: 275 })
|
||||
|
||||
function updateReply() {
|
||||
event.sender.send('bounds-changed', {
|
||||
size: win.getSize(),
|
||||
position: win.getPosition()
|
||||
})
|
||||
}
|
||||
|
||||
win.on('resize', updateReply)
|
||||
win.on('move', updateReply)
|
||||
win.loadURL('https://electronjs.org')
|
||||
})
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On macOS it is common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
|
||||
@@ -1,35 +1,25 @@
|
||||
const { BrowserWindow } = require('electron').remote
|
||||
const shell = require('electron').shell
|
||||
|
||||
const manageWindowBtn = document.getElementById('manage-window')
|
||||
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
let win
|
||||
|
||||
manageWindowBtn.addEventListener('click', (event) => {
|
||||
const modalPath = 'https://electronjs.org'
|
||||
win = new BrowserWindow({ width: 400, height: 275 })
|
||||
|
||||
win.on('resize', updateReply)
|
||||
win.on('move', updateReply)
|
||||
win.on('close', () => { win = null })
|
||||
win.loadURL(modalPath)
|
||||
win.show()
|
||||
|
||||
function updateReply () {
|
||||
const manageWindowReply = document.getElementById('manage-window-reply')
|
||||
const message = `Size: ${win.getSize()} Position: ${win.getPosition()}`
|
||||
manageWindowReply.innerText = message
|
||||
}
|
||||
})
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
})
|
||||
const { shell, ipcRenderer } = require('electron')
|
||||
|
||||
const manageWindowBtn = document.getElementById('manage-window')
|
||||
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
ipcRenderer.on('bounds-changed', (event, bounds) => {
|
||||
const manageWindowReply = document.getElementById('manage-window-reply')
|
||||
const message = `Size: ${bounds.size} Position: ${bounds.position}`
|
||||
manageWindowReply.textContent = message
|
||||
})
|
||||
|
||||
manageWindowBtn.addEventListener('click', (event) => {
|
||||
ipcRenderer.send('create-demo-window')
|
||||
})
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<h2>Create a new window</h2>
|
||||
<h3>Supports: Win, macOS, Linux <span>|</span> Process: Main</h3>
|
||||
<button id="new-window">View Demo</button>
|
||||
<p>The <code>BrowserWindow</code> module gives you the ability to create new windows in your app. This main process module can be used from the renderer process with the <code>remote</code> module, as is shown in this demo.</p>
|
||||
<p>The <code>BrowserWindow</code> module gives you the ability to create new windows in your app.</p>
|
||||
<p>There are a lot of options when creating a new window. A few are in this demo, but visit the <a id="browser-window-link" href="">documentation<span>(opens in new window)</span></a>
|
||||
<div>
|
||||
<h2>ProTip</h2>
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
const { app, BrowserWindow, ipcMain } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
ipcMain.on('new-window', (event, { url, width, height }) => {
|
||||
const win = new BrowserWindow({ width, height })
|
||||
win.loadURL(url)
|
||||
})
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
const mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
@@ -17,17 +18,6 @@ function createWindow () {
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
|
||||
@@ -1,16 +1,11 @@
|
||||
const { BrowserWindow } = require('electron').remote
|
||||
const { shell } = require('electron').remote
|
||||
const { shell, ipcRenderer } = require('electron')
|
||||
|
||||
const newWindowBtn = document.getElementById('new-window')
|
||||
const link = document.getElementById('browser-window-link')
|
||||
|
||||
newWindowBtn.addEventListener('click', (event) => {
|
||||
|
||||
let win = new BrowserWindow({ width: 400, height: 320 })
|
||||
|
||||
win.on('close', () => { win = null })
|
||||
win.loadURL('https://electronjs.org')
|
||||
win.show()
|
||||
const url = 'https://electronjs.org'
|
||||
ipcRenderer.send('new-window', { url, width: 400, height: 320 });
|
||||
})
|
||||
|
||||
link.addEventListener('click', (e) => {
|
||||
|
||||
@@ -1,56 +1,64 @@
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On macOS it is common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow, ipcMain } = require('electron')
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
const mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
let demoWindow
|
||||
ipcMain.on('show-demo-window', () => {
|
||||
if (demoWindow) {
|
||||
demoWindow.focus()
|
||||
return
|
||||
}
|
||||
demoWindow = new BrowserWindow({ width: 600, height: 400 })
|
||||
demoWindow.loadURL('https://electronjs.org')
|
||||
demoWindow.on('close', () => {
|
||||
mainWindow.webContents.send('window-close')
|
||||
})
|
||||
demoWindow.on('focus', () => {
|
||||
mainWindow.webContents.send('window-focus')
|
||||
})
|
||||
demoWindow.on('blur', () => {
|
||||
mainWindow.webContents.send('window-blur')
|
||||
})
|
||||
})
|
||||
|
||||
ipcMain.on('focus-demo-window', () => {
|
||||
if (demoWindow) demoWindow.focus()
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On macOS it is common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
|
||||
@@ -1,48 +1,39 @@
|
||||
const { BrowserWindow } = require('electron').remote
|
||||
const shell = require('electron').shell
|
||||
|
||||
const listenToWindowBtn = document.getElementById('listen-to-window')
|
||||
const focusModalBtn = document.getElementById('focus-on-modal-window')
|
||||
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
let win
|
||||
|
||||
listenToWindowBtn.addEventListener('click', () => {
|
||||
const modalPath = 'https://electronjs.org'
|
||||
win = new BrowserWindow({ width: 600, height: 400 })
|
||||
|
||||
const hideFocusBtn = () => {
|
||||
focusModalBtn.classList.add('disappear')
|
||||
focusModalBtn.classList.remove('smooth-appear')
|
||||
focusModalBtn.removeEventListener('click', clickHandler)
|
||||
}
|
||||
|
||||
const showFocusBtn = (btn) => {
|
||||
if (!win) return
|
||||
focusModalBtn.classList.add('smooth-appear')
|
||||
focusModalBtn.classList.remove('disappear')
|
||||
focusModalBtn.addEventListener('click', clickHandler)
|
||||
}
|
||||
|
||||
win.on('focus', hideFocusBtn)
|
||||
win.on('blur', showFocusBtn)
|
||||
win.on('close', () => {
|
||||
hideFocusBtn()
|
||||
win = null
|
||||
})
|
||||
win.loadURL(modalPath)
|
||||
win.show()
|
||||
|
||||
const clickHandler = () => { win.focus() }
|
||||
})
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
})
|
||||
const { shell, ipcRenderer } = require('electron')
|
||||
|
||||
const listenToWindowBtn = document.getElementById('listen-to-window')
|
||||
const focusModalBtn = document.getElementById('focus-on-modal-window')
|
||||
|
||||
const hideFocusBtn = () => {
|
||||
focusModalBtn.classList.add('disappear')
|
||||
focusModalBtn.classList.remove('smooth-appear')
|
||||
focusModalBtn.removeEventListener('click', focusWindow)
|
||||
}
|
||||
|
||||
const showFocusBtn = (btn) => {
|
||||
focusModalBtn.classList.add('smooth-appear')
|
||||
focusModalBtn.classList.remove('disappear')
|
||||
focusModalBtn.addEventListener('click', focusWindow)
|
||||
}
|
||||
const focusWindow = () => {
|
||||
ipcRenderer.send('focus-demo-window')
|
||||
}
|
||||
|
||||
ipcRenderer.on('window-focus', hideFocusBtn)
|
||||
ipcRenderer.on('window-close', hideFocusBtn)
|
||||
ipcRenderer.on('window-blur', showFocusBtn)
|
||||
|
||||
listenToWindowBtn.addEventListener('click', () => {
|
||||
ipcRenderer.send('show-demo-window')
|
||||
})
|
||||
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Accessibility
|
||||
|
||||
Making accessible applications is important and we're happy to introduce new
|
||||
Making accessible applications is important and we're happy to provide
|
||||
functionality to [Devtron][devtron] and [Spectron][spectron] that gives
|
||||
developers the opportunity to make their apps better for everyone.
|
||||
|
||||
@@ -11,7 +11,7 @@ websites because they're both ultimately HTML. With Electron apps, however,
|
||||
you can't use the online resources for accessibility audits because your app
|
||||
doesn't have a URL to point the auditor to.
|
||||
|
||||
These new features bring those auditing tools to your Electron app. You can
|
||||
These features bring those auditing tools to your Electron app. You can
|
||||
choose to add audits to your tests with Spectron or use them within DevTools
|
||||
with Devtron. Read on for a summary of the tools.
|
||||
|
||||
@@ -32,7 +32,7 @@ You can read more about this feature in [Spectron's documentation][spectron-a11y
|
||||
|
||||
## Devtron
|
||||
|
||||
In Devtron, there is a new accessibility tab which will allow you to audit a
|
||||
In Devtron, there is an accessibility tab which will allow you to audit a
|
||||
page in your app, sort and filter the results.
|
||||
|
||||
![devtron screenshot][devtron-screenshot]
|
||||
@@ -44,26 +44,29 @@ audit rules this library uses on that [repository's wiki][a11y-devtools-wiki].
|
||||
If you know of other great accessibility tools for Electron, add them to the
|
||||
accessibility documentation with a pull request.
|
||||
|
||||
## Enabling Accessibility
|
||||
## Manually enabling accessibility features
|
||||
|
||||
Electron applications keep accessibility disabled by default for performance
|
||||
reasons but there are multiple ways to enable it.
|
||||
Electron applications will automatically enable accessibility features in the
|
||||
presence of assistive technology (e.g. [JAWS](https://www.freedomscientific.com/products/software/jaws/)
|
||||
on Windows or [VoiceOver](https://help.apple.com/voiceover/mac/10.15/) on macOS).
|
||||
See Chrome's [accessibility documentation][a11y-docs] for more details.
|
||||
|
||||
### Inside Application
|
||||
You can also manually toggle these features either within your Electron application
|
||||
or by setting flags in third-party native software.
|
||||
|
||||
By using [`app.setAccessibilitySupportEnabled(enabled)`][setAccessibilitySupportEnabled],
|
||||
you can expose accessibility switch to users in the application preferences.
|
||||
User's system assistive utilities have priority over this setting and will
|
||||
override it.
|
||||
### Using Electron's API
|
||||
|
||||
### Assistive Technology
|
||||
By using the [`app.setAccessibilitySupportEnabled(enabled)`][setAccessibilitySupportEnabled]
|
||||
API, you can manually expose Chrome's accessibility tree to users in the application preferences.
|
||||
Note that the user's system assistive utilities have priority over this setting and
|
||||
will override it.
|
||||
|
||||
Electron application will enable accessibility automatically when it detects
|
||||
assistive technology (Windows) or VoiceOver (macOS). See Chrome's
|
||||
[accessibility documentation][a11y-docs] for more details.
|
||||
### Within third-party software
|
||||
|
||||
On macOS, third-party assistive technology can switch accessibility inside
|
||||
Electron applications by setting the attribute `AXManualAccessibility`
|
||||
#### macOS
|
||||
|
||||
On macOS, third-party assistive technology can toggle accessibility features inside
|
||||
Electron applications by setting the `AXManualAccessibility` attribute
|
||||
programmatically:
|
||||
|
||||
```objc
|
||||
|
||||
@@ -26,7 +26,8 @@ To test In-App Purchase in development with Electron you'll have to change the `
|
||||
Here is an example that shows how to use In-App Purchases in Electron. You'll have to replace the product ids by the identifiers of the products created with iTunes Connect (the identifier of `com.example.app.product1` is `product1`). Note that you have to listen to the `transactions-updated` event as soon as possible in your app.
|
||||
|
||||
```javascript
|
||||
const { inAppPurchase } = require('electron').remote
|
||||
// Main process
|
||||
const { inAppPurchase } = require('electron')
|
||||
const PRODUCT_IDS = ['id1', 'id2']
|
||||
|
||||
// Listen for transactions as soon as possible.
|
||||
|
||||
@@ -55,7 +55,6 @@ template("electron_extra_paks") {
|
||||
output = "${invoker.output_dir}/resources.pak"
|
||||
sources = [
|
||||
"$root_gen_dir/chrome/dev_ui_browser_resources.pak",
|
||||
"$root_gen_dir/chrome/print_preview_pdf_resources.pak",
|
||||
"$root_gen_dir/components/components_resources.pak",
|
||||
"$root_gen_dir/content/browser/resources/media/media_internals_resources.pak",
|
||||
"$root_gen_dir/content/browser/tracing/tracing_resources.pak",
|
||||
@@ -71,7 +70,6 @@ template("electron_extra_paks") {
|
||||
]
|
||||
deps = [
|
||||
"//chrome/browser:dev_ui_browser_resources",
|
||||
"//chrome/browser/resources:print_preview_pdf_resources",
|
||||
"//components/resources",
|
||||
"//content:content_resources",
|
||||
"//content:dev_ui_content_resources",
|
||||
@@ -96,6 +94,10 @@ template("electron_extra_paks") {
|
||||
sources +=
|
||||
[ "$root_gen_dir/content/browser/devtools/devtools_resources.pak" ]
|
||||
deps += [ "//content/browser/devtools:devtools_resources" ]
|
||||
if (enable_pdf_viewer) {
|
||||
sources += [ "$root_gen_dir/chrome/print_preview_pdf_resources.pak" ]
|
||||
deps += [ "//chrome/browser/resources:print_preview_pdf_resources" ]
|
||||
}
|
||||
if (enable_print_preview) {
|
||||
sources += [ "$root_gen_dir/chrome/print_preview_resources.pak" ]
|
||||
deps += [ "//chrome/browser/resources:print_preview_resources" ]
|
||||
|
||||
@@ -490,6 +490,7 @@ filenames = {
|
||||
"shell/common/gin_converters/file_path_converter.h",
|
||||
"shell/common/gin_converters/gfx_converter.cc",
|
||||
"shell/common/gin_converters/gfx_converter.h",
|
||||
"shell/common/gin_converters/guid_converter.h",
|
||||
"shell/common/gin_converters/gurl_converter.h",
|
||||
"shell/common/gin_converters/image_converter.cc",
|
||||
"shell/common/gin_converters/image_converter.h",
|
||||
@@ -565,7 +566,9 @@ filenames = {
|
||||
"shell/common/node_util.h",
|
||||
"shell/common/options_switches.cc",
|
||||
"shell/common/options_switches.h",
|
||||
"shell/common/platform_util.cc",
|
||||
"shell/common/platform_util.h",
|
||||
"shell/common/platform_util_internal.h",
|
||||
"shell/common/platform_util_linux.cc",
|
||||
"shell/common/platform_util_mac.mm",
|
||||
"shell/common/platform_util_win.cc",
|
||||
@@ -625,6 +628,8 @@ filenames = {
|
||||
"shell/browser/extensions/api/resources_private/resources_private_api.h",
|
||||
"shell/browser/extensions/api/runtime/electron_runtime_api_delegate.cc",
|
||||
"shell/browser/extensions/api/runtime/electron_runtime_api_delegate.h",
|
||||
"shell/browser/extensions/api/management/electron_management_api_delegate.cc",
|
||||
"shell/browser/extensions/api/management/electron_management_api_delegate.h",
|
||||
"shell/browser/extensions/api/tabs/tabs_api.cc",
|
||||
"shell/browser/extensions/api/tabs/tabs_api.h",
|
||||
"shell/browser/extensions/api/streams_private/streams_private_api.cc",
|
||||
|
||||
@@ -28,9 +28,11 @@ Object.setPrototypeOf(BrowserWindow.prototype, BaseWindow.prototype);
|
||||
// Though this hack is only needed on macOS when the app is launched from
|
||||
// Finder, we still do it on all platforms in case of other bugs we don't
|
||||
// know.
|
||||
this.webContents.once('load-url' as any, function (this: WebContents) {
|
||||
this.focus();
|
||||
});
|
||||
if (this.webContents._initiallyShown) {
|
||||
this.webContents.once('load-url' as any, function (this: WebContents) {
|
||||
this.focus();
|
||||
});
|
||||
}
|
||||
|
||||
// Redirect focus/blur event to app instance too.
|
||||
this.on('blur', (event: Event) => {
|
||||
@@ -90,11 +92,7 @@ BrowserWindow.getFocusedWindow = () => {
|
||||
};
|
||||
|
||||
BrowserWindow.fromWebContents = (webContents: WebContents) => {
|
||||
for (const window of BrowserWindow.getAllWindows()) {
|
||||
if (window.webContents && window.webContents.equal(webContents)) return window;
|
||||
}
|
||||
|
||||
return null;
|
||||
return webContents.getOwnerBrowserWindow();
|
||||
};
|
||||
|
||||
BrowserWindow.fromBrowserView = (browserView: BrowserView) => {
|
||||
|
||||
@@ -13,7 +13,7 @@ class CrashReporter {
|
||||
submitURL,
|
||||
uploadToServer = true,
|
||||
rateLimit = false,
|
||||
compress = false
|
||||
compress = true
|
||||
} = options || {};
|
||||
|
||||
if (submitURL == null) throw new Error('submitURL is a required option to crashReporter.start');
|
||||
|
||||
@@ -362,7 +362,7 @@ export class ClientRequest extends Writable implements Electron.ClientRequest {
|
||||
delete this._urlLoaderOptions.extraHeaders[key];
|
||||
}
|
||||
|
||||
_write (chunk: Buffer, encoding: string, callback: () => void) {
|
||||
_write (chunk: Buffer, encoding: BufferEncoding, callback: () => void) {
|
||||
this._firstWrite = true;
|
||||
if (!this._body) {
|
||||
this._body = new SlurpStream();
|
||||
@@ -481,6 +481,14 @@ export class ClientRequest extends Writable implements Electron.ClientRequest {
|
||||
}
|
||||
|
||||
_die (err?: Error) {
|
||||
// Node.js assumes that any stream which is ended is no longer capable of emitted events
|
||||
// which is a faulty assumption for the case of an object that is acting like a stream
|
||||
// (our urlRequest). If we don't emit here, this causes errors since we *do* expect
|
||||
// that error events can be emitted after urlRequest.end().
|
||||
if ((this as any)._writableState.destroyed && err) {
|
||||
this.emit('error', err);
|
||||
}
|
||||
|
||||
this.destroy(err);
|
||||
if (this._urlLoader) {
|
||||
this._urlLoader.cancel();
|
||||
|
||||
@@ -461,6 +461,11 @@ const addReturnValueToEvent = (event: any) => {
|
||||
});
|
||||
};
|
||||
|
||||
const loggingEnabled = () => {
|
||||
return Object.prototype.hasOwnProperty.call(process.env, 'ELECTRON_ENABLE_LOGGING') ||
|
||||
process.argv.some(arg => arg.toLowerCase().startsWith('--enable-logging'));
|
||||
};
|
||||
|
||||
// Add JavaScript wrappers for WebContents class.
|
||||
WebContents.prototype._init = function () {
|
||||
// The navigation controller.
|
||||
@@ -543,6 +548,11 @@ WebContents.prototype._init = function () {
|
||||
|
||||
this.on('crashed', (event, ...args) => {
|
||||
app.emit('renderer-process-crashed', event, this, ...args);
|
||||
|
||||
// Log out a hint to help users better debug renderer crashes.
|
||||
if (loggingEnabled()) {
|
||||
console.info('Renderer process crashed - see https://www.electronjs.org/docs/tutorial/application-debugging for potential debugging information.');
|
||||
}
|
||||
});
|
||||
|
||||
this.on('render-process-gone', (event, ...args) => {
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
const {
|
||||
createDesktopCapturer,
|
||||
getMediaSourceIdForWebContents: getMediaSourceIdForWebContentsBinding
|
||||
} = process._linkedBinding('electron_browser_desktop_capturer');
|
||||
const { createDesktopCapturer } = process._linkedBinding('electron_browser_desktop_capturer');
|
||||
|
||||
const deepEqual = (a: ElectronInternal.GetSourcesOptions, b: ElectronInternal.GetSourcesOptions) => JSON.stringify(a) === JSON.stringify(b);
|
||||
|
||||
@@ -80,7 +77,3 @@ export const getSourcesImpl = (event: Electron.IpcMainEvent | null, args: Electr
|
||||
|
||||
return getSources;
|
||||
};
|
||||
|
||||
export const getMediaSourceIdForWebContents = (event: Electron.IpcMainEvent, webContentsId: number) => {
|
||||
return getMediaSourceIdForWebContentsBinding(event.sender.id, webContentsId);
|
||||
};
|
||||
|
||||
@@ -4,6 +4,7 @@ import * as fs from 'fs';
|
||||
import { Socket } from 'net';
|
||||
import * as path from 'path';
|
||||
import * as util from 'util';
|
||||
|
||||
const Module = require('module');
|
||||
|
||||
// We modified the original process.argv to let node.js load the init.js,
|
||||
@@ -62,7 +63,7 @@ process.on('uncaughtException', function (error) {
|
||||
// Emit 'exit' event on quit.
|
||||
const { app } = require('electron');
|
||||
|
||||
app.on('quit', function (event, exitCode) {
|
||||
app.on('quit', (_event, exitCode) => {
|
||||
process.emit('exit', exitCode);
|
||||
});
|
||||
|
||||
|
||||
@@ -353,7 +353,7 @@ handleRemoteCommand('ELECTRON_BROWSER_REQUIRE', function (event, contextId, modu
|
||||
if (customEvent.defaultPrevented) {
|
||||
throw new Error(`Blocked remote.require('${moduleName}')`);
|
||||
} else {
|
||||
customEvent.returnValue = process.mainModule!.require(moduleName);
|
||||
customEvent.returnValue = (process as any).mainModule.require(moduleName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -71,10 +71,6 @@ if (BUILDFLAG(ENABLE_DESKTOP_CAPTURER)) {
|
||||
|
||||
return typeUtils.serialize(await desktopCapturer.getSourcesImpl(event, options));
|
||||
});
|
||||
|
||||
ipcMainInternal.handle('ELECTRON_BROWSER_DESKTOP_CAPTURER_GET_MEDIA_SOURCE_ID_FOR_WEB_CONTENTS', function (event: IpcMainInvokeEvent, webContentsId: number) {
|
||||
return desktopCapturer.getMediaSourceIdForWebContents(event, webContentsId);
|
||||
});
|
||||
}
|
||||
|
||||
const isRemoteModuleEnabled = BUILDFLAG(ENABLE_REMOTE_MODULE)
|
||||
|
||||
@@ -1 +1,7 @@
|
||||
export default process._linkedBinding('electron_common_shell');
|
||||
import { deprecate } from 'electron/main';
|
||||
|
||||
const shell = process._linkedBinding('electron_common_shell');
|
||||
|
||||
shell.moveItemToTrash = deprecate.renameFunction(shell.moveItemToTrash, 'shell.trashItem');
|
||||
|
||||
export default shell;
|
||||
|
||||
@@ -16,7 +16,3 @@ function getCurrentStack () {
|
||||
export async function getSources (options: Electron.SourcesOptions) {
|
||||
return deserialize(await ipcRendererInternal.invoke('ELECTRON_BROWSER_DESKTOP_CAPTURER_GET_SOURCES', options, getCurrentStack()));
|
||||
}
|
||||
|
||||
export function getMediaSourceIdForWebContents (webContentsId: number) {
|
||||
return ipcRendererInternal.invoke<string>('ELECTRON_BROWSER_DESKTOP_CAPTURER_GET_MEDIA_SOURCE_ID_FOR_WEB_CONTENTS', webContentsId, getCurrentStack());
|
||||
}
|
||||
|
||||
@@ -3,9 +3,12 @@ import { isPromise, isSerializableObject, serialize, deserialize } from '../../c
|
||||
import { MetaTypeFromRenderer, ObjectMember, ObjProtoDescriptor, MetaType } from '../../common/remote/types';
|
||||
import { ipcRendererInternal } from '../ipc-renderer-internal';
|
||||
import type { BrowserWindow, WebContents } from 'electron/main';
|
||||
import deprecate from '@electron/internal/common/api/deprecate';
|
||||
import { browserModuleNames } from '@electron/internal/browser/api/module-names';
|
||||
import { commonModuleList } from '@electron/internal/common/api/module-list';
|
||||
|
||||
deprecate.log('The remote module is deprecated. Use https://github.com/electron/remote instead.');
|
||||
|
||||
const v8Util = process._linkedBinding('electron_common_v8_util');
|
||||
const { hasSwitch } = process._linkedBinding('electron_common_command_line');
|
||||
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
import { webFrame } from 'electron';
|
||||
|
||||
import * as ipcRendererUtils from '@electron/internal/renderer/ipc-renderer-internal-utils';
|
||||
|
||||
const v8Util = process._linkedBinding('electron_common_v8_util');
|
||||
|
||||
const IsolatedWorldIDs = {
|
||||
/**
|
||||
* Start of extension isolated world IDs, as defined in
|
||||
* electron_render_frame_observer.h
|
||||
*/
|
||||
ISOLATED_WORLD_EXTENSIONS: 1 << 20
|
||||
};
|
||||
|
||||
let isolatedWorldIds = IsolatedWorldIDs.ISOLATED_WORLD_EXTENSIONS;
|
||||
const extensionWorldId: {[key: string]: number | undefined} = {};
|
||||
|
||||
// https://cs.chromium.org/chromium/src/extensions/renderer/script_injection.cc?type=cs&sq=package:chromium&g=0&l=52
|
||||
const getIsolatedWorldIdForInstance = () => {
|
||||
// TODO(samuelmaddock): allocate and cleanup IDs
|
||||
return isolatedWorldIds++;
|
||||
};
|
||||
|
||||
const escapePattern = function (pattern: string) {
|
||||
return pattern.replace(/[\\^$+?.()|[\]{}]/g, '\\$&');
|
||||
};
|
||||
|
||||
// Check whether pattern matches.
|
||||
// https://developer.chrome.com/extensions/match_patterns
|
||||
const matchesPattern = function (pattern: string) {
|
||||
if (pattern === '<all_urls>') return true;
|
||||
const regexp = new RegExp(`^${pattern.split('*').map(escapePattern).join('.*')}$`);
|
||||
const url = `${location.protocol}//${location.host}${location.pathname}`;
|
||||
return url.match(regexp);
|
||||
};
|
||||
|
||||
// Run the code with chrome API integrated.
|
||||
const runContentScript = function (this: any, extensionId: string, url: string, code: string) {
|
||||
// Assign unique world ID to each extension
|
||||
const worldId = extensionWorldId[extensionId] ||
|
||||
(extensionWorldId[extensionId] = getIsolatedWorldIdForInstance());
|
||||
|
||||
// store extension ID for content script to read in isolated world
|
||||
v8Util.setHiddenValue(global, `extension-${worldId}`, extensionId);
|
||||
|
||||
webFrame.setIsolatedWorldInfo(worldId, {
|
||||
name: `${extensionId} [${worldId}]`
|
||||
// TODO(samuelmaddock): read `content_security_policy` from extension manifest
|
||||
// csp: manifest.content_security_policy,
|
||||
});
|
||||
|
||||
const sources = [{ code, url }];
|
||||
return webFrame.executeJavaScriptInIsolatedWorld(worldId, sources);
|
||||
};
|
||||
|
||||
const runAllContentScript = function (scripts: Array<Electron.InjectionBase>, extensionId: string) {
|
||||
for (const { url, code } of scripts) {
|
||||
runContentScript.call(window, extensionId, url, code);
|
||||
}
|
||||
};
|
||||
|
||||
const runStylesheet = function (this: any, url: string, code: string) {
|
||||
webFrame.insertCSS(code);
|
||||
};
|
||||
|
||||
const runAllStylesheet = function (css: Array<Electron.InjectionBase>) {
|
||||
for (const { url, code } of css) {
|
||||
runStylesheet.call(window, url, code);
|
||||
}
|
||||
};
|
||||
|
||||
// Run injected scripts.
|
||||
// https://developer.chrome.com/extensions/content_scripts
|
||||
const injectContentScript = function (extensionId: string, script: Electron.ContentScript) {
|
||||
if (!process.isMainFrame && !script.allFrames) return;
|
||||
if (!script.matches.some(matchesPattern)) return;
|
||||
|
||||
if (script.js) {
|
||||
const fire = runAllContentScript.bind(window, script.js, extensionId);
|
||||
if (script.runAt === 'document_start') {
|
||||
process.once('document-start', fire);
|
||||
} else if (script.runAt === 'document_end') {
|
||||
process.once('document-end', fire);
|
||||
} else {
|
||||
document.addEventListener('DOMContentLoaded', fire);
|
||||
}
|
||||
}
|
||||
|
||||
if (script.css) {
|
||||
const fire = runAllStylesheet.bind(window, script.css);
|
||||
if (script.runAt === 'document_start') {
|
||||
process.once('document-start', fire);
|
||||
} else if (script.runAt === 'document_end') {
|
||||
process.once('document-end', fire);
|
||||
} else {
|
||||
document.addEventListener('DOMContentLoaded', fire);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Handle the request of chrome.tabs.executeJavaScript.
|
||||
ipcRendererUtils.handle('CHROME_TABS_EXECUTE_SCRIPT', function (
|
||||
event: Electron.Event,
|
||||
extensionId: string,
|
||||
url: string,
|
||||
code: string
|
||||
) {
|
||||
return runContentScript.call(window, extensionId, url, code);
|
||||
});
|
||||
|
||||
module.exports = (entries: Electron.ContentScriptEntry[]) => {
|
||||
for (const entry of entries) {
|
||||
if (entry.contentScripts) {
|
||||
for (const script of entry.contentScripts) {
|
||||
injectContentScript(entry.extensionId, script);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,20 +0,0 @@
|
||||
export class Event {
|
||||
private listeners: Function[] = []
|
||||
|
||||
addListener (callback: Function) {
|
||||
this.listeners.push(callback);
|
||||
}
|
||||
|
||||
removeListener (callback: Function) {
|
||||
const index = this.listeners.indexOf(callback);
|
||||
if (index !== -1) {
|
||||
this.listeners.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
emit (...args: any[]) {
|
||||
for (const listener of this.listeners) {
|
||||
listener(...args);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
// Implementation of chrome.i18n.getMessage
|
||||
// https://developer.chrome.com/extensions/i18n#method-getMessage
|
||||
//
|
||||
// Does not implement predefined messages:
|
||||
// https://developer.chrome.com/extensions/i18n#overview-predefined
|
||||
|
||||
import * as ipcRendererUtils from '@electron/internal/renderer/ipc-renderer-internal-utils';
|
||||
|
||||
interface Placeholder {
|
||||
content: string;
|
||||
example?: string;
|
||||
}
|
||||
|
||||
const getMessages = (extensionId: number) => {
|
||||
try {
|
||||
const data = ipcRendererUtils.invokeSync<string>('CHROME_GET_MESSAGES', extensionId);
|
||||
return JSON.parse(data) || {};
|
||||
} catch {
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
const replaceNumberedSubstitutions = (message: string, substitutions: string[]) => {
|
||||
return message.replace(/\$(\d+)/, (_, number) => {
|
||||
const index = parseInt(number, 10) - 1;
|
||||
return substitutions[index] || '';
|
||||
});
|
||||
};
|
||||
|
||||
const replacePlaceholders = (message: string, placeholders: Record<string, Placeholder>, substitutions: string[] | string) => {
|
||||
if (typeof substitutions === 'string') substitutions = [substitutions];
|
||||
if (!Array.isArray(substitutions)) substitutions = [];
|
||||
|
||||
if (placeholders) {
|
||||
Object.keys(placeholders).forEach((name: string) => {
|
||||
let { content } = placeholders[name];
|
||||
const substitutionsArray = Array.isArray(substitutions) ? substitutions : [];
|
||||
content = replaceNumberedSubstitutions(content, substitutionsArray);
|
||||
message = message.replace(new RegExp(`\\$${name}\\$`, 'gi'), content);
|
||||
});
|
||||
}
|
||||
|
||||
return replaceNumberedSubstitutions(message, substitutions);
|
||||
};
|
||||
|
||||
const getMessage = (extensionId: number, messageName: string, substitutions: string[]) => {
|
||||
const messages = getMessages(extensionId);
|
||||
if (Object.prototype.hasOwnProperty.call(messages, messageName)) {
|
||||
const { message, placeholders } = messages[messageName];
|
||||
return replacePlaceholders(message, placeholders, substitutions);
|
||||
}
|
||||
};
|
||||
|
||||
exports.setup = (extensionId: number) => {
|
||||
return {
|
||||
getMessage (messageName: string, substitutions: string[]) {
|
||||
return getMessage(extensionId, messageName, substitutions);
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -1,86 +0,0 @@
|
||||
import { ipcRendererInternal } from '@electron/internal/renderer/ipc-renderer-internal';
|
||||
|
||||
const getStorage = (storageType: string, extensionId: number, callback: Function) => {
|
||||
if (typeof callback !== 'function') throw new TypeError('No callback provided');
|
||||
|
||||
ipcRendererInternal.invoke<string>('CHROME_STORAGE_READ', storageType, extensionId)
|
||||
.then(data => {
|
||||
if (data !== null) {
|
||||
callback(JSON.parse(data));
|
||||
} else {
|
||||
// Disabled due to false positive in StandardJS
|
||||
// eslint-disable-next-line standard/no-callback-literal
|
||||
callback({});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const setStorage = (storageType: string, extensionId: number, storage: Record<string, any>, callback: Function) => {
|
||||
const json = JSON.stringify(storage);
|
||||
ipcRendererInternal.invoke('CHROME_STORAGE_WRITE', storageType, extensionId, json)
|
||||
.then(() => {
|
||||
if (callback) callback();
|
||||
});
|
||||
};
|
||||
|
||||
const getStorageManager = (storageType: string, extensionId: number) => {
|
||||
return {
|
||||
get (keys: string[], callback: Function) {
|
||||
getStorage(storageType, extensionId, (storage: Record<string, any>) => {
|
||||
if (keys == null) return callback(storage);
|
||||
|
||||
let defaults: Record<string, any> = {};
|
||||
switch (typeof keys) {
|
||||
case 'string':
|
||||
keys = [keys];
|
||||
break;
|
||||
case 'object':
|
||||
if (!Array.isArray(keys)) {
|
||||
defaults = keys;
|
||||
keys = Object.keys(keys);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Disabled due to false positive in StandardJS
|
||||
// eslint-disable-next-line standard/no-callback-literal
|
||||
if (keys.length === 0) return callback({});
|
||||
|
||||
const items: Record<string, any> = {};
|
||||
keys.forEach((key: string) => {
|
||||
let value = storage[key];
|
||||
if (value == null) value = defaults[key];
|
||||
items[key] = value;
|
||||
});
|
||||
callback(items);
|
||||
});
|
||||
},
|
||||
|
||||
set (items: Record<string, any>, callback: Function) {
|
||||
getStorage(storageType, extensionId, (storage: Record<string, any>) => {
|
||||
Object.keys(items).forEach(name => { storage[name] = items[name]; });
|
||||
setStorage(storageType, extensionId, storage, callback);
|
||||
});
|
||||
},
|
||||
|
||||
remove (keys: string[], callback: Function) {
|
||||
getStorage(storageType, extensionId, (storage: Record<string, any>) => {
|
||||
if (!Array.isArray(keys)) keys = [keys];
|
||||
keys.forEach((key: string) => {
|
||||
delete storage[key];
|
||||
});
|
||||
|
||||
setStorage(storageType, extensionId, storage, callback);
|
||||
});
|
||||
},
|
||||
|
||||
clear (callback: Function) {
|
||||
setStorage(storageType, extensionId, {}, callback);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export const setup = (extensionId: number) => ({
|
||||
sync: getStorageManager('sync', extensionId),
|
||||
local: getStorageManager('local', extensionId)
|
||||
});
|
||||
@@ -1,19 +0,0 @@
|
||||
import { Event } from '@electron/internal/renderer/extensions/event';
|
||||
import { ipcRendererInternal } from '@electron/internal/renderer/ipc-renderer-internal';
|
||||
|
||||
class WebNavigation {
|
||||
private onBeforeNavigate = new Event()
|
||||
private onCompleted = new Event()
|
||||
|
||||
constructor () {
|
||||
ipcRendererInternal.on('CHROME_WEBNAVIGATION_ONBEFORENAVIGATE', (event: Electron.IpcRendererEvent, details: any) => {
|
||||
this.onBeforeNavigate.emit(details);
|
||||
});
|
||||
|
||||
ipcRendererInternal.on('CHROME_WEBNAVIGATION_ONCOMPLETED', (event: Electron.IpcRendererEvent, details: any) => {
|
||||
this.onCompleted.emit(details);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const setup = () => new WebNavigation();
|
||||
@@ -9,7 +9,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@electron/get": "^1.0.1",
|
||||
"@types/node": "^12.0.12",
|
||||
"@types/node": "^14.6.2",
|
||||
"extract-zip": "^1.0.3"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"name": "electron",
|
||||
"version": "11.0.0-nightly.20200826",
|
||||
"version": "12.0.0-nightly.20200918",
|
||||
"repository": "https://github.com/electron/electron",
|
||||
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
|
||||
"devDependencies": {
|
||||
"@electron/docs-parser": "^0.9.1",
|
||||
"@electron/typescript-definitions": "^8.7.5",
|
||||
"@electron/typescript-definitions": "^8.7.9",
|
||||
"@octokit/rest": "^18.0.3",
|
||||
"@primer/octicons": "^10.0.0",
|
||||
"@types/basic-auth": "^1.1.3",
|
||||
@@ -16,7 +16,7 @@
|
||||
"@types/express": "^4.17.7",
|
||||
"@types/fs-extra": "^9.0.1",
|
||||
"@types/mocha": "^7.0.2",
|
||||
"@types/node": "^12.12.6",
|
||||
"@types/node": "^14.6.2",
|
||||
"@types/semver": "^7.3.3",
|
||||
"@types/send": "^0.14.5",
|
||||
"@types/split": "^1.0.0",
|
||||
|
||||
@@ -100,3 +100,4 @@ remove_some_deps_that_do_not_work_on_arm64.patch
|
||||
fix_check_issecureeventinputenabled_in_constructor_before_setting.patch
|
||||
skip_atk_toolchain_check.patch
|
||||
worker_feat_add_hook_to_notify_script_ready.patch
|
||||
fix_properly_honor_printing_page_ranges.patch
|
||||
|
||||
129
patches/chromium/fix_properly_honor_printing_page_ranges.patch
Normal file
129
patches/chromium/fix_properly_honor_printing_page_ranges.patch
Normal file
@@ -0,0 +1,129 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shelley Vohr <shelley.vohr@gmail.com>
|
||||
Date: Thu, 20 Aug 2020 10:55:48 -0700
|
||||
Subject: fix: properly honor printing page ranges
|
||||
|
||||
The print ranges in Chromium's print job settings were not being properly
|
||||
plumbed through to PMPrintSettings on mcOS. This fixes that by setting
|
||||
them should they exist.
|
||||
|
||||
This will be upstreamed.
|
||||
|
||||
diff --git a/printing/printing_context_mac.h b/printing/printing_context_mac.h
|
||||
index 06cdc0e1a4a50e29a148c97c964c30a939e800da..5db5cdb61be0beee4506313dcde46c499e011383 100644
|
||||
--- a/printing/printing_context_mac.h
|
||||
+++ b/printing/printing_context_mac.h
|
||||
@@ -81,6 +81,10 @@ class PRINTING_EXPORT PrintingContextMac : public PrintingContext {
|
||||
// Returns true if the orientation was set.
|
||||
bool SetOrientationIsLandscape(bool landscape);
|
||||
|
||||
+ // Set the page range in native print info object.
|
||||
+ // Returns true if the range was set.
|
||||
+ bool SetPrintRangeInPrintSettings(const PageRanges& ranges);
|
||||
+
|
||||
// Sets duplex mode in PMPrintSettings.
|
||||
// Returns true if duplex mode is set.
|
||||
bool SetDuplexModeInPrintSettings(mojom::DuplexMode mode);
|
||||
diff --git a/printing/printing_context_mac.mm b/printing/printing_context_mac.mm
|
||||
index 56bcfbe625537c7b1bc2a999c261836bb15896ba..f916e78de99b87e0dae4f5f87329886b658ccd93 100644
|
||||
--- a/printing/printing_context_mac.mm
|
||||
+++ b/printing/printing_context_mac.mm
|
||||
@@ -188,7 +188,8 @@ PMPaper MatchPaper(CFArrayRef paper_list,
|
||||
!SetCopiesInPrintSettings(settings_->copies()) ||
|
||||
!SetCollateInPrintSettings(settings_->collate()) ||
|
||||
!SetDuplexModeInPrintSettings(settings_->duplex_mode()) ||
|
||||
- !SetOutputColor(settings_->color())) {
|
||||
+ !SetOutputColor(settings_->color()) ||
|
||||
+ !SetPrintRangeInPrintSettings(settings_->ranges()) ) {
|
||||
return OnError();
|
||||
}
|
||||
}
|
||||
@@ -341,6 +342,22 @@ PMPaper MatchPaper(CFArrayRef paper_list,
|
||||
return PMSetCopies(print_settings, copies, false) == noErr;
|
||||
}
|
||||
|
||||
+bool PrintingContextMac::SetPrintRangeInPrintSettings(const PageRanges& ranges) {
|
||||
+ // Default is already NSPrintAllPages - we can safely bail.
|
||||
+ if (ranges.empty())
|
||||
+ return true;
|
||||
+
|
||||
+ auto* print_settings =
|
||||
+ static_cast<PMPrintSettings>([print_info_.get() PMPrintSettings]);
|
||||
+
|
||||
+ // macOS does not allow multiple ranges, so pluck the first.
|
||||
+ auto range = ranges.front();
|
||||
+ bool set_first_page = PMSetFirstPage(print_settings, range.from + 1, false) == noErr;
|
||||
+ bool set_last_page = PMSetLastPage(print_settings, range.to + 1, false) == noErr;
|
||||
+
|
||||
+ return set_first_page && set_last_page;
|
||||
+}
|
||||
+
|
||||
bool PrintingContextMac::SetCollateInPrintSettings(bool collate) {
|
||||
PMPrintSettings print_settings =
|
||||
static_cast<PMPrintSettings>([print_info_.get() PMPrintSettings]);
|
||||
diff --git a/printing/printing_context_system_dialog_win.cc b/printing/printing_context_system_dialog_win.cc
|
||||
index d3c8677f30d72efc49b28f293260c74c7b8d8b4e..f6e66aaa58ab1881d64dcbb320ae8b5ac7631b28 100644
|
||||
--- a/printing/printing_context_system_dialog_win.cc
|
||||
+++ b/printing/printing_context_system_dialog_win.cc
|
||||
@@ -52,14 +52,28 @@ void PrintingContextSystemDialogWin::AskUserForSettings(
|
||||
PRINTPAGERANGE ranges[32];
|
||||
dialog_options.nStartPage = START_PAGE_GENERAL;
|
||||
if (max_pages) {
|
||||
- // Default initialize to print all the pages.
|
||||
memset(ranges, 0, sizeof(ranges));
|
||||
- ranges[0].nFromPage = 1;
|
||||
- ranges[0].nToPage = max_pages;
|
||||
- dialog_options.nPageRanges = 1;
|
||||
- dialog_options.nMaxPageRanges = base::size(ranges);
|
||||
+
|
||||
+ auto page_ranges = settings_->ranges();
|
||||
+ if (!page_ranges.empty()) {
|
||||
+ for (size_t i = 0; i < page_ranges.size(); i++) {
|
||||
+ auto range = page_ranges[i];
|
||||
+ ranges[i].nFromPage = range.from + 1;
|
||||
+ ranges[i].nToPage = range.to + 1;
|
||||
+ }
|
||||
+ dialog_options.nPageRanges = page_ranges.size();
|
||||
+
|
||||
+ // Ensure the Pages radio button is selected.
|
||||
+ dialog_options.Flags |= PD_PAGENUMS;
|
||||
+ } else {
|
||||
+ ranges[0].nFromPage = 1;
|
||||
+ ranges[0].nToPage = max_pages;
|
||||
+ dialog_options.nPageRanges = 1;
|
||||
+ }
|
||||
+
|
||||
dialog_options.nMinPage = 1;
|
||||
dialog_options.nMaxPage = max_pages;
|
||||
+ dialog_options.nMaxPageRanges = base::size(ranges);
|
||||
dialog_options.lpPageRanges = ranges;
|
||||
} else {
|
||||
// No need to bother, we don't know how many pages are available.
|
||||
diff --git a/ui/gtk/printing/print_dialog_gtk.cc b/ui/gtk/printing/print_dialog_gtk.cc
|
||||
index 8a78a609295a1d90208bdc7e73d7a850c319f361..2f5bc01bedf84126d8fb1597a0b813a2b7230279 100644
|
||||
--- a/ui/gtk/printing/print_dialog_gtk.cc
|
||||
+++ b/ui/gtk/printing/print_dialog_gtk.cc
|
||||
@@ -239,6 +239,23 @@ void PrintDialogGtk::UpdateSettings(
|
||||
|
||||
gtk_print_settings_set_n_copies(gtk_settings_, settings->copies());
|
||||
gtk_print_settings_set_collate(gtk_settings_, settings->collate());
|
||||
+
|
||||
+ auto print_ranges = settings->ranges();
|
||||
+ if (!print_ranges.empty()) {
|
||||
+ // Tell the system that we only intend to print a subset of pages.
|
||||
+ gtk_print_settings_set_print_pages(gtk_settings_, GTK_PRINT_PAGES_RANGES);
|
||||
+
|
||||
+ GtkPageRange* ranges;
|
||||
+ ranges = g_new(GtkPageRange, print_ranges.size());
|
||||
+ for (size_t i = 0; i < print_ranges.size(); i++) {
|
||||
+ auto range = print_ranges[i];
|
||||
+ ranges[i].start = range.from;
|
||||
+ ranges[i].end = range.to;
|
||||
+ }
|
||||
+
|
||||
+ gtk_print_settings_set_page_ranges(gtk_settings_, ranges, 1);
|
||||
+ g_free(ranges);
|
||||
+ }
|
||||
|
||||
#if defined(USE_CUPS)
|
||||
// Set advanced settings first so they can be overridden by user applied
|
||||
@@ -22,24 +22,14 @@ chore_prevent_warn_non_context-aware_native_modules_being_loaded.patch
|
||||
chore_read_nobrowserglobals_from_global_not_process.patch
|
||||
build_bring_back_node_with_ltcg_configuration.patch
|
||||
revert_crypto_add_oaeplabel_option.patch
|
||||
refactor_transferrablemodule_is_deprecated_use_compiledwasmmodule.patch
|
||||
enable_31_bit_smis_on_64bit_arch_and_ptr_compression.patch
|
||||
remove_deprecated_task_api_override_removed_in_latest_v8.patch
|
||||
remove_serialization_deserialization_of_wasmmoduleobject.patch
|
||||
override_existing_v8_reallocate.patch
|
||||
fix_use_crypto_impls_for_compat.patch
|
||||
avoid_calling_deprecated_method.patch
|
||||
remove_deprecated_wasm_module_type_check.patch
|
||||
weakrefs_rename_finalizationgroup_to_finalizationregistry_for_js.patch
|
||||
weakrefs_split_out_finalizationregistry_cleanupsome.patch
|
||||
fix_window_c-ares_incompatibilities.patch
|
||||
chore_sethostcleanupfinalizationgroupcallback_has_been_removed_from.patch
|
||||
fix_comment_out_incompatible_crypto_modules.patch
|
||||
lib_src_switch_buffer_kmaxlength_to_size_t.patch
|
||||
update_tests_after_increasing_typed_array_size.patch
|
||||
darwin_work_around_clock_jumping_back_in_time.patch
|
||||
fix_do_not_register_the_esm_loader_in_renderer_processes.patch
|
||||
fix_allow_preventing_setpromiserejectcallback.patch
|
||||
lib_use_non-symbols_in_isurlinstance_check.patch
|
||||
feat_add_implementation_of_v8_platform_postjob.patch
|
||||
fix_enable_tls_renegotiation.patch
|
||||
n-api_src_provide_asynchronous_cleanup_hooks.patch
|
||||
crypto_update_certdata_to_nss_3_56.patch
|
||||
fix_-wincompatible-pointer-types-discards-qualifiers_error.patch
|
||||
fix_allow_preventing_initializeinspector_in_env.patch
|
||||
test_make_some_tests_embedder_agnostic.patch
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Attard <samuel.r.attard@gmail.com>
|
||||
Date: Thu, 13 Feb 2020 10:34:31 -0800
|
||||
Subject: Avoid calling deprecated method
|
||||
|
||||
The {SetExpectInlineWasm} method is deprecated and non-functional since
|
||||
V8 v8.1.
|
||||
|
||||
This is already present in Node.js v14 and can be removed when we upgrade.
|
||||
|
||||
diff --git a/src/node_serdes.cc b/src/node_serdes.cc
|
||||
index bcdcd19b261e8815e3c0c0f150f2eda72ef47cf5..86fb822dd5bfa9da7767418e6c6f206f8e96ca73 100644
|
||||
--- a/src/node_serdes.cc
|
||||
+++ b/src/node_serdes.cc
|
||||
@@ -286,7 +286,6 @@ DeserializerContext::DeserializerContext(Environment* env,
|
||||
length_(Buffer::Length(buffer)),
|
||||
deserializer_(env->isolate(), data_, length_, this) {
|
||||
object()->Set(env->context(), env->buffer_string(), buffer).Check();
|
||||
- deserializer_.SetExpectInlineWasm(true);
|
||||
|
||||
MakeWeak();
|
||||
}
|
||||
@@ -7,10 +7,10 @@ This adds GN build files for Node, so we don't have to build with GYP.
|
||||
|
||||
diff --git a/BUILD.gn b/BUILD.gn
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..99192976f2bdfd900240aa58b8989fe2c9d8c771
|
||||
index 0000000000000000000000000000000000000000..446119163d1f7bad577cb0b7b217ecf24b994526
|
||||
--- /dev/null
|
||||
+++ b/BUILD.gn
|
||||
@@ -0,0 +1,361 @@
|
||||
@@ -0,0 +1,360 @@
|
||||
+import("//electron/build/asar.gni")
|
||||
+import("//v8/gni/v8.gni")
|
||||
+
|
||||
@@ -205,7 +205,6 @@ index 0000000000000000000000000000000000000000..99192976f2bdfd900240aa58b8989fe2
|
||||
+ ":node_js2c",
|
||||
+ "deps/cares",
|
||||
+ "deps/histogram",
|
||||
+ "deps/http_parser",
|
||||
+ "deps/llhttp",
|
||||
+ "deps/nghttp2",
|
||||
+ "deps/uvwasi",
|
||||
@@ -532,25 +531,6 @@ index 0000000000000000000000000000000000000000..e741a2a9c238a782a674ddcb9a1f98de
|
||||
+ "src/hdr_histogram.h",
|
||||
+ ]
|
||||
+}
|
||||
diff --git a/deps/http_parser/BUILD.gn b/deps/http_parser/BUILD.gn
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..da9e2b42dccacc1ed9b00202c1ff73ebc60d0e8a
|
||||
--- /dev/null
|
||||
+++ b/deps/http_parser/BUILD.gn
|
||||
@@ -0,0 +1,13 @@
|
||||
+config("http_parser_config") {
|
||||
+ defines = [ "HTTP_PARSER_STRICT=0" ]
|
||||
+ include_dirs = [ "." ]
|
||||
+}
|
||||
+
|
||||
+static_library("http_parser") {
|
||||
+ include_dirs = [ "." ]
|
||||
+ public_configs = [ ":http_parser_config" ]
|
||||
+ cflags_c = [ "-Wno-string-conversion" ]
|
||||
+ sources = [
|
||||
+ "http_parser.c",
|
||||
+ ]
|
||||
+}
|
||||
diff --git a/deps/llhttp/BUILD.gn b/deps/llhttp/BUILD.gn
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..ce15bc57093caa1bd84ea77e7438e892fb916427
|
||||
@@ -625,7 +605,7 @@ index 0000000000000000000000000000000000000000..66af819990b338caa49ca59d1fe6c5ad
|
||||
+}
|
||||
diff --git a/deps/uv/BUILD.gn b/deps/uv/BUILD.gn
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..67116f2070bb9200aace81afdf0b1e7a6e4fd0c0
|
||||
index 0000000000000000000000000000000000000000..565819942513be6b7e9d7ad21c8531ad51a8d557
|
||||
--- /dev/null
|
||||
+++ b/deps/uv/BUILD.gn
|
||||
@@ -0,0 +1,191 @@
|
||||
@@ -664,6 +644,7 @@ index 0000000000000000000000000000000000000000..67116f2070bb9200aace81afdf0b1e7a
|
||||
+ defines += [ "BUILDING_UV_SHARED=1" ]
|
||||
+
|
||||
+ cflags_c = [
|
||||
+ "-Wno-incompatible-pointer-types",
|
||||
+ "-Wno-bitwise-op-parentheses",
|
||||
+ "-Wno-implicit-function-declaration",
|
||||
+ "-Wno-missing-braces",
|
||||
@@ -806,7 +787,6 @@ index 0000000000000000000000000000000000000000..67116f2070bb9200aace81afdf0b1e7a
|
||||
+ "src/unix/procfs-exepath.c",
|
||||
+ "src/unix/random-getrandom.c",
|
||||
+ "src/unix/random-sysctl-linux.c",
|
||||
+ "src/unix/sysinfo-loadavg.c",
|
||||
+ ]
|
||||
+ libs += [
|
||||
+ "dl",
|
||||
@@ -866,10 +846,10 @@ index 0000000000000000000000000000000000000000..2c9d2826c85bdd033f1df1d6188df636
|
||||
+}
|
||||
diff --git a/filenames.json b/filenames.json
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..2e07ea28437ee25ddaea4d730e1a65a56f4d6751
|
||||
index 0000000000000000000000000000000000000000..b09510a6048f6cff3905240e3c969f143a382047
|
||||
--- /dev/null
|
||||
+++ b/filenames.json
|
||||
@@ -0,0 +1,519 @@
|
||||
@@ -0,0 +1,527 @@
|
||||
+// This file is automatically generated by generate_gn_filenames_json.py
|
||||
+// DO NOT EDIT
|
||||
+{
|
||||
@@ -892,6 +872,7 @@ index 0000000000000000000000000000000000000000..2e07ea28437ee25ddaea4d730e1a65a5
|
||||
+ "//v8/include/cppgc/allocation.h",
|
||||
+ "//v8/include/cppgc/common.h",
|
||||
+ "//v8/include/cppgc/custom-space.h",
|
||||
+ "//v8/include/cppgc/default-platform.h",
|
||||
+ "//v8/include/cppgc/garbage-collected.h",
|
||||
+ "//v8/include/cppgc/heap.h",
|
||||
+ "//v8/include/cppgc/liveness-broker.h",
|
||||
@@ -929,6 +910,7 @@ index 0000000000000000000000000000000000000000..2e07ea28437ee25ddaea4d730e1a65a5
|
||||
+ "//v8/include/v8-cppgc.h",
|
||||
+ "//v8/include/v8-fast-api-calls.h",
|
||||
+ "//v8/include/v8-internal.h",
|
||||
+ "//v8/include/v8-metrics.h",
|
||||
+ "//v8/include/v8-platform.h",
|
||||
+ "//v8/include/v8-profiler.h",
|
||||
+ "//v8/include/v8-util.h",
|
||||
@@ -1001,6 +983,7 @@ index 0000000000000000000000000000000000000000..2e07ea28437ee25ddaea4d730e1a65a5
|
||||
+ "lib/domain.js",
|
||||
+ "lib/events.js",
|
||||
+ "lib/fs.js",
|
||||
+ "lib/fs/promises.js",
|
||||
+ "lib/http.js",
|
||||
+ "lib/http2.js",
|
||||
+ "lib/_http_agent.js",
|
||||
@@ -1045,6 +1028,7 @@ index 0000000000000000000000000000000000000000..2e07ea28437ee25ddaea4d730e1a65a5
|
||||
+ "lib/zlib.js",
|
||||
+ "lib/internal/assert.js",
|
||||
+ "lib/internal/assert/assertion_error.js",
|
||||
+ "lib/internal/assert/calltracker.js",
|
||||
+ "lib/internal/async_hooks.js",
|
||||
+ "lib/internal/buffer.js",
|
||||
+ "lib/internal/cli_table.js",
|
||||
@@ -1076,7 +1060,8 @@ index 0000000000000000000000000000000000000000..2e07ea28437ee25ddaea4d730e1a65a5
|
||||
+ "lib/internal/dtrace.js",
|
||||
+ "lib/internal/encoding.js",
|
||||
+ "lib/internal/errors.js",
|
||||
+ "lib/internal/error-serdes.js",
|
||||
+ "lib/internal/error_serdes.js",
|
||||
+ "lib/internal/event_target.js",
|
||||
+ "lib/internal/fixed_queue.js",
|
||||
+ "lib/internal/freelist.js",
|
||||
+ "lib/internal/freeze_intrinsics.js",
|
||||
@@ -1151,6 +1136,7 @@ index 0000000000000000000000000000000000000000..2e07ea28437ee25ddaea4d730e1a65a5
|
||||
+ "lib/internal/url.js",
|
||||
+ "lib/internal/util.js",
|
||||
+ "lib/internal/util/comparisons.js",
|
||||
+ "lib/internal/util/compositekey.js",
|
||||
+ "lib/internal/util/debuglog.js",
|
||||
+ "lib/internal/util/inspect.js",
|
||||
+ "lib/internal/util/inspector.js",
|
||||
@@ -1165,6 +1151,7 @@ index 0000000000000000000000000000000000000000..2e07ea28437ee25ddaea4d730e1a65a5
|
||||
+ "lib/internal/vm/module.js",
|
||||
+ "lib/internal/worker.js",
|
||||
+ "lib/internal/worker/io.js",
|
||||
+ "lib/internal/worker/js_transferable.js",
|
||||
+ "lib/internal/watchdog.js",
|
||||
+ "lib/internal/streams/lazy_transform.js",
|
||||
+ "lib/internal/streams/async_iterator.js",
|
||||
@@ -1223,6 +1210,7 @@ index 0000000000000000000000000000000000000000..2e07ea28437ee25ddaea4d730e1a65a5
|
||||
+ "src/js_native_api_v8_internals.h",
|
||||
+ "src/js_stream.cc",
|
||||
+ "src/json_utils.cc",
|
||||
+ "src/js_udp_wrap.cc",
|
||||
+ "src/module_wrap.cc",
|
||||
+ "src/node.cc",
|
||||
+ "src/node_api.cc",
|
||||
@@ -1236,8 +1224,7 @@ index 0000000000000000000000000000000000000000..2e07ea28437ee25ddaea4d730e1a65a5
|
||||
+ "src/node_env_var.cc",
|
||||
+ "src/node_errors.cc",
|
||||
+ "src/node_file.cc",
|
||||
+ "src/node_http_parser_llhttp.cc",
|
||||
+ "src/node_http_parser_traditional.cc",
|
||||
+ "src/node_http_parser.cc",
|
||||
+ "src/node_http2.cc",
|
||||
+ "src/node_i18n.cc",
|
||||
+ "src/node_main_instance.cc",
|
||||
@@ -1272,7 +1259,6 @@ index 0000000000000000000000000000000000000000..2e07ea28437ee25ddaea4d730e1a65a5
|
||||
+ "src/node_zlib.cc",
|
||||
+ "src/pipe_wrap.cc",
|
||||
+ "src/process_wrap.cc",
|
||||
+ "src/sharedarraybuffer_metadata.cc",
|
||||
+ "src/signal_wrap.cc",
|
||||
+ "src/spawn_sync.cc",
|
||||
+ "src/stream_base.cc",
|
||||
@@ -1292,6 +1278,10 @@ index 0000000000000000000000000000000000000000..2e07ea28437ee25ddaea4d730e1a65a5
|
||||
+ "src/util.cc",
|
||||
+ "src/uv.cc",
|
||||
+ "src/aliased_buffer.h",
|
||||
+ "src/aliased_struct.h",
|
||||
+ "src/aliased_struct-inl.h",
|
||||
+ "src/allocated_buffer.h",
|
||||
+ "src/allocated_buffer-inl.h",
|
||||
+ "src/async_wrap.h",
|
||||
+ "src/async_wrap-inl.h",
|
||||
+ "src/base_object.h",
|
||||
@@ -1308,7 +1298,6 @@ index 0000000000000000000000000000000000000000..2e07ea28437ee25ddaea4d730e1a65a5
|
||||
+ "src/handle_wrap.h",
|
||||
+ "src/histogram.h",
|
||||
+ "src/histogram-inl.h",
|
||||
+ "src/http_parser_adaptor.h",
|
||||
+ "src/js_stream.h",
|
||||
+ "src/json_utils.h",
|
||||
+ "src/large_pages/node_large_page.cc",
|
||||
@@ -1328,7 +1317,8 @@ index 0000000000000000000000000000000000000000..2e07ea28437ee25ddaea4d730e1a65a5
|
||||
+ "src/node_errors.h",
|
||||
+ "src/node_file.h",
|
||||
+ "src/node_file-inl.h",
|
||||
+ "src/node_http_parser_impl.h",
|
||||
+ "src/node_http_common.h",
|
||||
+ "src/node_http_common-inl.h",
|
||||
+ "src/node_http2.h",
|
||||
+ "src/node_http2_state.h",
|
||||
+ "src/node_i18n.h",
|
||||
@@ -1364,7 +1354,6 @@ index 0000000000000000000000000000000000000000..2e07ea28437ee25ddaea4d730e1a65a5
|
||||
+ "src/pipe_wrap.h",
|
||||
+ "src/req_wrap.h",
|
||||
+ "src/req_wrap-inl.h",
|
||||
+ "src/sharedarraybuffer_metadata.h",
|
||||
+ "src/spawn_sync.h",
|
||||
+ "src/stream_base.h",
|
||||
+ "src/stream_base-inl.h",
|
||||
@@ -1385,8 +1374,7 @@ index 0000000000000000000000000000000000000000..2e07ea28437ee25ddaea4d730e1a65a5
|
||||
+ "src/udp_wrap.h",
|
||||
+ "src/util.h",
|
||||
+ "src/util-inl.h",
|
||||
+ "deps/http_parser/http_parser.h",
|
||||
+ "deps/v8/include/v8.h"
|
||||
+ "//v8/include/v8.h"
|
||||
+ ]
|
||||
+}
|
||||
diff --git a/src/inspector/BUILD.gn b/src/inspector/BUILD.gn
|
||||
@@ -1595,7 +1583,7 @@ index 0000000000000000000000000000000000000000..f3c5c798c0aefcb8cf9b1570a7b4817c
|
||||
+ args = rebase_path(inputs + outputs, root_build_dir)
|
||||
+}
|
||||
diff --git a/src/node_version.h b/src/node_version.h
|
||||
index 9252d51555f0e1bf0957bc4f8bc6e399c1ac6c23..431dd57a7dddc7476a179a5f30ce9e66814006ec 100644
|
||||
index 49e4e9d16f8732641248fd3ab15be1a74d9fd45f..35f90fcae715c5421c672a9397a8e25d93f80cd6 100644
|
||||
--- a/src/node_version.h
|
||||
+++ b/src/node_version.h
|
||||
@@ -89,7 +89,10 @@
|
||||
@@ -1604,7 +1592,7 @@ index 9252d51555f0e1bf0957bc4f8bc6e399c1ac6c23..431dd57a7dddc7476a179a5f30ce9e66
|
||||
*/
|
||||
+// Electron sets NODE_MODULE_VERSION in their GN configuration
|
||||
+#ifndef NODE_MODULE_VERSION
|
||||
#define NODE_MODULE_VERSION 72
|
||||
#define NODE_MODULE_VERSION 83
|
||||
+#endif
|
||||
|
||||
// The NAPI_VERSION provided by this version of the runtime. This is the version
|
||||
|
||||
@@ -10,7 +10,7 @@ THe fix for this should land in node-gyp as discussed in above issue,
|
||||
landing this as temporary patch.
|
||||
|
||||
diff --git a/common.gypi b/common.gypi
|
||||
index df69aecc74ef66b9501d4bed0e1311e7cda2d5b8..dfcf529cd501dc890c05425fcf9a33414a45f1a5 100644
|
||||
index 2fda2d685edc6b8f45441cda017f7cabfe60d91f..bd42d6cfa6006630d316faf2cddd93bea57102ba 100644
|
||||
--- a/common.gypi
|
||||
+++ b/common.gypi
|
||||
@@ -19,7 +19,7 @@
|
||||
@@ -22,7 +22,7 @@ index df69aecc74ef66b9501d4bed0e1311e7cda2d5b8..dfcf529cd501dc890c05425fcf9a3341
|
||||
'node_shared_openssl%': 'false',
|
||||
|
||||
'node_tag%': '',
|
||||
@@ -239,6 +239,26 @@
|
||||
@@ -215,6 +215,26 @@
|
||||
'cflags': [ '-fPIC' ],
|
||||
'ldflags': [ '-fPIC' ]
|
||||
}],
|
||||
|
||||
@@ -14,7 +14,7 @@ renderer/browser/worker/sandboxed bootstrap scripts). These are loaded
|
||||
through LoadEmbedderJavaScriptSource()
|
||||
|
||||
diff --git a/src/node_native_module.cc b/src/node_native_module.cc
|
||||
index 7362207412efa49bddfab4e32a64c7e07cf29074..acd9afa62d3aa1b01ce54f189a7261e7e61aa60d 100644
|
||||
index 74729c412674be2cbf01d68be1bc496b06b8ce1e..7311f249fbb24e0612d9f4f174e96fa13ed77acb 100644
|
||||
--- a/src/node_native_module.cc
|
||||
+++ b/src/node_native_module.cc
|
||||
@@ -20,6 +20,7 @@ NativeModuleLoader NativeModuleLoader::instance_;
|
||||
@@ -26,7 +26,7 @@ index 7362207412efa49bddfab4e32a64c7e07cf29074..acd9afa62d3aa1b01ce54f189a7261e7
|
||||
|
||||
NativeModuleLoader* NativeModuleLoader::GetInstance() {
|
||||
diff --git a/src/node_native_module.h b/src/node_native_module.h
|
||||
index c0bce3bce42c848d63a10147ef483c9d4465f5ce..7f296e459d46b4cda51baf9887df060f0372227d 100644
|
||||
index 3be3f2364dd252bcdd668c699a0e7ae1e754e873..b2af1bce312ffca44e7005e11f92327e7cb240f6 100644
|
||||
--- a/src/node_native_module.h
|
||||
+++ b/src/node_native_module.h
|
||||
@@ -44,6 +44,7 @@ class NativeModuleLoader {
|
||||
|
||||
@@ -6,10 +6,10 @@ Subject: Call process.log from fallback stream on Windows
|
||||
(cherry picked from commit d31e629b4f2daf3500a485caab2b2990a41e3ad4)
|
||||
|
||||
diff --git a/lib/internal/bootstrap/switches/is_main_thread.js b/lib/internal/bootstrap/switches/is_main_thread.js
|
||||
index ac8336fb6229e7f44eb00f43abb07bea83a9463c..2005e8ef9ebd090c1be19ff320f48b9cd365239e 100644
|
||||
index 08623898edafacfa8cee47ab35bd75887f9d3e2a..828589d4047ac49d16e9080ad1f364484941aa6e 100644
|
||||
--- a/lib/internal/bootstrap/switches/is_main_thread.js
|
||||
+++ b/lib/internal/bootstrap/switches/is_main_thread.js
|
||||
@@ -80,6 +80,11 @@ function createWritableStdioStream(fd) {
|
||||
@@ -85,6 +85,11 @@ function createWritableStdioStream(fd) {
|
||||
const { Writable } = require('stream');
|
||||
stream = new Writable({
|
||||
write(buf, enc, cb) {
|
||||
|
||||
@@ -8,25 +8,31 @@ once we stop warning and begin to unilaterally prevent non-context aware modules
|
||||
from being loaded.
|
||||
|
||||
diff --git a/lib/internal/bootstrap/pre_execution.js b/lib/internal/bootstrap/pre_execution.js
|
||||
index 0a7c4a47c11eb4bb360b6a46fccb4692241bd2dc..b4a0f71af5853f427a10449b52509052fbe3facd 100644
|
||||
index f947c6bf27e80c534a8f72265d0139a8b5b3f13a..d7e56d9c3fe5a56897989915984cb823d27b9c52 100644
|
||||
--- a/lib/internal/bootstrap/pre_execution.js
|
||||
+++ b/lib/internal/bootstrap/pre_execution.js
|
||||
@@ -89,8 +89,10 @@ function patchProcessObject(expandArgv1) {
|
||||
@@ -92,10 +92,12 @@ function patchProcessObject(expandArgv1) {
|
||||
|
||||
if (expandArgv1 && process.argv[1] && !process.argv[1].startsWith('-')) {
|
||||
// Expand process.argv[1] into a full path.
|
||||
- const path = require('path');
|
||||
- try {
|
||||
- process.argv[1] = path.resolve(process.argv[1]);
|
||||
- } catch {}
|
||||
+ if (!process.argv[1] || !process.argv[1].startsWith('electron/js2c')) {
|
||||
const path = require('path');
|
||||
process.argv[1] = path.resolve(process.argv[1]);
|
||||
+ const path = require('path');
|
||||
+ try {
|
||||
+ process.argv[1] = path.resolve(process.argv[1]);
|
||||
+ } catch {}
|
||||
+ }
|
||||
}
|
||||
|
||||
// TODO(joyeecheung): most of these should be deprecated and removed,
|
||||
diff --git a/lib/internal/modules/cjs/loader.js b/lib/internal/modules/cjs/loader.js
|
||||
index 7d08fb05e9a0abeb82d416891968b23002dc3685..1f6f5e0cee36fb2a07963264f513a930c349b8fa 100644
|
||||
index c633daa2b3557c98b05cca5f428d87775ef8a02a..4846370adb5206c53d57deef303b2c3f02342d24 100644
|
||||
--- a/lib/internal/modules/cjs/loader.js
|
||||
+++ b/lib/internal/modules/cjs/loader.js
|
||||
@@ -1111,6 +1111,13 @@ Module.prototype._compile = function(content, filename) {
|
||||
@@ -1049,6 +1049,13 @@ Module.prototype._compile = function(content, filename) {
|
||||
if (getOptionValue('--inspect-brk') && process._eval == null) {
|
||||
if (!resolvedArgv) {
|
||||
// We enter the repl if we're not given a filename argument.
|
||||
@@ -41,11 +47,11 @@ index 7d08fb05e9a0abeb82d416891968b23002dc3685..1f6f5e0cee36fb2a07963264f513a930
|
||||
try {
|
||||
resolvedArgv = Module._resolveFilename(process.argv[1], null, false);
|
||||
diff --git a/src/env.h b/src/env.h
|
||||
index d22b579b25ce4e6af8ec042e282e94248ea14162..67cefbe35f390ba25b49e422d10bca8b423a49a8 100644
|
||||
index bc222804010a035333cf6d7becc9a0a8f385af85..dea62b38cb20a0a0913128e17e8904c4ca71ac1a 100644
|
||||
--- a/src/env.h
|
||||
+++ b/src/env.h
|
||||
@@ -890,6 +890,15 @@ class Environment : public MemoryRetainer {
|
||||
uint64_t thread_id = kNoThreadId);
|
||||
@@ -885,6 +885,15 @@ class Environment : public MemoryRetainer {
|
||||
ThreadId thread_id);
|
||||
~Environment() override;
|
||||
|
||||
+ void ForceOnlyContextAwareNativeModules() {
|
||||
@@ -57,10 +63,10 @@ index d22b579b25ce4e6af8ec042e282e94248ea14162..67cefbe35f390ba25b49e422d10bca8b
|
||||
+ bool force_context_aware() { return force_context_aware_; }
|
||||
+ bool warn_non_context_aware() { return warn_non_context_aware_; }
|
||||
+
|
||||
void InitializeLibuv(bool start_profiler_idle_notifier);
|
||||
void InitializeLibuv();
|
||||
inline const std::vector<std::string>& exec_argv();
|
||||
inline const std::vector<std::string>& argv();
|
||||
@@ -1271,6 +1280,9 @@ class Environment : public MemoryRetainer {
|
||||
@@ -1235,6 +1244,9 @@ class Environment : public MemoryRetainer {
|
||||
inline void ThrowError(v8::Local<v8::Value> (*fun)(v8::Local<v8::String>),
|
||||
const char* errmsg);
|
||||
|
||||
@@ -71,7 +77,7 @@ index d22b579b25ce4e6af8ec042e282e94248ea14162..67cefbe35f390ba25b49e422d10bca8b
|
||||
v8::Isolate* const isolate_;
|
||||
IsolateData* const isolate_data_;
|
||||
diff --git a/src/node_binding.cc b/src/node_binding.cc
|
||||
index 5291858bb164a262ca1d69d2582e037aeab23d55..a9ce41fbba4e8b0c4704c1d7795308ce18916739 100644
|
||||
index 0ab18f7aeda3511338cbf115a4b636a6c72437b2..51ae4c89a61a176a9629e537f9409b38c3397aa2 100644
|
||||
--- a/src/node_binding.cc
|
||||
+++ b/src/node_binding.cc
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
@@ -7,7 +7,7 @@ This is used so that we can modify the flag at runtime where
|
||||
config can only be set at compile time.
|
||||
|
||||
diff --git a/lib/internal/bootstrap/node.js b/lib/internal/bootstrap/node.js
|
||||
index 4e7c3c10255a0eae4d5333f88e51cf7178163a44..a6e33757ca00771671583203c37d9b121abf489b 100644
|
||||
index e1f70addc28e4fe31d3a7089ecec3b5874dde75a..659145e31bbfb6ce782e8dcad452b59202df7573 100644
|
||||
--- a/lib/internal/bootstrap/node.js
|
||||
+++ b/lib/internal/bootstrap/node.js
|
||||
@@ -118,7 +118,7 @@ const {
|
||||
|
||||
@@ -1,145 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Attard <samuel.r.attard@gmail.com>
|
||||
Date: Mon, 4 May 2020 16:57:05 -0700
|
||||
Subject: chore: SetHostCleanupFinalizationGroupCallback has been removed from
|
||||
V8
|
||||
|
||||
diff --git a/src/api/environment.cc b/src/api/environment.cc
|
||||
index e2aa9c821de685a022fd78935399b7d219468403..2bfba8a011c2b902932e6b1714bbb55b945cd96d 100644
|
||||
--- a/src/api/environment.cc
|
||||
+++ b/src/api/environment.cc
|
||||
@@ -12,7 +12,6 @@ using errors::TryCatchScope;
|
||||
using v8::Array;
|
||||
using v8::Context;
|
||||
using v8::EscapableHandleScope;
|
||||
-using v8::FinalizationGroup;
|
||||
using v8::Function;
|
||||
using v8::FunctionCallbackInfo;
|
||||
using v8::HandleScope;
|
||||
@@ -72,15 +71,6 @@ static MaybeLocal<Value> PrepareStackTraceCallback(Local<Context> context,
|
||||
return result;
|
||||
}
|
||||
|
||||
-static void HostCleanupFinalizationGroupCallback(
|
||||
- Local<Context> context, Local<FinalizationGroup> group) {
|
||||
- Environment* env = Environment::GetCurrent(context);
|
||||
- if (env == nullptr) {
|
||||
- return;
|
||||
- }
|
||||
- env->RegisterFinalizationGroupForCleanup(group);
|
||||
-}
|
||||
-
|
||||
void* NodeArrayBufferAllocator::Allocate(size_t size) {
|
||||
void* ret;
|
||||
if (zero_fill_field_ || per_process::cli_options->zero_fill_all_buffers)
|
||||
@@ -249,11 +239,6 @@ void SetIsolateMiscHandlers(v8::Isolate* isolate, const IsolateSettings& s) {
|
||||
s.promise_reject_callback : task_queue::PromiseRejectCallback;
|
||||
isolate->SetPromiseRejectCallback(promise_reject_cb);
|
||||
|
||||
- auto* host_cleanup_cb = s.host_cleanup_finalization_group_callback ?
|
||||
- s.host_cleanup_finalization_group_callback :
|
||||
- HostCleanupFinalizationGroupCallback;
|
||||
- isolate->SetHostCleanupFinalizationGroupCallback(host_cleanup_cb);
|
||||
-
|
||||
if (s.flags & DETAILED_SOURCE_POSITIONS_FOR_PROFILING)
|
||||
v8::CpuProfiler::UseDetailedSourcePositionsForProfiling(isolate);
|
||||
}
|
||||
diff --git a/src/env-inl.h b/src/env-inl.h
|
||||
index c6ef9dc13ab6f1d1a778871a62a0a98a01d84ec6..222555831aa1bf0b7b29b4b46e235c98a5dd4ac5 100644
|
||||
--- a/src/env-inl.h
|
||||
+++ b/src/env-inl.h
|
||||
@@ -1123,12 +1123,6 @@ void Environment::RemoveCleanupHook(void (*fn)(void*), void* arg) {
|
||||
cleanup_hooks_.erase(search);
|
||||
}
|
||||
|
||||
-inline void Environment::RegisterFinalizationGroupForCleanup(
|
||||
- v8::Local<v8::FinalizationGroup> group) {
|
||||
- cleanup_finalization_groups_.emplace_back(isolate(), group);
|
||||
- uv_async_send(&task_queues_async_);
|
||||
-}
|
||||
-
|
||||
size_t CleanupHookCallback::Hash::operator()(
|
||||
const CleanupHookCallback& cb) const {
|
||||
return std::hash<void*>()(cb.arg_);
|
||||
diff --git a/src/env.cc b/src/env.cc
|
||||
index 18788e4ceaf208c13704c9c43f017bb1b6dfb0b6..ee76d5889e5672716ac2f0c586f1ddc47fa56be7 100644
|
||||
--- a/src/env.cc
|
||||
+++ b/src/env.cc
|
||||
@@ -30,7 +30,6 @@ using v8::ArrayBuffer;
|
||||
using v8::Boolean;
|
||||
using v8::Context;
|
||||
using v8::EmbedderGraph;
|
||||
-using v8::FinalizationGroup;
|
||||
using v8::Function;
|
||||
using v8::FunctionTemplate;
|
||||
using v8::HandleScope;
|
||||
@@ -487,7 +486,6 @@ void Environment::InitializeLibuv(bool start_profiler_idle_notifier) {
|
||||
[](uv_async_t* async) {
|
||||
Environment* env = ContainerOf(
|
||||
&Environment::task_queues_async_, async);
|
||||
- env->CleanupFinalizationGroups();
|
||||
env->RunAndClearNativeImmediates();
|
||||
});
|
||||
uv_unref(reinterpret_cast<uv_handle_t*>(&idle_prepare_handle_));
|
||||
@@ -1085,25 +1083,6 @@ void Environment::RunWeakRefCleanup() {
|
||||
isolate()->ClearKeptObjects();
|
||||
}
|
||||
|
||||
-void Environment::CleanupFinalizationGroups() {
|
||||
- HandleScope handle_scope(isolate());
|
||||
- Context::Scope context_scope(context());
|
||||
- TryCatchScope try_catch(this);
|
||||
-
|
||||
- while (!cleanup_finalization_groups_.empty() && can_call_into_js()) {
|
||||
- Local<FinalizationGroup> fg =
|
||||
- cleanup_finalization_groups_.front().Get(isolate());
|
||||
- cleanup_finalization_groups_.pop_front();
|
||||
- if (!FinalizationGroup::Cleanup(fg).FromMaybe(false)) {
|
||||
- if (try_catch.HasCaught() && !try_catch.HasTerminated())
|
||||
- errors::TriggerUncaughtException(isolate(), try_catch);
|
||||
- // Re-schedule the execution of the remainder of the queue.
|
||||
- uv_async_send(&task_queues_async_);
|
||||
- return;
|
||||
- }
|
||||
- }
|
||||
-}
|
||||
-
|
||||
// Not really any better place than env.cc at this moment.
|
||||
void BaseObject::DeleteMe(void* data) {
|
||||
BaseObject* self = static_cast<BaseObject*>(data);
|
||||
diff --git a/src/env.h b/src/env.h
|
||||
index 67cefbe35f390ba25b49e422d10bca8b423a49a8..9420bdf3f71e2df1011ddd7e583071f5c99beac8 100644
|
||||
--- a/src/env.h
|
||||
+++ b/src/env.h
|
||||
@@ -1130,9 +1130,7 @@ class Environment : public MemoryRetainer {
|
||||
void AtExit(void (*cb)(void* arg), void* arg);
|
||||
void RunAtExitCallbacks();
|
||||
|
||||
- void RegisterFinalizationGroupForCleanup(v8::Local<v8::FinalizationGroup> fg);
|
||||
void RunWeakRefCleanup();
|
||||
- void CleanupFinalizationGroups();
|
||||
|
||||
// Strings and private symbols are shared across shared contexts
|
||||
// The getters simply proxy to the per-isolate primitive.
|
||||
@@ -1355,8 +1353,6 @@ class Environment : public MemoryRetainer {
|
||||
uint64_t thread_id_;
|
||||
std::unordered_set<worker::Worker*> sub_worker_contexts_;
|
||||
|
||||
- std::deque<v8::Global<v8::FinalizationGroup>> cleanup_finalization_groups_;
|
||||
-
|
||||
static void* const kNodeContextTagPtr;
|
||||
static int const kNodeContextTag;
|
||||
|
||||
diff --git a/src/node.h b/src/node.h
|
||||
index 638a1a85b046ce4db303d532f7cf36cca2271db5..b9b11b4331bd3ae4a87f65758ee09af25222e19a 100644
|
||||
--- a/src/node.h
|
||||
+++ b/src/node.h
|
||||
@@ -322,8 +322,6 @@ struct IsolateSettings {
|
||||
v8::PromiseRejectCallback promise_reject_callback = nullptr;
|
||||
v8::AllowWasmCodeGenerationCallback
|
||||
allow_wasm_code_generation_callback = nullptr;
|
||||
- v8::HostCleanupFinalizationGroupCallback
|
||||
- host_cleanup_finalization_group_callback = nullptr;
|
||||
};
|
||||
|
||||
// Overriding IsolateSettings may produce unexpected behavior
|
||||
2407
patches/node/crypto_update_certdata_to_nss_3_56.patch
Normal file
2407
patches/node/crypto_update_certdata_to_nss_3_56.patch
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,64 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ben Noordhuis <info@bnoordhuis.nl>
|
||||
Date: Wed, 1 Jul 2020 10:32:57 +0200
|
||||
Subject: darwin: work around clock jumping back in time
|
||||
|
||||
It was reported that mach_absolute_time() can jump backward in time when
|
||||
the machine is suspended. Use mach_continuous_time() when available to
|
||||
work around that (macOS 10.12 and up.)
|
||||
|
||||
Fixes: https://github.com/libuv/libuv/issues/2891
|
||||
PR-URL: https://github.com/libuv/libuv/pull/2894
|
||||
Reviewed-By: Phil Willoughby <philwill@fb.com>
|
||||
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
|
||||
|
||||
diff --git a/deps/uv/src/unix/darwin.c b/deps/uv/src/unix/darwin.c
|
||||
index 654aba26b1f9249e3e76b48ae1ad674d9fd12718..4f53ad1fc7f1907281013ca5dc4b251c692d3a7b 100644
|
||||
--- a/deps/uv/src/unix/darwin.c
|
||||
+++ b/deps/uv/src/unix/darwin.c
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
|
||||
+#include <dlfcn.h>
|
||||
#include <mach/mach.h>
|
||||
#include <mach/mach_time.h>
|
||||
#include <mach-o/dyld.h> /* _NSGetExecutablePath */
|
||||
@@ -32,6 +33,10 @@
|
||||
#include <sys/sysctl.h>
|
||||
#include <unistd.h> /* sysconf */
|
||||
|
||||
+static uv_once_t once = UV_ONCE_INIT;
|
||||
+static uint64_t (*time_func)(void);
|
||||
+static mach_timebase_info_data_t timebase;
|
||||
+
|
||||
|
||||
int uv__platform_loop_init(uv_loop_t* loop) {
|
||||
loop->cf_state = NULL;
|
||||
@@ -48,15 +53,19 @@ void uv__platform_loop_delete(uv_loop_t* loop) {
|
||||
}
|
||||
|
||||
|
||||
-uint64_t uv__hrtime(uv_clocktype_t type) {
|
||||
- static mach_timebase_info_data_t info;
|
||||
-
|
||||
- if ((ACCESS_ONCE(uint32_t, info.numer) == 0 ||
|
||||
- ACCESS_ONCE(uint32_t, info.denom) == 0) &&
|
||||
- mach_timebase_info(&info) != KERN_SUCCESS)
|
||||
+static void uv__hrtime_init_once(void) {
|
||||
+ if (KERN_SUCCESS != mach_timebase_info(&timebase))
|
||||
abort();
|
||||
|
||||
- return mach_absolute_time() * info.numer / info.denom;
|
||||
+ time_func = (uint64_t (*)(void)) dlsym(RTLD_DEFAULT, "mach_continuous_time");
|
||||
+ if (time_func == NULL)
|
||||
+ time_func = mach_absolute_time;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+uint64_t uv__hrtime(uv_clocktype_t type) {
|
||||
+ uv_once(&once, uv__hrtime_init_once);
|
||||
+ return time_func() * timebase.numer / timebase.denom;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,22 +8,21 @@ node modules will have different (wrong) ideas about how v8 structs are laid
|
||||
out in memory on 64-bit machines, and will summarily fail to work.
|
||||
|
||||
diff --git a/common.gypi b/common.gypi
|
||||
index dfcf529cd501dc890c05425fcf9a33414a45f1a5..38e7b2802f6225ac0e1ff4789b9ff8f4fb04cb79 100644
|
||||
index bd42d6cfa6006630d316faf2cddd93bea57102ba..734c2917535c50e260192abe6acb4726104b7b6a 100644
|
||||
--- a/common.gypi
|
||||
+++ b/common.gypi
|
||||
@@ -71,6 +71,9 @@
|
||||
# TODO(refack): make v8-perfetto happen
|
||||
'v8_use_perfetto': 0,
|
||||
@@ -64,7 +64,7 @@
|
||||
# options but default values are required here as this file is also used by
|
||||
# node-gyp to build addons.
|
||||
'v8_enable_pointer_compression%': 0,
|
||||
- 'v8_enable_31bit_smis_on_64bit_arch%': 0,
|
||||
+ 'v8_enable_31bit_smis_on_64bit_arch%': 1,
|
||||
|
||||
+ 'v8_enable_pointer_compression%': 0,
|
||||
+ 'v8_enable_31bit_smis_on_64bit_arch': 1,
|
||||
+
|
||||
##### end V8 defaults #####
|
||||
|
||||
# When building native modules using 'npm install' with the system npm,
|
||||
@@ -148,6 +151,9 @@
|
||||
['OS=="mac"', {
|
||||
'clang%': 1,
|
||||
# Disable V8 untrusted code mitigations.
|
||||
# See https://github.com/v8/v8/wiki/Untrusted-code-mitigations
|
||||
@@ -124,6 +124,9 @@
|
||||
'obj_dir%': '<(PRODUCT_DIR)/obj.target',
|
||||
'v8_base': '<(PRODUCT_DIR)/libv8_snapshot.a',
|
||||
}],
|
||||
+ ['target_arch == "arm64" or target_arch == "x64"', {
|
||||
+ 'v8_enable_pointer_compression': 1,
|
||||
@@ -31,16 +30,3 @@ index dfcf529cd501dc890c05425fcf9a33414a45f1a5..38e7b2802f6225ac0e1ff4789b9ff8f4
|
||||
['target_arch in "ppc64 s390x"', {
|
||||
'v8_enable_backtrace': 1,
|
||||
}],
|
||||
@@ -378,6 +384,12 @@
|
||||
}],
|
||||
],
|
||||
}],
|
||||
+ ['v8_enable_pointer_compression == 1', {
|
||||
+ 'defines': ['V8_COMPRESS_POINTERS'],
|
||||
+ }],
|
||||
+ ['v8_enable_pointer_compression == 1 or v8_enable_31bit_smis_on_64bit_arch == 1', {
|
||||
+ 'defines': ['V8_31BIT_SMIS_ON_64BIT_ARCH'],
|
||||
+ }],
|
||||
['OS == "win"', {
|
||||
'defines': [
|
||||
'WIN32',
|
||||
|
||||
@@ -9,10 +9,10 @@ modules to sandboxed renderers.
|
||||
TODO(codebytere): remove and replace with a public facing API.
|
||||
|
||||
diff --git a/src/node_binding.cc b/src/node_binding.cc
|
||||
index 0b5f6cfa038369be758e3b0857ee6fa594358b58..5291858bb164a262ca1d69d2582e037aeab23d55 100644
|
||||
index 1072ed34667262d7ef729c3235766f056acd659c..0ab18f7aeda3511338cbf115a4b636a6c72437b2 100644
|
||||
--- a/src/node_binding.cc
|
||||
+++ b/src/node_binding.cc
|
||||
@@ -605,6 +605,10 @@ void GetInternalBinding(const FunctionCallbackInfo<Value>& args) {
|
||||
@@ -608,6 +608,10 @@ void GetInternalBinding(const FunctionCallbackInfo<Value>& args) {
|
||||
args.GetReturnValue().Set(exports);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,10 +24,10 @@ Environment on the V8 context of blink, so no new V8 context is created.
|
||||
As a result, a renderer process may have multiple Node Environments in it.
|
||||
|
||||
diff --git a/src/node.cc b/src/node.cc
|
||||
index 728785d5d2773df68a891a4c81e7b0ebfa6021bb..15abe45edb39597d4fcc686cca4d79314090fa6f 100644
|
||||
index 0dc7040381889541d9b5257158c2564ef0e728a2..cda0220071196fb7eced326985002bf0588aa23f 100644
|
||||
--- a/src/node.cc
|
||||
+++ b/src/node.cc
|
||||
@@ -122,6 +122,8 @@ using v8::Undefined;
|
||||
@@ -134,6 +134,8 @@ using v8::Undefined;
|
||||
using v8::V8;
|
||||
using v8::Value;
|
||||
|
||||
@@ -36,7 +36,7 @@ index 728785d5d2773df68a891a4c81e7b0ebfa6021bb..15abe45edb39597d4fcc686cca4d7931
|
||||
namespace per_process {
|
||||
|
||||
// node_revert.h
|
||||
@@ -736,7 +738,9 @@ int InitializeNodeWithArgs(std::vector<std::string>* argv,
|
||||
@@ -836,7 +838,9 @@ int InitializeNodeWithArgs(std::vector<std::string>* argv,
|
||||
binding::RegisterBuiltinModules();
|
||||
|
||||
// Make inherited handles noninheritable.
|
||||
@@ -47,7 +47,7 @@ index 728785d5d2773df68a891a4c81e7b0ebfa6021bb..15abe45edb39597d4fcc686cca4d7931
|
||||
|
||||
// Cache the original command line to be
|
||||
// used in diagnostic reports.
|
||||
@@ -770,6 +774,8 @@ int InitializeNodeWithArgs(std::vector<std::string>* argv,
|
||||
@@ -870,6 +874,8 @@ int InitializeNodeWithArgs(std::vector<std::string>* argv,
|
||||
if (exit_code != 0) return exit_code;
|
||||
}
|
||||
#endif
|
||||
@@ -56,7 +56,7 @@ index 728785d5d2773df68a891a4c81e7b0ebfa6021bb..15abe45edb39597d4fcc686cca4d7931
|
||||
|
||||
const int exit_code = ProcessGlobalArgs(argv,
|
||||
exec_argv,
|
||||
@@ -814,6 +820,7 @@ int InitializeNodeWithArgs(std::vector<std::string>* argv,
|
||||
@@ -914,6 +920,7 @@ int InitializeNodeWithArgs(std::vector<std::string>* argv,
|
||||
}
|
||||
per_process::metadata.versions.InitializeIntlVersions();
|
||||
#endif
|
||||
@@ -65,10 +65,10 @@ index 728785d5d2773df68a891a4c81e7b0ebfa6021bb..15abe45edb39597d4fcc686cca4d7931
|
||||
NativeModuleEnv::InitializeCodeCache();
|
||||
|
||||
diff --git a/src/node.h b/src/node.h
|
||||
index 886216e2cb533e7337bc4f6816e2de796f64f81e..8378553f28671e4685b4ed20279b2be5d202e527 100644
|
||||
index 1914e72ee8fa4361379725b8d44892c8a62084e1..d051b422d7c5a51a8590abda382676d3f661b532 100644
|
||||
--- a/src/node.h
|
||||
+++ b/src/node.h
|
||||
@@ -211,6 +211,8 @@ namespace node {
|
||||
@@ -218,6 +218,8 @@ namespace node {
|
||||
|
||||
class IsolateData;
|
||||
class Environment;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user