@schukai/monster 3.81.0 → 3.82.0

Sign up to get free protection for your applications and to get access to all the features.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
 
4
4
 
5
+ ## [3.82.0] - 2024-10-16
6
+
7
+ ### Add Features
8
+
9
+ - new iframe feature for replace target
10
+
11
+
12
+
5
13
  ## [3.81.0] - 2024-10-15
6
14
 
7
15
  ### Add Features
package/package.json CHANGED
@@ -1 +1 @@
1
- {"author":"schukai GmbH","dependencies":{"@floating-ui/dom":"^1.6.11","@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":"3.81.0"}
1
+ {"author":"schukai GmbH","dependencies":{"@floating-ui/dom":"^1.6.11","@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":"3.82.0"}
@@ -10,20 +10,20 @@
10
10
  * For more information about purchasing a commercial license, please contact schukai GmbH.
11
11
  */
12
12
 
13
- import { instanceSymbol } from "../../constants.mjs";
14
- import { ATTRIBUTE_ROLE } from "../../dom/constants.mjs";
15
- import { CustomElement } from "../../dom/customelement.mjs";
13
+ import {instanceSymbol} from "../../constants.mjs";
14
+ import {ATTRIBUTE_ROLE} from "../../dom/constants.mjs";
15
+ import {CustomElement} from "../../dom/customelement.mjs";
16
16
  import {
17
- assembleMethodSymbol,
18
- registerCustomElement,
17
+ assembleMethodSymbol,
18
+ registerCustomElement,
19
19
  } from "../../dom/customelement.mjs";
20
- import { findTargetElementFromEvent } from "../../dom/events.mjs";
21
- import { isFunction } from "../../types/is.mjs";
22
- import { DeadMansSwitch } from "../../util/deadmansswitch.mjs";
23
- import { IframeStyleSheet } from "./stylesheet/iframe.mjs";
24
- import { fireCustomEvent } from "../../dom/events.mjs";
20
+ import {findTargetElementFromEvent} from "../../dom/events.mjs";
21
+ import {isFunction} from "../../types/is.mjs";
22
+ import {DeadMansSwitch} from "../../util/deadmansswitch.mjs";
23
+ import {IframeStyleSheet} from "./stylesheet/iframe.mjs";
24
+ import {fireCustomEvent} from "../../dom/events.mjs";
25
25
 
26
- export { Iframe };
26
+ export {Iframe};
27
27
 
28
28
  /**
29
29
  * @private
@@ -62,124 +62,133 @@ const timerCallbackSymbol = Symbol("timerCallback");
62
62
  * @summary A cool and fancy Iframe that can make your life easier and also looks good.
63
63
  */
64
64
  class Iframe extends CustomElement {
65
- /**
66
- * This method is called by the `instanceof` operator.
67
- * @return {symbol}
68
- */
69
- static get [instanceSymbol]() {
70
- return Symbol.for("@schukai/monster/components/layout/iframe@@instance");
71
- }
72
-
73
- /**
74
- *
75
- * @return {Components.Layout.Iframe
76
- */
77
- [assembleMethodSymbol]() {
78
- super[assembleMethodSymbol]();
79
- initControlReferences.call(this);
80
- initEventHandler.call(this);
81
- calcHeight.call(this);
82
- return this;
83
- }
84
-
85
- /**
86
- * This method is called by the dom and should not be called directly.
87
- *
88
- * @return {void}
89
- */
90
- connectedCallback() {
91
- super.connectedCallback();
92
- attachResizeObserver.call(this);
93
-
94
- // disable scrolling in parent node
95
- if (this.parentNode && this.parentNode instanceof HTMLElement) {
96
- this.parentNode.style.overflow = "hidden";
97
- }
98
- }
99
-
100
- /**
101
- * This method is called by the dom and should not be called directly.
102
- *
103
- * @return {void}
104
- */
105
- disconnectedCallback() {
106
- super.disconnectedCallback();
107
- disconnectResizeObserver.call(this);
108
- }
109
-
110
- /**
111
- * To set the options via the HTML tag, the attribute `data-monster-options` must be used.
112
- * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
113
- *
114
- * The individual configuration values can be found in the table.
115
- *
116
- * @property {Object} templates Template definitions
117
- * @property {string} templates.main Main template
118
- * @property {Object} labels Label definitions
119
- * @property {Object} actions Callbacks
120
- * @property {string} actions.click="throw Error" Callback when clicked
121
- * @property {Object} features Features
122
- * @property {Object} classes CSS classes
123
- * @property {boolean} disabled=false Disabled state
124
- */
125
- get defaults() {
126
- return Object.assign({}, super.defaults, {
127
- templates: {
128
- main: getTemplate(),
129
- },
130
- src: null,
131
-
132
- /* "allow-forms allow-pointer-lock allow-popups allow-same-origin allow-scripts allow-top-navigation"*/
133
- sandbox: null,
134
-
135
- labels: {},
136
- classes: {},
137
-
138
- name: "",
139
-
140
- referrerpolicy: "no-referrer",
141
-
142
- disabled: false,
143
- features: {
144
- allowfullscreen: true,
145
- allowpaymentrequest: true,
146
- loading: "egager",
147
- },
148
- actions: {
149
- click: () => {
150
- throw new Error("the click action is not defined");
151
- },
152
- },
153
- });
154
- }
155
-
156
- /**
157
- * @return {string}
158
- */
159
- static getTag() {
160
- return "monster-iframe";
161
- }
162
-
163
- /**
164
- * @return {CSSStyleSheet[]}
165
- */
166
- static getCSSStyleSheet() {
167
- return [IframeStyleSheet];
168
- }
65
+ /**
66
+ * This method is called by the `instanceof` operator.
67
+ * @return {symbol}
68
+ */
69
+ static get [instanceSymbol]() {
70
+ return Symbol.for("@schukai/monster/components/layout/iframe@@instance");
71
+ }
72
+
73
+ /**
74
+ *
75
+ * @return {Components.Layout.Iframe
76
+ */
77
+ [assembleMethodSymbol]() {
78
+ super[assembleMethodSymbol]();
79
+ initControlReferences.call(this);
80
+ initEventHandler.call(this);
81
+ calcHeight.call(this);
82
+ return this;
83
+ }
84
+
85
+ /**
86
+ * This method is called by the dom and should not be called directly.
87
+ *
88
+ * @return {void}
89
+ */
90
+ connectedCallback() {
91
+ super.connectedCallback();
92
+ attachResizeObserver.call(this);
93
+
94
+ // disable scrolling in parent node
95
+ if (this.parentNode && this.parentNode instanceof HTMLElement) {
96
+ this.parentNode.style.overflow = "hidden";
97
+ }
98
+ }
99
+
100
+ /**
101
+ * This method is called by the dom and should not be called directly.
102
+ *
103
+ * @return {void}
104
+ */
105
+ disconnectedCallback() {
106
+ super.disconnectedCallback();
107
+ disconnectResizeObserver.call(this);
108
+ }
109
+
110
+ /**
111
+ * To set the options via the HTML tag, the attribute `data-monster-options` must be used.
112
+ * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
113
+ *
114
+ * The individual configuration values can be found in the table.
115
+ *
116
+ * @property {Object} templates Template definitions
117
+ * @property {string} templates.main Main template
118
+ * @property {Object} labels Label definitions
119
+ * @property {Object} actions Callbacks
120
+ * @property {string} actions.click="throw Error" Callback when clicked
121
+ * @property {Object} features Features
122
+ * @property {boolean} features.allowFullScreen=true Allow fullscreen
123
+ * @property {boolean} features.allowPaymentRequest=true Allow payment request
124
+ * @property {boolean} features.replaceTargets=true Replace parent target in iframe
125
+ * @property {string} loading="eager" Loading state
126
+ * @property {string} referrerPolicy="no-referrer" Referrer policy
127
+ * @property {string} src Source
128
+ * @property {Object} classes CSS classes
129
+ * @property {boolean} disabled=false Disabled state
130
+ */
131
+ get defaults() {
132
+ return Object.assign({}, super.defaults, {
133
+ templates: {
134
+ main: getTemplate(),
135
+ },
136
+ src: null,
137
+
138
+ /* "allow-forms allow-pointer-lock allow-popups allow-same-origin allow-scripts allow-top-navigation"*/
139
+ sandbox: null,
140
+
141
+ labels: {},
142
+ classes: {},
143
+
144
+ name: "",
145
+
146
+ referrerPolicy: "no-referrer",
147
+
148
+ disabled: false,
149
+ features: {
150
+ allowFullScreen: true,
151
+ allowPaymentRequest: true,
152
+ replaceTargets: true,
153
+ },
154
+
155
+ loading: "eager",
156
+
157
+ actions: {
158
+ click: () => {
159
+ throw new Error("the click action is not defined");
160
+ },
161
+ },
162
+ });
163
+ }
164
+
165
+ /**
166
+ * @return {string}
167
+ */
168
+ static getTag() {
169
+ return "monster-iframe";
170
+ }
171
+
172
+ /**
173
+ * @return {CSSStyleSheet[]}
174
+ */
175
+ static getCSSStyleSheet() {
176
+ return [IframeStyleSheet];
177
+ }
169
178
  }
170
179
 
171
180
  /**
172
181
  * @private
173
182
  */
174
183
  function calcHeight() {
175
- this.style.boxSizing = "border-box";
184
+ this.style.boxSizing = "border-box";
176
185
 
177
- const height = calculateMaximumHeight.call(this, this.parentNode);
178
- if (height < 0 || isNaN(height)) {
179
- return;
180
- }
186
+ const height = calculateMaximumHeight.call(this, this.parentNode);
187
+ if (height < 0 || isNaN(height)) {
188
+ return;
189
+ }
181
190
 
182
- this[iframeElementSymbol].style.height = `${height}px`;
191
+ this[iframeElementSymbol].style.height = `${height}px`;
183
192
  }
184
193
 
185
194
  /**
@@ -188,90 +197,90 @@ function calcHeight() {
188
197
  * @return {*}
189
198
  */
190
199
  function calculateMaximumHeight(element) {
191
- let totalBottomBorder = 0;
192
- let totalBottomPadding = 0;
193
- let totalBottomMargin = 0;
194
- let totalOutlineHeight = 0;
195
- let totalBoxShadowHeight = 0;
196
- let currentElement = element;
197
-
198
- while (currentElement && currentElement !== document.body) {
199
- const style = window.getComputedStyle(currentElement);
200
- const boxSizing = style.boxSizing;
201
-
202
- const elementHeight = currentElement.getBoundingClientRect().height;
203
-
204
- const borderBottomWidth = parseFloat(style.borderBottomWidth);
205
- const paddingBottom = parseFloat(style.paddingBottom);
206
- const marginBottom = parseFloat(style.marginBottom);
207
-
208
- const outlineHeight = parseFloat(style.outlineWidth);
209
-
210
- totalBottomBorder += isNaN(borderBottomWidth) ? 0 : borderBottomWidth;
211
- totalBottomPadding +=
212
- isNaN(paddingBottom) || boxSizing === "border-box" ? 0 : paddingBottom;
213
- totalBottomMargin += isNaN(marginBottom) ? 0 : marginBottom;
214
- totalOutlineHeight += isNaN(outlineHeight) ? 0 : outlineHeight;
215
-
216
- const boxShadow = style.boxShadow;
217
- let boxShadowVerticalTotal = 0;
218
-
219
- if (boxShadow !== "none") {
220
- const boxShadowValues = boxShadow.split(" ");
221
- const verticalOffset = parseFloat(boxShadowValues[3]);
222
- const blurRadius = parseFloat(boxShadowValues[4]);
223
- const spreadRadius = parseFloat(boxShadowValues[5]);
224
-
225
- boxShadowVerticalTotal = verticalOffset + blurRadius + spreadRadius;
226
- }
227
-
228
- totalBoxShadowHeight += isNaN(boxShadowVerticalTotal)
229
- ? 0
230
- : boxShadowVerticalTotal;
231
-
232
- if (elementHeight > 200) {
233
- return (
234
- elementHeight -
235
- totalBottomBorder -
236
- totalBottomPadding -
237
- totalBottomMargin -
238
- totalOutlineHeight -
239
- totalBoxShadowHeight
240
- );
241
- }
242
-
243
- currentElement = currentElement.parentNode || currentElement.host;
244
- }
200
+ let totalBottomBorder = 0;
201
+ let totalBottomPadding = 0;
202
+ let totalBottomMargin = 0;
203
+ let totalOutlineHeight = 0;
204
+ let totalBoxShadowHeight = 0;
205
+ let currentElement = element;
206
+
207
+ while (currentElement && currentElement !== document.body) {
208
+ const style = window.getComputedStyle(currentElement);
209
+ const boxSizing = style.boxSizing;
210
+
211
+ const elementHeight = currentElement.getBoundingClientRect().height;
212
+
213
+ const borderBottomWidth = parseFloat(style.borderBottomWidth);
214
+ const paddingBottom = parseFloat(style.paddingBottom);
215
+ const marginBottom = parseFloat(style.marginBottom);
216
+
217
+ const outlineHeight = parseFloat(style.outlineWidth);
218
+
219
+ totalBottomBorder += isNaN(borderBottomWidth) ? 0 : borderBottomWidth;
220
+ totalBottomPadding +=
221
+ isNaN(paddingBottom) || boxSizing === "border-box" ? 0 : paddingBottom;
222
+ totalBottomMargin += isNaN(marginBottom) ? 0 : marginBottom;
223
+ totalOutlineHeight += isNaN(outlineHeight) ? 0 : outlineHeight;
224
+
225
+ const boxShadow = style.boxShadow;
226
+ let boxShadowVerticalTotal = 0;
227
+
228
+ if (boxShadow !== "none") {
229
+ const boxShadowValues = boxShadow.split(" ");
230
+ const verticalOffset = parseFloat(boxShadowValues[3]);
231
+ const blurRadius = parseFloat(boxShadowValues[4]);
232
+ const spreadRadius = parseFloat(boxShadowValues[5]);
233
+
234
+ boxShadowVerticalTotal = verticalOffset + blurRadius + spreadRadius;
235
+ }
236
+
237
+ totalBoxShadowHeight += isNaN(boxShadowVerticalTotal)
238
+ ? 0
239
+ : boxShadowVerticalTotal;
240
+
241
+ if (elementHeight > 200) {
242
+ return (
243
+ elementHeight -
244
+ totalBottomBorder -
245
+ totalBottomPadding -
246
+ totalBottomMargin -
247
+ totalOutlineHeight -
248
+ totalBoxShadowHeight
249
+ );
250
+ }
251
+
252
+ currentElement = currentElement.parentNode || currentElement.host;
253
+ }
245
254
  }
246
255
 
247
256
  /**
248
257
  * @private
249
258
  */
250
259
  function attachResizeObserver() {
251
- // against flickering
252
- this[resizeObserverSymbol] = new ResizeObserver(() => {
253
- if (this[timerCallbackSymbol] instanceof DeadMansSwitch) {
254
- try {
255
- this[timerCallbackSymbol].touch();
256
- return;
257
- } catch (e) {
258
- delete this[timerCallbackSymbol];
259
- }
260
- }
261
-
262
- this[timerCallbackSymbol] = new DeadMansSwitch(200, () => {
263
- calcHeight.call(this);
264
- });
265
- });
266
-
267
- this[resizeObserverSymbol].observe(this.ownerDocument.body);
268
- this[resizeObserverSymbol].observe(document.scrollingElement);
260
+ // against flickering
261
+ this[resizeObserverSymbol] = new ResizeObserver(() => {
262
+ if (this[timerCallbackSymbol] instanceof DeadMansSwitch) {
263
+ try {
264
+ this[timerCallbackSymbol].touch();
265
+ return;
266
+ } catch (e) {
267
+ delete this[timerCallbackSymbol];
268
+ }
269
+ }
270
+
271
+ this[timerCallbackSymbol] = new DeadMansSwitch(200, () => {
272
+ calcHeight.call(this);
273
+ });
274
+ });
275
+
276
+ this[resizeObserverSymbol].observe(this.ownerDocument.body);
277
+ this[resizeObserverSymbol].observe(document.scrollingElement);
269
278
  }
270
279
 
271
280
  function disconnectResizeObserver() {
272
- if (this[resizeObserverSymbol] instanceof ResizeObserver) {
273
- this[resizeObserverSymbol].disconnect();
274
- }
281
+ if (this[resizeObserverSymbol] instanceof ResizeObserver) {
282
+ this[resizeObserverSymbol].disconnect();
283
+ }
275
284
  }
276
285
 
277
286
  /**
@@ -280,36 +289,46 @@ function disconnectResizeObserver() {
280
289
  * @fires monster-iframe-clicked
281
290
  */
282
291
  function initEventHandler() {
283
- const self = this;
284
- const element = this[iframeElementSymbol];
285
-
286
- const type = "click";
287
-
288
- element.addEventListener(type, function (event) {
289
- const callback = self.getOption("actions.click");
290
-
291
- fireCustomEvent(self, "monster-iframe-clicked", {
292
- element: self,
293
- });
294
-
295
- if (!isFunction(callback)) {
296
- return;
297
- }
298
-
299
- const element = findTargetElementFromEvent(
300
- event,
301
- ATTRIBUTE_ROLE,
302
- "control",
303
- );
304
-
305
- if (!(element instanceof Node && self.hasNode(element))) {
306
- return;
307
- }
308
-
309
- callback.call(self, event);
310
- });
311
-
312
- return this;
292
+ const self = this;
293
+ const element = this[iframeElementSymbol];
294
+
295
+ const type = "click";
296
+
297
+ element.addEventListener(type, function (event) {
298
+ const callback = self.getOption("actions.click");
299
+
300
+ fireCustomEvent(self, "monster-iframe-clicked", {
301
+ element: self,
302
+ });
303
+
304
+ if (!isFunction(callback)) {
305
+ return;
306
+ }
307
+
308
+ const element = findTargetElementFromEvent(
309
+ event,
310
+ ATTRIBUTE_ROLE,
311
+ "control",
312
+ );
313
+
314
+ if (!(element instanceof Node && self.hasNode(element))) {
315
+ return;
316
+ }
317
+
318
+ callback.call(self, event);
319
+ });
320
+
321
+ this[iframeElementSymbol].addEventListener("load", () => {
322
+ calcHeight.call(this);
323
+ if (this.getOption("features.replaceParentTarget")) {
324
+ var links = this[iframeElementSymbol].contentDocument.querySelectorAll('a[target="_parent"], form[target="_parent"], a[target="_top"], form[target="_top"]');
325
+ links.forEach(function(link) {
326
+ link.target = '_self';
327
+ });
328
+ }
329
+ });
330
+
331
+ return this;
313
332
  }
314
333
 
315
334
  /**
@@ -317,17 +336,17 @@ function initEventHandler() {
317
336
  * @return {void}
318
337
  */
319
338
  function initControlReferences() {
320
- if (!this.shadowRoot) {
321
- throw new Error("no shadow-root is defined");
322
- }
339
+ if (!this.shadowRoot) {
340
+ throw new Error("no shadow-root is defined");
341
+ }
323
342
 
324
- this[PanelElementSymbol] = this.shadowRoot.querySelector(
325
- "[data-monster-role=control]",
326
- );
343
+ this[PanelElementSymbol] = this.shadowRoot.querySelector(
344
+ "[data-monster-role=control]",
345
+ );
327
346
 
328
- this[iframeElementSymbol] = this.shadowRoot.querySelector(
329
- `[${ATTRIBUTE_ROLE}="control"] iframe`,
330
- );
347
+ this[iframeElementSymbol] = this.shadowRoot.querySelector(
348
+ `[${ATTRIBUTE_ROLE}="control"] iframe`,
349
+ );
331
350
  }
332
351
 
333
352
  /**
@@ -335,16 +354,16 @@ function initControlReferences() {
335
354
  * @return {string}
336
355
  */
337
356
  function getTemplate() {
338
- // language=HTML
339
- return `
357
+ // language=HTML
358
+ return `
340
359
  <div data-monster-role="control" part="control">
341
360
  <iframe data-monster-role="iframe"
342
361
  data-monster-attributes="sandbox path:sandbox,
343
362
  name path:name,
344
- referrerpolicy path:referrerpolicy,
345
- loading path:features.loading,
346
- allowpaymentrequest path:features.allowpaymentrequest,
347
- allowfullscreen path:features.allowfullscreen,
363
+ referrerpolicy path:referrerPolicy,
364
+ loading path:loading,
365
+ allowpaymentrequest path:features.allowPaymentRequest,
366
+ allowfullscreen path:features.allowFullScreen,
348
367
  src path:src"
349
368
  ></iframe>
350
369
  </div>`;