mirror of
https://github.com/penpot/penpot-plugins.git
synced 2025-01-06 14:50:21 -05:00
fix: multi plugin dev support
This commit is contained in:
parent
8e7a44c5be
commit
50d11177a6
4 changed files with 48 additions and 12 deletions
|
@ -33,7 +33,7 @@ export const validEvents = [
|
|||
|
||||
export let uiMessagesCallbacks: Callback<unknown>[] = [];
|
||||
|
||||
let modal: PluginModalElement | null = null;
|
||||
let modals = new Set<PluginModalElement>([]);
|
||||
|
||||
const eventListeners: Map<string, Callback<unknown>[]> = new Map();
|
||||
|
||||
|
@ -47,17 +47,23 @@ export function triggerEvent(
|
|||
type: keyof EventsMap,
|
||||
message: EventsMap[keyof EventsMap]
|
||||
) {
|
||||
if (type === 'themechange' && modal) {
|
||||
modal.setTheme(message as PenpotTheme);
|
||||
if (type === 'themechange') {
|
||||
modals.forEach((modal) => {
|
||||
modal.setTheme(message as PenpotTheme);
|
||||
});
|
||||
}
|
||||
const listeners = eventListeners.get(type) || [];
|
||||
listeners.forEach((listener) => listener(message));
|
||||
}
|
||||
|
||||
export function createApi(context: PenpotContext, manifest: Manifest): Penpot {
|
||||
let modal: PluginModalElement | null = null;
|
||||
|
||||
const closePlugin = () => {
|
||||
modal?.removeEventListener('close', closePlugin);
|
||||
if (modal) {
|
||||
modals.delete(modal);
|
||||
|
||||
modal.removeEventListener('close', closePlugin);
|
||||
modal.remove();
|
||||
}
|
||||
uiMessagesCallbacks = [];
|
||||
|
@ -87,6 +93,8 @@ export function createApi(context: PenpotContext, manifest: Manifest): Penpot {
|
|||
modal.addEventListener('close', closePlugin, {
|
||||
once: true,
|
||||
});
|
||||
|
||||
modals.add(modal);
|
||||
},
|
||||
|
||||
sendMessage(message: unknown) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
export const dragHandler = (el: HTMLElement) => {
|
||||
export const dragHandler = (el: HTMLElement, move?: () => void) => {
|
||||
let currentTranslate = { x: 0, y: 0 };
|
||||
let initialTranslate = { x: 0, y: 0 };
|
||||
let initialClientPosition = { x: 0, y: 0 };
|
||||
|
@ -11,6 +11,8 @@ export const dragHandler = (el: HTMLElement) => {
|
|||
currentTranslate = { x: deltaX, y: deltaY };
|
||||
|
||||
el.style.transform = `translate(${deltaX}px, ${deltaY}px)`;
|
||||
|
||||
move?.();
|
||||
};
|
||||
|
||||
const handleMouseUp = () => {
|
||||
|
|
|
@ -5,7 +5,8 @@ import { loadManifest, loadManifestCode } from './parse-manifest.js';
|
|||
import { Manifest } from './models/manifest.model.js';
|
||||
|
||||
let isLockedDown = false;
|
||||
let lastApi: ReturnType<typeof createApi> | undefined;
|
||||
let createdApis: ReturnType<typeof createApi>[] = [];
|
||||
const multiPlugin = false;
|
||||
|
||||
let pluginContext: PenpotContext | null = null;
|
||||
|
||||
|
@ -22,15 +23,18 @@ export const ɵloadPlugin = async function (manifest: Manifest) {
|
|||
hardenIntrinsics();
|
||||
}
|
||||
|
||||
if (lastApi) {
|
||||
lastApi.closePlugin();
|
||||
if (createdApis && !multiPlugin) {
|
||||
createdApis.forEach((pluginApi) => {
|
||||
pluginApi.closePlugin();
|
||||
});
|
||||
}
|
||||
|
||||
if (pluginContext) {
|
||||
lastApi = createApi(pluginContext, manifest);
|
||||
const pluginApi = createApi(pluginContext, manifest);
|
||||
createdApis.push(pluginApi);
|
||||
|
||||
const c = new Compartment({
|
||||
penpot: harden(lastApi),
|
||||
penpot: harden(pluginApi),
|
||||
fetch: window.fetch.bind(window),
|
||||
console: harden(window.console),
|
||||
Math: harden(Math),
|
||||
|
@ -49,7 +53,10 @@ export const ɵloadPlugin = async function (manifest: Manifest) {
|
|||
c.evaluate(code);
|
||||
|
||||
const listenerId: symbol = pluginContext.addListener('finish', () => {
|
||||
lastApi?.closePlugin();
|
||||
createdApis.forEach((pluginApi) => {
|
||||
pluginApi.closePlugin();
|
||||
});
|
||||
|
||||
pluginContext?.removeListener(listenerId);
|
||||
});
|
||||
} else {
|
||||
|
|
|
@ -24,6 +24,20 @@ export class PluginModalElement extends HTMLElement {
|
|||
this.#dragEvents?.();
|
||||
}
|
||||
|
||||
calculateZIndex() {
|
||||
const modals = document.querySelectorAll<HTMLElement>('plugin-modal');
|
||||
|
||||
const zIndexModals = Array.from(modals)
|
||||
.filter((modal) => modal !== this)
|
||||
.map((modal) => {
|
||||
return Number(modal.style.zIndex);
|
||||
});
|
||||
|
||||
const maxZIndex = Math.max(...zIndexModals, 0);
|
||||
|
||||
this.style.zIndex = (maxZIndex + 1).toString();
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
const title = this.getAttribute('title');
|
||||
const iframeSrc = this.getAttribute('iframe-src');
|
||||
|
@ -43,7 +57,10 @@ export class PluginModalElement extends HTMLElement {
|
|||
this.#wrapper.style.inlineSize = `${width}px`;
|
||||
this.#wrapper.style.blockSize = `${height}px`;
|
||||
|
||||
this.#dragEvents = dragHandler(this.#wrapper);
|
||||
// move modal to the top
|
||||
this.#dragEvents = dragHandler(this.#wrapper, () => {
|
||||
this.calculateZIndex();
|
||||
});
|
||||
|
||||
const header = document.createElement('div');
|
||||
header.classList.add('header');
|
||||
|
@ -100,6 +117,8 @@ export class PluginModalElement extends HTMLElement {
|
|||
style.textContent = modalCss;
|
||||
|
||||
this.shadowRoot.appendChild(style);
|
||||
|
||||
this.calculateZIndex();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue