Skip to content

Commit

Permalink
🚸 Assorted new tab fixes (#43)
Browse files Browse the repository at this point in the history
  • Loading branch information
trickypr authored Dec 29, 2023
1 parent b09dea0 commit c2e1dcc
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 6 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
9 changes: 7 additions & 2 deletions src/content/browser/lib/window/tab.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,12 @@ export class Tab {
public hidden = writable(false)

constructor(uri: nsIURIType) {
this.uri = viewableWritable(uri)
this.goToUri(uri)
this.browserElement = createBrowser({
remoteType: getBrowserRemoteType(uri),
})

this.uri = viewableWritable(uri)
this.goToUri(uri)
this.title.set(uri.asciiHost)

this.uri.subscribe(async (uri) =>
Expand All @@ -79,6 +80,10 @@ export class Tab {
return this.tabId || 0
}

public getBrowserElement() {
return this.browserElement
}

public getDragRepresentation() {
return {
windowId: window.windowApi.id,
Expand Down
33 changes: 29 additions & 4 deletions src/content/browser/lib/xul/NSBrowserAccess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,22 @@

/* eslint-disable @typescript-eslint/no-unused-vars */

export enum OpenWhere {
DefaultWindow = 0,
CurrentWindow = 1,
NewWindow = 2,
NewTab = 3,
PrintBrowser = 4,
}

export enum OpenFlags {
New = 0x0,
/** Open was triggered by a thirdparty application */
External = 0x1,
NoOpener = 0x4,
NoReferer = 0x8,
}

export class NSBrowserAccess {
createContentWindow(
aURI: nsIURIType,
Expand All @@ -15,15 +31,24 @@ export class NSBrowserAccess {
) {
throw new Error('Method not implemented.')
}

createContentWindowInFrame(
aURI: nsIURIType,
params: nsIOpenURIInFrameParamsType,
aWhere: number,
aFlags: number,
aName: string,
): Element {
throw new Error('Method not implemented.')
): Element | null {
if (aWhere !== OpenWhere.NewTab) {
console.warn('NSBrowserAccess: Only OpenWhere.NewTab is supported')
return null
}

// TODO: Handle params
// TODO: Handle unhandled arguments (see nsIBrowserDOMWindow)
const tab = window.windowApi.tabs.openTab(aURI)
const browser = tab.getBrowserElement()
return browser
}

openURI(
aURI: nsIURIType,
aOpenWindowInfo: nsIOpenWindowInfoType,
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 c2e1dcc

Please sign in to comment.