Move login nav menu functions into class

Because we need translations, so we use a class where we require the translation class to be in the constructor

Code fix for i18n variable not set check and default fill for the translation class
This commit is contained in:
2025-03-07 15:26:38 +09:00
parent 55972b4ab7
commit f9ffcd3327
7 changed files with 172 additions and 209 deletions

View File

@@ -3,29 +3,29 @@
<title>JavaScript Test</title> <title>JavaScript Test</title>
<script type="text/javascript" src="js/general/jquery.min.js"></script> <script type="text/javascript" src="js/general/jquery.min.js"></script>
<!-- <script type="text/javascript" src="js/general/translateTest-ja_JP.UTF-8.js"></script> --> <!-- <script type="text/javascript" src="js/general/translateTest-ja_JP.UTF-8.js"></script> -->
<script type="text/javascript" src="js/output/utilsAll.min.js"></script> <script type="text/javascript" src="js/output/utils.min.js"></script>
</head> </head>
<body> <body>
<div> <div>
<h1>JavaScript tests</h1> <h1>JavaScript Utils Test</h1>
<div id="test-div"> <div id="test-div">
</div> </div>
</div> </div>
</body> </body>
<script languagae="JavaScript"> <script languagae="JavaScript">
document.addEventListener('DOMContentLoaded', function() { document.addEventListener('DOMContentLoaded', function() {
console.log('MAIN PAGE LOADED'); console.log('JavaScript Utils Test');
let el = document.getElementById('test-div'); let el = document.getElementById('test-div');
if (el === null) { if (el === null) {
throw new Error("element test-div not found"); throw new Error("element test-div not found");
} }
let bytes = 1021152; let bytes = 1021152;
// //
el.html = ''; el.innerHTML = '';
el.html += '<div>randomIdF: ' + randomIdF() + '</div>'; el.innerHTML += '<div>randomIdF: ' + randomIdF() + '</div>';
el.html += '<div>getWindowSize: ' + getWindowSize() + '</div>'; el.innerHTML += '<div>getWindowSize: ' + JSON.stringify(getWindowSize()) + '</div>';
el.html += '<div>formatBytes: ' + formatBytes(bytes) + '</div>'; el.innerHTML += '<div>formatBytes: ' + formatBytes(bytes) + '</div>';
el.html += '<div>formatBytesLong: ' + formatBytesLong(bytes) + '</div>'; el.innerHTML += '<div>formatBytesLong: ' + formatBytesLong(bytes) + '</div>';
// console.log('TR: %s', l10n.__('Original')); // console.log('TR: %s', l10n.__('Original'));
// console.log('TR: %s', l10n.__('Not exists')); // console.log('TR: %s', l10n.__('Not exists'));

18
package-lock.json generated
View File

@@ -9,6 +9,7 @@
"version": "1.0.0", "version": "1.0.0",
"devDependencies": { "devDependencies": {
"@eslint/js": "^9.20.0", "@eslint/js": "^9.20.0",
"@types/jquery": "^3.5.32",
"esbuild": "^0.25.0", "esbuild": "^0.25.0",
"eslint": "^9.20.1", "eslint": "^9.20.1",
"globals": "^15.15.0" "globals": "^15.15.0"
@@ -653,6 +654,16 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/jquery": {
"version": "3.5.32",
"resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.32.tgz",
"integrity": "sha512-b9Xbf4CkMqS02YH8zACqN1xzdxc3cO735Qe5AbSUFmyOiaWAbcpqh9Wna+Uk0vgACvoQHpWDg2rGdHkYPLmCiQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/sizzle": "*"
}
},
"node_modules/@types/json-schema": { "node_modules/@types/json-schema": {
"version": "7.0.15", "version": "7.0.15",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
@@ -660,6 +671,13 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/sizzle": {
"version": "2.3.9",
"resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.9.tgz",
"integrity": "sha512-xzLEyKB50yqCUPUJkIsrVvoWNfFUbIZI+RspLWt8u+tIW/BetMBZtgV2LY/2o+tYH8dRvQ+eoPf3NdhQCcLE2w==",
"dev": true,
"license": "MIT"
},
"node_modules/acorn": { "node_modules/acorn": {
"version": "8.14.1", "version": "8.14.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",

View File

@@ -4,16 +4,17 @@
"main": "", "main": "",
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1", "test": "echo \"Error: no test specified\" && exit 1",
"utilsAll-min-build": "node_modules/esbuild/bin/esbuild utilsAll.min=src/utilsAll.mjs --outdir=build/js/output/ --format=esm --bundle --charset=utf8 --tree-shaking=false --minify-whitespace --minify-syntax --sourcemap", "utils-min-build": "node_modules/esbuild/bin/esbuild utils.min=src/utils.mjs --outdir=build/js/output/ --format=esm --bundle --charset=utf8 --tree-shaking=false --minify-whitespace --minify-syntax --sourcemap",
"utilsAll-build": "node_modules/esbuild/bin/esbuild utilsAll=src/utilsAll.mjs --outdir=build/js/output/ --format=esm --bundle --charset=utf8 --tree-shaking=false", "utils-build": "node_modules/esbuild/bin/esbuild utils=src/utils.mjs --outdir=build/js/output/ --format=esm --bundle --charset=utf8 --tree-shaking=false",
"utilsAll-build-all": "npm run utilsAll-min-build && npm run utilsAll-build", "utils-build-all": "npm run utils-min-build && npm run utils-build",
"utilsAll-develop": "node_modules/esbuild/bin/esbuild utilsAll=src/utilsAll.mjs --outdir=build/js/output/ --format=esm --bundle --charset=utf8 --tree-shaking=false --watch" "utils-develop": "node_modules/esbuild/bin/esbuild utils=src/utils.mjs --outdir=build/js/output/ --format=esm --bundle --charset=utf8 --tree-shaking=false --watch"
}, },
"author": "Clemens Schwaighofer", "author": "Clemens Schwaighofer",
"license": "", "license": "",
"description": "Javascript Utils Collection", "description": "Javascript Utils Collection",
"devDependencies": { "devDependencies": {
"@eslint/js": "^9.20.0", "@eslint/js": "^9.20.0",
"@types/jquery": "^3.5.32",
"esbuild": "^0.25.0", "esbuild": "^0.25.0",
"eslint": "^9.20.1", "eslint": "^9.20.1",
"globals": "^15.15.0" "globals": "^15.15.0"

View File

@@ -65,9 +65,7 @@ import {
} from './utils/UrlParser.mjs'; } from './utils/UrlParser.mjs';
import { import {
loginLogout as _loginLogout, loginLogout as _loginLogout,
createLoginRow as _createLoginRow, } from './utils/LoginLogout.mjs';
createNavMenu as _createNavMenu
} from './utils/LoginMenu.mjs';
import { import {
ActionIndicatorOverlayBox, ActionIndicatorOverlayBox,
actionIndicator as _actionIndicator, actionIndicator as _actionIndicator,
@@ -82,93 +80,16 @@ import {
import { l10nTranslation } from './utils/l10nTranslation.mjs'; 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';
let aiob = new ActionIndicatorOverlayBox(); let aiob = new ActionIndicatorOverlayBox();
let hec = new HtmlElementCreator(); let hec = new HtmlElementCreator();
// if ( undef === "undefined") {
// @ts-ignore // @ts-ignore
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
let l10n = new l10nTranslation(i18n ?? {}); let l10n = new l10nTranslation(typeof i18n === "undefined" ? {} : i18n);
let ab = new ActionBox(hec, l10n); let ab = new ActionBox(hec, l10n);
let lnm = new LoginNavMenu(hec, l10n);
/* export {
escapeHtml,
roundPrecision,
formatString,
unescapeHtml,
loadEl,
pop,
expandTA,
getWindowSize,
getScrollOffset,
getScrollOffsetOpener,
setCenter,
goToPos,
goTo,
__,
numberWithCommas,
convertLBtoBR,
getTimestamp,
dec2hex,
generateId,
randomIdF,
getRandomIntInclusive,
isFunction,
executeFunctionByName,
isObject,
getObjectCount,
keyInObject,
getKeyByValue,
valueInObject,
deepCopyFunction,
exists,
formatBytes,
formatBytesLong,
stringByteFormat,
errorCatch,
actionIndicator,
actionIndicatorShow,
actionIndicatorHide,
overlayBoxShow,
overlayBoxHide,
setOverlayBox,
hideOverlayBox,
ClearCall,
showActionIndicator,
hideActionIndicator,
checkOverlayExists,
showOverlayBoxLayers,
hideOverlayBoxLayers,
clearCallActionBox,
cel,
ael,
aelx,
aelxar,
rel,
rcssel,
acssel,
scssel,
phfo,
phfa,
html_options,
html_options_block,
html_options_refill,
parseQueryString,
getQueryStringParam,
loginLogout,
createLoginRow,
createNavMenu,
showFillActionBox,
fillActionBox,
adjustActionBox,
hideAllActionBoxes,
hideActionBox,
showActionBox,
closeActionBox,
showActionBoxFloat,
closeActionBoxFloat,
createActionBox,
adjustActionBoxHeight,
}; */
// MARK: deprecated String/Number override // MARK: deprecated String/Number override
@@ -1071,7 +992,7 @@ function loginLogout() // eslint-disable-line no-unused-vars
// @ts-ignore // @ts-ignore
function createLoginRow(login_string, header_id = 'mainHeader') // eslint-disable-line no-unused-vars function createLoginRow(login_string, header_id = 'mainHeader') // eslint-disable-line no-unused-vars
{ {
_createLoginRow(login_string, header_id); lnm.createLoginRow(login_string, header_id);
} }
/** /**
@@ -1085,7 +1006,7 @@ function createLoginRow(login_string, header_id = 'mainHeader') // eslint-disabl
// @ts-ignore // @ts-ignore
function createNavMenu(nav_menu, header_id = 'mainHeader') // eslint-disable-line no-unused-vars function createNavMenu(nav_menu, header_id = 'mainHeader') // eslint-disable-line no-unused-vars
{ {
_createNavMenu(nav_menu, header_id); lnm.createNavMenu(nav_menu, header_id);
} }
// MARK: ACTION BOX // MARK: ACTION BOX

25
src/utils/LoginLogout.mjs Normal file
View File

@@ -0,0 +1,25 @@
/*
Description: Login access and menu
Date: 2025//3/6
Creator: Clemens Schwaighofer
*/
export { loginLogout };
/**
* submits basic data for form logout
*/
function loginLogout()
{
const form = document.createElement('form');
form.method = 'post';
const hiddenField = document.createElement('input');
hiddenField.type = 'hidden';
hiddenField.name = 'login_logout';
hiddenField.value = 'Logout';
form.appendChild(hiddenField);
document.body.appendChild(form);
form.submit();
}
// __END__

View File

@@ -1,111 +0,0 @@
/*
Description: Login access and menu
Date: 2025//3/6
Creator: Clemens Schwaighofer
*/
export { loginLogout, createLoginRow, createNavMenu };
import { isObject, getObjectCount } from './JavaScriptHelpers.mjs';
import { exists } from './DomHelpers.mjs';
import { HtmlElementCreator } from './HtmlElementCreator.mjs';
import { l10nTranslation } from './l10nTranslation.mjs';
let hec = new HtmlElementCreator();
let l10n = new l10nTranslation(i18n ?? {});
/**
* submits basic data for form logout
*/
function loginLogout()
{
const form = document.createElement('form');
form.method = 'post';
const hiddenField = document.createElement('input');
hiddenField.type = 'hidden';
hiddenField.name = 'login_logout';
hiddenField.value = 'Logout';
form.appendChild(hiddenField);
document.body.appendChild(form);
form.submit();
}
/**
* create login string and logout button elements
* @param {String} login_string the login string to show on the left
* @param {String} [header_id='mainHeader'] the target for the main element block
* if not set mainHeader is assumed
* this is the target div for the "loginRow"
*/
function createLoginRow(login_string, header_id = 'mainHeader')
{
// if header does not exist, we do nothing
if (exists(header_id)) {
// that row must exist already, if not it must be the first in the "mainHeader"
if (!exists('loginRow')) {
$('#' + header_id).html(hec.phfo(hec.cel('div', 'loginRow', '', ['loginRow', 'flx-spbt'])));
}
// clear out just in case for first entry
// fill with div name & login/logout button
$('#loginRow').html(hec.phfo(hec.cel('div', 'loginRow-name', login_string)));
$('#loginRow').append(hec.phfo(hec.cel('div', 'loginRow-info', '')));
$('#loginRow').append(hec.phfo(
hec.aelx(
// outer div
hec.cel('div', 'loginRow-logout'),
// inner element
hec.cel('input', 'logout', '', [], {
value: l10n.__('Logout'),
type: 'button',
onClick: 'loginLogout()'
})
)
));
}
}
/**
* create the top nav menu that switches physical between pages
* (edit access data based)
* @param {Object} nav_menu the built nav menu with highlight info
* @param {String} [header_id='mainHeader'] the target for the main element block
* if not set mainHeader is assumed
* this is the target div for the "menuRow"
*/
function createNavMenu(nav_menu, header_id = 'mainHeader')
{
// must be an object
if (isObject(nav_menu) && getObjectCount(nav_menu) > 1) {
// do we have more than one entry, if not, do not show (single page)
if (!exists('menuRow')) {
$('#' + header_id).html(hec.phfo(hec.cel('div', 'menuRow', '', ['menuRow', 'flx-s'])));
}
var content = [];
$.each(nav_menu, function(key, item) {
// key is number
// item is object with entries
if (key != 0) {
content.push(hec.phfo(hec.cel('div', '', '&middot;', ['pd-2'])));
}
// ignore item.popup for now
if (item.enabled) {
// set selected based on window.location.href as the php set will not work
if (window.location.href.indexOf(item.url) != -1) {
item.selected = 1;
}
// create the entry
content.push(hec.phfo(
hec.aelx(
hec.cel('div'),
hec.cel('a', '', item.name, ['pd-2'].concat(item.selected ? 'highlight': ''), {
href: item.url
})
)
));
}
});
$('#menuRow').html(content.join(''));
} else {
$('#menuRow').hide();
}
}
// __END__

109
src/utils/LoginNavMenu.mjs Normal file
View File

@@ -0,0 +1,109 @@
/*
Description: Login access and menu
Date: 2025//3/6
Creator: Clemens Schwaighofer
*/
export { LoginNavMenu };
import { isObject, getObjectCount } from './JavaScriptHelpers.mjs';
import { exists } from './DomHelpers.mjs';
class LoginNavMenu {
hec;
l10n;
/**
* action box creator
* @param {Object} hec HtmlElementCreator
* @param {Object} l10n l10nTranslation
*/
constructor(hec, l10n)
{
this.hec = hec;
this.l10n = l10n;
}
/**
* create login string and logout button elements
* @param {String} login_string the login string to show on the left
* @param {String} [header_id='mainHeader'] the target for the main element block
* if not set mainHeader is assumed
* this is the target div for the "loginRow"
*/
createLoginRow(login_string, header_id = 'mainHeader')
{
// if header does not exist, we do nothing
if (exists(header_id)) {
// that row must exist already, if not it must be the first in the "mainHeader"
if (!exists('loginRow')) {
$('#' + header_id).html(this.hec.phfo(this.hec.cel('div', 'loginRow', '', ['loginRow', 'flx-spbt'])));
}
// clear out just in case for first entry
// fill with div name & login/logout button
$('#loginRow').html(this.hec.phfo(this.hec.cel('div', 'loginRow-name', login_string)));
$('#loginRow').append(this.hec.phfo(this.hec.cel('div', 'loginRow-info', '')));
$('#loginRow').append(this.hec.phfo(
this.hec.aelx(
// outer div
this.hec.cel('div', 'loginRow-logout'),
// inner element
this.hec.cel('input', 'logout', '', [], {
value: this.l10n.__('Logout'),
type: 'button',
onClick: 'loginLogout()'
})
)
));
}
}
/**
* create the top nav menu that switches physical between pages
* (edit access data based)
* @param {Object} nav_menu the built nav menu with highlight info
* @param {String} [header_id='mainHeader'] the target for the main element block
* if not set mainHeader is assumed
* this is the target div for the "menuRow"
*/
createNavMenu(nav_menu, header_id = 'mainHeader')
{
// must be an object
if (isObject(nav_menu) && getObjectCount(nav_menu) > 1) {
// do we have more than one entry, if not, do not show (single page)
if (!exists('menuRow')) {
$('#' + header_id).html(this.hec.phfo(this.hec.cel('div', 'menuRow', '', ['menuRow', 'flx-s'])));
}
var content = [];
$.each(nav_menu, function(key, item) {
// key is number
// item is object with entries
if (key != 0) {
content.push(this.hec.phfo(this.hec.cel('div', '', '&middot;', ['pd-2'])));
}
// ignore item.popup for now
if (item.enabled) {
// set selected based on window.location.href as the php set will not work
if (window.location.href.indexOf(item.url) != -1) {
item.selected = 1;
}
// create the entry
content.push(this.hec.phfo(
this.hec.aelx(
this.hec.cel('div'),
this.hec.cel('a', '', item.name, ['pd-2'].concat(item.selected ? 'highlight': ''), {
href: item.url
})
)
));
}
});
$('#menuRow').html(content.join(''));
} else {
$('#menuRow').hide();
}
}
}
// __END__