Skip to content

Commit 255a923

Browse files
feat: browser action list positioning (#115)
* feat: browser action list positioning * readme updated * alignment property change * revise docs --------- Co-authored-by: Samuel Maddock <[email protected]>
1 parent 59f67a9 commit 255a923

File tree

5 files changed

+39
-5
lines changed

5 files changed

+39
-5
lines changed

packages/electron-chrome-extensions/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ To enable the element on a webpage, you must define a preload script which injec
215215
- `partition` string (optional) - The `Electron.Session` partition which extensions are loaded in. Defaults to the session in which `<browser-action-list>` lives.
216216
- `tab` string (optional) - The tab's `Electron.WebContents` ID to use for displaying
217217
the relevant browser action state. Defaults to the active tab of the current browser window.
218+
- `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`.
218219
219220
#### Browser action example
220221
@@ -246,6 +247,10 @@ Add the `<browser-action-list>` element with attributes appropriate for your app
246247

247248
<!-- Show actions for custom session and a specific tab of current window. -->
248249
<browser-action-list partition="persist:custom" tab="1"></browser-action-list>
250+
251+
<!-- If extensions are displayed in the bottom left of your browser UI, then
252+
you can align the popup to the top right of the extension action. -->
253+
<browser-action-list alignment="top right"></browser-action-list>
249254
```
250255
251256
##### Custom CSS

packages/electron-chrome-extensions/src/browser-action.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export const injectBrowserAction = () => {
1919
extensionId: string
2020
tabId: number
2121
anchorRect: { x: number; y: number; width: number; height: number }
22+
alignment?: string
2223
}
2324

2425
const __browserAction__ = {
@@ -115,8 +116,16 @@ export const injectBrowserAction = () => {
115116
}
116117
}
117118

119+
get alignment(): string {
120+
return this.getAttribute('alignment') || ''
121+
}
122+
123+
set alignment(alignment: string) {
124+
this.setAttribute('alignment', alignment)
125+
}
126+
118127
static get observedAttributes() {
119-
return ['id', 'tab', 'partition']
128+
return ['id', 'tab', 'partition', 'alignment']
120129
}
121130

122131
constructor() {
@@ -156,6 +165,7 @@ export const injectBrowserAction = () => {
156165
eventType: event.type,
157166
extensionId: this.id,
158167
tabId: this.tab,
168+
alignment: this.alignment,
159169
anchorRect: {
160170
x: rect.left,
161171
y: rect.top,
@@ -280,8 +290,16 @@ export const injectBrowserAction = () => {
280290
}
281291
}
282292

293+
get alignment(): string {
294+
return this.getAttribute('alignment') || ''
295+
}
296+
297+
set alignment(alignment: string) {
298+
this.setAttribute('alignment', alignment)
299+
}
300+
283301
static get observedAttributes() {
284-
return ['tab', 'partition']
302+
return ['tab', 'partition', 'alignment']
285303
}
286304

287305
constructor() {
@@ -413,12 +431,14 @@ export const injectBrowserAction = () => {
413431
}) as BrowserActionElement
414432
node.id = action.id
415433
node.className = 'action'
434+
;(node as any).alignment = this.alignment
416435
;(node as any).part = 'action'
417436
browserActionNode = node
418437
this.shadowRoot?.appendChild(browserActionNode)
419438
}
420439

421440
if (this.partition) browserActionNode.partition = this.partition
441+
if (this.alignment) browserActionNode.alignment = this.alignment
422442
browserActionNode.tab = tabId
423443
}
424444

packages/electron-chrome-extensions/src/browser/api/browser-action.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ interface ActivateDetails {
3535
extensionId: string
3636
tabId: number
3737
anchorRect: { x: number; y: number; width: number; height: number }
38+
alignment?: string
3839
}
3940

4041
const getBrowserActionDefaults = (extension: Electron.Extension): ExtensionAction | undefined => {
@@ -391,7 +392,7 @@ export class BrowserActionAPI {
391392
}
392393

393394
private activateClick(details: ActivateDetails) {
394-
const { extensionId, tabId, anchorRect } = details
395+
const { extensionId, tabId, anchorRect, alignment } = details
395396

396397
if (this.popup) {
397398
const toggleExtension = !this.popup.isDestroyed() && this.popup.extensionId === extensionId
@@ -423,6 +424,7 @@ export class BrowserActionAPI {
423424
parent: win,
424425
url: popupUrl,
425426
anchorRect,
427+
alignment,
426428
})
427429

428430
d(`opened popup: ${popupUrl}`)

packages/electron-chrome-extensions/src/browser/popup.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ interface PopupViewOptions {
1717
parent: Electron.BaseWindow
1818
url: string
1919
anchorRect: PopupAnchorRect
20+
alignment?: string
2021
}
2122

2223
const supportsPreferredSize = () => {
@@ -41,6 +42,7 @@ export class PopupView {
4142
private anchorRect: PopupAnchorRect
4243
private destroyed: boolean = false
4344
private hidden: boolean = true
45+
private alignment?: string
4446

4547
/** Preferred size changes are only received in Electron v12+ */
4648
private usingPreferredSize = supportsPreferredSize()
@@ -51,6 +53,7 @@ export class PopupView {
5153
this.parent = opts.parent
5254
this.extensionId = opts.extensionId
5355
this.anchorRect = opts.anchorRect
56+
this.alignment = opts.alignment
5457

5558
this.browserWindow = new BrowserWindow({
5659
show: false,
@@ -201,10 +204,14 @@ export class PopupView {
201204
const winBounds = this.parent.getBounds()
202205
const viewBounds = this.browserWindow.getBounds()
203206

204-
// TODO: support more orientations than just top-right
205207
let x = winBounds.x + this.anchorRect.x + this.anchorRect.width - viewBounds.width
206208
let y = winBounds.y + this.anchorRect.y + this.anchorRect.height + PopupView.POSITION_PADDING
207209

210+
// If aligned to a differently then we need to offset the popup position
211+
if (this.alignment?.includes('right')) x = winBounds.x + this.anchorRect.x
212+
if (this.alignment?.includes('top'))
213+
y = winBounds.y - viewBounds.height + this.anchorRect.y - PopupView.POSITION_PADDING
214+
208215
// Convert to ints
209216
x = Math.floor(x)
210217
y = Math.floor(y)

packages/shell/browser/ui/webui.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@
244244
<div class="address-bar">
245245
<input id="addressurl" spellcheck="false" />
246246
</div>
247-
<browser-action-list id="actions"></browser-action-list>
247+
<browser-action-list id="actions" alignment="bottom left"></browser-action-list>
248248
</div>
249249
</div>
250250
</div>

0 commit comments

Comments
 (0)