mirror of
https://github.com/Llewellynvdm/nativefier.git
synced 2024-11-04 20:38:03 +00:00
This PR adds an optional, customizable menu of predefined bookmarks. In addition to containing a list of bookmarks, this file customizes the name of the menu and (optionally) allows assigning keyboard shortcuts to bookmarks. It adds a new command-line flag, `--bookmarks-menu <string>`, which can be set as the path to a JSON file containing configuration for the bookmarks menu. Example of such a JSON file: ```json { "menuLabel": "Music", "bookmarks": [ { "title": "lofi.cafe", "url": "https://lofi.cafe/", "type": "link", "shortcut": "Cmd+1" }, { "title": "beats to relax/study to", "url": "https://www.youtube.com/watch?v=5qap5aO4i9A", "type": "link", "shortcut": "Cmd+2" }, { "type": "separator" }, { "title": "RÜFÜS DU SOL Live from Joshua Tree", "type": "link", "url": "https://www.youtube.com/watch?v=Zy4KtD98S2c" } ] } ``` ## Checks - [x] `npm run ci` passes ## Notes Compared to the fork linked in #1065, this PR: - adds no dependencies - doesn't currently support submenus (this should be easy enough to add, but I didn't need it) ## Screenshot <img width="853" alt="screenshot" src="https://user-images.githubusercontent.com/102904/115882015-5493a800-a41a-11eb-85ef-a190f3dbfe76.png">
This commit is contained in:
parent
fa9bd2aba5
commit
b4ddd6865c
@ -230,6 +230,9 @@ export function createMainWindow(
|
||||
const getCurrentUrl = (): void =>
|
||||
withFocusedWindow((focusedWindow) => focusedWindow.webContents.getURL());
|
||||
|
||||
const gotoUrl = (url: string): void =>
|
||||
withFocusedWindow((focusedWindow) => void focusedWindow.loadURL(url));
|
||||
|
||||
const onBlockedExternalUrl = (url: string) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
dialog.showMessageBox(mainWindow, {
|
||||
@ -342,6 +345,7 @@ export function createMainWindow(
|
||||
goBack: onGoBack,
|
||||
goForward: onGoForward,
|
||||
getCurrentUrl,
|
||||
gotoUrl,
|
||||
clearAppData,
|
||||
disableDevTools: options.disableDevTools,
|
||||
};
|
||||
|
@ -1,5 +1,23 @@
|
||||
import * as fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
import { Menu, clipboard, shell, MenuItemConstructorOptions } from 'electron';
|
||||
|
||||
type BookmarksLink = {
|
||||
type: 'link';
|
||||
title: string;
|
||||
url: string;
|
||||
shortcut?: string;
|
||||
};
|
||||
type BookmarksSeparator = {
|
||||
type: 'separator';
|
||||
};
|
||||
type BookmarkConfig = BookmarksLink | BookmarksSeparator;
|
||||
type BookmarksMenuConfig = {
|
||||
menuLabel: string;
|
||||
bookmarks: BookmarkConfig[];
|
||||
};
|
||||
|
||||
export function createMenu({
|
||||
nativefierVersion,
|
||||
appQuit,
|
||||
@ -10,6 +28,7 @@ export function createMenu({
|
||||
goBack,
|
||||
goForward,
|
||||
getCurrentUrl,
|
||||
gotoUrl,
|
||||
clearAppData,
|
||||
disableDevTools,
|
||||
}): void {
|
||||
@ -286,6 +305,58 @@ export function createMenu({
|
||||
menuTemplate = [editMenu, viewMenu, windowMenu, helpMenu];
|
||||
}
|
||||
|
||||
try {
|
||||
const bookmarkConfigPath = path.join(__dirname, '..', 'bookmarks.json');
|
||||
if (fs.existsSync(bookmarkConfigPath)) {
|
||||
const bookmarksMenuConfig: BookmarksMenuConfig = JSON.parse(
|
||||
fs.readFileSync(bookmarkConfigPath, 'utf-8'),
|
||||
);
|
||||
const bookmarksMenu: MenuItemConstructorOptions = {
|
||||
label: bookmarksMenuConfig.menuLabel,
|
||||
submenu: bookmarksMenuConfig.bookmarks.map((bookmark) => {
|
||||
if (bookmark.type === 'link') {
|
||||
if (!('title' in bookmark && 'url' in bookmark)) {
|
||||
throw Error(
|
||||
'All links in the bookmarks menu must have a title and url.',
|
||||
);
|
||||
}
|
||||
try {
|
||||
new URL(bookmark.url);
|
||||
} catch (_) {
|
||||
throw Error('Bookmark URL "' + bookmark.url + '"is invalid.');
|
||||
}
|
||||
let accelerator = null;
|
||||
if ('shortcut' in bookmark) {
|
||||
accelerator = bookmark.shortcut;
|
||||
}
|
||||
return {
|
||||
label: bookmark.title,
|
||||
click: () => {
|
||||
gotoUrl(bookmark.url);
|
||||
},
|
||||
accelerator: accelerator,
|
||||
};
|
||||
} else if (bookmark.type === 'separator') {
|
||||
return {
|
||||
type: 'separator',
|
||||
};
|
||||
} else {
|
||||
throw Error(
|
||||
'A bookmarks menu entry has an invalid type; type must be one of "link", "separator".',
|
||||
);
|
||||
}
|
||||
}),
|
||||
};
|
||||
// Insert custom bookmarks menu between menus "View" and "Window"
|
||||
menuTemplate.splice(menuTemplate.length - 2, 0, bookmarksMenu);
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn(
|
||||
'Failed to load & parse bookmarks configuration JSON file.',
|
||||
err,
|
||||
);
|
||||
}
|
||||
|
||||
const menu = Menu.buildFromTemplate(menuTemplate);
|
||||
Menu.setApplicationMenu(menu);
|
||||
}
|
||||
|
46
docs/api.md
46
docs/api.md
@ -68,6 +68,7 @@
|
||||
- [[browserwindow-options]](#browserwindow-options)
|
||||
- [[darwin-dark-mode-support]](#darwin-dark-mode-support)
|
||||
- [[background-color]](#background-color)
|
||||
- [[bookmarks-menu]](#bookmarks-menu)
|
||||
- [Deprecated](#deprecated)
|
||||
- [[flash] and [flash-path]](#flash) (DEPRECATED)
|
||||
- [Programmatic API](#programmatic-api)
|
||||
@ -794,6 +795,51 @@ Enables Dark Mode support on macOS 10.14+.
|
||||
|
||||
See https://electronjs.org/docs/api/browser-window#setting-backgroundcolor
|
||||
|
||||
#### [bookmarks-menu]
|
||||
|
||||
```
|
||||
--bookmarks-menu <string>
|
||||
```
|
||||
|
||||
Path to a JSON file defining a bookmarks menu. In addition to containing a list of bookmarks, this file customizes the name of the menu and (optionally) allows assigning keyboard shortcuts to bookmarks.
|
||||
|
||||
This menu is a simple list; folders are not supported.
|
||||
|
||||
Your `menuLabel` can be bound to a `Alt + letter` shortcut using the letter `&` before the `letter` you want. Be careful to not conflict with the letter of other menus!
|
||||
|
||||
Keyboard shortcuts can use the modifier keys `Cmd`, `Ctrl`, `CmdOrCtrl`, `Alt`, `Option`, `AltGr`, `Shift`, and `Super`. See [the Electron documentation](https://www.electronjs.org/docs/api/accelerator) for more information.
|
||||
|
||||
Example of such a JSON file:
|
||||
|
||||
```json
|
||||
{
|
||||
"menuLabel": "&Music",
|
||||
"bookmarks": [
|
||||
{
|
||||
"title": "lofi.cafe",
|
||||
"url": "https://lofi.cafe/",
|
||||
"type": "link",
|
||||
"shortcut": "CmdOrCtrl+1"
|
||||
},
|
||||
{
|
||||
"title": "beats to relax/study to",
|
||||
"url": "https://www.youtube.com/watch?v=5qap5aO4i9A",
|
||||
"type": "link",
|
||||
"shortcut": "CmdOrCtrl+2"
|
||||
},
|
||||
{
|
||||
"type": "separator"
|
||||
},
|
||||
{
|
||||
"title": "RÜFÜS DU SOL Live from Joshua Tree",
|
||||
"type": "link",
|
||||
"url": "https://www.youtube.com/watch?v=Zy4KtD98S2c"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Deprecated
|
||||
|
||||
#### [flash]
|
||||
|
@ -156,6 +156,15 @@ export async function prepareElectronApp(
|
||||
JSON.stringify(pickElectronAppArgs(options)),
|
||||
);
|
||||
|
||||
if (options.nativefier.bookmarksMenu) {
|
||||
const bookmarksJsonPath = path.join(dest, '/bookmarks.json');
|
||||
try {
|
||||
await copyFileOrDir(options.nativefier.bookmarksMenu, bookmarksJsonPath);
|
||||
} catch (err) {
|
||||
log.error('Error copying bookmarks menu config file.', err);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
await maybeCopyScripts(options.nativefier.inject, dest);
|
||||
} catch (err) {
|
||||
|
@ -274,6 +274,10 @@ if (require.main === module) {
|
||||
.option(
|
||||
'--darwin-dark-mode-support',
|
||||
'(macOS only) enable Dark Mode support on macOS 10.14+',
|
||||
)
|
||||
.option(
|
||||
'--bookmarks-menu <value>',
|
||||
'Path to JSON configuration file for the bookmarks menu.',
|
||||
);
|
||||
|
||||
try {
|
||||
|
@ -13,6 +13,7 @@ export interface AppOptions {
|
||||
backgroundColor: string;
|
||||
basicAuthPassword: string;
|
||||
basicAuthUsername: string;
|
||||
bookmarksMenu: string;
|
||||
bounce: boolean;
|
||||
browserwindowOptions: any;
|
||||
clearCache: boolean;
|
||||
|
@ -52,6 +52,7 @@ export async function getOptions(rawOptions: any): Promise<AppOptions> {
|
||||
backgroundColor: rawOptions.backgroundColor || null,
|
||||
basicAuthPassword: rawOptions.basicAuthPassword || null,
|
||||
basicAuthUsername: rawOptions.basicAuthUsername || null,
|
||||
bookmarksMenu: rawOptions.bookmarksMenu || null,
|
||||
bounce: rawOptions.bounce || false,
|
||||
browserwindowOptions: rawOptions.browserwindowOptions,
|
||||
clearCache: rawOptions.clearCache || false,
|
||||
|
Loading…
Reference in New Issue
Block a user