@eclipse-docks/extension-media-viewer 0.7.130 → 0.7.132

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,4 +8,4 @@ var i18n_de_default = {
8
8
  //#endregion
9
9
  export { EXT_MEDIAVIEWER_DESC, EXT_MEDIAVIEWER_NAME, i18n_de_default as default };
10
10
 
11
- //# sourceMappingURL=i18n.de-BgRO7Rh7.js.map
11
+ //# sourceMappingURL=i18n.de-CgHihdaU.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"i18n.de-BgRO7Rh7.js","names":[],"sources":["../src/i18n.de.json"],"sourcesContent":["{\n \"EXT_MEDIAVIEWER_NAME\": \"Medien-Viewer\",\n \"EXT_MEDIAVIEWER_DESC\": \"PDF-, Bild- und HTML-Dateien im Browser anzeigen\"\n}\n"],"mappings":""}
1
+ {"version":3,"file":"i18n.de-CgHihdaU.js","names":[],"sources":["../src/i18n.de.json"],"sourcesContent":["{\n \"EXT_MEDIAVIEWER_NAME\": \"Medien-Viewer\",\n \"EXT_MEDIAVIEWER_DESC\": \"PDF-, Bild- und HTML-Dateien im Browser anzeigen\"\n}\n"],"mappings":""}
@@ -8,4 +8,4 @@ var i18n_en_default = {
8
8
  //#endregion
9
9
  export { EXT_MEDIAVIEWER_DESC, EXT_MEDIAVIEWER_NAME, i18n_en_default as default };
10
10
 
11
- //# sourceMappingURL=i18n.en-DyeoJm7D.js.map
11
+ //# sourceMappingURL=i18n.en-55SVlTbu.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"i18n.en-DyeoJm7D.js","names":[],"sources":["../src/i18n.en.json"],"sourcesContent":["{\n \"EXT_MEDIAVIEWER_NAME\": \"Media Viewer\",\n \"EXT_MEDIAVIEWER_DESC\": \"View PDF, image, and HTML files in the browser\"\n}\n"],"mappings":""}
1
+ {"version":3,"file":"i18n.en-55SVlTbu.js","names":[],"sources":["../src/i18n.en.json"],"sourcesContent":["{\n \"EXT_MEDIAVIEWER_NAME\": \"Media Viewer\",\n \"EXT_MEDIAVIEWER_DESC\": \"View PDF, image, and HTML files in the browser\"\n}\n"],"mappings":""}
package/dist/index.js CHANGED
@@ -1,15 +1,15 @@
1
1
  import { extensionRegistry, i18n } from "@eclipse-docks/core";
2
2
  import pkg from "../package.json";
3
3
  //#region src/index.ts
4
- var t = await i18n(/* @__PURE__ */ Object.assign({
5
- "./i18n.de.json": () => import("./i18n.de-BgRO7Rh7.js"),
6
- "./i18n.en.json": () => import("./i18n.en-DyeoJm7D.js")
4
+ var t = await i18n(/* #__PURE__ */ Object.assign({
5
+ "./i18n.de.json": () => import("./i18n.de-CgHihdaU.js"),
6
+ "./i18n.en.json": () => import("./i18n.en-55SVlTbu.js")
7
7
  }), true);
8
8
  extensionRegistry.registerExtension({
9
9
  id: pkg.name,
10
10
  name: t.EXT_MEDIAVIEWER_NAME,
11
11
  description: t.EXT_MEDIAVIEWER_DESC,
12
- loader: () => import("./media-viewer-extension-CpuQxfjF.js"),
12
+ loader: () => import("./media-viewer-extension-DGwr_Jqs.js"),
13
13
  icon: "image"
14
14
  });
15
15
  //#endregion
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import { extensionRegistry, i18n } from '@eclipse-docks/core';\nimport pkg from '../package.json';\n\nconst t = await i18n(import.meta.glob('./i18n*.json'), true);\n\nextensionRegistry.registerExtension({\n id: pkg.name,\n name: t.EXT_MEDIAVIEWER_NAME,\n description: t.EXT_MEDIAVIEWER_DESC,\n loader: () => import(\"./media-viewer-extension\"),\n icon: \"image\",\n\n\n});\n"],"mappings":";;;AAGA,IAAM,IAAI,MAAM,KAAK,uBAAA,OAAA;CAAA,wBAAA,OAAA;CAAA,wBAAA,OAAA;CAAA,CAAgC,EAAE,KAAK;AAE5D,kBAAkB,kBAAkB;CAClC,IAAI,IAAI;CACR,MAAM,EAAE;CACR,aAAa,EAAE;CACf,cAAc,OAAO;CACrB,MAAM;CAGP,CAAC"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import { extensionRegistry, i18n } from '@eclipse-docks/core';\nimport pkg from '../package.json';\n\nconst t = await i18n(import.meta.glob('./i18n*.json'), true);\n\nextensionRegistry.registerExtension({\n id: pkg.name,\n name: t.EXT_MEDIAVIEWER_NAME,\n description: t.EXT_MEDIAVIEWER_DESC,\n loader: () => import(\"./media-viewer-extension\"),\n icon: \"image\",\n\n\n});\n"],"mappings":";;;AAGA,IAAM,IAAI,MAAM,KAAK,uBAAA,OAAA;CAAA,wBAAA,OAAA;CAAA,wBAAA,OAAA;AAAA,CAAA,GAAkC,IAAI;AAE3D,kBAAkB,kBAAkB;CAClC,IAAI,IAAI;CACR,MAAM,EAAE;CACR,aAAa,EAAE;CACf,cAAc,OAAO;CACrB,MAAM;AAGR,CAAC"}
@@ -106,7 +106,8 @@ var DocksMediaViewer = class DocksMediaViewer extends DocksPart {
106
106
  }
107
107
  async loadMedia() {
108
108
  if (!this.input?.data || !(this.input.data instanceof File)) return;
109
- this.mediaUrl = await this.input.data.getContents({ uri: true });
109
+ const url = await this.input.data.getContents({ uri: true });
110
+ this.mediaUrl = url;
110
111
  this.overlays = [];
111
112
  }
112
113
  renderContent() {
@@ -252,4 +253,4 @@ DocksMediaViewer = _decorate([customElement("docks-media-viewer")], DocksMediaVi
252
253
  //#endregion
253
254
  export { DocksMediaViewer };
254
255
 
255
- //# sourceMappingURL=media-viewer-extension-CpuQxfjF.js.map
256
+ //# sourceMappingURL=media-viewer-extension-DGwr_Jqs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"media-viewer-extension-CpuQxfjF.js","names":[],"sources":["../src/media-viewer-extension.ts"],"sourcesContent":["import { customElement, property, state } from \"lit/decorators.js\";\nimport { css, html, nothing } from \"lit\";\nimport { DocksPart, EditorInput, editorRegistry, File } from \"@eclipse-docks/core\";\n\nconst SUPPORTED_EXTENSIONS = [\n '.pdf',\n '.jpg', '.jpeg', '.png', '.gif', '.svg', '.webp', '.bmp', '.ico'\n];\n\nconst getFileIcon = (fileName: string): string => {\n const lowerName = fileName.toLowerCase();\n if (lowerName.endsWith('.pdf')) return 'file-pdf';\n if (lowerName.match(/\\.(jpg|jpeg|png|gif|webp|bmp|ico|svg)$/)) return 'image';\n return 'file';\n};\n\nconst isSupportedMediaFile = (file: File): boolean => {\n const fileName = file.getName().toLowerCase();\n return SUPPORTED_EXTENSIONS.some(ext => fileName.endsWith(ext));\n};\n\nconst IMAGE_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.gif', '.svg', '.webp', '.bmp', '.ico'];\n\nconst isImageFile = (file: File): boolean => {\n const name = file.getName().toLowerCase();\n return IMAGE_EXTENSIONS.some(ext => name.endsWith(ext));\n};\n\n/** Normalized bounding box overlay (0–1). Used by extensions to draw on the image. */\nexport interface BboxOverlay {\n type: 'bbox';\n left: number;\n top: number;\n width: number;\n height: number;\n label?: string;\n /** CSS color for border and label (e.g. by category). */\n color?: string;\n}\n\n/** Segment mask overlay: PNG data URL (alpha where segment is), drawn over the image. */\nexport interface MaskOverlay {\n type: 'mask';\n /** Data URL of the mask image (e.g. image/png with alpha). */\n dataUrl: string;\n label?: string;\n color?: string;\n}\n\nexport type MediaViewerOverlay = BboxOverlay | MaskOverlay;\n\neditorRegistry.registerEditorInputHandler({\n editorId: \"system.media-viewer\",\n label: \"Media viewer\",\n canHandle: input => input instanceof File && isSupportedMediaFile(input),\n handle: async (input: File) => {\n const editorInput = {\n title: input.getWorkspacePath(),\n data: input,\n key: input.getWorkspacePath(),\n icon: getFileIcon(input.getName()),\n state: {},\n } as EditorInput\n editorInput.component = (id: string) => html`\n <docks-media-viewer id=\"${id}\" .input=${editorInput}></docks-media-viewer>`\n return editorInput;\n },\n ranking: 1000\n})\n\n@customElement('docks-media-viewer')\nexport class DocksMediaViewer extends DocksPart {\n protected scrollMode: 'scroller' | 'native' = 'native';\n @property({attribute: false})\n public input?: EditorInput\n\n @state()\n private mediaUrl?: string\n\n @state()\n private imageNaturalWidth = 0\n\n @state()\n private imageNaturalHeight = 0\n\n @state()\n private overlays: MediaViewerOverlay[] = []\n\n getMediaUrl(): string | undefined {\n return this.mediaUrl;\n }\n\n getIsImage(): boolean {\n return !!(this.input?.data instanceof File && this.mediaUrl && isImageFile(this.input.data));\n }\n\n getImageDimensions(): { width: number; height: number } {\n return { width: this.imageNaturalWidth, height: this.imageNaturalHeight };\n }\n\n /** Set overlays drawn on the image (e.g. from object detection or other extensions). Coordinates in 0–1. */\n setOverlays(overlays: MediaViewerOverlay[]): void {\n this.overlays = overlays ?? [];\n }\n\n getOverlays(): MediaViewerOverlay[] {\n return [...this.overlays];\n }\n\n clearOverlays(): void {\n this.overlays = [];\n }\n\n protected doClose() {\n if (this.mediaUrl && this.mediaUrl.startsWith('blob:')) {\n URL.revokeObjectURL(this.mediaUrl)\n }\n this.input = undefined\n this.mediaUrl = undefined\n this.overlays = []\n this.imageNaturalWidth = 0\n this.imageNaturalHeight = 0\n }\n\n protected async doInitUI() {\n await this.loadMedia()\n }\n\n private async loadMedia() {\n if (!this.input?.data || !(this.input.data instanceof File)) {\n return\n }\n\n const file = this.input.data\n const url = await file.getContents({uri: true}) as string\n this.mediaUrl = url\n this.overlays = []\n }\n\n private onImageLoad = (e: Event): void => {\n const img = e.target as HTMLImageElement;\n if (img?.naturalWidth && img?.naturalHeight) {\n this.imageNaturalWidth = img.naturalWidth;\n this.imageNaturalHeight = img.naturalHeight;\n }\n }\n\n protected renderContent() {\n if (!this.mediaUrl) {\n return html`\n <div style=\"display: flex; align-items: center; justify-content: center; height: 100%;\">\n <wa-spinner></wa-spinner>\n </div>\n `\n }\n\n const isImage = this.getIsImage();\n if (isImage) {\n return html`\n <div class=\"image-container\">\n <div class=\"image-wrapper\">\n <img\n class=\"media-image\"\n src=\"${this.mediaUrl}\"\n alt=\"\"\n @load=${this.onImageLoad}\n />\n ${this.overlays.length > 0 ? html`\n <div class=\"overlay-layer\">\n ${this.overlays.map((o) => o.type === 'bbox' ? html`\n <div\n class=\"overlay-bbox\"\n style=\"left: ${o.left * 100}%; top: ${o.top * 100}%; width: ${o.width * 100}%; height: ${o.height * 100}%;${o.color ? ` --overlay-color: ${o.color};` : ''}\"\n title=\"${o.label ?? ''}\"\n >\n ${o.label ? html`<span class=\"overlay-label\">${o.label}</span>` : nothing}\n </div>\n ` : o.type === 'mask' ? html`\n <img\n class=\"overlay-mask\"\n src=\"${o.dataUrl}\"\n alt=\"${o.label ?? ''}\"\n title=\"${o.label ?? ''}\"\n />\n ` : nothing)}\n </div>\n ` : nothing}\n </div>\n </div>\n `;\n }\n\n return html`\n <div class=\"media-iframe-container\">\n <iframe\n src=\"${this.mediaUrl}\"\n class=\"media-iframe\"\n title=\"Media Viewer\"></iframe>\n </div>\n `\n }\n\n static styles = css`\n :host {\n display: flex;\n flex-direction: column;\n position: relative;\n width: 100%;\n height: 100%;\n background: var(--wa-color-surface-default, #1a1a1a);\n }\n\n .image-container {\n position: relative;\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n }\n\n .image-wrapper {\n position: relative;\n width: 100%;\n height: 100%;\n max-width: 100%;\n max-height: 100%;\n overflow: hidden;\n }\n\n .media-iframe-container {\n position: absolute;\n inset: 0;\n min-height: 0;\n }\n\n .media-iframe {\n display: block;\n width: 100%;\n height: 100%;\n border: 0;\n }\n\n .media-image {\n display: block;\n width: 100%;\n height: 100%;\n object-fit: contain;\n }\n\n .overlay-layer {\n position: absolute;\n inset: 0;\n pointer-events: none;\n }\n\n .overlay-bbox {\n position: absolute;\n border: 2px solid var(--overlay-color, var(--wa-color-brand-fill, #0d6efd));\n background: color-mix(in srgb, var(--overlay-color, #0d6efd) 15%, transparent);\n pointer-events: auto;\n box-sizing: border-box;\n }\n\n .overlay-label {\n position: absolute;\n left: 0;\n top: -1.25em;\n font-size: 0.7rem;\n white-space: nowrap;\n background: var(--overlay-color, var(--wa-color-brand-fill, #0d6efd));\n color: var(--wa-color-surface-default, #fff);\n padding: 1px 4px;\n border-radius: 2px;\n }\n\n .overlay-mask {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n object-fit: fill;\n pointer-events: none;\n }\n `\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'docks-media-viewer': DocksMediaViewer\n }\n}\n\n"],"mappings":";;;;;AAIA,IAAM,uBAAuB;CACzB;CACA;CAAQ;CAAS;CAAQ;CAAQ;CAAQ;CAAS;CAAQ;CAC7D;AAED,IAAM,eAAe,aAA6B;CAC9C,MAAM,YAAY,SAAS,aAAa;AACxC,KAAI,UAAU,SAAS,OAAO,CAAE,QAAO;AACvC,KAAI,UAAU,MAAM,yCAAyC,CAAE,QAAO;AACtE,QAAO;;AAGX,IAAM,wBAAwB,SAAwB;CAClD,MAAM,WAAW,KAAK,SAAS,CAAC,aAAa;AAC7C,QAAO,qBAAqB,MAAK,QAAO,SAAS,SAAS,IAAI,CAAC;;AAGnE,IAAM,mBAAmB;CAAC;CAAQ;CAAS;CAAQ;CAAQ;CAAQ;CAAS;CAAQ;CAAO;AAE3F,IAAM,eAAe,SAAwB;CACzC,MAAM,OAAO,KAAK,SAAS,CAAC,aAAa;AACzC,QAAO,iBAAiB,MAAK,QAAO,KAAK,SAAS,IAAI,CAAC;;AA0B3D,eAAe,2BAA2B;CACtC,UAAU;CACV,OAAO;CACP,YAAW,UAAS,iBAAiB,QAAQ,qBAAqB,MAAM;CACxE,QAAQ,OAAO,UAAgB;EAC3B,MAAM,cAAc;GAChB,OAAO,MAAM,kBAAkB;GAC/B,MAAM;GACN,KAAK,MAAM,kBAAkB;GAC7B,MAAM,YAAY,MAAM,SAAS,CAAC;GAClC,OAAO,EAAE;GACZ;AACD,cAAY,aAAa,OAAe,IAAI;sCACd,GAAG,WAAW,YAAY;AACxD,SAAO;;CAEX,SAAS;CACZ,CAAC;AAGK,IAAA,mBAAA,MAAM,yBAAyB,UAAU;;;oBACE;2BAQlB;4BAGC;kBAGY,EAAE;sBAqDpB,MAAmB;GACtC,MAAM,MAAM,EAAE;AACd,OAAI,KAAK,gBAAgB,KAAK,eAAe;AACzC,SAAK,oBAAoB,IAAI;AAC7B,SAAK,qBAAqB,IAAI;;;;CAvDtC,cAAkC;AAC9B,SAAO,KAAK;;CAGhB,aAAsB;AAClB,SAAO,CAAC,EAAE,KAAK,OAAO,gBAAgB,QAAQ,KAAK,YAAY,YAAY,KAAK,MAAM,KAAK;;CAG/F,qBAAwD;AACpD,SAAO;GAAE,OAAO,KAAK;GAAmB,QAAQ,KAAK;GAAoB;;;CAI7E,YAAY,UAAsC;AAC9C,OAAK,WAAW,YAAY,EAAE;;CAGlC,cAAoC;AAChC,SAAO,CAAC,GAAG,KAAK,SAAS;;CAG7B,gBAAsB;AAClB,OAAK,WAAW,EAAE;;CAGtB,UAAoB;AAChB,MAAI,KAAK,YAAY,KAAK,SAAS,WAAW,QAAQ,CAClD,KAAI,gBAAgB,KAAK,SAAS;AAEtC,OAAK,QAAQ,KAAA;AACb,OAAK,WAAW,KAAA;AAChB,OAAK,WAAW,EAAE;AAClB,OAAK,oBAAoB;AACzB,OAAK,qBAAqB;;CAG9B,MAAgB,WAAW;AACvB,QAAM,KAAK,WAAW;;CAG1B,MAAc,YAAY;AACtB,MAAI,CAAC,KAAK,OAAO,QAAQ,EAAE,KAAK,MAAM,gBAAgB,MAClD;AAKJ,OAAK,WADO,MADC,KAAK,MAAM,KACD,YAAY,EAAC,KAAK,MAAK,CAAC;AAE/C,OAAK,WAAW,EAAE;;CAWtB,gBAA0B;AACtB,MAAI,CAAC,KAAK,SACN,QAAO,IAAI;;;;;AAQf,MADgB,KAAK,YAAY,CAE7B,QAAO,IAAI;;;;;mCAKY,KAAK,SAAS;;oCAEb,KAAK,YAAY;;0BAE3B,KAAK,SAAS,SAAS,IAAI,IAAI;;kCAEvB,KAAK,SAAS,KAAK,MAAM,EAAE,SAAS,SAAS,IAAI;;;uDAG5B,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,IAAI,YAAY,EAAE,QAAQ,IAAI,aAAa,EAAE,SAAS,IAAI,IAAI,EAAE,QAAQ,qBAAqB,EAAE,MAAM,KAAK,GAAG;iDAClJ,EAAE,SAAS,GAAG;;0CAErB,EAAE,QAAQ,IAAI,+BAA+B,EAAE,MAAM,WAAW,QAAQ;;oCAE9E,EAAE,SAAS,SAAS,IAAI;;;+CAGb,EAAE,QAAQ;+CACV,EAAE,SAAS,GAAG;iDACZ,EAAE,SAAS,GAAG;;oCAE3B,QAAQ,CAAC;;4BAEjB,QAAQ;;;;AAM5B,SAAO,IAAI;;;2BAGQ,KAAK,SAAS;;;;;;;gBAOrB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAjIlB,SAAS,EAAC,WAAW,OAAM,CAAC,CAAA,EAAA,iBAAA,WAAA,SAAA,KAAA,EAAA;WAG5B,OAAO,CAAA,EAAA,iBAAA,WAAA,YAAA,KAAA,EAAA;WAGP,OAAO,CAAA,EAAA,iBAAA,WAAA,qBAAA,KAAA,EAAA;WAGP,OAAO,CAAA,EAAA,iBAAA,WAAA,sBAAA,KAAA,EAAA;WAGP,OAAO,CAAA,EAAA,iBAAA,WAAA,YAAA,KAAA,EAAA;8BAfX,cAAc,qBAAqB,CAAA,EAAA,iBAAA"}
1
+ {"version":3,"file":"media-viewer-extension-DGwr_Jqs.js","names":[],"sources":["../src/media-viewer-extension.ts"],"sourcesContent":["import { customElement, property, state } from \"lit/decorators.js\";\nimport { css, html, nothing } from \"lit\";\nimport { DocksPart, EditorInput, editorRegistry, File } from \"@eclipse-docks/core\";\n\nconst SUPPORTED_EXTENSIONS = [\n '.pdf',\n '.jpg', '.jpeg', '.png', '.gif', '.svg', '.webp', '.bmp', '.ico'\n];\n\nconst getFileIcon = (fileName: string): string => {\n const lowerName = fileName.toLowerCase();\n if (lowerName.endsWith('.pdf')) return 'file-pdf';\n if (lowerName.match(/\\.(jpg|jpeg|png|gif|webp|bmp|ico|svg)$/)) return 'image';\n return 'file';\n};\n\nconst isSupportedMediaFile = (file: File): boolean => {\n const fileName = file.getName().toLowerCase();\n return SUPPORTED_EXTENSIONS.some(ext => fileName.endsWith(ext));\n};\n\nconst IMAGE_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.gif', '.svg', '.webp', '.bmp', '.ico'];\n\nconst isImageFile = (file: File): boolean => {\n const name = file.getName().toLowerCase();\n return IMAGE_EXTENSIONS.some(ext => name.endsWith(ext));\n};\n\n/** Normalized bounding box overlay (0–1). Used by extensions to draw on the image. */\nexport interface BboxOverlay {\n type: 'bbox';\n left: number;\n top: number;\n width: number;\n height: number;\n label?: string;\n /** CSS color for border and label (e.g. by category). */\n color?: string;\n}\n\n/** Segment mask overlay: PNG data URL (alpha where segment is), drawn over the image. */\nexport interface MaskOverlay {\n type: 'mask';\n /** Data URL of the mask image (e.g. image/png with alpha). */\n dataUrl: string;\n label?: string;\n color?: string;\n}\n\nexport type MediaViewerOverlay = BboxOverlay | MaskOverlay;\n\neditorRegistry.registerEditorInputHandler({\n editorId: \"system.media-viewer\",\n label: \"Media viewer\",\n canHandle: input => input instanceof File && isSupportedMediaFile(input),\n handle: async (input: File) => {\n const editorInput = {\n title: input.getWorkspacePath(),\n data: input,\n key: input.getWorkspacePath(),\n icon: getFileIcon(input.getName()),\n state: {},\n } as EditorInput\n editorInput.component = (id: string) => html`\n <docks-media-viewer id=\"${id}\" .input=${editorInput}></docks-media-viewer>`\n return editorInput;\n },\n ranking: 1000\n})\n\n@customElement('docks-media-viewer')\nexport class DocksMediaViewer extends DocksPart {\n protected scrollMode: 'scroller' | 'native' = 'native';\n @property({attribute: false})\n public input?: EditorInput\n\n @state()\n private mediaUrl?: string\n\n @state()\n private imageNaturalWidth = 0\n\n @state()\n private imageNaturalHeight = 0\n\n @state()\n private overlays: MediaViewerOverlay[] = []\n\n getMediaUrl(): string | undefined {\n return this.mediaUrl;\n }\n\n getIsImage(): boolean {\n return !!(this.input?.data instanceof File && this.mediaUrl && isImageFile(this.input.data));\n }\n\n getImageDimensions(): { width: number; height: number } {\n return { width: this.imageNaturalWidth, height: this.imageNaturalHeight };\n }\n\n /** Set overlays drawn on the image (e.g. from object detection or other extensions). Coordinates in 0–1. */\n setOverlays(overlays: MediaViewerOverlay[]): void {\n this.overlays = overlays ?? [];\n }\n\n getOverlays(): MediaViewerOverlay[] {\n return [...this.overlays];\n }\n\n clearOverlays(): void {\n this.overlays = [];\n }\n\n protected doClose() {\n if (this.mediaUrl && this.mediaUrl.startsWith('blob:')) {\n URL.revokeObjectURL(this.mediaUrl)\n }\n this.input = undefined\n this.mediaUrl = undefined\n this.overlays = []\n this.imageNaturalWidth = 0\n this.imageNaturalHeight = 0\n }\n\n protected async doInitUI() {\n await this.loadMedia()\n }\n\n private async loadMedia() {\n if (!this.input?.data || !(this.input.data instanceof File)) {\n return\n }\n\n const file = this.input.data\n const url = await file.getContents({uri: true}) as string\n this.mediaUrl = url\n this.overlays = []\n }\n\n private onImageLoad = (e: Event): void => {\n const img = e.target as HTMLImageElement;\n if (img?.naturalWidth && img?.naturalHeight) {\n this.imageNaturalWidth = img.naturalWidth;\n this.imageNaturalHeight = img.naturalHeight;\n }\n }\n\n protected renderContent() {\n if (!this.mediaUrl) {\n return html`\n <div style=\"display: flex; align-items: center; justify-content: center; height: 100%;\">\n <wa-spinner></wa-spinner>\n </div>\n `\n }\n\n const isImage = this.getIsImage();\n if (isImage) {\n return html`\n <div class=\"image-container\">\n <div class=\"image-wrapper\">\n <img\n class=\"media-image\"\n src=\"${this.mediaUrl}\"\n alt=\"\"\n @load=${this.onImageLoad}\n />\n ${this.overlays.length > 0 ? html`\n <div class=\"overlay-layer\">\n ${this.overlays.map((o) => o.type === 'bbox' ? html`\n <div\n class=\"overlay-bbox\"\n style=\"left: ${o.left * 100}%; top: ${o.top * 100}%; width: ${o.width * 100}%; height: ${o.height * 100}%;${o.color ? ` --overlay-color: ${o.color};` : ''}\"\n title=\"${o.label ?? ''}\"\n >\n ${o.label ? html`<span class=\"overlay-label\">${o.label}</span>` : nothing}\n </div>\n ` : o.type === 'mask' ? html`\n <img\n class=\"overlay-mask\"\n src=\"${o.dataUrl}\"\n alt=\"${o.label ?? ''}\"\n title=\"${o.label ?? ''}\"\n />\n ` : nothing)}\n </div>\n ` : nothing}\n </div>\n </div>\n `;\n }\n\n return html`\n <div class=\"media-iframe-container\">\n <iframe\n src=\"${this.mediaUrl}\"\n class=\"media-iframe\"\n title=\"Media Viewer\"></iframe>\n </div>\n `\n }\n\n static styles = css`\n :host {\n display: flex;\n flex-direction: column;\n position: relative;\n width: 100%;\n height: 100%;\n background: var(--wa-color-surface-default, #1a1a1a);\n }\n\n .image-container {\n position: relative;\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n }\n\n .image-wrapper {\n position: relative;\n width: 100%;\n height: 100%;\n max-width: 100%;\n max-height: 100%;\n overflow: hidden;\n }\n\n .media-iframe-container {\n position: absolute;\n inset: 0;\n min-height: 0;\n }\n\n .media-iframe {\n display: block;\n width: 100%;\n height: 100%;\n border: 0;\n }\n\n .media-image {\n display: block;\n width: 100%;\n height: 100%;\n object-fit: contain;\n }\n\n .overlay-layer {\n position: absolute;\n inset: 0;\n pointer-events: none;\n }\n\n .overlay-bbox {\n position: absolute;\n border: 2px solid var(--overlay-color, var(--wa-color-brand-fill, #0d6efd));\n background: color-mix(in srgb, var(--overlay-color, #0d6efd) 15%, transparent);\n pointer-events: auto;\n box-sizing: border-box;\n }\n\n .overlay-label {\n position: absolute;\n left: 0;\n top: -1.25em;\n font-size: 0.7rem;\n white-space: nowrap;\n background: var(--overlay-color, var(--wa-color-brand-fill, #0d6efd));\n color: var(--wa-color-surface-default, #fff);\n padding: 1px 4px;\n border-radius: 2px;\n }\n\n .overlay-mask {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n object-fit: fill;\n pointer-events: none;\n }\n `\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'docks-media-viewer': DocksMediaViewer\n }\n}\n\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eclipse-docks/extension-media-viewer",
3
- "version": "0.7.130",
3
+ "version": "0.7.132",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "exports": {