@schukai/monster 3.33.0 → 3.34.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@schukai/monster",
3
- "version": "3.33.0",
3
+ "version": "3.34.0",
4
4
  "description": "Monster is a simple library for creating fast, robust and lightweight websites.",
5
5
  "keywords": [
6
6
  "framework",
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Copyright schukai GmbH and contributors 2023. All Rights Reserved.
3
+ * Node module: @schukai/monster
4
+ * This file is licensed under the AGPLv3 License.
5
+ * License text available at https://www.gnu.org/licenses/agpl-3.0.en.html
6
+ */
7
+
8
+ import {getWindow} from './util.mjs';
9
+
10
+ export {convertToPixels, getDeviceDPI}
11
+
12
+
13
+ /**
14
+ * Stores the DPI of the device.
15
+ *
16
+ * @returns {number}
17
+ * @type {number}
18
+ */
19
+ let CURRENT_DEVICE_DPI = function () {
20
+ let i = 0;
21
+ for (i = 56; i < 2000; i++) {
22
+ if (getWindow().matchMedia("(max-resolution: " + i + "dpi)").matches === true) {
23
+ return i;
24
+ }
25
+ }
26
+ return i;
27
+ };
28
+
29
+ /**
30
+ * Returns the DPI of the device.
31
+ *
32
+ * @returns {number}
33
+ */
34
+ function getDeviceDPI() {
35
+ // only call the function once
36
+ if (typeof CURRENT_DEVICE_DPI === 'function') {
37
+ CURRENT_DEVICE_DPI = CURRENT_DEVICE_DPI();
38
+ }
39
+
40
+ return getWindow().devicePixelRatio * CURRENT_DEVICE_DPI;
41
+ }
42
+
43
+
44
+ /**
45
+ * Converts a CSS value to pixels.
46
+ *
47
+ * As Example:
48
+ *
49
+ * ```js
50
+ * convertToPixels('1em') // returns the current font size in pixels
51
+ * convertToPixels('1rem') // returns the current root font size in pixels
52
+ * convertToPixels('1px') // returns 1
53
+ * convertToPixels('100%') // returns the current width of the parent element in pixels
54
+ * ```
55
+ *
56
+ * Following units are supported:
57
+ * - px
58
+ * - em
59
+ * - rem
60
+ * - %
61
+ *
62
+ * @param value
63
+ * @param parentElement
64
+ * @param fontSizeElement
65
+ * @returns {number}
66
+ * @license AGPLv3
67
+ * @since 1.6.0
68
+ * @copyright schukai GmbH
69
+ * @memberOf Monster.DOM
70
+ * @throws {Error} Unsupported unit
71
+ */
72
+
73
+ function convertToPixels(value, parentElement = document.documentElement, fontSizeElement = document.documentElement) {
74
+ const regex = /^([\d.]+)(.*)$/;
75
+ const [, num, unit] = value.match(regex);
76
+ const number = parseFloat(num);
77
+ const dpi = getDeviceDPI();
78
+
79
+ if (unit === 'px') {
80
+ return number;
81
+ } else if (unit === 'em') {
82
+ const fontSize = parseFloat(window.getComputedStyle(fontSizeElement).fontSize);
83
+ return number * fontSize;
84
+ } else if (unit === 'rem') {
85
+ const rootFontSize = parseFloat(window.getComputedStyle(parentElement).fontSize);
86
+ return number * rootFontSize;
87
+ } else if (unit === '%') {
88
+ const parentWidth = parseFloat(window.getComputedStyle(parentElement).width);
89
+ return (number * parentWidth) / 100;
90
+ } else if (unit === 'in') {
91
+ return number * dpi;
92
+ } else if (unit === 'cm') {
93
+ return (number * dpi) / 2.54;
94
+ } else if (unit === 'mm') {
95
+ return (number * dpi) / 25.4;
96
+ } else if (unit === 'pt') {
97
+ return (number * dpi) / 72;
98
+ } else if (unit === 'pc') {
99
+ return (number * dpi) / 6;
100
+ } else {
101
+ throw new Error(`Unsupported unit: ${unit}`);
102
+ }
103
+ }
104
+
105
+
@@ -142,7 +142,7 @@ function getMonsterVersion() {
142
142
  }
143
143
 
144
144
  /** don't touch, replaced by make with package.json version */
145
- monsterVersion = new Version("3.33.0");
145
+ monsterVersion = new Version("3.34.0");
146
146
 
147
147
  return monsterVersion;
148
148
  }
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Copyright schukai GmbH and contributors 2023. All Rights Reserved.
3
+ * Node module: @schukai/monster
4
+ * This file is licensed under the AGPLv3 License.
5
+ * License text available at https://www.gnu.org/licenses/agpl-3.0.en.html
6
+ */
7
+
8
+ const ENV_AWS_LAMBDA = 'aws-lambda';
9
+ const ENV_GOOGLE_FUNCTIONS = 'google-functions';
10
+ const ENV_ELECTRON = 'electron';
11
+ const ENV_NODE = 'node';
12
+ const ENV_BROWSER = 'browser';
13
+ const ENV_WEB_WORKER = 'web-worker';
14
+ const ENV_DENO = 'deno';
15
+ const ENV_UNKNOWN = 'unknown';
16
+
17
+ /**
18
+ * Detects and returns the current runtime environment.
19
+ *
20
+ * - 'aws-lambda': AWS Lambda environment
21
+ * - 'google-functions': Google Cloud Functions environment
22
+ * - 'electron': Electron environment
23
+ * - 'node': Node.js environment
24
+ * - 'browser': Browser environment
25
+ * - 'web-worker': Web Worker environment
26
+ * - 'deno': Deno environment
27
+ * - 'react-native': React Native environment
28
+ * - 'unknown': Unknown environment
29
+ *
30
+ * @returns {string} The detected runtime environment. Possible values are:
31
+ */
32
+ function detectRuntimeEnvironment() {
33
+ // AWS Lambda environment
34
+ if (
35
+ typeof process !== 'undefined' &&
36
+ process.env != null &&
37
+ process.env.AWS_LAMBDA_FUNCTION_NAME
38
+ ) {
39
+ return ENV_AWS_LAMBDA;
40
+ }
41
+
42
+ // Google Cloud Functions environment
43
+ if (
44
+ typeof process !== 'undefined' &&
45
+ process.env != null &&
46
+ process.env.FUNCTION_NAME
47
+ ) {
48
+ return ENV_GOOGLE_FUNCTIONS;
49
+ }
50
+
51
+ // Node.js environment
52
+ if (
53
+ typeof process !== 'undefined' &&
54
+ process.versions != null &&
55
+ process.versions.node != null
56
+ ) {
57
+ // Electron environment
58
+ if (process.versions.electron != null) {
59
+ return ENV_ELECTRON;
60
+ }
61
+ return ENV_NODE;
62
+ }
63
+
64
+ // Browser environment
65
+ if (
66
+ typeof window !== 'undefined' &&
67
+ typeof window.document !== 'undefined' &&
68
+ typeof navigator !== 'undefined' &&
69
+ typeof navigator.userAgent === 'string'
70
+ ) {
71
+ // Web Worker environment
72
+ if (typeof self === 'object' && typeof importScripts === 'function') {
73
+ return ENV_WEB_WORKER;
74
+ }
75
+ return ENV_BROWSER;
76
+ }
77
+
78
+ // Deno environment
79
+ if (typeof Deno !== 'undefined') {
80
+ return ENV_DENO;
81
+ }
82
+
83
+ // Unknown environment
84
+ return ENV_UNKNOWN;
85
+ }
86
+
87
+ export {
88
+ ENV_AWS_LAMBDA,
89
+ ENV_GOOGLE_FUNCTIONS,
90
+ ENV_ELECTRON,
91
+ ENV_NODE,
92
+ ENV_BROWSER,
93
+ ENV_WEB_WORKER,
94
+ ENV_DENO,
95
+ ENV_UNKNOWN,
96
+ detectRuntimeEnvironment}
@@ -1,5 +1,3 @@
1
- 'use strict';
2
-
3
1
  import {expect} from "chai"
4
2
 
5
3
  import {ATTRIBUTEPREFIX, Assembler} from "../../../../application/source/dom/assembler.mjs";
@@ -1,4 +1,3 @@
1
- 'use strict';
2
1
 
3
2
  import {expect} from "chai"
4
3
 
@@ -0,0 +1,128 @@
1
+ import {expect} from 'chai';
2
+ import {convertToPixels, getDeviceDPI} from "../../../../application/source/dom/dimension.mjs";
3
+ import {getWindow} from "../../../../application/source/dom/util.mjs";
4
+ import {initJSDOM, isBrowser, JSDOMExport as JSDOM} from "../../util/jsdom.mjs";
5
+ import {getGlobal} from "../../../../application/source/types/global.mjs";
6
+ import {detectRuntimeEnvironment} from "../../../../application/source/util/runtime.mjs";
7
+
8
+
9
+ function getMockWindow(dpi) {
10
+
11
+ if(detectRuntimeEnvironment() === 'browser') {
12
+ return getWindow();
13
+ }
14
+
15
+
16
+ const dom = new JSDOM('', {
17
+ pretendToBeVisual: true,
18
+ resources: 'usable',
19
+ });
20
+
21
+ dom.window.matchMedia = (query) => {
22
+ const dpiRegex = /\(max-resolution: (\d+)dpi\)/;
23
+ const match = query.match(dpiRegex);
24
+
25
+ if (match) {
26
+ const maxDpi = parseInt(match[1], 10);
27
+ return {matches: dpi <= maxDpi};
28
+ }
29
+
30
+ return {matches: false};
31
+ };
32
+
33
+ return dom.window;
34
+ }
35
+
36
+ describe('dimension', () => {
37
+ let currentEnvironment;
38
+
39
+ before(function (done) {
40
+ initJSDOM().then(() => {
41
+ //chaiDom(getDocument());
42
+ done();
43
+ });
44
+ })
45
+
46
+ beforeEach(() => {
47
+
48
+ const testDpi = 96;
49
+ const testWindow = getMockWindow(testDpi);
50
+ getGlobal().window = testWindow;
51
+
52
+ });
53
+
54
+ afterEach(() => {
55
+ delete getGlobal().window;
56
+ });
57
+
58
+ describe('convertToPixels', () => {
59
+ it('should correctly convert px values', () => {
60
+ const result = convertToPixels('100px');
61
+ expect(result).to.equal(100);
62
+ });
63
+
64
+ it('should correctly convert em values', () => {
65
+ const testElement = document.createElement('div');
66
+ testElement.style.fontSize = '16px';
67
+ document.body.appendChild(testElement);
68
+
69
+ const result = convertToPixels('2em', testElement, testElement);
70
+ expect(result).to.equal(32);
71
+
72
+ document.body.removeChild(testElement);
73
+ });
74
+
75
+ it('should correctly convert rem values', () => {
76
+ const testElement = document.createElement('div');
77
+ testElement.style.fontSize = '16px';
78
+ document.documentElement.appendChild(testElement);
79
+
80
+ const result = convertToPixels('2rem', testElement);
81
+ expect(result).to.equal(32);
82
+
83
+ document.documentElement.removeChild(testElement);
84
+ });
85
+
86
+ it('should correctly convert percentage values', () => {
87
+ const testElement = document.createElement('div');
88
+ testElement.style.width = '500px';
89
+ document.body.appendChild(testElement);
90
+
91
+ const result = convertToPixels('50%', testElement);
92
+ expect(result).to.equal(250);
93
+
94
+ document.body.removeChild(testElement);
95
+ });
96
+
97
+ it('should throw an error for unsupported units', () => {
98
+ expect(() => convertToPixels('10unsupportedUnit')).to.throw('Unsupported unit: unsupportedUnit');
99
+ });
100
+ });
101
+
102
+
103
+ describe('getDeviceDPI', () => {
104
+ it('should return the correct device DPI', () => {
105
+ const testDpi = 96;
106
+ const testWindow = getMockWindow(testDpi);
107
+ getGlobal().window = testWindow;
108
+
109
+ const deviceDpi = getDeviceDPI();
110
+ expect(deviceDpi).to.equal(testDpi * testWindow.devicePixelRatio);
111
+
112
+ delete getGlobal().window;
113
+ });
114
+
115
+ it('should cache the result and return the same value', () => {
116
+ const testDpi = 96;
117
+ const testWindow = getMockWindow(testDpi);
118
+ getGlobal().window = testWindow;
119
+
120
+ const deviceDpi1 = getDeviceDPI();
121
+ const deviceDpi2 = getDeviceDPI();
122
+ expect(deviceDpi1).to.equal(deviceDpi2);
123
+
124
+ delete getGlobal().window;
125
+ });
126
+ });
127
+
128
+ });
@@ -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("3.33.0")
10
+ monsterVersion = new Version("3.34.0")
11
11
 
12
12
  let m = getMonsterVersion();
13
13
 
@@ -6,6 +6,7 @@ import {getGlobal} from "../../../application/source/types/global.mjs";
6
6
  export const isBrowser = new Function("try {return this===window;}catch(e){ return false;}");
7
7
  export const isNode = new Function("try {return this===global;}catch(e){return false;}");
8
8
 
9
+ let JSDOMExport = null;
9
10
 
10
11
  /**
11
12
  * this helper function creates the dom stack in the node environment
@@ -27,6 +28,7 @@ function initJSDOM(options) {
27
28
  }, options || {})
28
29
 
29
30
  return import("jsdom").then(({JSDOM}) => {
31
+ JSDOMExport = JSDOM;
30
32
  const {window} = new JSDOM(`<html>
31
33
  <head>
32
34
  </head>
@@ -85,5 +87,5 @@ function initJSDOM(options) {
85
87
  });
86
88
  }
87
89
 
88
- export {initJSDOM}
90
+ export {initJSDOM,JSDOMExport}
89
91
 
@@ -20,6 +20,7 @@ import "../cases/dom/resource.mjs";
20
20
  import "../cases/dom/resourcemanager.mjs";
21
21
  import "../cases/dom/util.mjs";
22
22
  import "../cases/dom/find.mjs";
23
+ import "../cases/dom/dimension.mjs";
23
24
  import "../cases/dom/customelement.mjs";
24
25
  import "../cases/dom/attributes.mjs";
25
26
  import "../cases/dom/events.mjs";
@@ -14,8 +14,8 @@
14
14
  </head>
15
15
  <body>
16
16
  <div id="headline" style="display: flex;align-items: center;justify-content: center;flex-direction: column;">
17
- <h1 style='margin-bottom: 0.1em;'>Monster 3.32.0</h1>
18
- <div id="lastupdate" style='font-size:0.7em'>last update So 26. Mär 17:02:25 CEST 2023</div>
17
+ <h1 style='margin-bottom: 0.1em;'>Monster 3.33.0</h1>
18
+ <div id="lastupdate" style='font-size:0.7em'>last update Mo 27. Mär 18:10:51 CEST 2023</div>
19
19
  </div>
20
20
  <div id="mocks"></div>
21
21
  <div id="mocha"></div>