@schukai/monster 4.32.1 → 4.33.0

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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,25 @@
2
2
 
3
3
 
4
4
 
5
+ ## [4.33.0] - 2025-07-12
6
+
7
+ ### Add Features
8
+
9
+ - Add image error handling and improve styles
10
+ ### Changes
11
+
12
+ - update tests
13
+
14
+
15
+
16
+ ## [4.32.2] - 2025-07-12
17
+
18
+ ### Bug Fixes
19
+
20
+ - Update Message Viewer - fetch URL and improve error handling
21
+
22
+
23
+
5
24
  ## [4.32.1] - 2025-07-08
6
25
 
7
26
  ### Bug Fixes
package/package.json CHANGED
@@ -1 +1 @@
1
- {"author":"schukai GmbH","dependencies":{"@floating-ui/dom":"^1.7.2","@popperjs/core":"^2.11.8"},"description":"Monster is a simple library for creating fast, robust and lightweight websites.","homepage":"https://monsterjs.org/","keywords":["framework","web","dom","css","sass","mobile-first","app","front-end","templates","schukai","core","shopcloud","alvine","monster","buildmap","stack","observer","observable","uuid","node","nodelist","css-in-js","logger","log","theme"],"license":"AGPL 3.0","main":"source/monster.mjs","module":"source/monster.mjs","name":"@schukai/monster","repository":{"type":"git","url":"https://gitlab.schukai.com/oss/libraries/javascript/monster.git"},"type":"module","version":"4.32.1"}
1
+ {"author":"schukai GmbH","dependencies":{"@floating-ui/dom":"^1.7.2","@popperjs/core":"^2.11.8"},"description":"Monster is a simple library for creating fast, robust and lightweight websites.","homepage":"https://monsterjs.org/","keywords":["framework","web","dom","css","sass","mobile-first","app","front-end","templates","schukai","core","shopcloud","alvine","monster","buildmap","stack","observer","observable","uuid","node","nodelist","css-in-js","logger","log","theme"],"license":"AGPL 3.0","main":"source/monster.mjs","module":"source/monster.mjs","name":"@schukai/monster","repository":{"type":"git","url":"https://gitlab.schukai.com/oss/libraries/javascript/monster.git"},"type":"module","version":"4.33.0"}
@@ -14,10 +14,10 @@
14
14
 
15
15
  import { instanceSymbol } from "../../../constants.mjs";
16
16
  import {
17
- assembleMethodSymbol,
18
- CustomElement,
19
- registerCustomElement,
20
- updaterTransformerMethodsSymbol,
17
+ assembleMethodSymbol,
18
+ CustomElement,
19
+ registerCustomElement,
20
+ updaterTransformerMethodsSymbol,
21
21
  } from "../../../dom/customelement.mjs";
22
22
  import { HtmlStyleSheet } from "./stylesheet/html.mjs";
23
23
  import { sanitizeHtml } from "../../../dom/sanitize-html.mjs";
@@ -38,106 +38,133 @@ const htmlContentElementSymbol = Symbol("htmlContentElement");
38
38
  * @summary An HTML content component that can display sanitized HTML.
39
39
  */
40
40
  class HtmlContent extends CustomElement {
41
- /**
42
- * This method is called by the `instanceof` operator.
43
- * @return {symbol}
44
- */
45
- static get [instanceSymbol]() {
46
- return Symbol.for(
47
- "@schukai/monster/components/content/viewer/html-content@@instance",
48
- );
49
- }
50
-
51
- /**
52
- * To set the options via the HTML tag, the attribute `data-monster-options` must be used.
53
- * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
54
- *
55
- * The individual configuration values can be found in the table.
56
- *
57
- * @property {Object} templates Template definitions
58
- * @property {string} templates.main Main template
59
- * @property {string} content The HTML string to be displayed.
60
- * @property {Object} features Features to enable or disable specific functionalities.
61
- * @property {boolean} features.sanitize Whether to sanitize the HTML content (removes scripts, etc.). Defaults to true.
62
- * @property {object} sanitize Sanitization options.
63
- * @property {function} sanitize.callback A callback function to sanitize the HTML content. Defaults to a built-in sanitizer. You can use libraries like DOMPurify for this purpose.
64
- */
65
- get defaults() {
66
- return Object.assign({}, super.defaults, {
67
- templates: {
68
- main: getTemplate(),
69
- },
70
- content: "", // Default content is an empty slot
71
-
72
- features: {
73
- sanitize: true,
74
- },
75
-
76
- sanitize: {
77
- callback: sanitizeHtml.bind(this),
78
- },
79
- });
80
- }
81
-
82
- /**
83
- * Returns the updater transformer methods for this component.
84
- * @returns {{sanitizeHtml: ((function(*): (*))|*)}}
85
- */
86
- [updaterTransformerMethodsSymbol]() {
87
- return {
88
- sanitizeHtml: (value) => {
89
- if (this.getOption("features.sanitize")) {
90
- return this.getOption("sanitize.callback")(value);
91
- }
92
- return value;
93
- },
94
- };
95
- }
96
-
97
- /**
98
- * Sets the content of the HtmlContent component.
99
- * @param content
100
- * @returns {HtmlContent}
101
- */
102
- setContent(content) {
103
- this.setOption("content", content);
104
- return this;
105
- }
106
-
107
- /**
108
- * @return {string}
109
- */
110
- static getTag() {
111
- return "monster-html-content";
112
- }
113
-
114
- /**
115
- * @return {HtmlContent}
116
- */
117
- [assembleMethodSymbol]() {
118
- super[assembleMethodSymbol]();
119
- initControlReferences.call(this);
120
- grabChildren.call(this);
121
- }
122
-
123
- /**
124
- * @return {Array}
125
- */
126
- static getCSSStyleSheet() {
127
- return [HtmlStyleSheet];
128
- }
41
+ /**
42
+ * This method is called by the `instanceof` operator.
43
+ * @return {symbol}
44
+ */
45
+ static get [instanceSymbol]() {
46
+ return Symbol.for(
47
+ "@schukai/monster/components/content/viewer/html-content@@instance",
48
+ );
49
+ }
50
+
51
+ /**
52
+ * To set the options via the HTML tag, the attribute `data-monster-options` must be used.
53
+ * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
54
+ *
55
+ * The individual configuration values can be found in the table.
56
+ *
57
+ * @property {Object} templates Template definitions
58
+ * @property {string} templates.main Main template
59
+ * @property {string} content The HTML string to be displayed.
60
+ * @property {Object} features Features to enable or disable specific functionalities.
61
+ * @property {boolean} features.sanitize Whether to sanitize the HTML content (removes scripts, etc.). Defaults to true.
62
+ * @property {object} sanitize Sanitization options.
63
+ * @property {function} sanitize.callback A callback function to sanitize the HTML content. Defaults to a built-in sanitizer. You can use libraries like DOMPurify for this purpose.
64
+ */
65
+ get defaults() {
66
+ return Object.assign({}, super.defaults, {
67
+ templates: {
68
+ main: getTemplate(),
69
+ },
70
+ content: "", // Default content is an empty slot
71
+
72
+ features: {
73
+ sanitize: true,
74
+ },
75
+
76
+ sanitize: {
77
+ callback: sanitizeHtml.bind(this),
78
+ },
79
+ });
80
+ }
81
+
82
+ /**
83
+ * Returns the updater transformer methods for this component.
84
+ * @returns {{sanitizeHtml: ((function(*): (*))|*)}}
85
+ */
86
+ [updaterTransformerMethodsSymbol]() {
87
+ return {
88
+ sanitizeHtml: (value) => {
89
+ if (this.getOption("features.sanitize")) {
90
+ return this.getOption("sanitize.callback")(value);
91
+ }
92
+ return value;
93
+ },
94
+ addErrorHandler: (value) => {
95
+ // Add error handling for images
96
+ if (typeof value === "string") {
97
+ const parser = new DOMParser();
98
+ const doc = parser.parseFromString(value, "text/html");
99
+ const images = doc.querySelectorAll("img");
100
+ images.forEach((img) => {
101
+ img.setAttribute(
102
+ "onerror",
103
+ "this.classList.add('notFoundImage'); this.src='data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';",
104
+ );
105
+ img.classList.add("notFoundError");
106
+ });
107
+
108
+ return doc.body.innerHTML;
109
+ }
110
+ return value;
111
+ },
112
+ };
113
+ }
114
+
115
+ /**
116
+ * Sets the content of the HtmlContent component.
117
+ * @param content
118
+ * @returns {HtmlContent}
119
+ */
120
+ setContent(content) {
121
+ this.setOption("content", content);
122
+ return this;
123
+ }
124
+
125
+ /**
126
+ * @return {string}
127
+ */
128
+ static getTag() {
129
+ return "monster-html-content";
130
+ }
131
+
132
+ /**
133
+ * @return {HtmlContent}
134
+ */
135
+ [assembleMethodSymbol]() {
136
+ super[assembleMethodSymbol]();
137
+ initControlReferences.call(this);
138
+ initEventHandler.call(this);
139
+ grabChildren.call(this);
140
+ }
141
+
142
+ /**
143
+ * @return {Array}
144
+ */
145
+ static getCSSStyleSheet() {
146
+ return [HtmlStyleSheet];
147
+ }
129
148
  }
130
149
 
131
150
  function grabChildren() {
132
- // If there are children, we grab them and set the content
133
- if (this.children.length > 0) {
134
- const content = Array.from(this.children)
135
- .map((child) => child.outerHTML)
136
- .join("");
137
- this.setContent(content);
138
-
139
- this.innerHTML = "";
140
- }
151
+ // If there are children, we grab them and set the content
152
+ if (this.children.length > 0) {
153
+ const content = Array.from(this.children)
154
+ .map((child) => child.outerHTML)
155
+ .join("");
156
+ this.setContent(content);
157
+
158
+ this.innerHTML = "";
159
+ }
160
+ }
161
+
162
+ /**
163
+ * @private
164
+ * @return {HtmlContent}
165
+ */
166
+ function initEventHandler() {
167
+ return this;
141
168
  }
142
169
 
143
170
  /**
@@ -145,14 +172,14 @@ function grabChildren() {
145
172
  * @return {HtmlContent}
146
173
  */
147
174
  function initControlReferences() {
148
- if (!this.shadowRoot) {
149
- throw new Error("no shadow-root is defined");
150
- }
151
-
152
- this[htmlContentElementSymbol] = this.shadowRoot.querySelector(
153
- "[data-monster-role=content-container]",
154
- );
155
- return this;
175
+ if (!this.shadowRoot) {
176
+ throw new Error("no shadow-root is defined");
177
+ }
178
+
179
+ this[htmlContentElementSymbol] = this.shadowRoot.querySelector(
180
+ "[data-monster-role=content-container]",
181
+ );
182
+ return this;
156
183
  }
157
184
 
158
185
  /**
@@ -160,10 +187,10 @@ function initControlReferences() {
160
187
  * @return {string}
161
188
  */
162
189
  function getTemplate() {
163
- // language=HTML
164
- return `
190
+ // language=HTML
191
+ return `
165
192
  <div data-monster-role="content-container" part="content-container"
166
- data-monster-replace="path:content | call:sanitizeHtml | default: "
193
+ data-monster-replace="path:content | call:sanitizeHtml | call:addErrorHandler | default: "
167
194
  ></div>
168
195
  `;
169
196
  }