@schukai/monster 4.68.0 → 4.69.1

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.
@@ -39,6 +39,7 @@ import { DeadMansSwitch } from "../../util/deadmansswitch.mjs";
39
39
  import { CommonStyleSheet } from "../stylesheet/common.mjs";
40
40
  import { ThemeStyleSheet } from "../stylesheet/theme.mjs";
41
41
  import { FileManagerStyleSheet } from "./stylesheet/file-manager.mjs";
42
+ import "../content/image-editor.mjs";
42
43
  import { ATTRIBUTE_BUTTON_LABEL } from "../form/constants.mjs";
43
44
  import { getLocaleOfDocument } from "../../dom/locale.mjs";
44
45
 
@@ -235,13 +236,13 @@ class FileManager extends CustomElement {
235
236
  readOnly: false,
236
237
  defaultTag: "textarea",
237
238
  byMimeType: {
238
- "image/png": "canvas",
239
- "image/jpeg": "canvas",
240
- "image/gif": "canvas",
241
- "image/svg+xml": "canvas",
242
- "image/webp": "canvas",
243
- "image/bmp": "canvas",
244
- "image/x-icon": "canvas",
239
+ "image/png": "monster-image-editor",
240
+ "image/jpeg": "monster-image-editor",
241
+ "image/gif": "monster-image-editor",
242
+ "image/svg+xml": "monster-image-editor",
243
+ "image/webp": "monster-image-editor",
244
+ "image/bmp": "monster-image-editor",
245
+ "image/x-icon": "monster-image-editor",
245
246
  "text/plain": "textarea",
246
247
  "text/markdown": "textarea",
247
248
  "text/css": "textarea",
@@ -1348,11 +1349,18 @@ function updateEditorSizes() {
1348
1349
 
1349
1350
  for (const tabData of this[tabsByReferenceSymbol].values()) {
1350
1351
  const editor = tabData?.editor;
1352
+ const tabElement = tabData?.tabElement;
1353
+ if (tabElement instanceof HTMLElement) {
1354
+ tabElement.style.height = `${available}px`;
1355
+ tabElement.style.minHeight = `${available}px`;
1356
+ }
1351
1357
  if (!(editor instanceof HTMLElement)) {
1352
1358
  continue;
1353
1359
  }
1354
- editor.style.height = `${available}px`;
1355
- editor.style.minHeight = `${available}px`;
1360
+ if (!isCanvasElement(editor)) {
1361
+ editor.style.height = "100%";
1362
+ editor.style.minHeight = "0";
1363
+ }
1356
1364
  if (isCanvasElement(editor)) {
1357
1365
  editor.width = Math.max(1, Math.floor(containerRect.width));
1358
1366
  editor.height = Math.max(1, Math.floor(available));
@@ -1652,6 +1660,14 @@ function getEditorAdapter() {
1652
1660
  const custom = this.getOption("editor.adapter");
1653
1661
  const base = {
1654
1662
  getValue: (element) => {
1663
+ if (isImageEditorElement(element)) {
1664
+ if (typeof element.getImageDataUrl === "function") {
1665
+ return element.getImageDataUrl(
1666
+ element.dataset.monsterOutputType || undefined,
1667
+ );
1668
+ }
1669
+ return element.dataset.monsterValue || "";
1670
+ }
1655
1671
  if (isCanvasElement(element)) {
1656
1672
  return element.dataset.monsterValue || "";
1657
1673
  }
@@ -1662,6 +1678,16 @@ function getEditorAdapter() {
1662
1678
  },
1663
1679
  setValue: (element, value) => {
1664
1680
  const next = value ?? "";
1681
+ if (isImageEditorElement(element)) {
1682
+ element.dataset.monsterValue = next;
1683
+ if (typeof element.setImage === "function") {
1684
+ element.setImage(next, {
1685
+ contentType: element.dataset.monsterContentType,
1686
+ storeOriginal: true,
1687
+ });
1688
+ }
1689
+ return;
1690
+ }
1665
1691
  if (isCanvasElement(element)) {
1666
1692
  renderCanvasFromValue(element, next);
1667
1693
  return;
@@ -1678,6 +1704,17 @@ function getEditorAdapter() {
1678
1704
  if (!element || typeof callback !== "function") {
1679
1705
  return () => {};
1680
1706
  }
1707
+ if (isCanvasElement(element)) {
1708
+ return () => {};
1709
+ }
1710
+ if (isImageEditorElement(element)) {
1711
+ const handler = () => callback();
1712
+ element.addEventListener("monster-image-editor-changed", handler);
1713
+ return () => {
1714
+ element.removeEventListener("monster-image-editor-changed", handler);
1715
+ };
1716
+ }
1717
+
1681
1718
  if (isCanvasElement(element)) {
1682
1719
  return () => {};
1683
1720
  }
@@ -1694,6 +1731,14 @@ function getEditorAdapter() {
1694
1731
  if (!element) {
1695
1732
  return;
1696
1733
  }
1734
+ if (isImageEditorElement(element)) {
1735
+ if (readOnly === true) {
1736
+ element.setAttribute("data-monster-readonly", "");
1737
+ } else {
1738
+ element.removeAttribute("data-monster-readonly");
1739
+ }
1740
+ return;
1741
+ }
1697
1742
  if (isCanvasElement(element)) {
1698
1743
  return;
1699
1744
  }
@@ -1737,7 +1782,17 @@ function getEditorAdapter() {
1737
1782
  */
1738
1783
  function createEditorElement(entry) {
1739
1784
  const tag = resolveEditorTag.call(this, entry);
1740
- return getDocument().createElement(tag);
1785
+ const editor = getDocument().createElement(tag);
1786
+ const mimeType = getMimeTypeForEntry(entry);
1787
+ if (isImageEditorElement(editor) && isString(mimeType)) {
1788
+ editor.dataset.monsterContentType = mimeType;
1789
+ editor.dataset.monsterOutputType = mimeType;
1790
+ if (typeof editor.setOption === "function") {
1791
+ editor.setOption("source.contentType", mimeType);
1792
+ editor.setOption("output.type", mimeType);
1793
+ }
1794
+ }
1795
+ return editor;
1741
1796
  }
1742
1797
 
1743
1798
  /**
@@ -1768,6 +1823,18 @@ function isCanvasElement(element) {
1768
1823
  return element instanceof HTMLCanvasElement;
1769
1824
  }
1770
1825
 
1826
+ /**
1827
+ * @private
1828
+ * @param {HTMLElement} element
1829
+ * @return {boolean}
1830
+ */
1831
+ function isImageEditorElement(element) {
1832
+ return (
1833
+ element instanceof HTMLElement &&
1834
+ element.tagName.toLowerCase() === "monster-image-editor"
1835
+ );
1836
+ }
1837
+
1771
1838
  /**
1772
1839
  * @private
1773
1840
  * @param {HTMLCanvasElement} canvas
@@ -39,7 +39,7 @@ monster-split-panel::part(endPanel){overflow:hidden}
39
39
  [data-monster-role=tabs-container]{flex:1;min-height:0;display:flex;flex-direction:column;overflow:hidden}
40
40
  monster-tabs{flex:1;min-height:0;height:100%}
41
41
  [data-monster-role=empty]{align-items:center;display:flex;inset:0;justify-content:center;padding:var(--monster-space-4);position:absolute;text-align:center}
42
- [data-monster-role=tab-content]{display:flex;flex-direction:column;flex:1;min-height:0;overflow:hidden}
42
+ [data-monster-role=tab-content]{display:flex;flex-direction:column;flex:1;height:100%;min-height:0;overflow:auto}
43
43
  [data-monster-role=tab-content]:not(.active){display:none}
44
44
  [data-monster-role=editor]{flex:1;font-family:var(--monster-font-family-monospace);height:100%;min-height:0;overflow:auto;resize:none;width:100%}
45
45
  }
@@ -141,11 +141,18 @@ class Panel extends CustomElement {
141
141
  function calcHeight() {
142
142
  this.style.boxSizing = "border-box";
143
143
 
144
- const height = calculateMaximumHeight.call(this, this);
144
+ let height = calculateMaximumHeight.call(this, this);
145
145
  if (height < 0) {
146
146
  return;
147
147
  }
148
148
 
149
+ const parent =
150
+ this.parentNode instanceof HTMLElement ? this.parentNode : null;
151
+ const parentHeight = parent?.clientHeight || 0;
152
+ if (parentHeight > 0) {
153
+ height = Math.min(height, parentHeight);
154
+ }
155
+
149
156
  this.style.height = `${height}px`;
150
157
  }
151
158
 
@@ -379,11 +379,11 @@ function initValueAttributeObserver() {
379
379
 
380
380
  self[debounceValueSymbol] = new DeadMansSwitch(10, () => {
381
381
  const oldValue = self.getAttribute("value");
382
- const newValue = self.getOption("value");
382
+ const newValue = self.value;
383
383
 
384
384
  if (oldValue !== newValue) {
385
385
  setTimeout(() => {
386
- this.setOption("value", this.getAttribute("value"));
386
+ self.value = self.getAttribute("value");
387
387
  }, 0);
388
388
  }
389
389
  });
@@ -34,6 +34,7 @@ export * from "./components/content/fetch-box.mjs";
34
34
  export * from "./components/content/viewer.mjs";
35
35
  export * from "./components/content/camera-capture.mjs";
36
36
  export * from "./components/content/copy.mjs";
37
+ export * from "./components/content/image-editor.mjs";
37
38
  export * from "./components/content/viewer/html.mjs";
38
39
  export * from "./components/content/viewer/message.mjs";
39
40
  export * from "./components/files/file-manager.mjs";
@@ -156,7 +156,7 @@ function getMonsterVersion() {
156
156
  }
157
157
 
158
158
  /** don't touch, replaced by make with package.json version */
159
- monsterVersion = new Version("4.67.0");
159
+ monsterVersion = new Version("4.68.0");
160
160
 
161
161
  return monsterVersion;
162
162
  }
@@ -7,7 +7,7 @@ describe('Monster', function () {
7
7
  let monsterVersion
8
8
 
9
9
  /** don´t touch, replaced by make with package.json version */
10
- monsterVersion = new Version("4.67.0")
10
+ monsterVersion = new Version("4.68.0")
11
11
 
12
12
  let m = getMonsterVersion();
13
13
 
@@ -9,8 +9,8 @@
9
9
  </head>
10
10
  <body>
11
11
  <div id="headline" style="display: flex;align-items: center;justify-content: center;flex-direction: column;">
12
- <h1 style='margin-bottom: 0.1em;'>Monster 4.67.0</h1>
13
- <div id="lastupdate" style='font-size:0.7em'>last update Do 1. Jan 21:29:16 CET 2026</div>
12
+ <h1 style='margin-bottom: 0.1em;'>Monster 4.68.0</h1>
13
+ <div id="lastupdate" style='font-size:0.7em'>last update Fr 2. Jan 17:20:55 CET 2026</div>
14
14
  </div>
15
15
  <div id="mocha-errors"
16
16
  style="color: red;font-weight: bold;display: flex;align-items: center;justify-content: center;flex-direction: column;margin:20px;"></div>