electron#MenuItem TypeScript Examples

The following examples show how to use electron#MenuItem. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: contextMenuBuilder.ts    From TidGi-Desktop with Mozilla Public License 2.0 6 votes vote down vote up
/**
   * Adds the "Developer Tools" menu item.
   */
  addDeveloperTools(menu: Menu, menuInfo: IOnContextMenuInfo, needsSeparator = false): Menu {
    if (needsSeparator) {
      this.addSeparator(menu);
    }
    const inspect = new MenuItem({
      label: this.stringTable.developerTools(),
      click: () => this.webContents.openDevTools(),
    });
    menu.append(inspect);
    return menu;
  }
Example #2
Source File: context-menus.ts    From electron-browser-shell with GNU General Public License v3.0 6 votes vote down vote up
buildMenuItemsForParams(
    webContents: Electron.WebContents,
    params: Electron.ContextMenuParams
  ): Electron.MenuItem[] {
    if (webContents.session !== this.ctx.session) return []

    const menuItemOptions = []

    const conditions = {
      contextTypes: getContextTypesFromParams(params),
      targetUrl: params.srcURL || params.linkURL,
      documentUrl: params.frameURL || params.pageURL,
    }

    for (const [extensionId, propItems] of this.menus) {
      const extension = this.ctx.session.getExtension(extensionId)
      if (!extension) continue

      for (const [, props] of propItems) {
        if (matchesConditions(props, conditions)) {
          const menuItem = {
            extension,
            props,
            webContents,
            params,
            showIcon: true,
          }
          menuItemOptions.push(menuItem)
        }
      }
    }

    return this.buildMenuItemsFromTemplate(menuItemOptions)
  }
Example #3
Source File: context-menus.ts    From electron-browser-shell with GNU General Public License v3.0 6 votes vote down vote up
private buildMenuItemsForExtension(
    extensionId: string,
    menuType: ContextMenuType
  ): Electron.MenuItem[] {
    const extensionItems = this.menus.get(extensionId)
    const extension = this.ctx.session.getExtension(extensionId)
    const activeTab = this.ctx.store.getActiveTabOfCurrentWindow()

    const menuItemOptions = []

    if (extensionItems && extension && activeTab) {
      const conditions = {
        contextTypes: new Set<ContextMenuType>(['all', menuType]),
      }

      for (const [, props] of extensionItems) {
        if (matchesConditions(props, conditions)) {
          const menuItem = { extension, props, webContents: activeTab }
          menuItemOptions.push(menuItem)
        }
      }
    }

    return this.buildMenuItemsFromTemplate(menuItemOptions)
  }
Example #4
Source File: setup.ts    From react-sqlite-app-starter with MIT License 6 votes vote down vote up
constructor(
    capacitorFileConfig: CapacitorElectronConfig,
    trayMenuTemplate?: (MenuItemConstructorOptions | MenuItem)[],
    appMenuBarMenuTemplate?: (MenuItemConstructorOptions | MenuItem)[],
  ) {
    this.CapacitorFileConfig = capacitorFileConfig;

    this.customScheme =
      this.CapacitorFileConfig.electron?.customUrlScheme ??
      'capacitor-electron';

    if (trayMenuTemplate) {
      this.TrayMenuTemplate = trayMenuTemplate;
    }

    if (appMenuBarMenuTemplate) {
      this.AppMenuBarMenuTemplate = appMenuBarMenuTemplate;
    }

    // Setup our web app loader, this lets us load apps like react, vue, and angular without changing their build chains.
    this.loadWebApp = electronServe({
      directory: join(app.getAppPath(), 'app'),
      scheme: this.customScheme,
    });
  }
Example #5
Source File: contextMenuBuilder.ts    From TidGi-Desktop with Mozilla Public License 2.0 6 votes vote down vote up
/**
   * Builds a menu applicable to a link element.
   *
   * @return {Menu}  The `Menu`
   */
  private buildMenuForLink(menuInfo: IOnContextMenuInfo): Menu {
    const menu = new Menu();
    if (menuInfo.linkURL === undefined || menuInfo.linkText === undefined) return menu;
    const isEmailAddress = menuInfo.linkURL.startsWith('mailto:');
    const copyLink = new MenuItem({
      label: isEmailAddress ? this.stringTable.copyMail() : this.stringTable.copyLinkUrl(),
      click: () => {
        // Omit the mailto: portion of the link; we just want the address
        clipboard.writeText(isEmailAddress ? menuInfo.linkText! : menuInfo.linkURL!);
      },
    });
    const openLink = new MenuItem({
      label: this.stringTable.openLinkUrl(),
      click: () => {
        void shell.openExternal(menuInfo.linkURL!);
      },
    });
    menu.append(copyLink);
    menu.append(openLink);
    if (this.isSrcUrlValid(menuInfo)) {
      this.addSeparator(menu);
      this.addImageItems(menu, menuInfo);
    }
    this.addInspectElement(menu, menuInfo);
    this.addDeveloperTools(menu, menuInfo);
    this.processMenu(menu, menuInfo);
    return menu;
  }
Example #6
Source File: contextMenuBuilder.ts    From TidGi-Desktop with Mozilla Public License 2.0 6 votes vote down vote up
/**
   * Checks if the current text selection contains a single misspelled word and
   * if so, adds suggested spellings as individual menu items.
   */
  private addSpellingItems(menu: Menu, menuInfo: IOnContextMenuInfo): Menu {
    if (typeof menuInfo.misspelledWord !== 'string' || menuInfo.misspelledWord.length === 0) {
      return menu;
    }
    // Ensure that we have valid corrections for that word
    const corrections = menuInfo.dictionarySuggestions;
    if (Array.isArray(corrections) && corrections.length > 0) {
      corrections.forEach((correction: string) => {
        const item = new MenuItem({
          label: correction,
          click: () => this.webContents.replaceMisspelling(correction),
        });
        menu.append(item);
      });
      this.addSeparator(menu);
    }
    return menu;
  }
Example #7
Source File: contextMenuBuilder.ts    From TidGi-Desktop with Mozilla Public License 2.0 6 votes vote down vote up
/**
   * Adds search-related menu items.
   */
  private addSearchItems(menu: Menu, menuInfo: IOnContextMenuInfo): Menu {
    if (typeof menuInfo.selectionText !== 'string' || menuInfo.selectionText.length === 0) {
      return menu;
    }
    const match = matchesWord(menuInfo.selectionText);
    if (match === null || match.length === 0) {
      return menu;
    }
    if (process.platform === 'darwin') {
      const lookUpDefinition = new MenuItem({
        label: this.stringTable.lookUpDefinition({ word: truncateString(menuInfo.selectionText) }),
        click: () => this.webContents.showDefinitionForSelection(),
      });
      menu.append(lookUpDefinition);
    }
    const search = new MenuItem({
      label: this.stringTable.searchGoogle(),
      click: () => {
        const url = `https://www.google.com/#q=${encodeURIComponent(menuInfo.selectionText!)}`;
        void shell.openExternal(url);
      },
    });
    menu.append(search);
    this.addSeparator(menu);
    return menu;
  }
Example #8
Source File: setup.ts    From angular-sqlite-app-starter with MIT License 6 votes vote down vote up
constructor(
    capacitorFileConfig: CapacitorElectronConfig,
    trayMenuTemplate?: (MenuItemConstructorOptions | MenuItem)[],
    appMenuBarMenuTemplate?: (MenuItemConstructorOptions | MenuItem)[]
  ) {
    this.CapacitorFileConfig = capacitorFileConfig;

    this.customScheme = this.CapacitorFileConfig.electron?.customUrlScheme ?? 'capacitor-electron';

    if (trayMenuTemplate) {
      this.TrayMenuTemplate = trayMenuTemplate;
    }

    if (appMenuBarMenuTemplate) {
      this.AppMenuBarMenuTemplate = appMenuBarMenuTemplate;
    }

    // Setup our web app loader, this lets us load apps like react, vue, and angular without changing their build chains.
    this.loadWebApp = electronServe({
      directory: join(app.getAppPath(), 'app'),
      scheme: this.customScheme,
    });
  }
Example #9
Source File: contextMenuBuilder.ts    From TidGi-Desktop with Mozilla Public License 2.0 6 votes vote down vote up
/**
   * Adds "Copy Image URL" items when `src` is valid.
   */
  private addImageItems(menu: Menu, menuInfo: IOnContextMenuInfo): Menu {
    if (menuInfo.srcURL === undefined) return menu;
    const copyImageUrl = new MenuItem({
      label: this.stringTable.copyImageUrl(),
      click: () => clipboard.writeText(menuInfo.srcURL!),
    });
    menu.append(copyImageUrl);
    return menu;
  }
Example #10
Source File: contextMenuBuilder.ts    From TidGi-Desktop with Mozilla Public License 2.0 6 votes vote down vote up
/**
   * Adds the Cut menu item
   */
  private addCut(menu: Menu, menuInfo: IOnContextMenuInfo): Menu {
    menu.append(
      new MenuItem({
        label: this.stringTable.cut(),
        accelerator: 'CommandOrControl+X',
        enabled: menuInfo?.editFlags?.canCut,
        click: () => this.webContents.cut(),
      }),
    );
    return menu;
  }
Example #11
Source File: menu.ts    From excalidraw-desktop with MIT License 6 votes vote down vote up
setupMenu = (activeWindow: BrowserWindow, options = {}) => {
  const isDarwin = process.platform === "darwin";
  const defaultMenuItems: MenuItem[] = Menu.getApplicationMenu().items;
  const menuTemplate = [];
  if (isDarwin) {
    defaultMenuItems.shift();
    menuTemplate.push({
      label: APP_NAME,
      submenu: [
        {
          label: `About ${APP_NAME}`,
          enabled: true,
          click: () => openAboutWindow(),
        },
      ],
    });
    menuTemplate.push(...defaultMenuItems);
  } else {
    defaultMenuItems.pop();
    menuTemplate.push(...defaultMenuItems);
    menuTemplate.push({
      label: "Help",
      submenu: [
        {
          label: `About ${APP_NAME}`,
          enabled: true,
          click: () => openAboutWindow(),
        },
      ],
    });
  }

  // TODO: Remove default menu items that aren't relevant
  const appMenu = Menu.buildFromTemplate(menuTemplate);
  Menu.setApplicationMenu(appMenu);
}
Example #12
Source File: contextMenuBuilder.ts    From TidGi-Desktop with Mozilla Public License 2.0 6 votes vote down vote up
/**
   * Adds the Copy menu item.
   */
  addCopy(menu: Menu, menuInfo: IOnContextMenuInfo): Menu {
    menu.append(
      new MenuItem({
        label: this.stringTable.copy(),
        accelerator: 'CommandOrControl+C',
        enabled: menuInfo?.editFlags?.canCopy,
        click: () => this.webContents.copy(),
      }),
    );
    return menu;
  }
Example #13
Source File: contextMenuBuilder.ts    From TidGi-Desktop with Mozilla Public License 2.0 6 votes vote down vote up
/**
   * Adds the Paste menu item.
   */
  addPaste(menu: Menu, menuInfo: IOnContextMenuInfo): Menu {
    menu.append(
      new MenuItem({
        label: this.stringTable.paste(),
        accelerator: 'CommandOrControl+V',
        enabled: menuInfo?.editFlags?.canPaste,
        click: () => this.webContents.paste(),
      }),
    );
    return menu;
  }
Example #14
Source File: app-menu.ts    From WowUp with GNU General Public License v3.0 6 votes vote down vote up
function createMenuItems(win: BrowserWindow, config?: MenuConfig): Array<MenuItemConstructorOptions | MenuItem> {
  if (!config) {
    return [];
  }

  if (platform.isWin) {
    return createWindowsMenuItems(win, config);
  } else if (platform.isMac) {
    return createMacMenuItems(win, config);
  } else if (platform.isLinux) {
    return createLinuxMenuItems(win, config);
  }

  return [];
}
Example #15
Source File: app-menu.ts    From WowUp with GNU General Public License v3.0 6 votes vote down vote up
function createWindowsMenuItems(win: BrowserWindow, config?: MenuConfig): Array<MenuItemConstructorOptions | MenuItem> {
  const viewMenu: MenuItemConstructorOptions = {
    label: config.viewLabel,
    submenu: [{ label: config.toggleDevToolsLabel, role: "toggleDevTools", accelerator: "CommandOrControl+Shift+I" }],
  };

  const submenu = viewMenu.submenu as MenuItemConstructorOptions[];
  createViewMenu(submenu, win, config);

  submenu.push({ type: "separator" }, { label: config.toggleFullScreenLabel, role: "togglefullscreen" });

  return [viewMenu];
}
Example #16
Source File: app-menu.ts    From WowUp with GNU General Public License v3.0 6 votes vote down vote up
function createLinuxMenuItems(win: BrowserWindow, config?: MenuConfig): Array<MenuItemConstructorOptions | MenuItem> {
  const viewMenu: MenuItemConstructorOptions = {
    label: config.viewLabel,
    submenu: [
      { label: config.reloadLabel, role: "reload" },
      { label: config.forceReloadLabel, role: "forceReload" },
      { label: config.toggleDevToolsLabel, role: "toggleDevTools", accelerator: "CommandOrControl+Shift+I" },
    ],
  };

  const submenu = viewMenu.submenu as MenuItemConstructorOptions[];
  createViewMenu(submenu, win, config);

  submenu.push({ type: "separator" }, { label: config.toggleFullScreenLabel, role: "togglefullscreen" });

  return [
    {
      label: app.name,
      submenu: [{ label: config.quitLabel, role: "quit" }],
    },
    {
      label: "Edit",
      submenu: [
        { label: config.undoLabel, role: "undo" },
        { label: config.redoLabel, role: "redo" },
        { type: "separator" },
        { label: config.cutLabel, role: "cut" },
        { label: config.copyLabel, role: "copy" },
        { label: config.pasteLabel, role: "paste" },
        { label: config.selectAllLabel, role: "selectAll" },
      ],
    },
    viewMenu,
  ];
}
Example #17
Source File: app-menu.ts    From kliveide with MIT License 6 votes vote down vote up
/**
 * Traverses all menu items and executed the specified action
 * @param action Action to execute
 */
export function traverseMenu(action: (item: MenuItem) => void): void {
  const menu = Menu.getApplicationMenu().items;
  traverseMenu(menu, action);

  function traverseMenu(
    items: MenuItem[],
    action: (item: MenuItem) => void
  ): void {
    for (let item of items) {
      action(item);
      if (item.submenu) {
        traverseMenu(item.submenu.items, action);
      }
    }
  }
}
Example #18
Source File: contextMenuBuilder.ts    From TidGi-Desktop with Mozilla Public License 2.0 6 votes vote down vote up
/**
   * Adds the "Inspect Element" menu item.
   */
  addInspectElement(menu: Menu, menuInfo: IOnContextMenuInfo, needsSeparator = true): Menu {
    if (needsSeparator) {
      this.addSeparator(menu);
    }
    const inspect = new MenuItem({
      label: this.stringTable.inspectElement(),
      click: () => this.webContents.inspectElement(menuInfo.x, menuInfo.y),
    });
    menu.append(inspect);
    return menu;
  }
Example #19
Source File: contextMenuBuilder.ts    From TidGi-Desktop with Mozilla Public License 2.0 5 votes vote down vote up
/**
   * Adds a separator item.
   */
  addSeparator(menu: Menu): Menu {
    menu.append(new MenuItem({ type: 'separator' }));
    return menu;
  }
Example #20
Source File: context-menus.ts    From electron-browser-shell with GNU General Public License v3.0 5 votes vote down vote up
private buildMenuItemsFromTemplate = (menuItemTemplates: ContextItemConstructorOptions[]) => {
    const itemMap = new Map<string, MenuItemConstructorOptions>()

    // Group by ID
    for (const item of menuItemTemplates) {
      const menuItem = this.buildMenuItem(item)
      itemMap.set(item.props.id, menuItem)
    }

    // Organize in tree
    for (const item of menuItemTemplates) {
      const menuItem = itemMap.get(item.props.id)
      if (item.props.parentId) {
        const parentMenuItem = itemMap.get(item.props.parentId)
        if (parentMenuItem) {
          const submenu = (parentMenuItem.submenu || []) as Electron.MenuItemConstructorOptions[]
          submenu.push(menuItem!)
          parentMenuItem.submenu = submenu
        }
      }
    }

    const menuItems: Electron.MenuItem[] = []

    const buildFromTemplate = (opts: Electron.MenuItemConstructorOptions) => {
      if (Array.isArray(opts.submenu)) {
        const submenu = new Menu()
        opts.submenu.forEach((item) => submenu.append(buildFromTemplate(item)))
        opts.submenu = submenu
      }
      return new MenuItem(opts)
    }

    // Build all final MenuItems in-order
    for (const item of menuItemTemplates) {
      // Items with parents will be handled recursively
      if (item.props.parentId) continue

      const menuItem = itemMap.get(item.props.id)!
      menuItems.push(buildFromTemplate(menuItem))
    }

    return menuItems
  }
Example #21
Source File: TrayMenu.ts    From wiregui with MIT License 5 votes vote down vote up
private mountTrayMenuItems(): (MenuItemConstructorOptions | MenuItem)[] {
    const header: (MenuItemConstructorOptions | MenuItem)[] = [
      {
        label: "Open Wire GUI",
        type: "normal",
        click: () => {
          this.window.show();
          this.window.focus();
        },
      },
    ];

    const body: (MenuItemConstructorOptions | MenuItem)[] = this.tunnels.map(
      (tunnel) => {
        return {
          label: tunnel.active ? `${tunnel.name} (active)` : tunnel.name,
          type: "normal",
          click: () => {
            this.window.webContents.send("toggleTunnel", tunnel);
          },
        };
      }
    );

    const footer: (MenuItemConstructorOptions | MenuItem)[] = [
      {
        label: "Quit",
        type: "normal",
        click: () => {
          this.isQuitting = true;
          app.quit();
        },
      },
    ];

    header.push({ type: "separator" });
    if (body.length > 0) {
      footer.unshift({ type: "separator" });
    }

    return header.concat(body, footer);
  }
Example #22
Source File: browser-action.ts    From electron-browser-shell with GNU General Public License v3.0 5 votes vote down vote up
private activateContextMenu(details: ActivateDetails) {
    const { extensionId, anchorRect } = details

    const extension = this.ctx.session.getExtension(extensionId)
    if (!extension) {
      throw new Error(`Unregistered extension '${extensionId}'`)
    }

    const manifest = getExtensionManifest(extension)
    const menu = new Menu()
    const append = (opts: Electron.MenuItemConstructorOptions) => menu.append(new MenuItem(opts))
    const appendSeparator = () => menu.append(new MenuItem({ type: 'separator' }))

    append({
      label: extension.name,
      click: () => {
        const homePageUrl =
          manifest.homepage_url || `https://chrome.google.com/webstore/detail/${extension.id}`
        this.ctx.store.createTab({ url: homePageUrl })
      },
    })

    appendSeparator()

    const contextMenuItems: MenuItem[] = this.ctx.store.buildMenuItems(
      extensionId,
      'browser_action'
    )
    if (contextMenuItems.length > 0) {
      contextMenuItems.forEach((item) => menu.append(item))
      appendSeparator()
    }

    const optionsPage = manifest.options_page || manifest.options_ui?.page
    const optionsPageUrl = optionsPage ? getExtensionUrl(extension, optionsPage) : undefined

    append({
      label: 'Options',
      enabled: typeof optionsPageUrl === 'string',
      click: () => {
        this.ctx.store.createTab({ url: optionsPageUrl })
      },
    })

    menu.popup({
      x: Math.floor(anchorRect.x),
      y: Math.floor(anchorRect.y + anchorRect.height),
    })
  }
Example #23
Source File: MenuBar.ts    From wiregui with MIT License 5 votes vote down vote up
public generateTemplate(): MenuItemConstructorOptions[] | MenuItem[] {
    return [
      {
        label: "File",
        submenu: [
          {
            label: "Import",
            accelerator: "Ctrl+O",
            click: this.import,
          },
          {
            type: "separator",
          },
          {
            label: "Quit",
            accelerator: "Ctrl+Q",
            click: this.quit,
          },
        ],
      },
      {
        label: "Edit",
        submenu: [
          { role: "undo" },
          { role: "redo" },
          { type: "separator" },
          { role: "cut" },
          { role: "copy" },
          { role: "paste" },
          { role: "delete" },
          { type: "separator" },
          { role: "selectAll" },
        ],
      },
      {
        label: "View",
        submenu: [
          { role: "resetZoom" },
          { role: "zoomIn" },
          { role: "zoomOut" },
          { type: "separator" },
          { role: "togglefullscreen" },
        ],
      },
      {
        label: "Window",
        submenu: [{ role: "minimize" }, { role: "close" }],
      },
      {
        role: "help",
        submenu: [
          {
            label: "Learn More",
            click: async () => {
              (await import("electron")).shell.openExternal(
                "https://github.com/Devsfy/wiregui"
              );
            },
          },
        ],
      },
    ];
  }
Example #24
Source File: setup.ts    From react-sqlite-app-starter with MIT License 5 votes vote down vote up
private AppMenuBarMenuTemplate: (MenuItem | MenuItemConstructorOptions)[] = [
    { role: process.platform === 'darwin' ? 'appMenu' : 'fileMenu' },
    { role: 'viewMenu' },
  ];
Example #25
Source File: setup.ts    From react-sqlite-app-starter with MIT License 5 votes vote down vote up
private TrayMenuTemplate: (MenuItem | MenuItemConstructorOptions)[] = [
    new MenuItem({ label: 'Quit App', role: 'quit' }),
  ];
Example #26
Source File: index.ts    From react-sqlite-app-starter with MIT License 5 votes vote down vote up
appMenuBarMenuTemplate: (MenuItemConstructorOptions | MenuItem)[] = [
  { role: process.platform === 'darwin' ? 'appMenu' : 'fileMenu' },
  { role: 'viewMenu' },
]
Example #27
Source File: index.ts    From react-sqlite-app-starter with MIT License 5 votes vote down vote up
trayMenuTemplate: (MenuItemConstructorOptions | MenuItem)[] = [
  new MenuItem({ label: 'Quit App', role: 'quit' }),
]
Example #28
Source File: setup.ts    From angular-sqlite-app-starter with MIT License 5 votes vote down vote up
private AppMenuBarMenuTemplate: (MenuItem | MenuItemConstructorOptions)[] = [
    { role: process.platform === 'darwin' ? 'appMenu' : 'fileMenu' },
    { role: 'viewMenu' },
  ];
Example #29
Source File: setup.ts    From angular-sqlite-app-starter with MIT License 5 votes vote down vote up
private TrayMenuTemplate: (MenuItem | MenuItemConstructorOptions)[] = [
    new MenuItem({ label: 'Quit App', role: 'quit' }),
  ];