sindresorhus/electron-context-menu

Electron 11 - TypeError: win.addEventListener is not a function

sergeyd63 opened this issue · 12 comments

Version: 2.3.0

Electron: 11.0.1

contextMenu({ window: contents });

is failing

Electron WebContents does not have addEventListener , instead (i guess) it has addListener

the thing that worked for me was changing the webContents function
by adding win.getType && win.getType() == 'webview' ? win :

to return win in case win is a webview

const webContents = win => win.getType && win.getType() == 'webview' ? win : win.webContents || (win.getWebContentsId && electron.remote.webContents.fromId(win.getWebContentsId()));

@sindresorhus can you please check this fork https://github.com/heitara/electron-context-menu.
Here is how to add it to you package.json:

"electron-context-menu": "github:heitara/electron-context-menu#feature/electron-11",
    "jquery": "^3.5.1",

@heitara I've tried adding this to my app but the problem still persists.

"electron-context-menu": "github:heitara/electron-context-menu#feature/electron-11",
"jquery": "^3.5.1",

Any ideas on how I can make it work? I really want a context menu for my app but I keep running into errors. The way I'm adding it is like this since I'm using webview:

app.on("web-contents-created", (e, contents) => {
  // Check for a webview
  if (contents.getType() == "webview") {
    contextMenu({
      window: contents,
      showSaveImageAs: true,
    });
  }
}); 

If I remove the window option my app does not crash but the context menu does not show either.

The error I keep receiving:
Error occurred in handler for 'ELECTRON_GUEST_VIEW_MANAGER_CREATE_GUEST': TypeError: win.addEventListener is not a function at module.exports

@jimodelid

You have to see the context menu.

This is from the context-menu docs:

'When not specified, the context menu will be added to all existing and new windows.'

@heitara

@jimodelid

You have to see the context menu.

This is from the context-menu docs:

'When not specified, the context menu will be added to all existing and new windows.'

That's what I figured, I've read the context menu several times. So by not defining the window it should show for all windows, but right-clicking does not work, the context menu is not showing.

I'm using macOS, not sure if the problem is related to macOS Big Sur?

I’ve used this as a reference too since he also had problems with the context menu but I still have the issue as mentioned above.

https://medium.com/@kofronmichael/how-to-add-a-context-menu-to-a-webview-in-electronjs-3bf86fd6863f

Maybe you can take a look at my code if I attach it here?

Please, create a dummy public project that illustrates the problem and publish item GitHub. Then share it here and I'll check it. Cheers!

Please, create a dummy public project that illustrates the problem and publish item GitHub. Then share it here and I'll check it. Cheers!

@heitara Here you go: https://github.com/jimodelid/dummy-context-menu

I've check the project and I've done the following things to check that it "works".

  1. I've added some text before the webview tag in index.html.
  2. I've updated the code
contextMenu({
      window: mainWindow,
      showSaveImageAs: true,
      showInspectElement: true,
    });

Once, you do right click, then you will see a menu on top of the text in the main index.html

So far, the problem is - the context menu is not activated for any of the sub-frames.
To make that work, you should "create" the context menu in the render process (here you can think of another JS that's part of the index.html like preload.js)
Screenshot 2020-12-13 at 22 41 17

meeq commented

Workaround:

contextMenu({
  /**
   * Work-around issue with passing `WebContents` to `electron-context-menu` in Electron 11
   * @see https://github.com/sindresorhus/electron-context-menu/issues/123
   */
  window: ({
    webContents: webContents,
    inspectElement: webContents.inspectElement.bind(webContents),
  } as unknown) as BrowserWindow,
})

Also worth noting:

inspectElement is not a method of BrowserWindow, but it is being called as one:

win.inspectElement(props.x, props.y);

However, inspectElement is available on WebContents and WebviewTag

Workaround:

contextMenu({
  /**
   * Work-around issue with passing `WebContents` to `electron-context-menu` in Electron 11
   * @see https://github.com/sindresorhus/electron-context-menu/issues/123
   */
  window: ({
    webContents: webContents,
    inspectElement: webContents.inspectElement.bind(webContents),
  } as unknown) as BrowserWindow,
})

Also worth noting:

inspectElement is not a method of BrowserWindow, but it is being called as one:

win.inspectElement(props.x, props.y);

However, inspectElement is available on WebContents and WebviewTag

Seems like this uses typescript which I’m not using, I have looked into the basic functions and are currently building my own functions, which seems easier since I’m not getting this module to work.

I’ve tried the previous post too but can’t seem to get anything to pop when I right click so building it myself seems like the easiest way to do.

No fix yet?

It works.

import contextMenu from 'electron-context-menu'

contextMenu()

app.on('web-contents-created', (_, contents) => {
  // Check for a webview
  if (contents.getType() === 'webview') {
    contextMenu({
      /**
       * Work-around issue with passing `WebContents` to `electron-context-menu` in Electron 11
       * @see https://github.com/sindresorhus/electron-context-menu/issues/123
       */
      window: ({
        webContents: contents,
        inspectElement: contents.inspectElement.bind(contents)
      } as unknown) as BrowserWindow
    })
  }
})

@jimodelid Javascript? It is as simple as removing type definitions.

import contextMenu from 'electron-context-menu'

contextMenu()

app.on('web-contents-created', (_, contents) => {
  // Check for a webview
  if (contents.getType() === 'webview') {
    contextMenu({
      /**
       * Work-around issue with passing `WebContents` to `electron-context-menu` in Electron 11
       * @see https://github.com/sindresorhus/electron-context-menu/issues/123
       */
      window: {
        webContents: contents,
        inspectElement: contents.inspectElement.bind(contents)
      }
    })
  }
})

Thanks @patarapolw - that works 👍