@schukai/monster 4.128.1 → 4.128.3

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.
Files changed (39) hide show
  1. package/package.json +1 -1
  2. package/source/components/content/stylesheet/camera-capture.mjs +1 -1
  3. package/source/components/content/stylesheet/copy.mjs +1 -1
  4. package/source/components/content/viewer/stylesheet/message.mjs +1 -1
  5. package/source/components/datatable/columnbar.mjs +30 -3
  6. package/source/components/datatable/datatable.mjs +26 -1
  7. package/source/components/datatable/stylesheet/filter-controls-defaults.mjs +1 -1
  8. package/source/components/form/stylesheet/button-bar.mjs +1 -1
  9. package/source/components/form/stylesheet/confirm-button.mjs +1 -1
  10. package/source/components/form/stylesheet/context-error.mjs +1 -1
  11. package/source/components/form/stylesheet/context-help.mjs +1 -1
  12. package/source/components/form/stylesheet/digits.mjs +1 -1
  13. package/source/components/form/stylesheet/field-set.mjs +1 -1
  14. package/source/components/form/stylesheet/login.mjs +1 -1
  15. package/source/components/form/stylesheet/popper-button.mjs +1 -1
  16. package/source/components/form/stylesheet/select.mjs +1 -1
  17. package/source/components/layout/stylesheet/popper.mjs +1 -1
  18. package/source/components/style/floating-ui.css +7 -0
  19. package/source/components/style/floating-ui.pcss +8 -0
  20. package/source/components/stylesheet/floating-ui.mjs +1 -1
  21. package/source/dom/customcontrol.mjs +1 -1
  22. package/source/dom/customelement.mjs +37 -15
  23. package/source/dom/updater.mjs +32 -12
  24. package/source/types/is.mjs +3 -0
  25. package/source/types/proxyobserver.mjs +10 -13
  26. package/source/types/version.mjs +1 -1
  27. package/test/cases/components/content/image-editor.mjs +98 -0
  28. package/test/cases/components/datatable/drag-scroll.mjs +218 -14
  29. package/test/cases/components/form/select.mjs +70 -32
  30. package/test/cases/dom/customcontrol.mjs +44 -10
  31. package/test/cases/dom/customelement-initfromscripthost.mjs +22 -1
  32. package/test/cases/dom/customelement.mjs +83 -0
  33. package/test/cases/dom/updater.mjs +98 -0
  34. package/test/cases/monster.mjs +1 -1
  35. package/test/cases/types/proxyobserver.mjs +31 -0
  36. package/test/web/import.js +3 -0
  37. package/test/web/puppeteer.mjs +94 -71
  38. package/test/web/test.html +29 -2
  39. package/test/web/tests.js +25120 -15937
@@ -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.125.0")
10
+ monsterVersion = new Version("4.128.2")
11
11
 
12
12
  let m = getMonsterVersion();
13
13
 
@@ -261,4 +261,35 @@ describe('ProxyObserver', function () {
261
261
  });
262
262
  });
263
263
 
264
+ describe('runtime compatibility', function () {
265
+ it('should allow nested object access without DOM globals', function () {
266
+ const proxy = new ProxyObserver({options: {enabled: true}});
267
+ expect(proxy.getSubject().options.enabled).to.equal(true);
268
+ });
269
+
270
+ it('should preserve setter semantics for accessor-backed instances', function () {
271
+ let setterCalls = 0;
272
+
273
+ class Example {
274
+ set value(v) {
275
+ setterCalls++;
276
+ this._value = v;
277
+ }
278
+
279
+ get value() {
280
+ return this._value;
281
+ }
282
+ }
283
+
284
+ const instance = new Example();
285
+ const proxy = new ProxyObserver({instance});
286
+
287
+ proxy.getSubject().instance.value = 7;
288
+
289
+ expect(setterCalls).to.equal(1);
290
+ expect(instance.value).to.equal(7);
291
+ expect(Object.prototype.hasOwnProperty.call(instance, 'value')).to.be.false;
292
+ });
293
+ });
294
+
264
295
  })
@@ -3,6 +3,7 @@ import "./prepare.js";
3
3
  import "../cases/components/layout/tabs.mjs";
4
4
  import "../cases/components/layout/slit-panel.mjs";
5
5
  import "../cases/components/layout/panel.mjs";
6
+ import "../cases/components/content/image-editor.mjs";
6
7
  import "../cases/components/form/buy-box.mjs";
7
8
  import "../cases/components/form/message-state-button.mjs";
8
9
  import "../cases/components/form/button-bar.mjs";
@@ -12,6 +13,7 @@ import "../cases/components/form/select.mjs";
12
13
  import "../cases/components/form/confirm-button.mjs";
13
14
  import "../cases/components/form/form.mjs";
14
15
  import "../cases/components/form/tree-select.mjs";
16
+ import "../cases/components/form/wizard.mjs";
15
17
  import "../cases/components/form/button.mjs";
16
18
  import "../cases/components/form/toggle-switch.mjs";
17
19
  import "../cases/components/form/template.mjs";
@@ -21,6 +23,7 @@ import "../cases/components/host/host.mjs";
21
23
  import "../cases/components/host/overlay.mjs";
22
24
  import "../cases/components/host/util.mjs";
23
25
  import "../cases/components/host/details.mjs";
26
+ import "../cases/components/datatable/drag-scroll.mjs";
24
27
  import "../cases/components/datatable/writeback-sanitizer.mjs";
25
28
  import "../cases/components/datatable/pagination.mjs";
26
29
  import "../cases/text/formatter.mjs";
@@ -1,6 +1,9 @@
1
1
  import puppeteer from 'puppeteer';
2
2
  import {unlinkSync} from 'fs';
3
3
  import {existsSync} from 'fs';
4
+ import {mkdtempSync, rmSync} from 'fs';
5
+ import {tmpdir} from 'os';
6
+ import path from 'path';
4
7
 
5
8
 
6
9
  // args auswerten mit --path und --browser, get from args
@@ -30,82 +33,102 @@ if (!config.browser) {
30
33
 
31
34
 
32
35
  (async () => {
33
- const browser = await puppeteer.launch({
34
- headless: 'new', // if you want to see the browser, set this to false
35
- executablePath: config.browser,
36
- //args: ['--no-sandbox',"--window-size=1440,1000", "--no-sandbox", "--disable-setuid-sandbox", "--disable-gpu"],
37
- args: ["--disable-gpu",
38
- '--no-sandbox',
39
- '--disable-setuid-sandbox',
40
- '--user-data-dir=/tmp',
41
- '--enable-logging=stderr',
42
- '--disable-web-security',
43
- '--disable-features=IsolateOrigins',
44
- '--disable-site-isolation-trials'
45
- ],
36
+ const userDataDir = mkdtempSync(path.join(tmpdir(), 'monster-webtest-'));
37
+ let browser;
38
+
39
+ try {
40
+ try {
41
+ browser = await puppeteer.launch({
42
+ headless: 'new', // if you want to see the browser, set this to false
43
+ executablePath: config.browser,
44
+ //args: ['--no-sandbox',"--window-size=1440,1000", "--no-sandbox", "--disable-setuid-sandbox", "--disable-gpu"],
45
+ args: ["--disable-gpu",
46
+ '--no-sandbox',
47
+ '--disable-setuid-sandbox',
48
+ `--user-data-dir=${userDataDir}`,
49
+ '--enable-logging=stderr',
50
+ '--disable-web-security',
51
+ '--disable-features=IsolateOrigins',
52
+ '--disable-site-isolation-trials',
53
+ '--disable-crash-reporter',
54
+ '--disable-breakpad',
55
+ '--no-first-run',
56
+ '--no-default-browser-check',
57
+ '--disable-dev-shm-usage'
58
+ ],
59
+
60
+ userAgent: 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36',
61
+ waitUntil: 'load',
62
+ timeout: 0,
63
+ protocolTimeout: 0,
64
+ dumpio: true
65
+ });
66
+ } catch (error) {
67
+ console.error('Browser launch failed');
68
+ console.error(`Browser executable: ${config.browser}`);
69
+ console.error(`Browser profile: ${userDataDir}`);
70
+ throw error;
71
+ }
72
+
73
+ const page = await browser.newPage();
74
+ const fileUrl = 'file://' + config.path;
75
+
76
+ console.log('Loading page... '+fileUrl);
77
+
78
+ await page.goto(fileUrl, {waitUntil: 'load', timeout: 0});
79
+
80
+ const title = await page.title();
81
+ console.log('Page title:', title);
82
+
83
+ // page.on('console', async e => {
84
+ // const args = await Promise.all(e.args().map(a => a.jsonValue()));
85
+ // console[e.type() === 'warning' ? 'warn' : e.type()](...args);
86
+ // });
87
+ //
88
+ //
89
+ //
90
+ console.log('Running tests...');
91
+ await page.waitForFunction('document.getElementById("mocha-done").textContent.length > 0',
92
+ {
93
+ timeout: 1000000,
94
+ polling: 1000
95
+ }
96
+ ) ;
97
+
98
+ const passes = await page.evaluate(() => document.getElementById('mocha-stats').querySelector('li.passes em').textContent);
99
+ const failures = await page.evaluate(() => document.getElementById('mocha-stats').querySelector('li.failures em').textContent);
100
+ const duration = await page.evaluate(() => document.getElementById('mocha-stats').querySelector('li.duration em').textContent);
101
+
102
+ console.log('Tests passed:', passes);
103
+ console.log('Tests failed:', failures);
104
+ console.log('Duration:', duration);
46
105
 
47
- userAgent: 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36',
48
- waitUntil: 'load',
49
- timeout: 0,
50
- protocolTimeout: 0,
51
- dumpio: true
52
- });
53
-
54
- const page = await browser.newPage();
55
- const fileUrl = 'file://' + config.path;
56
-
57
- console.log('Loading page... '+fileUrl);
58
-
59
- await page.goto(fileUrl, {waitUntil: 'load', timeout: 0});
60
-
61
- const title = await page.title();
62
- console.log('Page title:', title);
63
-
64
- // page.on('console', async e => {
65
- // const args = await Promise.all(e.args().map(a => a.jsonValue()));
66
- // console[e.type() === 'warning' ? 'warn' : e.type()](...args);
67
- // });
68
- //
69
- //
70
- //
71
- console.log('Running tests...');
72
- await page.waitForFunction('document.getElementById("mocha-done").textContent.length > 0',
73
- {
74
- timeout: 1000000,
75
- polling: 1000
106
+ if (existsSync('screenshot.png')) {
107
+ unlinkSync('screenshot.png');
76
108
  }
77
- ) ;
78
-
79
- const passes = await page.evaluate(() => document.getElementById('mocha-stats').querySelector('li.passes em').textContent);
80
- const failures = await page.evaluate(() => document.getElementById('mocha-stats').querySelector('li.failures em').textContent);
81
- const duration = await page.evaluate(() => document.getElementById('mocha-stats').querySelector('li.duration em').textContent);
82
-
83
- console.log('Tests passed:', passes);
84
- console.log('Tests failed:', failures);
85
- console.log('Duration:', duration);
86
-
87
- if (existsSync('screenshot.png')) {
88
- unlinkSync('screenshot.png');
89
- }
90
-
91
- await page.screenshot({ path: 'screenshot.png' });
109
+
110
+ await page.screenshot({ path: 'screenshot.png' });
92
111
 
93
- const failuresAsInt = parseInt(failures);
94
- if (failuresAsInt > 0) {
95
- console.error('Tests failed');
112
+ const failuresAsInt = parseInt(failures);
113
+ if (failuresAsInt > 0) {
114
+ console.error('Tests failed');
96
115
 
97
- await page.evaluate(() => {
98
- document.querySelectorAll('.test.fail').forEach((node) => {
99
- console.error(node.textContent);
116
+ await page.evaluate(() => {
117
+ document.querySelectorAll('.test.fail').forEach((node) => {
118
+ console.error(node.textContent);
119
+ });
100
120
  });
101
- });
102
121
 
103
- await browser.close();
104
- process.exit(1);
105
- } else {
106
- await browser.close();
107
- console.log('Tests passed');
108
- }
122
+ process.exitCode = 1;
123
+ } else {
124
+ console.log('Tests passed');
125
+ }
126
+ } finally {
127
+ if (browser) {
128
+ await browser.close().catch(() => {});
129
+ }
109
130
 
131
+ rmSync(userDataDir, { recursive: true, force: true });
132
+ }
110
133
 
111
- })();
134
+ })();
@@ -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.125.0</h1>
13
- <div id="lastupdate" style='font-size:0.7em'>last update Fr 6. Mär 02:15:36 CET 2026</div>
12
+ <h1 style='margin-bottom: 0.1em;'>Monster 4.128.2</h1>
13
+ <div id="lastupdate" style='font-size:0.7em'>last update Do 26. Mär 19:17:38 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>
@@ -26,8 +26,24 @@
26
26
  <script>
27
27
 
28
28
  try {
29
+ const ignoredBrowserErrorMessages = new Set([
30
+ "ResizeObserver loop completed with undelivered notifications.",
31
+ "ResizeObserver loop limit exceeded",
32
+ ]);
33
+
34
+ const isIgnoredBrowserError = (message, error) => {
35
+ const normalizedMessage = typeof message === "string" && message !== ""
36
+ ? message
37
+ : error?.message;
38
+ return ignoredBrowserErrorMessages.has(normalizedMessage);
39
+ };
29
40
 
30
41
  addEventListener("error", (event) => {
42
+ if (isIgnoredBrowserError(event.message, event.error)) {
43
+ event.preventDefault?.();
44
+ return;
45
+ }
46
+
31
47
  document.getElementById('mocha-errors').insertAdjacentHTML("afterbegin", event.message);
32
48
  document.getElementById('mocha-stats').style.backgroundColor = 'red';
33
49
  });
@@ -41,6 +57,17 @@
41
57
 
42
58
  });
43
59
 
60
+ const mochaOnError = window.onerror;
61
+ if (typeof mochaOnError === "function") {
62
+ window.onerror = function(message, source, line, column, error) {
63
+ if (isIgnoredBrowserError(message, error)) {
64
+ return true;
65
+ }
66
+
67
+ return mochaOnError.call(this, message, source, line, column, error);
68
+ };
69
+ }
70
+
44
71
  runner.on('end', function () {
45
72
  document.getElementById('mocha-done').insertAdjacentHTML("afterbegin", 'the execution is done');
46
73
  document.getElementById('lastupdate').innerHTML = 'last update ' + new Date();