diff --git a/src/content/browser/components/omnibox/PageAction.svelte b/src/content/browser/components/omnibox/PageAction.svelte index 520a12d..6534ad1 100644 --- a/src/content/browser/components/omnibox/PageAction.svelte +++ b/src/content/browser/components/omnibox/PageAction.svelte @@ -5,10 +5,108 @@ - + + +{#if pageAction.popupUrl} + +{/if} + + diff --git a/src/content/browser/lib/xul/browser.ts b/src/content/browser/lib/xul/browser.ts index 52458bd..d2b05f0 100644 --- a/src/content/browser/lib/xul/browser.ts +++ b/src/content/browser/lib/xul/browser.ts @@ -39,19 +39,32 @@ export function getBrowserRemoteType(uri: nsIURIType) { ) } -export function createBrowser({ remoteType }: { remoteType?: string } = {}) { +export function createBrowser({ + remoteType, + attributes, +}: { + remoteType?: string + attributes?: { + disableglobalhistory?: string + messagemanagergroup?: string + ['webextension-view-type']?: string + } +} = {}): XULBrowserElement { const browser = document.createXULElement('browser') if (remoteType) { browser.setAttribute('remoteType', remoteType) browser.setAttribute('remote', true) } - for (const attribute in DEFAULT_BROWSER_ATTRIBUTES) + const mergedAttributes = { + ...DEFAULT_BROWSER_ATTRIBUTES, + ...(attributes || {}), + } + + for (const attribute in mergedAttributes) browser.setAttribute( attribute, - DEFAULT_BROWSER_ATTRIBUTES[ - attribute as keyof typeof DEFAULT_BROWSER_ATTRIBUTES - ], + mergedAttributes[attribute as keyof typeof mergedAttributes], ) if (useRemoteTabs) browser.setAttribute('maychangeremoteness', 'true') diff --git a/src/content/shared/xul/messageReciver.ts b/src/content/shared/xul/messageReciver.ts new file mode 100644 index 0000000..ee6e90f --- /dev/null +++ b/src/content/shared/xul/messageReciver.ts @@ -0,0 +1,10 @@ +export class MessageReviver< + Cb extends (argument: ReceiveMessageArgument) => unknown, +> implements MessageListener +{ + receiveMessage: Cb + + constructor(callback: Cb) { + this.receiveMessage = callback + } +} diff --git a/src/link.d.ts b/src/link.d.ts index 7c80def..cc7a2db 100644 --- a/src/link.d.ts +++ b/src/link.d.ts @@ -6,6 +6,9 @@ /// +/// +/// + declare module 'resource://app/modules/FaviconLoader.sys.mjs' { export const FaviconLoader: typeof import('./modules/FaviconLoader').FaviconLoader } @@ -82,6 +85,8 @@ declare interface XULBrowserElement extends HTMLElement { docShell: unknown swapDocShells(aOtherBrowser: XULBrowserElement) + + messageManager: ChromeMessageSender } declare interface XULFindBarElement extends HTMLElement { @@ -632,97 +637,3 @@ declare module ChromeUtils { ): T } -interface MatchPatternOptions { - /** - * If true, the path portion of the pattern is ignored, and replaced with a - * wildcard. The `pattern` property is updated to reflect this. - */ - ignorePath?: boolean - - /** - * If true, the set of schemes this pattern can match is restricted to - * those accessible by WebExtensions. - */ - restrictSchemes?: boolean -} - -interface MatchPattern { - // eslint-disable-next-line @typescript-eslint/no-misused-new - constructor(pattern: string, options?: MatchPatternOptions) - - /** - * Returns true if the given URI matches the pattern. - * - * If explicit is true, only explicit domain matches, without wildcards, are - * considered. - */ - matches(uri: URI, explicit?: boolean): boolean - matches(url: string, explicit?: boolean): boolean - - /** - * Returns true if a URL exists which a) would be able to access the given - * cookie, and b) would be matched by this match pattern. - */ - matchesCookie(cookie: Cookie): boolean - - /** - * Returns true if this pattern will match any host which would be matched - * by the given pattern. - */ - subsumes(pattern: MatchPattern): boolean - - /** - * Returns true if this pattern will match any host which would be matched - * by the given pattern, ignoring the scheme. - */ - subsumesDomain(pattern: MatchPattern): boolean - - /** - * Returns true if there is any host which would be matched by both this - * pattern and the given pattern. - */ - overlaps(pattern: MatchPattern): boolean - - /** - * The match pattern string represented by this pattern. - */ - readonly pattern: string - - /** - * Whether the match pattern matches all http(s) URLs. - */ - readonly matchesAllWebUrls: boolean -} - -class MatchPatternSet { - // eslint-disable-next-line @typescript-eslint/no-misused-new - constructor( - patterns: Array, - options?: MatchPatternOptions, - ) - - matches(uri: URI, explicit?: boolean): boolean - matches(url: string, explicit?: boolean): boolean - - matchesCookie(cookie: Cookie): boolean - - subsumes(pattern: MatchPattern): boolean - - subsumesDomain(pattern: MatchPattern): boolean - - overlaps(pattern: MatchPattern): boolean - - overlaps(patternSet: MatchPatternSet): boolean - - overlapsAll(patternSet: MatchPatternSet): boolean - - readonly patterns: Array - - readonly matchesAllWebUrls: boolean -} - -declare global { - interface Window { - MatchPatternSet: typeof MatchPatternSet - } -} diff --git a/src/types/MatchPattern.d.ts b/src/types/MatchPattern.d.ts new file mode 100644 index 0000000..00d8e66 --- /dev/null +++ b/src/types/MatchPattern.d.ts @@ -0,0 +1,94 @@ +interface MatchPatternOptions { + /** + * If true, the path portion of the pattern is ignored, and replaced with a + * wildcard. The `pattern` property is updated to reflect this. + */ + ignorePath?: boolean + + /** + * If true, the set of schemes this pattern can match is restricted to + * those accessible by WebExtensions. + */ + restrictSchemes?: boolean +} + +interface MatchPattern { + // eslint-disable-next-line @typescript-eslint/no-misused-new + constructor(pattern: string, options?: MatchPatternOptions) + + /** + * Returns true if the given URI matches the pattern. + * + * If explicit is true, only explicit domain matches, without wildcards, are + * considered. + */ + matches(uri: URI, explicit?: boolean): boolean + matches(url: string, explicit?: boolean): boolean + + /** + * Returns true if a URL exists which a) would be able to access the given + * cookie, and b) would be matched by this match pattern. + */ + matchesCookie(cookie: Cookie): boolean + + /** + * Returns true if this pattern will match any host which would be matched + * by the given pattern. + */ + subsumes(pattern: MatchPattern): boolean + + /** + * Returns true if this pattern will match any host which would be matched + * by the given pattern, ignoring the scheme. + */ + subsumesDomain(pattern: MatchPattern): boolean + + /** + * Returns true if there is any host which would be matched by both this + * pattern and the given pattern. + */ + overlaps(pattern: MatchPattern): boolean + + /** + * The match pattern string represented by this pattern. + */ + readonly pattern: string + + /** + * Whether the match pattern matches all http(s) URLs. + */ + readonly matchesAllWebUrls: boolean +} + +class MatchPatternSet { + // eslint-disable-next-line @typescript-eslint/no-misused-new + constructor( + patterns: Array, + options?: MatchPatternOptions, + ) + + matches(uri: URI, explicit?: boolean): boolean + matches(url: string, explicit?: boolean): boolean + + matchesCookie(cookie: Cookie): boolean + + subsumes(pattern: MatchPattern): boolean + + subsumesDomain(pattern: MatchPattern): boolean + + overlaps(pattern: MatchPattern): boolean + + overlaps(patternSet: MatchPatternSet): boolean + + overlapsAll(patternSet: MatchPatternSet): boolean + + readonly patterns: Array + + readonly matchesAllWebUrls: boolean +} + +declare global { + interface Window { + MatchPatternSet: typeof MatchPatternSet + } +} diff --git a/src/types/MessageManager.d.ts b/src/types/MessageManager.d.ts new file mode 100644 index 0000000..daac8e1 --- /dev/null +++ b/src/types/MessageManager.d.ts @@ -0,0 +1,135 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/// + +type nsIEventTarget = nsIEventTargetType +interface Principal {} + +type nsISupports = nsISupportsType + +interface FrameLoader {} + +interface MessagePort {} + +declare interface ReceiveMessageArgument { + target: nsISupports + name: string + sync: boolean + data?: any + json?: any + ports: MessagePort[] + targetFrameLoader?: FrameLoader +} + +declare interface MessageListener { + receiveMessage(argument: ReceiveMessageArgument): any +} + +declare interface MessageListenerManagerMixin { + addMessageListener( + messageName: string, + listener: MessageListener, + listenWhenClosed?: boolean, + ): void + removeMessageListener(messageName: string, listener: MessageListener): void + addWeakMessageListener(messageName: string, listener: MessageListener): void + removeWeakMessageListener( + messageName: string, + listener: MessageListener, + ): void +} + +declare interface MessageListenerManager extends MessageListenerManagerMixin {} + +declare interface MessageSenderMixin { + sendAsyncMessage(messageName?: string, obj?: any, transfers?: any): void + readonly processMessageManager?: MessageSender + readonly remoteType: string +} + +declare interface MessageSender + extends MessageListenerManager, + MessageSenderMixin {} + +declare interface SyncMessageSenderMixin { + sendSyncMessage(messageName?: string, obj?: any): any[] +} + +declare interface SyncMessageSender + extends MessageSender, + SyncMessageSenderMixin {} + +declare interface ChildProcessMessageManager extends SyncMessageSender {} + +declare interface MessageManagerGlobal { + dump(str: string): void + atob(asciiString: string): string + btoa(base64Data: string): string +} + +declare interface FrameScriptLoader { + loadFrameScript( + url: string, + allowDelayedLoad: boolean, + runInGlobalScope?: boolean, + ): void + removeDelayedFrameScript(url: string): void + getDelayedFrameScripts(): any[][] +} + +declare interface ProcessScriptLoader { + loadProcessScript(url: string, allowDelayedLoad: boolean): void + removeDelayedProcessScript(url: string): void + getDelayedProcessScripts(): any[][] +} + +declare interface GlobalProcessScriptLoader { + readonly initialProcessData: any + readonly sharedData: any +} + +declare interface ContentFrameMessageManager + extends EventTarget, + MessageManagerGlobal, + SyncMessageSenderMixin, + MessageSenderMixin, + MessageListenerManagerMixin { + readonly content?: Window + readonly docShell?: any + readonly tabEventTarget?: nsIEventTarget +} + +declare interface ContentProcessMessageManager + extends MessageManagerGlobal, + SyncMessageSenderMixin, + MessageSenderMixin, + MessageListenerManagerMixin { + readonly initialProcessData: any + readonly sharedData?: any +} + +declare interface MessageBroadcaster extends MessageListenerManager { + broadcastAsyncMessage(messageName?: string, obj?: any): void + readonly childCount: number + getChildAt(aIndex: number): MessageListenerManager | null + releaseCachedProcesses(): void +} + +declare interface ChromeMessageBroadcaster + extends MessageBroadcaster, + FrameScriptLoader {} + +declare interface ParentProcessMessageManager + extends MessageBroadcaster, + ProcessScriptLoader, + GlobalProcessScriptLoader {} + +declare interface ChromeMessageSender + extends MessageSender, + FrameScriptLoader {} + +declare interface ProcessMessageManager + extends MessageSender, + ProcessScriptLoader { + readonly osPid: number + readonly isInProcess: boolean +}