improve structure

This commit is contained in:
Dennis Eichhorn 2022-08-16 19:09:02 +02:00
parent 5252b76ef3
commit d4c7a05f72
13 changed files with 172 additions and 96 deletions

View File

@ -1,5 +1,6 @@
import { LogLevel } from './LogLevel.js';
import { Request } from '../Message/Request/Request.js';
import { SystemUtils } from '../System/SystemUtils.js';
/**
* Logger class.
@ -63,7 +64,7 @@ export class Logger
*
* @since 1.0.0
*/
interpolate (message, context, level)
interpolate (message, context)
{
message = typeof message === 'undefined' ? Logger.MSG_FULL : message;
@ -89,13 +90,15 @@ export class Logger
*/
createContext (message, context, level)
{
context.datetime = (new Date()).toISOString();
context.version = '1.0.0';
context.os = Request.getOS();
context.browser = Request.getBrowser();
context.path = window.location.href;
context.level = level;
context.message = message;
context.backtrace = console.trace();
context.datetime = (new Date()).toISOString();
context.version = '1.0.0';
context.os = SystemUtils.getOS();
context.browser = SystemUtils.getBrowser();
context.path = window.location.href;
context.datetime = (new Date()).toString();
context.level = level;
context.message = message;
return context;
};
@ -120,11 +123,11 @@ export class Logger
}
if (this.ui) {
this.writeUi(message, context, level);
this.writeUi(message, context);
}
if (this.remote) {
this.writeRemote(message, context, level);
this.writeRemote(context);
}
};
@ -133,20 +136,19 @@ export class Logger
*
* @param {string} message Message to display
* @param {Object} [context] Context to put into message
* @param {string} level Log level
*
* @return {void}
*
* @since 1.0.0
*/
writeUi (message, context, level)
writeUi (message, context)
{
/** global: Notification */
if (Notification.permission !== 'granted' && Notification.permission !== 'denied') {
Notification.requestPermission().then(function (permission) { });
}
const notification = new Notification('Logger', { body: this.interpolate(message, context, level) });
const notification = new Notification('Logger', { body: this.interpolate(message, context) });
setTimeout(notification.close.bind(notification), 4000);
};
@ -192,15 +194,13 @@ export class Logger
/**
* Create remote log message
*
* @param {string} message Message to display
* @param {Object} [context] Context to put into message
* @param {string} level Log level
*
* @return {void}
*
* @since 1.0.0
*/
writeRemote (message, context, level)
writeRemote (context)
{
const request = new Request();
request.setData(context);

View File

@ -1,7 +1,5 @@
import { Logger } from '../../Log/Logger.js';
import { UriFactory } from '../../Uri/UriFactory.js';
import { BrowserType } from './BrowserType.js';
import { OSType } from './OSType.js';
import { RequestMethod } from './RequestMethod.js';
import { RequestType } from './RequestType.js';
@ -85,61 +83,6 @@ export class Request
}
};
/**
* Get browser.
*
* @return {string}
*
* @since 1.0.0
*/
static getBrowser ()
{
/** global: InstallTrigger */
/** global: navigator */
/** global: window */
if ((!!window.opr && !!opr.addons) || !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0) {
return BrowserType.OPERA;
} else if (typeof InstallTrigger !== 'undefined') {
return BrowserType.FIREFOX;
} else if (Object.toString.call(window.HTMLElement).indexOf('Constructor') > 0) {
return BrowserType.SAFARI;
} else if (/* @cc_on!@ */false || !!document.documentMode) {
return BrowserType.IE;
} else if (!!window.StyleMedia) {
return BrowserType.EDGE;
} else if (!!window.chrome && !!window.chrome.webstore) {
return BrowserType.CHROME;
} else if (((typeof isChrome !== 'undefined' && isChrome)
|| (typeof isOpera !== 'undefined' && isOpera))
&& !!window.CSS
) {
return BrowserType.BLINK;
}
return BrowserType.UNKNOWN;
};
/**
* Get os.
*
* @return {string}
*
* @since 1.0.0
*/
static getOS ()
{
for (const os in OSType) {
if (Object.prototype.hasOwnProperty.call(OSType, os)) {
/** global: navigator */
if (navigator.appVersion.toLowerCase().indexOf(OSType[os]) !== -1) {
return OSType[os];
}
}
}
return OSType.UNKNOWN;
};
/**
* Set request method.
*
@ -378,13 +321,20 @@ export class Request
if (this.xhr.readyState !== 1) {
if (this.type === RequestType.FORM_DATA) {
let url = this.uri;
for (let pair of this.data.entries()) {
url += '&' + pair[0] + '=' + pair[1];
}
// GET request doesn't allow body/payload. Therefor we have to put the data into the uri
if (this.method === RequestMethod.GET) {
let url = this.uri;
for (let pair of this.data.entries()) {
url += '&' + pair[0] + '=' + pair[1];
}
this.xhr.open(this.method, UriFactory.build(url));
this.xhr.open(this.method, UriFactory.build(url));
} else {
this.xhr.open(this.method, UriFactory.build(this.uri));
}
} else {
console.log(UriFactory.build(this.uri));
this.xhr.open(this.method, UriFactory.build(this.uri));
}
@ -421,11 +371,7 @@ export class Request
} else if (this.type === RequestType.URL_ENCODE) {
this.xhr.send(this.queryfy(this.data));
} else if (this.type === RequestType.FORM_DATA) {
if (this.method === RequestMethod.GET) {
this.xhr.send();
} else {
this.xhr.send(this.data);
}
this.xhr.send(this.data);
}
};
};

View File

@ -56,7 +56,7 @@ General updates can be found in our info section at https://karaka.app/info and
## Tech stack
* Language: php, js, c++, html, css, markdown, shell script
* Database: Maria/MySQL, PostgreSQL, MSSQL, SQLite
* Database: Maria/MySQL, PostgreSQL, MSSQL/SQLSrv, SQLite
* Webserver: apache2, nginx
* Cache: Redis, Memcached

68
System/SystemUtils.js Normal file
View File

@ -0,0 +1,68 @@
import { BrowserType } from './BrowserType.js';
import { OSType } from './OSType.js';
/**
* System utils class.
*
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @since 1.0.0
*/
export class SystemUtils
{
/**
* Get browser.
*
* @return {string}
*
* @since 1.0.0
*/
static getBrowser ()
{
/** global: InstallTrigger */
/** global: navigator */
/** global: window */
if ((!!window.opr && !!opr.addons) || !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0) {
return BrowserType.OPERA;
} else if (typeof InstallTrigger !== 'undefined') {
return BrowserType.FIREFOX;
} else if (Object.toString.call(window.HTMLElement).indexOf('Constructor') > 0) {
return BrowserType.SAFARI;
} else if (/* @cc_on!@ */false || !!document.documentMode) {
return BrowserType.IE;
} else if (!!window.StyleMedia) {
return BrowserType.EDGE;
} else if (!!window.chrome && !!window.chrome.webstore) {
return BrowserType.CHROME;
} else if (((typeof isChrome !== 'undefined' && isChrome)
|| (typeof isOpera !== 'undefined' && isOpera))
&& !!window.CSS
) {
return BrowserType.BLINK;
}
return BrowserType.UNKNOWN;
};
/**
* Get os.
*
* @return {string}
*
* @since 1.0.0
*/
static getOS ()
{
for (const os in OSType) {
if (Object.prototype.hasOwnProperty.call(OSType, os)) {
/** global: navigator */
if (navigator.appVersion.toLowerCase().indexOf(OSType[os]) !== -1) {
return OSType[os];
}
}
}
return OSType.UNKNOWN;
};
};

View File

@ -118,9 +118,11 @@ export class Form
}
// don't overwrite existing bind
/*
@todo: removed because sometimes it is already bound but bound in a wrong way (e.g. no success is defined)
if (Object.prototype.hasOwnProperty.call(this.forms, id)) {
return;
}
}*/
this.forms[id] = new FormView(id);
const self = this;
@ -817,6 +819,12 @@ export class Form
) {
jsOMS.preventAll(event);
self.submit(self.forms[id], self.forms[id].getSubmit()[elementIndex]);
} else if ((elementIndex = '')) {
// @todo: if table head input field in popups changes -> check if input empty -> deactivate -> checkbox : else activate checkbox
// careful: the same checkbox is used for showing the filter popup. maybe create a separate checkbox, which only handles the highlighting if filter is defined.
// this means popup active highlights filter icon AND different content checkbox also highlights filter
// -> two hiddin checkboxes are necessary (one is already implemented)
// Consider: It might make sense to do this in the Table.js??? Kinda depends on additional functionality together with the form probably.
}
// remote actions (maybe solvable with callbacks?):
@ -905,7 +913,10 @@ export class Form
// select first input element (this allows fast consecutive data input)
const firstFormInputElement = form.getFirstInputElement();
firstFormInputElement.focus();
if (firstFormInputElement !== null) {
firstFormInputElement.focus();
}
};
/**
@ -950,14 +961,14 @@ export class Form
const self = this;
request.setData(data);
request.setType(RequestType.FORM_DATA);
request.setType(RequestType.FORM_DATA); // @todo: consider to allow different request type
request.setUri(action ? action : form.getAction());
request.setMethod(form.getMethod());
request.setSuccess(function (xhr)
{
window.omsApp.logger.log(xhr.response);
if (xhr.getResponseHeader('content-type') === 'application/octet-stream') {
if (xhr.getResponseHeader('content-type').includes('application/octet-stream')) {
const blob = new Blob([xhr.response], { type: 'application/octet-stream' });
const doc = document.createElement('a');
doc.style = 'display: none';
@ -981,6 +992,17 @@ export class Form
doc.click();
window.URL.revokeObjectURL(url);
document.body.removeChild(doc);
} else if (xhr.getResponseHeader('content-type').includes('text/html')) {
// window.location = UriFactory.build(uri);
document.documentElement.innerHTML = xhr.response;
/* This is not working as it reloads the page ?!
document.open();
document.write(html);
document.close();
*/
window.omsApp.reInit(); // @todo: fix memory leak which most likely exists because of continous binding without removing binds
} else {
try {
const o = JSON.parse(xhr.response)[0];

View File

@ -134,15 +134,15 @@ export class Tab
if (fragLength > 0 && fragmentString !== '') {
for (let i = 0; i < fragLength; ++i) {
const label = e.querySelectorAll('label[for="' + fragments[i] + '"]')[0];
if (typeof label !== 'undefined') {
const label = e.querySelector('label[for="' + fragments[i] + '"]');
if (typeof label !== 'undefined' && label !== null) {
label.click();
}
}
}
if (e.getElementsByClassName('active').length < 1) {
e.querySelector('label').click();
if (e.querySelector('.tab-links').querySelector('.active') === null) {
e.querySelector('.tab-links').querySelector('label').click();
}
};
};

View File

@ -67,6 +67,17 @@ export class GeneralUI
const length = e.length;
for (let i = 0; i < length; ++i) {
/*
@todo: bad solution, probably needs to be more navigation specific
const link = UriFactory.buildAbsolute(
e[i].getAttribute('href') !== null ? e[i].getAttribute('href') : e[i].getAttribute('data-href')
);
if (jsOMS.rtrim(link, '/') !== window.location.origin && window.location.href.startsWith(link)) {
jsOMS.addClass(e[i], 'active');
}
*/
if (e[i].getAttribute('data-action') !== null) {
continue;
}
@ -86,10 +97,10 @@ export class GeneralUI
}
jsOMS.preventAll(event);
history.pushState(null, null, window.location);
let uri = this.getAttribute('data-href');
uri = uri === null ? this.getAttribute('href') : uri;
history.pushState({}, null, UriFactory.build(uri));
if (this.getAttribute('target') === '_blank'
|| this.getAttribute(['data-target']) === '_blank'
@ -97,7 +108,23 @@ export class GeneralUI
) {
window.open(UriFactory.build(uri), '_blank');
} else {
window.location = UriFactory.build(uri);
// window.location = UriFactory.build(uri);
fetch(UriFactory.build(uri))
.then((response) => response.text())
.then((html) => {
document.documentElement.innerHTML = html;
/* This is not working as it reloads the page ?!
document.open();
document.write(html);
document.close();
*/
window.omsApp.reInit(); // @todo: fix memory leak which most likely exists because of continous binding without removing binds
})
.catch((error) => {
console.warn(error);
});
}
});
}

View File

@ -174,6 +174,17 @@ export class UriFactory
return url;
};
static buildAbsolute (uri, toMatch = null)
{
if (uri.startsWith('/')) {
return UriFactory.build(window.location.origin + uri, toMatch);
} else if (uri.indexOf('://') === -1) {
return UriFactory.build(window.location.origin + '/' + uri, toMatch);
}
return uri;
};
/**
* Build uri
*

View File

@ -644,7 +644,7 @@
throw new Error('callback param is required');
}
if (!showdown.helper.isfunction (callback)) {
if (!showdown.helper.isFunction (callback)) {
throw new Error('callback param must be a function/closure');
}
@ -826,7 +826,7 @@
showdown.helper.replaceRecursiveRegExp = function (str, replacement, left, right, flags) {
'use strict';
if (!showdown.helper.isfunction (replacement)) {
if (!showdown.helper.isFunction (replacement)) {
var repStr = replacement;
replacement = function () {
return repStr;

View File

@ -135,6 +135,7 @@
{
event.preventDefault();
event.stopImmediatePropagation();
event.stopPropagation();
event.cancelBubble = true;
};

View File

@ -331,6 +331,7 @@
{
event.preventDefault();
event.stopImmediatePropagation();
event.stopPropagation();
event.cancelBubble = true;
return false;