diff --git a/packages/electron-chrome-extensions/README.md b/packages/electron-chrome-extensions/README.md index ef8be088..9df2d8e3 100644 --- a/packages/electron-chrome-extensions/README.md +++ b/packages/electron-chrome-extensions/README.md @@ -219,6 +219,7 @@ To enable the element on a webpage, you must define a preload script which injec - `partition` string (optional) - The `Electron.Session` partition which extensions are loaded in. Defaults to the session in which `` lives. - `tab` string (optional) - The tab's `Electron.WebContents` ID to use for displaying the relevant browser action state. Defaults to the active tab of the current browser window. +- `alignment` string (optional) - How the popup window should be aligned relative to the extension action. Defaults to `bottom left`. Use any assortment of `top`, `bottom`, `left`, and `right`. #### Browser action example @@ -250,6 +251,10 @@ Add the `` element with attributes appropriate for your app + + + ``` ##### Custom CSS diff --git a/packages/electron-chrome-extensions/src/browser-action.ts b/packages/electron-chrome-extensions/src/browser-action.ts index 11792bb0..50ee0b17 100644 --- a/packages/electron-chrome-extensions/src/browser-action.ts +++ b/packages/electron-chrome-extensions/src/browser-action.ts @@ -19,6 +19,7 @@ export const injectBrowserAction = () => { extensionId: string tabId: number anchorRect: { x: number; y: number; width: number; height: number } + alignment?: string } const __browserAction__ = { @@ -115,8 +116,16 @@ export const injectBrowserAction = () => { } } + get alignment(): string { + return this.getAttribute('alignment') || '' + } + + set alignment(alignment: string) { + this.setAttribute('alignment', alignment) + } + static get observedAttributes() { - return ['id', 'tab', 'partition'] + return ['id', 'tab', 'partition', 'alignment'] } constructor() { @@ -156,6 +165,7 @@ export const injectBrowserAction = () => { eventType: event.type, extensionId: this.id, tabId: this.tab, + alignment: this.alignment, anchorRect: { x: rect.left, y: rect.top, @@ -280,8 +290,16 @@ export const injectBrowserAction = () => { } } + get alignment(): string { + return this.getAttribute('alignment') || '' + } + + set alignment(alignment: string) { + this.setAttribute('alignment', alignment) + } + static get observedAttributes() { - return ['tab', 'partition'] + return ['tab', 'partition', 'alignment'] } constructor() { @@ -413,12 +431,14 @@ export const injectBrowserAction = () => { }) as BrowserActionElement node.id = action.id node.className = 'action' + ;(node as any).alignment = this.alignment ;(node as any).part = 'action' browserActionNode = node this.shadowRoot?.appendChild(browserActionNode) } if (this.partition) browserActionNode.partition = this.partition + if (this.alignment) browserActionNode.alignment = this.alignment browserActionNode.tab = tabId } diff --git a/packages/electron-chrome-extensions/src/browser/api/browser-action.ts b/packages/electron-chrome-extensions/src/browser/api/browser-action.ts index f179d243..31780f6f 100644 --- a/packages/electron-chrome-extensions/src/browser/api/browser-action.ts +++ b/packages/electron-chrome-extensions/src/browser/api/browser-action.ts @@ -34,6 +34,7 @@ interface ActivateDetails { extensionId: string tabId: number anchorRect: { x: number; y: number; width: number; height: number } + alignment?: string } const getBrowserActionDefaults = (extension: Electron.Extension): ExtensionAction | undefined => { @@ -390,7 +391,7 @@ export class BrowserActionAPI { } private activateClick(details: ActivateDetails) { - const { extensionId, tabId, anchorRect } = details + const { extensionId, tabId, anchorRect, alignment } = details if (this.popup) { const toggleExtension = !this.popup.isDestroyed() && this.popup.extensionId === extensionId @@ -422,6 +423,7 @@ export class BrowserActionAPI { parent: win, url: popupUrl, anchorRect, + alignment, }) d(`opened popup: ${popupUrl}`) diff --git a/packages/electron-chrome-extensions/src/browser/popup.ts b/packages/electron-chrome-extensions/src/browser/popup.ts index 779edfe6..372428dc 100644 --- a/packages/electron-chrome-extensions/src/browser/popup.ts +++ b/packages/electron-chrome-extensions/src/browser/popup.ts @@ -16,6 +16,7 @@ interface PopupViewOptions { parent: Electron.BaseWindow url: string anchorRect: PopupAnchorRect + alignment?: string } const supportsPreferredSize = () => { @@ -40,6 +41,7 @@ export class PopupView { private anchorRect: PopupAnchorRect private destroyed: boolean = false private hidden: boolean = true + private alignment?: string /** Preferred size changes are only received in Electron v12+ */ private usingPreferredSize = supportsPreferredSize() @@ -50,6 +52,7 @@ export class PopupView { this.parent = opts.parent this.extensionId = opts.extensionId this.anchorRect = opts.anchorRect + this.alignment = opts.alignment this.browserWindow = new BrowserWindow({ show: false, @@ -200,10 +203,14 @@ export class PopupView { const winBounds = this.parent.getBounds() const viewBounds = this.browserWindow.getBounds() - // TODO: support more orientations than just top-right let x = winBounds.x + this.anchorRect.x + this.anchorRect.width - viewBounds.width let y = winBounds.y + this.anchorRect.y + this.anchorRect.height + PopupView.POSITION_PADDING + // If aligned to a differently then we need to offset the popup position + if (this.alignment?.includes('right')) x = winBounds.x + this.anchorRect.x + if (this.alignment?.includes('top')) + y = winBounds.y - viewBounds.height + this.anchorRect.y - PopupView.POSITION_PADDING + // Convert to ints x = Math.floor(x) y = Math.floor(y) diff --git a/packages/shell/browser/ui/webui.html b/packages/shell/browser/ui/webui.html index a3182f30..af78ce82 100644 --- a/packages/shell/browser/ui/webui.html +++ b/packages/shell/browser/ui/webui.html @@ -244,7 +244,7 @@
- +