diff --git a/src/actors/ClickHandlerChild.ts b/src/actors/ClickHandlerChild.ts new file mode 100644 index 0000000..aa368fd --- /dev/null +++ b/src/actors/ClickHandlerChild.ts @@ -0,0 +1,37 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/// + +export type ClickHandlerMessage = { + name: 'openlink' + data: { href: string } +} & { target: JSWindowActorParent } + +export class ClickHandlerChild extends JSWindowActorChild { + getHrefIfExists(target: Node): string | undefined { + if ((target as HTMLAnchorElement).href) { + return (target as HTMLAnchorElement).href + } + + if (target.parentElement) { + return this.getHrefIfExists(target.parentElement) + } + } + + handleEvent(event: MouseEvent) { + if (event.defaultPrevented || !event.target) return + + const href = this.getHrefIfExists(event.target as Node) + + const ctrlClick = event.button === 0 && event.ctrlKey + const middleClick = event.button === 1 + + const shouldOpenNewTab = href && (ctrlClick || middleClick) + + if (!shouldOpenNewTab) return + + this.sendAsyncMessage('openlink', { href }) + } +} diff --git a/src/actors/ClickHandlerParent.ts b/src/actors/ClickHandlerParent.ts new file mode 100644 index 0000000..fbc003c --- /dev/null +++ b/src/actors/ClickHandlerParent.ts @@ -0,0 +1,15 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +/// +import { ClickHandlerMessage } from './ClickHandlerChild' + +export class ClickHandlerParent extends JSWindowActorParent { + receiveMessage(event: ClickHandlerMessage) { + if (event.name == 'openlink') { + const win = event.target.browsingContext.embedderElement.ownerGlobal + const uri = Services.io.newURI(event.data.href) + win.windowApi.tabs.openTab(uri) + } + } +} diff --git a/src/actors/link.json b/src/actors/link.json index 758dc8a..3435b4d 100644 --- a/src/actors/link.json +++ b/src/actors/link.json @@ -1,4 +1,6 @@ [ + "ClickHandlerChild", + "ClickHandlerParent", "ContextMenuChild", "ContextMenuParent", "LinkHandlerChild", diff --git a/src/modules/BrowserGlue.ts b/src/modules/BrowserGlue.ts index e2b3acf..de848ac 100644 --- a/src/modules/BrowserGlue.ts +++ b/src/modules/BrowserGlue.ts @@ -10,6 +10,18 @@ const lazy = lazyESModuleGetters({ const JS_PROCESS_ACTORS = {} const JS_WINDOW_ACTORS = { + ClickHandler: { + parent: { esModuleURI: 'resource://app/actors/ClickHandlerParent.sys.mjs' }, + child: { + esModuleURI: 'resource://app/actors/ClickHandlerChild.sys.mjs', + events: { + chromelinkclick: { capture: true, mozSystemGroup: true }, + }, + }, + + allFrames: true, + }, + ContextMenu: { parent: { esModuleURI: 'resource://app/actors/ContextMenuParent.sys.mjs',