diff --git a/packages/app-desktop/ElectronAppWrapper.ts b/packages/app-desktop/ElectronAppWrapper.ts index 7351c80dd18..266fe35651b 100644 --- a/packages/app-desktop/ElectronAppWrapper.ts +++ b/packages/app-desktop/ElectronAppWrapper.ts @@ -412,6 +412,7 @@ export default class ElectronAppWrapper { action: 'allow', overrideBrowserWindowOptions: { webPreferences: { + nodeIntegration: false, preload: resolve(__dirname, './utils/window/secondaryWindowPreload.js'), }, }, diff --git a/packages/app-desktop/gui/NewWindowOrIFrame.tsx b/packages/app-desktop/gui/NewWindowOrIFrame.tsx index d7e9acc3054..2eb87fde53f 100644 --- a/packages/app-desktop/gui/NewWindowOrIFrame.tsx +++ b/packages/app-desktop/gui/NewWindowOrIFrame.tsx @@ -44,6 +44,12 @@ const useDocument = ( setDoc(iframeElement?.contentWindow?.document); } else if (mode === WindowMode.NewWindow) { openedWindow = window.open('about:blank'); + + // Required to support TinyMCE: + openedWindow.document.open(); + openedWindow.document.write(''); + openedWindow.document.close(); + setDoc(openedWindow.document); // .onbeforeunload and .onclose events don't seem to fire when closed by a user -- rely on polling diff --git a/packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/useContextMenu.ts b/packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/useContextMenu.ts index e296408582b..745d835bd78 100644 --- a/packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/useContextMenu.ts +++ b/packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/useContextMenu.ts @@ -16,6 +16,9 @@ import { menuItems } from '../../../utils/contextMenu'; import isItemId from '@joplin/lib/models/utils/isItemId'; import { extractResourceUrls } from '@joplin/lib/urlUtils'; import { WindowIdContext } from '../../../../NewWindowOrIFrame'; +import Logger from '@joplin/utils/Logger'; + +const logger = Logger.create('useContextMenu'); export type ResourceMarkupType = 'image' | 'file'; @@ -355,11 +358,21 @@ const useContextMenu = (props: ContextMenuProps) => { // Prepend the event listener so that it gets called before // the listener that shows the default menu. - targetWindow.webContents.prependListener('context-menu', onContextMenu); + try { + targetWindow.webContents.prependListener('context-menu', onContextMenu); + } catch (error) { + logger.warn('Error registering menu', error); + } return () => { - if (!targetWindow.isDestroyed()) { - targetWindow.webContents.off('context-menu', onContextMenu); + try { + if (!targetWindow.isDestroyed()) { + targetWindow.webContents.off('context-menu', onContextMenu); + } + } catch (error) { + // This can happen if the window closes after the isDestroyed check, but before webContents.off + // finishes running. + logger.warn('Error removing menu listener', error); } }; }, [ diff --git a/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useContextMenu.ts b/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useContextMenu.ts index 6f900ef3e51..51210f31361 100644 --- a/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useContextMenu.ts +++ b/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useContextMenu.ts @@ -19,6 +19,9 @@ import { _ } from '@joplin/lib/locale'; import type { MenuItem as MenuItemType } from 'electron'; import isItemId from '@joplin/lib/models/utils/isItemId'; import { WindowIdContext } from '../../../../NewWindowOrIFrame'; +import Logger from '@joplin/utils/Logger'; + +const logger = Logger.create('useContextMenu'); const Menu = bridge().Menu; const MenuItem = bridge().MenuItem; @@ -157,13 +160,24 @@ export default function(editor: Editor, plugins: PluginStates, dispatch: Dispatc } }; - targetWindow.webContents.prependListener('context-menu', onElectronContextMenu); + try { + targetWindow.webContents.prependListener('context-menu', onElectronContextMenu); + } catch (error) { + logger.error('Failed to register context menu', error); + } editor.on('contextmenu', onBrowserContextMenu); return () => { editor.off('contextmenu', onBrowserContextMenu); - if (!targetWindow.isDestroyed() && targetWindow?.webContents?.off) { - targetWindow.webContents.off('context-menu', onElectronContextMenu); + + try { + if (!targetWindow.isDestroyed() && targetWindow?.webContents?.off) { + targetWindow.webContents.off('context-menu', onElectronContextMenu); + } + } catch (error) { + // This can happen if the window closes after the isDestroyed check, but before webContents.off + // finishes running. + logger.error('Error removing context menu listener', error); } }; }, [editor, plugins, dispatch, htmlToMd, mdToHtml, editDialog, windowId]);