3 Commits

Author SHA1 Message Date
35d2ef8580 Remove package lock npm file
Some checks failed
JavaScriptUtilsVitest / ci-tests (push) Has been cancelled
2025-11-27 18:01:12 +09:00
5b69cecf9f Update isObject and isIterable, isArray
Some checks failed
JavaScriptUtilsVitest / ci-tests (push) Has been cancelled
isObject only returns true for objects and nothing else.
Update cel/ael in the HTML builder to use isArray for array check
2025-11-27 17:29:03 +09:00
ef8b4e04ce Add more URL parse helper functions, update Readme file
All checks were successful
JavaScriptUtilsVitest / ci-tests (push) Successful in 22s
`npm build` is deprecated it is now `npm run`

Add more url parser
- set/remove entry from URL
- get single entry from URL alt version
- check if url has key entry
2025-05-29 11:21:12 +09:00
18 changed files with 312 additions and 3959 deletions

1
.gitignore vendored
View File

@@ -1,2 +1,3 @@
node_modules/ node_modules/
coverage/* coverage/*
package-lock.json

View File

@@ -100,19 +100,19 @@ Build with the following commands, the output will be stored in "build/js/output
For full not minified version For full not minified version
```sh ```sh
npm build utils-build npm run utils-build
``` ```
For minified build (but keeps the function names as is) For minified build (but keeps the function names as is)
```sh ```sh
npm build utils-min-build npm run utils-min-build
``` ```
Or build both at the same time Or build both at the same time
```sh ```sh
npm build utils-build-all npm run utils-build-all
``` ```
## Develop ## Develop

3899
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -10,6 +10,8 @@ import {
isFunction as _isFunction, isFunction as _isFunction,
executeFunctionByName as _executeFunctionByName, executeFunctionByName as _executeFunctionByName,
isObject as _isObject, isObject as _isObject,
isArray as _isArray,
isIterable as _isIterable,
getObjectCount as _getObjectCount, getObjectCount as _getObjectCount,
keyInObject as _keyInObject, keyInObject as _keyInObject,
getKeyByValue as _getKeyByValue, getKeyByValue as _getKeyByValue,
@@ -61,7 +63,11 @@ import {
} from './utils/FormatBytes.mjs'; } from './utils/FormatBytes.mjs';
import { import {
parseQueryString as _parseQueryString, parseQueryString as _parseQueryString,
getQueryStringParam as _getQueryStringParam getQueryStringParam as _getQueryStringParam,
hasUrlParameter as _hasUrlParameter,
getUrlParameter as _getUrlParameter,
updateUrlParameter as _updateUrlParameter,
removeUrlParameter as _removeUrlParameter,
} from './utils/UrlParser.mjs'; } from './utils/UrlParser.mjs';
import { import {
loginLogout as _loginLogout, loginLogout as _loginLogout,
@@ -81,6 +87,11 @@ import { l10nTranslation } from './utils/l10nTranslation.mjs';
import { HtmlElementCreator } from './utils/HtmlElementCreator.mjs'; import { HtmlElementCreator } from './utils/HtmlElementCreator.mjs';
import { ActionBox } from './utils/ActionBox.mjs'; import { ActionBox } from './utils/ActionBox.mjs';
import { LoginNavMenu } from './utils/LoginNavMenu.mjs'; import { LoginNavMenu } from './utils/LoginNavMenu.mjs';
import {
isWebkit as _isWebkit,
isMobileWebKit as _isMobileWebKit,
isDesktopWebKit as _isDesktopWebKit
} from './utils/BrowserDetect.mjs';
let aiob = new ActionIndicatorOverlayBox(); let aiob = new ActionIndicatorOverlayBox();
let hec = new HtmlElementCreator(); let hec = new HtmlElementCreator();
@@ -433,8 +444,8 @@ function executeFunctionByName(functionName, context) // eslint-disable-line no-
/** /**
* checks if a variable is an object * checks if a variable is an object
* @param {any} val possible object * @param {any} val possible object
* @return {Boolean} true/false if it is an object or not * @return {Boolean} true/false if it is an object or not
*/ */
// @ts-ignore // @ts-ignore
function isObject(val) // eslint-disable-line no-unused-vars function isObject(val) // eslint-disable-line no-unused-vars
@@ -442,6 +453,28 @@ function isObject(val) // eslint-disable-line no-unused-vars
return _isObject(val); return _isObject(val);
} }
/**
* Check if variable is array
* @param {any} val possible array
* @returns {Boolean} true/false if it an array
*/
// @ts-ignore
function isArray(val) // eslint-disable-line no-unused-vars
{
return _isArray(val);
}
/**
* checks if a variable is an iterable
* @param {any} val possible iterable
* @return {Boolean} true/false if it is an object or not
*/
// @ts-ignore
function isIterable(val) // eslint-disable-line no-unused-vars
{
return _isIterable(val);
}
/** /**
* get the length of an object (entries) * get the length of an object (entries)
* @param {Object} object object to check * @param {Object} object object to check
@@ -937,16 +970,14 @@ function html_options_refill(name, data, sort = '') // eslint-disable-line no-un
* ALTERNATIVE CODE * ALTERNATIVE CODE
* var url = new URL(window.location.href); * var url = new URL(window.location.href);
* param_uid = url.searchParams.get('uid'); * param_uid = url.searchParams.get('uid');
* @param {String} [query=''] the query string to parse * @param {String} [query=''] the query string to parse, if not set will auto fill
* if not set will auto fill * @param {String} [return_key=''] if set only returns this key entry or empty for none
* @param {String} [return_key=''] if set only returns this key entry * @param {Boolean} [single=false] if set to true then only the first found will be returned
* or empty for none
* @return {Object|String} parameter entry list
*/ */
// @ts-ignore // @ts-ignore
function parseQueryString(query = '', return_key = '') // eslint-disable-line no-unused-vars function parseQueryString(query = '', return_key = '', single = false) // eslint-disable-line no-unused-vars
{ {
return _parseQueryString(query, return_key); return _parseQueryString(query, return_key, single);
} }
/** /**
@@ -955,15 +986,12 @@ function parseQueryString(query = '', return_key = '') // eslint-disable-line no
* if a parameter is set several times it will be returned as an array * if a parameter is set several times it will be returned as an array
* if search parameter set and nothing found and empty string is returned * if search parameter set and nothing found and empty string is returned
* if no parametes exist and no serach is set and empty object is returned * if no parametes exist and no serach is set and empty object is returned
* @param {String} [search=''] if set searches for this entry, if empty * @param {String} [search=''] if set searches for this entry, if empty all parameters are returned
* all parameters are returned * @param {String} [query=''] different query string to parse, if not set (default) the current window href is used
* @param {String} [query=''] different query string to parse, if not * @param {Boolean} [single=false] if set to true then only the first found will be returned
* set (default) the current window href is used * @return {Object|Array|String} if search is empty, object, if search is set
* @param {Boolean} [single=false] if set to true then only the first found * and only one entry, then string, else array
* will be returned * unless single is true
* @return {Object|Array|String} if search is empty, object, if search is set
* and only one entry, then string, else array
* unless single is true
*/ */
// @ts-ignore // @ts-ignore
function getQueryStringParam(search = '', query = '', single = false) // eslint-disable-line no-unused-vars function getQueryStringParam(search = '', query = '', single = false) // eslint-disable-line no-unused-vars
@@ -971,6 +999,51 @@ function getQueryStringParam(search = '', query = '', single = false) // eslint-
return _getQueryStringParam(search, query, single); return _getQueryStringParam(search, query, single);
} }
/**
* Add or update a query parameter in the current URL and update the browser's address bar
* @param {string} key - The parameter name to add or update
* @param {string} value - The value to set for the parameter
* @param {boolean} [reload=false] - Whether to reload the page after updating the URL
*/
// @ts-ignore
function updateUrlParameter(key, value, reload = false) // eslint-disable-line no-unused-vars
{
return _updateUrlParameter(key, value, reload);
}
/**
* Remove a parameter from the current URL and update the browser's address bar
* @param {string} key - The parameter name to remove
* @param {boolean} [reload=false] - Whether to reload the page after updating the URL
*/
// @ts-ignore
function removeUrlParameter(key, reload = false) // eslint-disable-line no-unused-vars
{
return _removeUrlParameter(key, reload);
}
/**
* Check if key exists as URL parameter
* @param {String} key URL parameter to search
* @returns {Boolean} True if key exists
*/
// @ts-ignore
function hasUrlParameter(key) // eslint-disable-line no-unused-vars
{
return _hasUrlParameter(key);
}
/**
* Return one value for a URL paramter or null if not found
* @param {String} key Which URL parameter to get
* @returns {String|Null} URL parameter content
*/
// @ts-ignore
function getUrlParameter(key) // eslint-disable-line no-unused-vars
{
return _getUrlParameter(key);
}
// MARK: ACL LOGIN // MARK: ACL LOGIN
// *** MASTER logout call // *** MASTER logout call
/** /**
@@ -1156,4 +1229,20 @@ function adjustActionBoxHeight(target_id = 'actionBox', override = 0, content_ov
ab.adjustActionBoxHeight(target_id, override, content_override); ab.adjustActionBoxHeight(target_id, override, content_override);
} }
// MARK: BROWSER DETECTION
function isWebkit() // eslint-disable-line no-unused-vars
{
return _isWebkit();
}
function isMobileWebKit() // eslint-disable-line no-unused-vars
{
return _isMobileWebKit();
}
function isDesktopWebKit() // eslint-disable-line no-unused-vars
{
return _isDesktopWebKit();
}
/* END */ /* END */

View File

@@ -0,0 +1,31 @@
/*
Description: Browser detect
Date: 2025/11.25
Creator: Clemens Schwaighofer
*/
export { isWebkit, isMobileWebKit, isDesktopWebKit };
// Desktop Safari, all mobile WebKit browsers on iOS and webview iOS
function isWebkit()
{
return "GestureEvent" in window;
}
// all mobile webkit browsers and webview iOS
function isMobileWebKit()
{
return "ongesturechange" in window;
}
// Desktop Safari
function isDesktopWebKit()
{
return (
typeof window !== 'undefined' &&
'safari' in window &&
'pushNotification' in window.safari
);
}
// __END__

View File

@@ -1,6 +1,6 @@
/* /*
Description: Date Time functions Description: Date Time functions
Date: 2025//3/6 Date: 2025/3/6
Creator: Clemens Schwaighofer Creator: Clemens Schwaighofer
*/ */

View File

@@ -1,6 +1,6 @@
/* /*
Description: DOM Helpers Description: DOM Helpers
Date: 2025//3/6 Date: 2025/3/6
Creator: Clemens Schwaighofer Creator: Clemens Schwaighofer
*/ */

View File

@@ -1,6 +1,6 @@
/* /*
Description: Byte string formatting Description: Byte string formatting
Date: 2025//3/6 Date: 2025/3/6
Creator: Clemens Schwaighofer Creator: Clemens Schwaighofer
*/ */

View File

@@ -1,6 +1,6 @@
/* /*
Description: DOM Management and HTML builder Description: DOM Management and HTML builder
Date: 2025//3/6 Date: 2025/3/6
Creator: Clemens Schwaighofer Creator: Clemens Schwaighofer
*/ */
@@ -9,7 +9,7 @@ export {
// deprecated name // deprecated name
HtmlElementCreator as DomManagement HtmlElementCreator as DomManagement
}; };
import { deepCopyFunction, isObject } from './JavaScriptHelpers.mjs'; import { deepCopyFunction, isObject, isArray } from './JavaScriptHelpers.mjs';
class HtmlElementCreator { class HtmlElementCreator {
/** /**
@@ -50,7 +50,7 @@ class HtmlElementCreator {
base.sub.push(deepCopyFunction(attach)); base.sub.push(deepCopyFunction(attach));
} else { } else {
// sub check // sub check
if (isObject(base.sub) && base.sub.length > 0) { if (isArray(base.sub) && base.sub.length > 0) {
for (var i = 0; i < base.sub.length; i ++) { for (var i = 0; i < base.sub.length; i ++) {
// recursive call to sub element // recursive call to sub element
this.ael(base.sub[i], attach, id); this.ael(base.sub[i], attach, id);
@@ -209,7 +209,7 @@ class HtmlElementCreator {
} }
} }
// second CSS // second CSS
if (isObject(tree.css) && tree.css.length > 0) { if (isArray(tree.css) && tree.css.length > 0) {
line += ' class="'; line += ' class="';
for (i = 0; i < tree.css.length; i ++) { for (i = 0; i < tree.css.length; i ++) {
line += tree.css[i] + ' '; line += tree.css[i] + ' ';
@@ -234,7 +234,7 @@ class HtmlElementCreator {
// dive into sub tree to attach sub nodes // dive into sub tree to attach sub nodes
// NOTES: we can have content (text) AND sub nodes at the same level // NOTES: we can have content (text) AND sub nodes at the same level
// CONTENT (TEXT) takes preference over SUB NODE in order // CONTENT (TEXT) takes preference over SUB NODE in order
if (isObject(tree.sub) && tree.sub.length > 0) { if (isArray(tree.sub) && tree.sub.length > 0) {
if (tree.content) { if (tree.content) {
content.push(tree.content); content.push(tree.content);
} }

View File

@@ -1,6 +1,6 @@
/* /*
Description: HTML Helpers Description: HTML Helpers
Date: 2025//3/6 Date: 2025/3/6
Creator: Clemens Schwaighofer Creator: Clemens Schwaighofer
*/ */

View File

@@ -1,13 +1,13 @@
/* /*
Description: JavaScript Helpers Description: JavaScript Helpers
Date: 2025//3/6 Date: 2025/3/6
Creator: Clemens Schwaighofer Creator: Clemens Schwaighofer
*/ */
export { export {
errorCatch, isFunction, errorCatch, isFunction,
executeFunctionByName, runFunction, runFunctionArgsArray, executeFunctionByName, runFunction, runFunctionArgsArray,
isObject, getObjectCount, isObject, isIterable, isArray, getObjectCount,
keyInObject, objectKeyExists, keyInObject, objectKeyExists,
getKeyByValue, valueInObject, objectValueExists, getKeyByValue, valueInObject, objectValueExists,
deepCopyFunction deepCopyFunction
@@ -114,10 +114,33 @@ function runFunctionArgsArray(name, args)
*/ */
function isObject(val) function isObject(val)
{ {
if (val === null) { return val !== null && typeof val === 'object' && !Array.isArray(val);
return false; }
}
return ((typeof val === 'function') || (typeof val === 'object')); /**
* Check if variable is array
* @param {any} val possible array
* @returns {Boolean} true/false if it an array
*/
function isArray(val)
{
return val !== null && Array.isArray(val);
}
/**
* Check if any iterable type
* @param {any} val possible iteratable object/array
* @returns {Boolean} true/false if it is iterable
*/
function isIterable(val)
{
if (val == null) return false;
// Check if it's iterable, but excldue strings
if (typeof val[Symbol.iterator] === 'function' && typeof val !== 'string') return true;
// Check if it's a plain object
return typeof val === 'object' && val.constructor === Object;
} }
/** /**

View File

@@ -1,6 +1,6 @@
/* /*
Description: Login access and menu Description: Login access and menu
Date: 2025//3/6 Date: 2025/3/6
Creator: Clemens Schwaighofer Creator: Clemens Schwaighofer
*/ */

View File

@@ -1,6 +1,6 @@
/* /*
Description: Login access and menu Description: Login access and menu
Date: 2025//3/6 Date: 2025/3/6
Creator: Clemens Schwaighofer Creator: Clemens Schwaighofer
*/ */

View File

@@ -1,6 +1,6 @@
/* /*
Description: Resize and Move Javascript Description: Resize and Move Javascript
Date: 2025//3/6 Date: 2025/3/6
Creator: Clemens Schwaighofer Creator: Clemens Schwaighofer
*/ */

View File

@@ -1,6 +1,6 @@
/* /*
Description: String Helpers Description: String Helpers
Date: 2025//3/6 Date: 2025/3/6
Creator: Clemens Schwaighofer Creator: Clemens Schwaighofer
*/ */

View File

@@ -1,10 +1,10 @@
/* /*
Description: HTML Helpers Description: HTML Helpers
Date: 2025//3/6 Date: 2025/3/6
Creator: Clemens Schwaighofer Creator: Clemens Schwaighofer
*/ */
export { parseQueryString, getQueryStringParam }; export { parseQueryString, getQueryStringParam, hasUrlParameter, getUrlParameter, updateUrlParameter, removeUrlParameter };
/** /**
* NOTE: this original code was wrong, now using URL and parsing through * NOTE: this original code was wrong, now using URL and parsing through
@@ -13,13 +13,10 @@ export { parseQueryString, getQueryStringParam };
* ALTERNATIVE CODE * ALTERNATIVE CODE
* var url = new URL(window.location.href); * var url = new URL(window.location.href);
* param_uid = url.searchParams.get('uid'); * param_uid = url.searchParams.get('uid');
* @param {String} [query=''] the query string to parse * @param {String} [query=''] the query string to parse, if not set will auto fill
* if not set will auto fill * @param {String} [return_key=''] if set only returns this key entry or empty for none
* @param {String} [return_key=''] if set only returns this key entry * @param {Boolean} [single=false] if set to true then only the first found will be returned
* or empty for none * @return {Object|String} parameter entry list
* @param {Boolean} [single=false] if set to true then only the first found
* will be returned
* @return {Object|String} parameter entry list
*/ */
function parseQueryString(query = '', return_key = '', single = false) function parseQueryString(query = '', return_key = '', single = false)
{ {
@@ -32,15 +29,12 @@ function parseQueryString(query = '', return_key = '', single = false)
* if a parameter is set several times it will be returned as an array * if a parameter is set several times it will be returned as an array
* if search parameter set and nothing found and empty string is returned * if search parameter set and nothing found and empty string is returned
* if no parametes exist and no serach is set and empty object is returned * if no parametes exist and no serach is set and empty object is returned
* @param {String} [search=''] if set searches for this entry, if empty * @param {String} [search=''] if set searches for this entry, if empty all parameters are returned
* all parameters are returned * @param {String} [query=''] different query string to parse, if not set (default) the current window href is used
* @param {String} [query=''] different query string to parse, if not * @param {Boolean} [single=false] if set to true then only the first found will be returned
* set (default) the current window href is used * @return {Object|Array|String} if search is empty, object, if search is set
* @param {Boolean} [single=false] if set to true then only the first found * and only one entry, then string, else array
* will be returned * unless single is true
* @return {Object|Array|String} if search is empty, object, if search is set
* and only one entry, then string, else array
* unless single is true
*/ */
function getQueryStringParam(search = '', query = '', single = false) function getQueryStringParam(search = '', query = '', single = false)
{ {
@@ -75,4 +69,74 @@ function getQueryStringParam(search = '', query = '', single = false)
return param; return param;
} }
/**
* Check if key exists as URL parameter
* @param {String} key URL parameter to search
* @returns {Boolean} True if key exists
*/
function hasUrlParameter(key)
{
var urlParams = new URLSearchParams(window.location.search);
return urlParams.has(key);
}
/**
* Return one value for a URL paramter or null if not found
* @param {String} key Which URL parameter to get
* @returns {String|Null} URL parameter content
*/
function getUrlParameter(key)
{
var urlParams = new URLSearchParams(window.location.search);
return urlParams.get(key);
}
/**
* Add or update a query parameter in the current URL and update the browser's address bar
* @param {string} key - The parameter name to add or update
* @param {string} value - The value to set for the parameter
* @param {boolean} [reload=false] - Whether to reload the page after updating the URL
*/
function updateUrlParameter(key, value, reload = false)
{
// Create a URL object from the current URL
const url = new URL(window.location.href);
// Set or update the parameter
url.searchParams.set(key, value);
const newUrl = url.toString();
// Update the browser's address bar without reloading the page
window.history.pushState({ path: newUrl }, '', newUrl);
// Optionally reload the page
if (reload) {
// window.location.href = newUrl;
window.location.reload();
}
}
/**
* Remove a parameter from the current URL and update the browser's address bar
* @param {string} key - The parameter name to remove
* @param {boolean} [reload=false] - Whether to reload the page after updating the URL
*/
function removeUrlParameter(key, reload = false)
{
// Create a URL object from the current URL
const url = new URL(window.location.href);
// Remove the parameter if it exists
url.searchParams.delete(key);
// Update the browser's address bar without reloading the page
window.history.pushState({}, '', url.toString());
// Optionally reload the page
if (reload) {
window.location.reload();
}
}
// __EMD__ // __EMD__

View File

@@ -1,6 +1,6 @@
/* /*
Description: Translation call Description: Translation call
Date: 2025//3/6 Date: 2025/3/6
Creator: Clemens Schwaighofer Creator: Clemens Schwaighofer
*/ */

View File

@@ -5,6 +5,8 @@ import {
// isFunction, // isFunction,
// executeFunctionByName, // executeFunctionByName,
isObject, isObject,
isArray,
isIterable,
getObjectCount, getObjectCount,
keyInObject, keyInObject,
objectKeyExists, objectKeyExists,
@@ -30,15 +32,57 @@ describe("isObject", () => {
let is_object = { let is_object = {
"a": 1 "a": 1
}; };
let empty_array = [];
let is_array = [1, 2, 3];
let is_string = ""; let is_string = "";
let is_number = 1; let is_number = 1;
expect(isObject(empty_object)).toEqual(true); expect(isObject(empty_object)).toEqual(true);
expect(isObject(is_object)).toEqual(true); expect(isObject(is_object)).toEqual(true);
expect(isObject(empty_array)).toEqual(false);
expect(isObject(is_array)).toEqual(false);
expect(isObject(is_string)).toEqual(false); expect(isObject(is_string)).toEqual(false);
expect(isObject(is_number)).toEqual(false); expect(isObject(is_number)).toEqual(false);
}); });
}); });
describe("isArray", () => {
it('should return bool if array', () => {
let empty_object = {};
let is_object = {
"a": 1
};
let empty_array = [];
let is_array = [1, 2, 3];
let is_string = "";
let is_number = 1;
expect(isArray(empty_object)).toEqual(false);
expect(isArray(is_object)).toEqual(false);
expect(isArray(empty_array)).toEqual(true);
expect(isArray(is_array)).toEqual(true);
expect(isArray(is_string)).toEqual(false);
expect(isArray(is_number)).toEqual(false);
});
});
describe("isIterable", () => {
it('should return bool if iterable', () => {
let empty_object = {};
let is_object = {
"a": 1
};
let empty_array = [];
let is_array = [1, 2, 3];
let is_string = "";
let is_number = 1;
expect(isIterable(empty_object)).toEqual(true);
expect(isIterable(is_object)).toEqual(true);
expect(isIterable(empty_array)).toEqual(true);
expect(isIterable(is_array)).toEqual(true);
expect(isIterable(is_string)).toEqual(false);
expect(isIterable(is_number)).toEqual(false);
});
});
describe("getObjectCount", () => { describe("getObjectCount", () => {
it('should return count of objects', () => { it('should return count of objects', () => {
let zero = {}; let zero = {};