Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions src/extension/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,79 @@ export const internalActions = {
saveDocument,
};

/**
* Resizes the palette in the sender's tab.
* @param {Object} message The message object
* @param {string} message.id The palette ID to resize
* @param {Object} [message.rect] The rect object with properties width and/or height (CSS values)
* optional: top, left, right, bottom
* @param {chrome.runtime.MessageSender} sender The sender
* @returns {Promise<boolean>} True if palette was resized, else false
*/
async function resizePalette({
id, rect,
}, { tab }) {
if (!tab?.id) {
log.warn('resizePalette: no tab id');
return false;
}
if (!id) {
log.info('resizePalette: no palette id');
return false;
}
if (!rect || !rect.width || !rect.height) {
log.info('resizePalette: no rect properties provided');
return false;
}
try {
await chrome.tabs.sendMessage(tab.id, {
action: 'resize_palette',
id,
rect,
});
return true;
} catch (e) {
log.warn('resizePalette: failed to send message', e);
return false;
}
}

/**
* Resizes the popover in the sender's tab.
* @param {Object} message The message object
* @param {string} message.id The popover ID to resize
* @param {Object} [message.rect] The rect object with properties width and/or height (CSS values)
* @param {chrome.runtime.MessageSender} sender The sender
* @returns {Promise<boolean>} True if popover was resized, else false
*/
async function resizePopover({
id, rect,
}, { tab }) {
if (!tab?.id) {
log.warn('resizePopover: no tab id');
return false;
}
if (!id) {
log.info('resizePopover: no popover id');
return false;
}
if (!rect || !rect.width || !rect.height) {
log.info('resizePopover: no rect properties');
return false;
}
try {
await chrome.tabs.sendMessage(tab.id, {
action: 'resize_popover',
id,
rect,
});
return true;
} catch (e) {
log.warn('resizePopover: failed to send message', e);
return false;
}
}

/**
* Actions which can be executed via external messaging API.
* @type {Object} The external actions
Expand All @@ -643,6 +716,8 @@ export const externalActions = {
updateSite,
removeSite,
updateAuthToken,
resizePalette,
resizePopover,
closePalette,
closePopover,
};
16 changes: 14 additions & 2 deletions src/extension/app/aem-sidekick.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ import { AppStore, appStoreContext } from './store/app.js';
import {
ALLOWED_EXTENSION_IDS, EVENTS, EXTERNAL_EVENTS, MODALS,
} from './constants.js';
import { detectBrowser } from './utils/browser.js';
import { EventBus } from './utils/event-bus.js';
import { detectBrowser, rectToStyles } from './utils/browser.js';
import { getConfig } from '../config.js';
import { EventBus } from './utils/event-bus.js';

@customElement('aem-sidekick')
export class AEMSidekick extends LitElement {
Expand Down Expand Up @@ -81,6 +81,18 @@ export class AEMSidekick extends LitElement {
confirmCallback: (response) => { sendResponse(response); },
},
});
} else if (msg.action === 'resize_palette') {
const { id, rect } = msg;
EventBus.instance.dispatchEvent(new CustomEvent(EVENTS.RESIZE_PALETTE, {
detail: { id, styles: rectToStyles(rect) },
}));
sendResponse(true);
} else if (msg.action === 'resize_popover') {
const { id, rect } = msg;
EventBus.instance.dispatchEvent(new CustomEvent(EVENTS.RESIZE_POPOVER, {
detail: { id, styles: rectToStyles(rect) },
}));
sendResponse(true);
} else if (msg.action === 'close_palette') {
EventBus.instance.dispatchEvent(new CustomEvent(EVENTS.CLOSE_PALETTE, {
detail: { id: msg.id },
Expand Down
11 changes: 11 additions & 0 deletions src/extension/app/components/plugin/palette-container.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,16 @@ export class PaletteContainer extends ConnectedElement {
this.plugin = e.detail.plugin;
});

EventBus.instance.addEventListener(EVENTS.RESIZE_PALETTE, async (e) => {
const { id, styles } = e.detail;
if (this.plugin?.id === id) {
const paletteContainer = await this.container;
if (paletteContainer && styles) {
paletteContainer.setAttribute('style', styles);
}
}
});

EventBus.instance.addEventListener(EVENTS.CLOSE_PALETTE, (e) => {
const { id } = e.detail || {};
// Only close palette if ID matches
Expand All @@ -128,6 +138,7 @@ export class PaletteContainer extends ConnectedElement {
disconnectedCallback() {
super.disconnectedCallback();
EventBus.instance.removeEventListener(EVENTS.OPEN_PALETTE);
EventBus.instance.removeEventListener(EVENTS.RESIZE_PALETTE);
EventBus.instance.removeEventListener(EVENTS.CLOSE_PALETTE);
this.removeEventListener('keydown', this.onKeyDown);
}
Expand Down
41 changes: 33 additions & 8 deletions src/extension/app/components/plugin/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@

import { html } from 'lit';
import { ifDefined } from 'lit/directives/if-defined.js';
import { EXTERNAL_EVENTS } from '../../constants.js';
import { EVENTS, EXTERNAL_EVENTS } from '../../constants.js';
import { EventBus } from '../../utils/event-bus.js';

/**
* @typedef {import('@spectrum-web-components/popover').Popover} Popover
Expand Down Expand Up @@ -69,7 +70,7 @@ export class Plugin {
config;

/**
* Reference to the popover element for closing
* Reference to the popover element for resizing and closing
* @type {Popover}
*/
popoverElement;
Expand All @@ -79,6 +80,34 @@ export class Plugin {
this.disabled = false;
this.config = plugin;
this.id = plugin.id;

// Listen for popover resize events
if (this.isPopover()) {
EventBus.instance.addEventListener(EVENTS.RESIZE_POPOVER, (e) => {
if (!this.popoverElement || !this.popoverElement.open) {
return;
}
const { id, styles } = e.detail;
if (this.id === id && styles) {
this.popoverElement.setAttribute('style', this.#filterUserStyles(styles));
// Re-render
this.popoverElement.open = true;
}
});
}
}

/**
* Filters out unsupported user-provided styles.
* @param {string} styles The user-provided styles
* @return {string} The filtered styles
*/
#filterUserStyles(styles = '') {
return `${styles
.split(';')
.map((s) => s.trim())
.filter((s) => s.startsWith('width:') || s.startsWith('height:'))
.join('; ')};`;
}

/**
Expand Down Expand Up @@ -260,13 +289,9 @@ export class Plugin {

const popoverTitle = titleI18n?.[this.appStore.siteStore.lang] || title;

let filteredPopoverRect = popoverRect;
let filteredPopoverRect;
if (popoverRect) {
filteredPopoverRect = `${popoverRect
.split(';')
.map((s) => s.trim())
.filter((s) => s.startsWith('width:') || s.startsWith('height:'))
.join('; ')};`;
filteredPopoverRect = this.#filterUserStyles(popoverRect);
}

return html`
Expand Down
2 changes: 2 additions & 0 deletions src/extension/app/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ export const EVENTS = {
OPEN_PALETTE: 'open-palette',
CLOSE_PALETTE: 'close-palette',
CLOSE_POPOVER: 'close-popover',
RESIZE_PALETTE: 'resize-palette',
RESIZE_POPOVER: 'resize-popover',
};

/**
Expand Down
17 changes: 17 additions & 0 deletions src/extension/app/utils/browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -247,3 +247,20 @@ export function isErrorPage(location, document) {
&& !document.querySelector('body > main > div')
&& document.querySelector('body > pre'));
}

/**
* Converts a rect object to a style string.
* Only width, height, top, left, right, and bottom properties are accepted.
* @param {Object} rect The rect object
* @returns {string} The style string
*/
export function rectToStyles(rect) {
if (!rect || typeof rect !== 'object' || Object.keys(rect).length === 0) {
return '';
}
return Object
.entries(rect)
.filter(([key]) => ['width', 'height', 'top', 'left', 'right', 'bottom'].includes(key))
.map(([key, value]) => `${key}: ${value}`)
.join('; ');
}
Loading