chore: refactor browser IPC into TS and app API into TS (#16921)
* chore: refactor browser IPC into typescript * chore: refactor app.ts into Typescript * Refactors app.dock into cpp * Removes app.launcher which has not existed for 3 years * Removes 2 deprecated APIs (that have been deprecated for more than one major) * Refactors deprecate.ts as well
This commit is contained in:
parent
4ccd6d5900
commit
5790869a3f
16 changed files with 258 additions and 201 deletions
|
@ -1259,6 +1259,46 @@ bool App::MoveToApplicationsFolder(mate::Arguments* args) {
|
|||
bool App::IsInApplicationsFolder() {
|
||||
return ui::cocoa::AtomBundleMover::IsCurrentAppInApplicationsFolder();
|
||||
}
|
||||
|
||||
int DockBounce(const std::string& type) {
|
||||
int request_id = -1;
|
||||
if (type == "critical")
|
||||
request_id = Browser::Get()->DockBounce(Browser::BOUNCE_CRITICAL);
|
||||
else if (type == "informational")
|
||||
request_id = Browser::Get()->DockBounce(Browser::BOUNCE_INFORMATIONAL);
|
||||
return request_id;
|
||||
}
|
||||
|
||||
void DockSetMenu(atom::api::Menu* menu) {
|
||||
Browser::Get()->DockSetMenu(menu->model());
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> App::GetDockAPI(v8::Isolate* isolate) {
|
||||
if (dock_.IsEmpty()) {
|
||||
// Initialize the Dock API, the methods are bound to "dock" which exists
|
||||
// for the lifetime of "app"
|
||||
auto browser = base::Unretained(Browser::Get());
|
||||
mate::Dictionary dock_obj = mate::Dictionary::CreateEmpty(isolate);
|
||||
dock_obj.SetMethod("bounce", &DockBounce);
|
||||
dock_obj.SetMethod("cancelBounce",
|
||||
base::Bind(&Browser::DockCancelBounce, browser));
|
||||
dock_obj.SetMethod("downloadFinished",
|
||||
base::Bind(&Browser::DockDownloadFinished, browser));
|
||||
dock_obj.SetMethod("setBadge",
|
||||
base::Bind(&Browser::DockSetBadgeText, browser));
|
||||
dock_obj.SetMethod("getBadge",
|
||||
base::Bind(&Browser::DockGetBadgeText, browser));
|
||||
dock_obj.SetMethod("hide", base::Bind(&Browser::DockHide, browser));
|
||||
dock_obj.SetMethod("show", base::Bind(&Browser::DockShow, browser));
|
||||
dock_obj.SetMethod("isVisible",
|
||||
base::Bind(&Browser::DockIsVisible, browser));
|
||||
dock_obj.SetMethod("setMenu", &DockSetMenu);
|
||||
dock_obj.SetMethod("setIcon", base::Bind(&Browser::DockSetIcon, browser));
|
||||
|
||||
dock_.Reset(isolate, dock_obj.GetHandle());
|
||||
}
|
||||
return v8::Local<v8::Value>::New(isolate, dock_);
|
||||
}
|
||||
#endif
|
||||
|
||||
// static
|
||||
|
@ -1357,6 +1397,9 @@ void App::BuildPrototype(v8::Isolate* isolate,
|
|||
#if defined(MAS_BUILD)
|
||||
.SetMethod("startAccessingSecurityScopedResource",
|
||||
&App::StartAccessingSecurityScopedResource)
|
||||
#endif
|
||||
#if defined(OS_MACOSX)
|
||||
.SetProperty("dock", &App::GetDockAPI)
|
||||
#endif
|
||||
.SetMethod("enableSandbox", &App::EnableSandbox);
|
||||
}
|
||||
|
@ -1367,21 +1410,6 @@ void App::BuildPrototype(v8::Isolate* isolate,
|
|||
|
||||
namespace {
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
int DockBounce(const std::string& type) {
|
||||
int request_id = -1;
|
||||
if (type == "critical")
|
||||
request_id = Browser::Get()->DockBounce(Browser::BOUNCE_CRITICAL);
|
||||
else if (type == "informational")
|
||||
request_id = Browser::Get()->DockBounce(Browser::BOUNCE_INFORMATIONAL);
|
||||
return request_id;
|
||||
}
|
||||
|
||||
void DockSetMenu(atom::api::Menu* menu) {
|
||||
Browser::Get()->DockSetMenu(menu->model());
|
||||
}
|
||||
#endif
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context,
|
||||
|
@ -1392,23 +1420,6 @@ void Initialize(v8::Local<v8::Object> exports,
|
|||
->GetFunction(context)
|
||||
.ToLocalChecked());
|
||||
dict.Set("app", atom::api::App::Create(isolate));
|
||||
#if defined(OS_MACOSX)
|
||||
auto browser = base::Unretained(Browser::Get());
|
||||
dict.SetMethod("dockBounce", &DockBounce);
|
||||
dict.SetMethod("dockCancelBounce",
|
||||
base::Bind(&Browser::DockCancelBounce, browser));
|
||||
dict.SetMethod("dockDownloadFinished",
|
||||
base::Bind(&Browser::DockDownloadFinished, browser));
|
||||
dict.SetMethod("dockSetBadgeText",
|
||||
base::Bind(&Browser::DockSetBadgeText, browser));
|
||||
dict.SetMethod("dockGetBadgeText",
|
||||
base::Bind(&Browser::DockGetBadgeText, browser));
|
||||
dict.SetMethod("dockHide", base::Bind(&Browser::DockHide, browser));
|
||||
dict.SetMethod("dockShow", base::Bind(&Browser::DockShow, browser));
|
||||
dict.SetMethod("dockIsVisible", base::Bind(&Browser::DockIsVisible, browser));
|
||||
dict.SetMethod("dockSetMenu", &DockSetMenu);
|
||||
dict.SetMethod("dockSetIcon", base::Bind(&Browser::DockSetIcon, browser));
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -210,6 +210,8 @@ class App : public AtomBrowserClient::Delegate,
|
|||
#if defined(OS_MACOSX)
|
||||
bool MoveToApplicationsFolder(mate::Arguments* args);
|
||||
bool IsInApplicationsFolder();
|
||||
v8::Local<v8::Value> GetDockAPI(v8::Isolate* isolate);
|
||||
v8::Global<v8::Value> dock_;
|
||||
#endif
|
||||
#if defined(MAS_BUILD)
|
||||
base::Callback<void()> StartAccessingSecurityScopedResource(
|
||||
|
|
|
@ -1307,6 +1307,10 @@ Returns `Boolean` - Whether the dock icon is visible.
|
|||
|
||||
Sets the application's [dock menu][dock-menu].
|
||||
|
||||
### `app.dock.getMenu()` _macOS_
|
||||
|
||||
Returns `Menu | null` - The application's [dock menu][dock-menu].
|
||||
|
||||
### `app.dock.setIcon(image)` _macOS_
|
||||
|
||||
* `image` ([NativeImage](native-image.md) | String)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
filenames = {
|
||||
js_sources = [
|
||||
"lib/browser/api/app.js",
|
||||
"lib/browser/api/app.ts",
|
||||
"lib/browser/api/auto-updater.js",
|
||||
"lib/browser/api/auto-updater/auto-updater-native.js",
|
||||
"lib/browser/api/auto-updater/auto-updater-win.js",
|
||||
|
@ -12,7 +12,7 @@ filenames = {
|
|||
"lib/browser/api/dialog.js",
|
||||
"lib/browser/api/exports/electron.js",
|
||||
"lib/browser/api/global-shortcut.js",
|
||||
"lib/browser/api/ipc-main.js",
|
||||
"lib/browser/api/ipc-main.ts",
|
||||
"lib/browser/api/in-app-purchase.js",
|
||||
"lib/browser/api/menu-item-roles.js",
|
||||
"lib/browser/api/menu-item.js",
|
||||
|
@ -41,13 +41,13 @@ filenames = {
|
|||
"lib/browser/guest-view-manager.js",
|
||||
"lib/browser/guest-window-manager.js",
|
||||
"lib/browser/init.ts",
|
||||
"lib/browser/ipc-main-internal-utils.js",
|
||||
"lib/browser/ipc-main-internal.js",
|
||||
"lib/browser/ipc-main-internal-utils.ts",
|
||||
"lib/browser/ipc-main-internal.ts",
|
||||
"lib/browser/navigation-controller.js",
|
||||
"lib/browser/objects-registry.js",
|
||||
"lib/browser/rpc-server.js",
|
||||
"lib/common/api/clipboard.js",
|
||||
"lib/common/api/deprecate.js",
|
||||
"lib/common/api/deprecate.ts",
|
||||
"lib/common/api/deprecations.js",
|
||||
"lib/common/api/is-promise.js",
|
||||
"lib/common/api/exports/electron.js",
|
||||
|
|
|
@ -1,113 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const bindings = process.atomBinding('app')
|
||||
const commandLine = process.atomBinding('command_line')
|
||||
const path = require('path')
|
||||
const { app, App } = bindings
|
||||
|
||||
// Only one app object permitted.
|
||||
module.exports = app
|
||||
|
||||
const electron = require('electron')
|
||||
const { deprecate, Menu } = electron
|
||||
const { EventEmitter } = require('events')
|
||||
|
||||
let dockMenu = null
|
||||
|
||||
// App is an EventEmitter.
|
||||
Object.setPrototypeOf(App.prototype, EventEmitter.prototype)
|
||||
EventEmitter.call(app)
|
||||
|
||||
Object.assign(app, {
|
||||
setApplicationMenu (menu) {
|
||||
return Menu.setApplicationMenu(menu)
|
||||
},
|
||||
getApplicationMenu () {
|
||||
return Menu.getApplicationMenu()
|
||||
},
|
||||
commandLine: {
|
||||
hasSwitch: (...args) => commandLine.hasSwitch(...args.map(String)),
|
||||
getSwitchValue: (...args) => commandLine.getSwitchValue(...args.map(String)),
|
||||
appendSwitch: (...args) => commandLine.appendSwitch(...args.map(String)),
|
||||
appendArgument: (...args) => commandLine.appendArgument(...args.map(String))
|
||||
},
|
||||
enableMixedSandbox () {
|
||||
deprecate.log(`'enableMixedSandbox' is deprecated. Mixed-sandbox mode is now enabled by default. You can safely remove the call to enableMixedSandbox().`)
|
||||
}
|
||||
})
|
||||
|
||||
app.getFileIcon = deprecate.promisify(app.getFileIcon)
|
||||
|
||||
const nativeAppMetrics = app.getAppMetrics
|
||||
app.getAppMetrics = () => {
|
||||
const metrics = nativeAppMetrics.call(app)
|
||||
for (const metric of metrics) {
|
||||
if ('memory' in metric) {
|
||||
deprecate.removeProperty(metric, 'memory')
|
||||
}
|
||||
}
|
||||
|
||||
return metrics
|
||||
}
|
||||
|
||||
app.isPackaged = (() => {
|
||||
const execFile = path.basename(process.execPath).toLowerCase()
|
||||
if (process.platform === 'win32') {
|
||||
return execFile !== 'electron.exe'
|
||||
}
|
||||
return execFile !== 'electron'
|
||||
})()
|
||||
|
||||
if (process.platform === 'darwin') {
|
||||
app.dock = {
|
||||
bounce (type = 'informational') {
|
||||
return bindings.dockBounce(type)
|
||||
},
|
||||
cancelBounce: bindings.dockCancelBounce,
|
||||
downloadFinished: bindings.dockDownloadFinished,
|
||||
setBadge: bindings.dockSetBadgeText,
|
||||
getBadge: bindings.dockGetBadgeText,
|
||||
hide: bindings.dockHide,
|
||||
show: bindings.dockShow,
|
||||
isVisible: bindings.dockIsVisible,
|
||||
setMenu (menu) {
|
||||
dockMenu = menu
|
||||
bindings.dockSetMenu(menu)
|
||||
},
|
||||
getMenu () {
|
||||
return dockMenu
|
||||
},
|
||||
setIcon: bindings.dockSetIcon
|
||||
}
|
||||
}
|
||||
|
||||
if (process.platform === 'linux') {
|
||||
app.launcher = {
|
||||
setBadgeCount: bindings.unityLauncherSetBadgeCount,
|
||||
getBadgeCount: bindings.unityLauncherGetBadgeCount,
|
||||
isCounterBadgeAvailable: bindings.unityLauncherAvailable,
|
||||
isUnityRunning: bindings.unityLauncherAvailable
|
||||
}
|
||||
}
|
||||
|
||||
app.allowNTLMCredentialsForAllDomains = function (allow) {
|
||||
deprecate.warn('app.allowNTLMCredentialsForAllDomains', 'session.allowNTLMCredentialsForDomains')
|
||||
const domains = allow ? '*' : ''
|
||||
if (!this.isReady()) {
|
||||
this.commandLine.appendSwitch('auth-server-whitelist', domains)
|
||||
} else {
|
||||
electron.session.defaultSession.allowNTLMCredentialsForDomains(domains)
|
||||
}
|
||||
}
|
||||
|
||||
// Routes the events to webContents.
|
||||
const events = ['login', 'certificate-error', 'select-client-certificate']
|
||||
for (const name of events) {
|
||||
app.on(name, (event, webContents, ...args) => {
|
||||
webContents.emit(name, event, ...args)
|
||||
})
|
||||
}
|
||||
|
||||
// Wrappers for native classes.
|
||||
const { DownloadItem } = process.atomBinding('download_item')
|
||||
Object.setPrototypeOf(DownloadItem.prototype, EventEmitter.prototype)
|
68
lib/browser/api/app.ts
Normal file
68
lib/browser/api/app.ts
Normal file
|
@ -0,0 +1,68 @@
|
|||
import * as path from 'path'
|
||||
|
||||
import * as electron from 'electron'
|
||||
import { EventEmitter } from 'events'
|
||||
|
||||
const bindings = process.atomBinding('app')
|
||||
const commandLine = process.atomBinding('command_line')
|
||||
const { app, App } = bindings
|
||||
|
||||
// Only one app object permitted.
|
||||
export default app
|
||||
|
||||
const { deprecate, Menu } = electron
|
||||
|
||||
let dockMenu: Electron.Menu | null = null
|
||||
|
||||
// App is an EventEmitter.
|
||||
Object.setPrototypeOf(App.prototype, EventEmitter.prototype)
|
||||
EventEmitter.call(app as any)
|
||||
|
||||
Object.assign(app, {
|
||||
setApplicationMenu (menu: Electron.Menu | null) {
|
||||
return Menu.setApplicationMenu(menu)
|
||||
},
|
||||
getApplicationMenu () {
|
||||
return Menu.getApplicationMenu()
|
||||
},
|
||||
commandLine: {
|
||||
hasSwitch: (theSwitch: string) => commandLine.hasSwitch(String(theSwitch)),
|
||||
getSwitchValue: (theSwitch: string) => commandLine.getSwitchValue(String(theSwitch)),
|
||||
appendSwitch: (theSwitch: string, value?: string) => commandLine.appendSwitch(String(theSwitch), typeof value === 'undefined' ? value : String(value)),
|
||||
appendArgument: (arg: string) => commandLine.appendArgument(String(arg))
|
||||
} as Electron.CommandLine,
|
||||
enableMixedSandbox () {
|
||||
deprecate.log(`'enableMixedSandbox' is deprecated. Mixed-sandbox mode is now enabled by default. You can safely remove the call to enableMixedSandbox().`)
|
||||
}
|
||||
})
|
||||
|
||||
app.getFileIcon = deprecate.promisify(app.getFileIcon)
|
||||
|
||||
app.isPackaged = (() => {
|
||||
const execFile = path.basename(process.execPath).toLowerCase()
|
||||
if (process.platform === 'win32') {
|
||||
return execFile !== 'electron.exe'
|
||||
}
|
||||
return execFile !== 'electron'
|
||||
})()
|
||||
|
||||
if (process.platform === 'darwin') {
|
||||
const setDockMenu = app.dock.setMenu
|
||||
app.dock.setMenu = (menu) => {
|
||||
dockMenu = menu
|
||||
setDockMenu(menu)
|
||||
}
|
||||
app.dock.getMenu = () => dockMenu
|
||||
}
|
||||
|
||||
// Routes the events to webContents.
|
||||
const events = ['login', 'certificate-error', 'select-client-certificate']
|
||||
for (const name of events) {
|
||||
app.on(name as 'login', (event, webContents, ...args: any[]) => {
|
||||
webContents.emit(name, event, ...args)
|
||||
})
|
||||
}
|
||||
|
||||
// Wrappers for native classes.
|
||||
const { DownloadItem } = process.atomBinding('download_item')
|
||||
Object.setPrototypeOf(DownloadItem.prototype, EventEmitter.prototype)
|
|
@ -1,10 +1,8 @@
|
|||
'use strict'
|
||||
|
||||
const { EventEmitter } = require('events')
|
||||
import { EventEmitter } from 'events'
|
||||
|
||||
const emitter = new EventEmitter()
|
||||
|
||||
// Do not throw exception when channel name is "error".
|
||||
emitter.on('error', () => {})
|
||||
|
||||
module.exports = emitter
|
||||
export default emitter
|
|
@ -1,9 +1,9 @@
|
|||
'use strict'
|
||||
import { ipcMainInternal } from '@electron/internal/browser/ipc-main-internal'
|
||||
import * as errorUtils from '@electron/internal/common/error-utils'
|
||||
|
||||
const { ipcMainInternal } = require('@electron/internal/browser/ipc-main-internal')
|
||||
const errorUtils = require('@electron/internal/common/error-utils')
|
||||
type IPCHandler = (...args: any[]) => any
|
||||
|
||||
const callHandler = async function (handler, event, args, reply) {
|
||||
const callHandler = async function (handler: IPCHandler, event: Electron.Event, args: any[], reply: (args: any[]) => void) {
|
||||
try {
|
||||
const result = await handler(event, ...args)
|
||||
reply([null, result])
|
||||
|
@ -12,7 +12,7 @@ const callHandler = async function (handler, event, args, reply) {
|
|||
}
|
||||
}
|
||||
|
||||
exports.handle = function (channel, handler) {
|
||||
export const handle = function <T extends IPCHandler> (channel: string, handler: T) {
|
||||
ipcMainInternal.on(channel, (event, requestId, ...args) => {
|
||||
callHandler(handler, event, args, responseArgs => {
|
||||
event._replyInternal(`${channel}_RESPONSE_${requestId}`, ...responseArgs)
|
||||
|
@ -20,7 +20,7 @@ exports.handle = function (channel, handler) {
|
|||
})
|
||||
}
|
||||
|
||||
exports.handleSync = function (channel, handler) {
|
||||
export const handleSync = function <T extends IPCHandler> (channel: string, handler: T) {
|
||||
ipcMainInternal.on(channel, (event, ...args) => {
|
||||
callHandler(handler, event, args, responseArgs => {
|
||||
event.returnValue = responseArgs
|
|
@ -1,12 +1,8 @@
|
|||
'use strict'
|
||||
|
||||
const { EventEmitter } = require('events')
|
||||
import { EventEmitter } from 'events'
|
||||
|
||||
const emitter = new EventEmitter()
|
||||
|
||||
// Do not throw exception when channel name is "error".
|
||||
emitter.on('error', () => {})
|
||||
|
||||
module.exports = {
|
||||
ipcMainInternal: emitter
|
||||
}
|
||||
export const ipcMainInternal = emitter
|
|
@ -1,8 +1,6 @@
|
|||
'use strict'
|
||||
let deprecationHandler: ElectronInternal.DeprecationHandler | null = null
|
||||
|
||||
let deprecationHandler = null
|
||||
|
||||
function warnOnce (oldName, newName) {
|
||||
function warnOnce (oldName: string, newName?: string) {
|
||||
let warned = false
|
||||
const msg = newName
|
||||
? `'${oldName}' is deprecated and will be removed. Please use '${newName}' instead.`
|
||||
|
@ -15,7 +13,7 @@ function warnOnce (oldName, newName) {
|
|||
}
|
||||
}
|
||||
|
||||
const deprecate = {
|
||||
const deprecate: ElectronInternal.DeprecationUtil = {
|
||||
setHandler: (handler) => { deprecationHandler = handler },
|
||||
getHandler: () => deprecationHandler,
|
||||
warn: (oldName, newName) => {
|
||||
|
@ -37,7 +35,7 @@ const deprecate = {
|
|||
|
||||
function: (fn, newName) => {
|
||||
const warn = warnOnce(fn.name, newName)
|
||||
return function () {
|
||||
return function (this: any) {
|
||||
warn()
|
||||
fn.apply(this, arguments)
|
||||
}
|
||||
|
@ -47,7 +45,7 @@ const deprecate = {
|
|||
const warn = newName.startsWith('-') /* internal event */
|
||||
? warnOnce(`${oldName} event`)
|
||||
: warnOnce(`${oldName} event`, `${newName} event`)
|
||||
return emitter.on(newName, function (...args) {
|
||||
return emitter.on(newName, function (this: NodeJS.EventEmitter, ...args) {
|
||||
if (this.listenerCount(oldName) !== 0) {
|
||||
warn()
|
||||
this.emit(oldName, ...args)
|
||||
|
@ -77,14 +75,14 @@ const deprecate = {
|
|||
})
|
||||
},
|
||||
|
||||
promisify: (fn) => {
|
||||
promisify: <T extends (...args: any[]) => any>(fn: T): T => {
|
||||
const fnName = fn.name || 'function'
|
||||
const oldName = `${fnName} with callbacks`
|
||||
const newName = `${fnName} with Promises`
|
||||
const warn = warnOnce(oldName, newName)
|
||||
|
||||
return function (...params) {
|
||||
let cb
|
||||
return function (this: any, ...params: any[]) {
|
||||
let cb: Function | undefined
|
||||
if (params.length > 0 && typeof params[params.length - 1] === 'function') {
|
||||
cb = params.pop()
|
||||
}
|
||||
|
@ -92,26 +90,26 @@ const deprecate = {
|
|||
if (!cb) return promise
|
||||
if (process.enablePromiseAPIs) warn()
|
||||
return promise
|
||||
.then(res => {
|
||||
.then((res: any) => {
|
||||
process.nextTick(() => {
|
||||
cb.length === 2 ? cb(null, res) : cb(res)
|
||||
cb!.length === 2 ? cb!(null, res) : cb!(res)
|
||||
})
|
||||
}, err => {
|
||||
}, (err: Error) => {
|
||||
process.nextTick(() => {
|
||||
cb.length === 2 ? cb(err) : cb()
|
||||
cb!.length === 2 ? cb!(err) : cb!()
|
||||
})
|
||||
})
|
||||
}
|
||||
} as T
|
||||
},
|
||||
|
||||
promisifyMultiArg: (fn) => {
|
||||
promisifyMultiArg: <T extends (...args: any[]) => any>(fn: T): T => {
|
||||
const fnName = fn.name || 'function'
|
||||
const oldName = `${fnName} with callbacks`
|
||||
const newName = `${fnName} with Promises`
|
||||
const warn = warnOnce(oldName, newName)
|
||||
|
||||
return function (...params) {
|
||||
let cb
|
||||
return function (this: any, ...params) {
|
||||
let cb: Function | undefined
|
||||
if (params.length > 0 && typeof params[params.length - 1] === 'function') {
|
||||
cb = params.pop()
|
||||
}
|
||||
|
@ -119,15 +117,15 @@ const deprecate = {
|
|||
if (!cb) return promise
|
||||
if (process.enablePromiseAPIs) warn()
|
||||
return promise
|
||||
.then(res => {
|
||||
.then((res: any) => {
|
||||
process.nextTick(() => {
|
||||
// eslint-disable-next-line standard/no-callback-literal
|
||||
cb.length > 2 ? cb(null, ...res) : cb(...res)
|
||||
cb!.length > 2 ? cb!(null, ...res) : cb!(...res)
|
||||
})
|
||||
}, err => {
|
||||
process.nextTick(() => cb(err))
|
||||
}, (err: Error) => {
|
||||
process.nextTick(() => cb!(err))
|
||||
})
|
||||
}
|
||||
} as T
|
||||
},
|
||||
|
||||
renameProperty: (o, oldName, newName) => {
|
||||
|
@ -137,7 +135,7 @@ const deprecate = {
|
|||
// inject it and warn about it
|
||||
if ((oldName in o) && !(newName in o)) {
|
||||
warn()
|
||||
o[newName] = o[oldName]
|
||||
o[newName] = (o as any)[oldName]
|
||||
}
|
||||
|
||||
// wrap the deprecated property in an accessor to warn
|
||||
|
@ -155,4 +153,4 @@ const deprecate = {
|
|||
}
|
||||
}
|
||||
|
||||
module.exports = deprecate
|
||||
export default deprecate
|
|
@ -24,7 +24,12 @@ exports.defineProperties = function (targetExports) {
|
|||
for (const module of moduleList) {
|
||||
descriptors[module.name] = {
|
||||
enumerable: !module.private,
|
||||
get: exports.memoizedGetter(() => require(`@electron/internal/common/api/${module.file}`))
|
||||
get: exports.memoizedGetter(() => {
|
||||
const value = require(`@electron/internal/common/api/${module.file}.js`)
|
||||
// Handle Typescript modules with an "export default X" statement
|
||||
if (value.__esModule) return value.default
|
||||
return value
|
||||
})
|
||||
}
|
||||
}
|
||||
return Object.defineProperties(targetExports, descriptors)
|
||||
|
|
|
@ -18,6 +18,11 @@ for (const {
|
|||
|
||||
Object.defineProperty(exports, name, {
|
||||
enumerable: !isPrivate,
|
||||
get: common.memoizedGetter(() => require(`@electron/internal/renderer/api/${file}`))
|
||||
get: common.memoizedGetter(() => {
|
||||
const value = require(`@electron/internal/renderer/api/${file}.js`)
|
||||
// Handle Typescript modules with an "export default X" statement
|
||||
if (value.__esModule) return value.default
|
||||
return value
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
@ -2,6 +2,12 @@
|
|||
|
||||
const moduleList = require('@electron/internal/sandboxed_renderer/api/module-list')
|
||||
|
||||
const handleESModule = (m) => {
|
||||
// Handle Typescript modules with an "export default X" statement
|
||||
if (m.__esModule) return m.default
|
||||
return m
|
||||
}
|
||||
|
||||
for (const {
|
||||
name,
|
||||
load,
|
||||
|
@ -14,6 +20,6 @@ for (const {
|
|||
|
||||
Object.defineProperty(exports, name, {
|
||||
enumerable: !isPrivate,
|
||||
get: load
|
||||
get: () => handleESModule(load())
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1110,20 +1110,69 @@ describe('app module', () => {
|
|||
})
|
||||
})
|
||||
|
||||
describe('dock APIs', () => {
|
||||
describe('dock.setMenu()', () => {
|
||||
it('keeps references to the menu', function () {
|
||||
if (process.platform !== 'darwin') this.skip()
|
||||
const dockDescribe = process.platform === 'darwin' ? describe : describe.skip
|
||||
dockDescribe('dock APIs', () => {
|
||||
describe('dock.setMenu', () => {
|
||||
it('can be retrieved via dock.getMenu', () => {
|
||||
expect(app.dock.getMenu()).to.equal(null)
|
||||
const menu = new Menu()
|
||||
app.dock.setMenu(menu)
|
||||
expect(app.dock.getMenu()).to.equal(menu)
|
||||
})
|
||||
|
||||
it('keeps references to the menu', () => {
|
||||
app.dock.setMenu(new Menu())
|
||||
const v8Util = process.atomBinding('v8_util')
|
||||
v8Util.requestGarbageCollectionForTesting()
|
||||
})
|
||||
})
|
||||
|
||||
describe('dock.show()', () => {
|
||||
before(function () {
|
||||
if (process.platform !== 'darwin') this.skip()
|
||||
describe('dock.bounce', () => {
|
||||
it('should return -1 for unknown bounce type', () => {
|
||||
expect(app.dock.bounce('bad type')).to.equal(-1)
|
||||
})
|
||||
|
||||
it('should return a positive number for informational type', () => {
|
||||
const appHasFocus = !!BrowserWindow.getFocusedWindow()
|
||||
if (!appHasFocus) {
|
||||
expect(app.dock.bounce('informational')).to.be.at.least(0)
|
||||
}
|
||||
})
|
||||
|
||||
it('should return a positive number for critical type', () => {
|
||||
const appHasFocus = !!BrowserWindow.getFocusedWindow()
|
||||
if (!appHasFocus) {
|
||||
expect(app.dock.bounce('critical')).to.be.at.least(0)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe('dock.cancelBounce', () => {
|
||||
it('should not throw', () => {
|
||||
app.dock.cancelBounce(app.dock.bounce('critical'))
|
||||
})
|
||||
})
|
||||
|
||||
describe('dock.setBadge', () => {
|
||||
after(() => {
|
||||
app.dock.setBadge('')
|
||||
})
|
||||
|
||||
it('should not throw', () => {
|
||||
app.dock.setBadge('1')
|
||||
})
|
||||
|
||||
it('should be retrievable via getBadge', () => {
|
||||
app.dock.setBadge('test')
|
||||
expect(app.dock.getBadge()).to.equal('test')
|
||||
})
|
||||
})
|
||||
|
||||
describe('dock.show', () => {
|
||||
it('should not throw', () => {
|
||||
return app.dock.show().then(() => {
|
||||
expect(app.dock.isVisible()).to.equal(true)
|
||||
})
|
||||
})
|
||||
|
||||
it('returns a Promise', () => {
|
||||
|
@ -1134,6 +1183,13 @@ describe('app module', () => {
|
|||
expect(app.dock.show()).to.be.eventually.fulfilled()
|
||||
})
|
||||
})
|
||||
|
||||
describe('dock.hide', () => {
|
||||
it('should not throw', () => {
|
||||
app.dock.hide()
|
||||
expect(app.dock.isVisible()).to.equal(false)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('whenReady', () => {
|
||||
|
|
2
typings/internal-ambient.d.ts
vendored
2
typings/internal-ambient.d.ts
vendored
|
@ -22,6 +22,8 @@ declare namespace NodeJS {
|
|||
atomBinding(name: string): any;
|
||||
atomBinding(name: 'features'): FeaturesBinding;
|
||||
atomBinding(name: 'v8_util'): V8UtilBinding;
|
||||
atomBinding(name: 'app'): { app: Electron.App, App: Function };
|
||||
atomBinding(name: 'command_line'): Electron.CommandLine;
|
||||
log: NodeJS.WriteStream['write'];
|
||||
activateUvLoop(): void;
|
||||
}
|
||||
|
|
19
typings/internal-electron.d.ts
vendored
19
typings/internal-electron.d.ts
vendored
|
@ -26,4 +26,23 @@ declare namespace Electron {
|
|||
cause: SerializedError,
|
||||
__ELECTRON_SERIALIZED_ERROR__: true
|
||||
}
|
||||
|
||||
const deprecate: ElectronInternal.DeprecationUtil;
|
||||
}
|
||||
|
||||
declare namespace ElectronInternal {
|
||||
type DeprecationHandler = (message: string) => void;
|
||||
interface DeprecationUtil {
|
||||
setHandler(handler: DeprecationHandler): void;
|
||||
getHandler(): DeprecationHandler | null;
|
||||
warn(oldName: string, newName: string): void;
|
||||
log(message: string): void;
|
||||
function(fn: Function, newName: string): Function;
|
||||
event(emitter: NodeJS.EventEmitter, oldName: string, newName: string): void;
|
||||
removeProperty<T, K extends (keyof T & string)>(object: T, propertyName: K): T;
|
||||
renameProperty<T, K extends (keyof T & string)>(object: T, oldName: string, newName: K): T;
|
||||
|
||||
promisify<T extends (...args: any[]) => any>(fn: T): T;
|
||||
promisifyMultiArg<T extends (...args: any[]) => any>(fn: T): T;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue