@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 +1 -1
- package/source/dom/dimension.mjs +105 -0
- package/source/types/version.mjs +1 -1
- package/source/util/runtime.mjs +96 -0
- package/test/cases/dom/assembler.mjs +0 -2
- package/test/cases/dom/attributes.mjs +0 -1
- package/test/cases/dom/dimension.mjs +128 -0
- package/test/cases/monster.mjs +1 -1
- package/test/util/jsdom.mjs +3 -1
- package/test/web/import.js +1 -0
- package/test/web/test.html +2 -2
- package/test/web/tests.js +218 -3
package/package.json
CHANGED
|
@@ -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
|
+
|
package/source/types/version.mjs
CHANGED
|
@@ -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}
|
|
@@ -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
|
+
});
|
package/test/cases/monster.mjs
CHANGED
package/test/util/jsdom.mjs
CHANGED
|
@@ -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
|
|
package/test/web/import.js
CHANGED
|
@@ -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";
|
package/test/web/test.html
CHANGED
|
@@ -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.
|
|
18
|
-
<div id="lastupdate" style='font-size:0.7em'>last update
|
|
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>
|