Skip to content

Commit

Permalink
✨ Control & middle click to open links in new tabs
Browse files Browse the repository at this point in the history
  • Loading branch information
trickypr committed Dec 29, 2023
1 parent faf55ad commit cdfdbfe
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 0 deletions.
37 changes: 37 additions & 0 deletions src/actors/ClickHandlerChild.ts
Original file line number Diff line number Diff line change
@@ -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/. */

/// <reference path="../link.d.ts" />

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 })
}
}
15 changes: 15 additions & 0 deletions src/actors/ClickHandlerParent.ts
Original file line number Diff line number Diff line change
@@ -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/. */
/// <reference path="../link.d.ts" />
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)
}
}
}
2 changes: 2 additions & 0 deletions src/actors/link.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
[
"ClickHandlerChild",
"ClickHandlerParent",
"ContextMenuChild",
"ContextMenuParent",
"LinkHandlerChild",
Expand Down
12 changes: 12 additions & 0 deletions src/modules/BrowserGlue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down

0 comments on commit cdfdbfe

Please sign in to comment.