Files

1930 lines
28 KiB
JavaScript
Raw Permalink Normal View History

2025-12-25 09:56:43 +01:00
/*
Copyright (c) 2020, 2023, The Unified Company.
This code is part of Unify.
This program is free software; you can redistribute it and/or modify
it under the terms of the ESA Software Community License - Strong Copyleft LICENSE,
as published by the ESA.
See the ESA Software Community License - Strong Copyleft LICENSE, for more details.
https://unifyjs.org
*/
import css from './css.js';
import definitions from './definitions.js';
import consoleColors from './consoleColors.js';
class tools{
css = new css();
isUnifyObject( propertyName, propertyValue ) {
const rejectClassNames = new Array( "core", "cssRules", "stateMachine", "socketManager", "animationManager", "permissionManager", "permissionObject", "fileLoader", "WriteStream", "client");
const rejectPropertyNames = new Array( "objectToManipulate", "parent", "client", "queryRoot", "queryChildren", "queryCount" );
if( propertyValue && typeof propertyValue.parseUnify == "boolean" && propertyValue.parseUnify == false ) {
return false;
}
if( propertyValue == null ) {
return false;
}
if( !propertyValue ) {
return false;
}
var className = this.getClassName( propertyValue );
if( rejectPropertyNames.includes( propertyName ) ) {
return false;
}
if( rejectClassNames.includes( className ) ) {
return false;
}
if( Array.isArray( propertyValue ) ) {
return false;
}
if( this.getEnvironment() == "Browser" ) {
if( propertyValue instanceof HTMLElement ) {
return false;
}
}
if( typeof propertyValue == "object" ){
return true;
} else {
return false;
}
}
htmlEntities( str ) {
var escapeChars = {
'¢' : 'cent',
'£' : 'pound',
'¥' : 'yen',
'€': 'euro',
'©' :'copy',
'®' : 'reg',
'<' : 'lt',
'>' : 'gt',
'"' : 'quot',
'&' : 'amp',
'\'' : '#39'
};
var regexString = '[';
for(var key in escapeChars) {
regexString += key;
}
regexString += ']';
var regex = new RegExp( regexString, 'g');
return str.replace(regex, function( m ) {
return '&' + escapeChars[ m ] + ';';
});
}
reverseString( string ) {
var splitString = string.split("");
var reverseArray = splitString.reverse();
var joinArray = reverseArray.join("");
return joinArray;
}
slash( path ) {
const isExtendedLengthPath = /^\\\\\?\\/.test(path);
if ( isExtendedLengthPath ) {
return path;
}
return path.replace(/\\/g, '/');
}
serializeString( json ) {
if( Buffer.isBuffer( json ) ) {
return json.toString();
} else {
return json;
}
}
isJsonString( str ) {
try {
JSON.parse( str );
} catch (e) {
return false;
}
return true;
}
serializeJSON( json ) {
if( this.isJsonString( json ) ) {
return JSON.parse( json );
}
}
createOrderedArray( array ) {
var keys = Object.keys( array );
var output = new Array();
for ( var i = 0; i < keys.length; i++ ) {
var key = keys[i];
output[ i ] = array[ key ];
}
return output;
}
getEnvironment() {
if( typeof document != "undefined" ) {
return "Browser";
}
if( global ) {
return "Node"
}
}
// Security
getObjectByPath( application, applicationPath ) {
var objectName = applicationPath.pop();
//console.log("getObjectByPath", objectName);
if( !application[ objectName ] || typeof objectName != "string" ) {
throw new Error('Get object by Path Failed, Faulty path');
}
var currentApplication = application[ objectName ];
if( !currentApplication ) {
throw new Error( 'Get object by Path Failed, Faulty path' );
}
if( applicationPath.length > 0 ) {
return this.getObjectByPath( currentApplication, applicationPath );
} else {
return currentApplication;
}
}
isNumber( value ) {
return ( typeof value === 'number' && isFinite( value ) );
}
isNumberObject( n ) {
return ( Object.prototype.toString.apply( n ) === '[object Number]' );
}
isCustomNumber( n ) {
return this.isNumber( n ) || this.isNumberObject( n );
}
structuredClone( object ) {
var prototype = Object.getPrototypeOf( object );
var create = Object.create( prototype );
return Object.assign( create , object );
}
extendedClassIsColumn() {
}
isUnifyColumn( object ) {
var extendedClasses = this.getExtendedClassesMulti( object );
var isColumn = false;
for ( var j = 0; j < extendedClasses.length; j++ ) {
var extendedClass = extendedClasses[j]
var className = this.getClassName( extendedClass );
if( className == "column" ) {
isColumn = object;
}
}
return isColumn;
}
filterPrims( item, prims, type ) {
if( prims[ type ].hasOwnProperty( item ) ) {
return false;
} else {
prims[ type ][ item ] = true;
return true;
}
}
filterObjects( item ) {
var filterObjects = this.filterObjects;
if( filterObjects.indexOf( item ) >= 0 ) {
return false;
} else {
filterObjects.push( item );
return filterObjects;
}
}
uniqueFilter( item ) {
var type = typeof item;
var prims = this.prims;
if( type in prims ) {
return this.filterPrims( item, prims, type );
} else {
return this.filterObjects( item );
}
}
uniqueArrayRows( a ) {
this.prims = new Object();
this.prims.boolean = new Object();
this.prims.number = new Object();
this.prims.string = new Object();
this.filterObjects = new Array();
return a.filter( this.uniqueFilter.bind( this ) );
}
simpleClone( object ) {
var prototype = Object.getPrototypeOf( object );
var created = Object.create( prototype );
let clone = Object.assign( created, object );
return clone;
}
getPrototypeRecursive( object, properties = new Array() ) {
properties.push( ...Object.getOwnPropertyNames( object ) )
var prototype = Object.getPrototypeOf( object )
if( prototype ) {
return this.getPrototypeRecursive( prototype, properties );
} else {
return properties;
}
}
filterFunctions( element, index, arr ) {
var nextElement = arr[ index + 1];
var elementType = typeof this[ element ];
if ( element != nextElement && elementType == "function" ){
return true;
}
}
getAllFuncs( object ) {
var properties = this.getPrototypeRecursive( object );
var sorted = properties.sort();
var filterd = sorted.filter( this.filterFunctions.bind( object ) )
return filterd;
}
createRandomKey( numCharacters ) {
var token = "";
for ( var i = 0; i < numCharacters; i++ ) {
token += Math.floor( Math.random() * 10 );
}
return token;
}
isCSSProperty( propertyName ) {
var object = definitions.css;
if( typeof object[propertyName] !== 'undefined' ) {
return true;
} else {
return false;
}
}
hasUserPrototype( obj ) {
return obj.constructor !== Object;
}
addTabToArrayLines( lines, numSpaces ) {
var tabbedRows = new Array();
for ( var i = 0; i < lines.length; i++ ) {
var row = lines[i];
tabbedRows[i] = "".padEnd( numSpaces ) + row;
}
return tabbedRows;
}
addTabToBeginOfString( string, numSpaces ) {
var lines = string.split("\n");
var tabbedRows = this.addTabToArrayLines( lines, numSpaces );
return tabbedRows.join("\n");
}
addTabToBegin( string, numSpaces ) {
if( typeof string == "string" ) {
return this.addTabToBeginOfString( string, numSpaces );
} else {
return string;
}
}
getChildFromEntry( parent, entry, children ) {
const invalid = new Array( "parent", "table", "user" );
var name = this.getClassNameByEntry( entry );
var child = this.getObjectByEntry( entry );
if( !this.isUnifyObject( name, child ) ) {
return false;
}
if( invalid.includes( name ) ) {
return false;
}
child.propertyName = name;
child.parent = parent;
children.push( child );
}
getChildren( object, bindParent = true ) {
var children = new Array();
var entries = Object.entries( object );
for( var c = 0; c < entries.length; c++ ){
var entry = entries[ c ];
this.getChildFromEntry( object, entry, children );
}
return children;
}
addPropertyToArray( property, properties ) {
const invalid = new Array( "user" );
if( this.isUnifyObject( property.name, property.value ) ) {
return false;
}
if( invalid.includes( property.name ) ) {
return false;
}
properties.push( property );
}
createPropertyFromEntry( entry ) {
var name = this.getClassNameByEntry( entry );
var object = this.getObjectByEntry( entry );
var property = new Object();
property.name = name;
property.value = object;
return property;
}
getProperties( object ) {
var properties = new Array();
var entries = Object.entries( object );
for( var c = 0; c < entries.length; c++ ){
var entry = entries[c];
var property = this.createPropertyFromEntry( entry ) ;
this.addPropertyToArray( property, properties )
}
return properties;
}
replaceChildWithFragment( source, newType ) {
const frag = document.createDocumentFragment();
while ( source.firstChild ) {
frag.appendChild( source.firstChild );
}
const newElem = document.createElement( newType );
newElem.appendChild( frag );
source.parentNode.replaceChild( newElem, source );
}
replaceElement( source, newType, parentElement ) {
if( parentElement ) {
source.parentNode = parentElement;
}
if( source.tagName != newType.toUpperCase() ) {
this.replaceChildWithFragment( source, newType );
}
}
parseObject( object ) {
var entries = Object.entries( object );
return entries[0];
}
getFirstEntry( object ) {
var entries = Object.entries( object );
if( entries[0] ) {
return entries[0];
} else {
return false;
}
}
getExtendedClass( object ) {
if( !object.prototype ) {
object = object.constructor;
}
return object.prototype.__proto__;
}
removeDuplicates( arr ) {
return arr.filter( ( item, index ) => arr.indexOf( item ) === index );
}
removeEmptyRows( arr ) {
return arr.filter( n => n );
}
isVisible( element ) {
if( !element ) {
return false;
}
if( !element.offsetWidth ) {
return false;
}
return element.offsetWidth > 0 || element.offsetHeight > 0;
}
getExtendedObjects( object ) {
if( !object.getClassName ) {
return false;
}
if( typeof document == "undefined" ){
var extendedObjects = global.extendMap[ object.getClassName() ];
} else {
var extendedObjects = document.extendMap[ object.getClassName() ];
}
return extendedObjects;
}
getSingleExtendedClassInArray( object ) {
if( !object.prototype ) {
object = object.constructor;
}
var extendedClass = this.getExtendedClass( object );
if( !extendedClass ) {
return false;
} else {
return new Array( new extendedClass.constructor() );
}
}
getExtendedClassesMulti( object ) {
var extendedObjects = this.getExtendedObjects( object );
if( extendedObjects ) {
return extendedObjects;
} else {
return this.getSingleExtendedClassInArray( object );
}
}
getExtendedClassName( object ) {
return this.getClassName( this.getExtendedClass( object ) );
}
logError( message ) {
console.log( this.consoleColors().red( message ) );
}
debugVar( object, variable ) {
var colors = this.consoleColors();
var path = this.getApplicationPath(object);
var pathColor = colors.red( "(" + path.toString() + ")" );
var variableColor = colors.magenta( variable );
console.log( variableColor + pathColor );
}
logParameter2( parameter2 ) {
if( typeof parameter2 == "string" ) {
console.log( parameter2 );
} else {
this.logObject( parameter2 );
}
}
log( parameter1, parameter2, parameter3 ) {
var colors = this.consoleColors();
if( typeof parameter1 == "string" ) {
console.log( colors.yellow("\n\n" + parameter1) );
} else {
this.logObject( parameter1 );
}
if( parameter2 ) {
this.logParameter2( parameter2 );
}
}
log( ...value ) {
for (var i = 0; i < value.length; i++) {
console.log( util.inspect( value[i], { showHidden: false, depth: 1, colors: true }) )
}
}
logObject( object ) {
var colors = this.consoleColors();
var path = this.getApplicationPath(object);
var pathColor = colors.red( "(" + path.reverse().toString() + ")" );
console.log( pathColor + " " + this.getClassName( object ) );
console.log( this.serialize( object ) );
}
saveImportDefault( importObject ) {
if( importObject.default ) {
return importObject.default;
} else {
console.log("error2 ", url, " does not exist");
}
}
async saveImport( url ) {
var importObject = await import( url );
if( importObject ) {
return this.saveImportDefault( importObject );
} else {
console.log("error1 ", url, " does not exist");
}
}
getApplicationDepth( object ) {
return this.getApplicationPath( object ).length;
}
getParentApplicationPath( object, array ) {
array.push( object.propertyName );
return this.getApplicationPath( object.parent, array );
}
getApplicationPath( object, array = new Array() ) {
if( object.parent ) {
return this.getParentApplicationPath( object, array )
} else {
return array;
}
}
getClassName( object ) {
if( object.__className ) {
return object.__className;
}
if( !object ) {
return false;
}
return object.constructor.name;
//var rollupFix = object.constructor.name.split("$")[0].split("$")[0];
//var webPackFix = rollupFix.split("_")
//return rollupFix;
//return webPackFix[webPackFix.length-1];
}
getID( object ){
if( object.id ){
return object.id;
} else {
return "";
}
}
getClassNameByObject( object ) {
if( typeof object == "string" ) {
return object;
}
var entry = this.parseObject( object );
var className = this.getClassNameByEntry( entry );
return className;
}
getClassNameByEntry( entry ) {
return entry[0];
}
getObjectByEntry( entry ) {
if( entry[1] ) {
return entry[1];
} else {
return false;
}
}
logObject( object, message ) {
if( object.debug ) {
console.log( message, object.getClassName(), "\n" );
}
}
getFirstEntryName( object ) {
var entries = Object.entries( object );
return entries[0][0];
}
delay( millisec ) {
return new Promise(resolve => {
setTimeout(() => { resolve('') }, millisec);
})
}
getPropertyNameWithID( object ) {
if( object.id ) {
// bug // + "_" + object.id; todo: Make that only id is added when css content differs from other rows/ids
// object.propertyName.replace( object.id, "" ) is, Unify objects rendered by rendercollections have an id in the propertyName
// This results in double ids
return this.CamelCase( object.propertyName ) + "_" + object.id;
} else {
return this.CamelCase( object.propertyName );
}
if( !propertyName ) {
return "";
}
}
createCSSClassName( object ) {
var propertyName = this.getPropertyNameWithID( object );
if( object.parent ) {
object = object.parent;
}
return this.getClassName( object ) + propertyName;
}
CamelCase( string ){
if( !string ) {
return false;
}
string = string.toUpperCase();
string = string[0].toUpperCase() + string.slice( 1, string.length ).toLowerCase();
return string;
}
firstLowerCase( string ){
if( string ) {
return string[0].toLowerCase() + string.slice( 1, string.length );
} else {
return false;
}
}
cleanRollup( term ) {
return term;
// Deprecated
//return term.replaceAll("$0", "").replaceAll("$1", "").replaceAll("$2", "");
}
cleanEntry( entry ) {
const invalid = new Array( "parent", "table", "user", "objectToManipulate" );
var name = this.getClassNameByEntry( entry );
var object = this.getObjectByEntry( entry );
if( invalid.includes( name ) ) {
delete object[name];
}
}
cleanObject( object ) {
var entries = Object.entries( this );
for ( var i = 0; i < entries.length; i++ ) {
var entry = entries[i];
this.cleanEntry( entry );
}
}
objectExtendsTablePrimitive( object ) {
var extendedClass = this.getExtendedClass( object );
if( !extendedClass ) {
return false;
}
var className = this.getClassName( extendedClass );
if( className == "table" ) {
return true;
} else {
return false;
}
}
objectIsTable( object ) {
if( !object ) {
return false;
}
if( !object.prototype ) {
object = object.constructor;
}
return this.objectExtendsTablePrimitive( object );
}
extendIsRenderCollection( object ) {
var extendedClass = this.getExtendedClass( object );
var className = this.getClassName( extendedClass );
if( className == "renderCollection" ) {
return true;
} else {
return false;
}
}
objectIsRenderCollection( object ) {
var className = this.getClassName( object );
if( className == "renderCollection" ) {
return true;
}
if( !object.prototype ) {
object = object.constructor;
}
return this.extendIsRenderCollection( object );
}
getTableName( object ) {
if( !this.objectIsTable( object ) ) {
object = this.getTableFromObject( object );
}
var className = this.getClassName( object );
return className;
}
isTableInHierarchy( object ) {
}
getParentWithTable( object, tableName ) {
if( this.getClassName( this.getTableFromObject( object ) ) == tableName ) {
return object;
} else {
return this.getParentWithTable( object.parent, tableName );
}
}
classNameIsTable( className ) {
// todo deprecated?
//if( className == "table" || className == "unify_table_table" || className == "server_table_table" || className == "table_table" ) {
if( className == "table" ){
return true;
} else {
return false;
}
}
evaluateExtendedClass( object, extendedClass ) {
var className = this.getClassName( extendedClass );
if( this.classNameIsTable( className ) ) {
return object;
}
var table = this.getTableFromObject( extendedClass );
if( table ) {
return table;
} else {
return false;
}
}
getTableFromExtendedClasses( object, extendedClasses ) {
for ( var i = 0; i < extendedClasses.length; i++ ) {
var extendedClass = extendedClasses[i];
var table = this.evaluateExtendedClass( object, extendedClass );
if( table ) {
return table;
}
}
}
getTableFromObject( object ) {
if( object.table ) {
return object.table;
}
var className = this.getClassName( object );
if( className ) {
var extendedClasses = this.getExtendedClassesMulti( object );
return this.getTableFromExtendedClasses( object, extendedClasses );
} else {
console.log("classname not found",object);
}
}
isServerValue( name, value ){
const invalid = new Array( "style", "type", "label", "flexDirection", "boxPadding", "width", "DOM_ELEMENT" );
const valid = new Array( "rows" );
if( valid.includes( name ) ){
return true;
}
if( invalid.includes( name ) ){
return false;
}
if( this.css.propertyIsStyle( name ) ) {
return false;
}
if( typeof value == "number" ){
return true;
}
if( typeof value == "string" ){
return true;
} else {
return false;
}
}
deleteNormalBrowserEvent( object, browserEvent ) {
if( object[ browserEvent ] ) {
delete object[ browserEvent ];
}
}
deleteServerBrowserEvent( object, browserEvent ) {
if( object[ "server" + this.CamelCase( browserEvent ) ] ) {
delete object[ "server" + this.CamelCase( browserEvent ) ];
}
}
groomBrowserEvents( object ) {
var browserEvents = definitions.browserEvents;
for ( var i = 0; i < browserEvents.length; i++ ) {
var browserEvent = browserEvents[ i ];
this.deleteNormalBrowserEvent( object, browserEvent );
this.deleteServerBrowserEvent( object, browserEvent );
}
}
getCircularReplacer( key, value ) {
if ( typeof value === "object" && value !== null ) {
if ( this.seen.has( value ) ) {
return;
}
this.seen.add( value );
}
return value;
}
sizeOf( object ) {
this.seen = new WeakSet();
var stringObject = JSON.stringify( object, this.getCircularReplacer.bind( this ) );
// OR stringObject = JSON.stringify( object, ( key, value ) => this.getCircularReplacer( key, value ) );
var finalObject = JSON.parse( stringObject );
return global.objectSizeof( finalObject );
}
groomCssProperties( object, propertyName ) {
var propertyNameWithoutBox = propertyName.replace("box", "");
if( this.css.propertyHasStyle( propertyNameWithoutBox ) ) {
delete object[ propertyName ];
}
}
groomRemainingProperties( object, propertyName, propertyValue ) {
//if( !this.isServerValue( propertyName, propertyValue ) && !this.isUnifyObject(propertyName, propertyValue ) ) {
// delete object[ propertyName ];
//}
}
groomPermissionMethods( object ) {
if( object.enableWRITE ) {
delete object.enableWRITE;
}
if( object.disableWRITE ) {
delete object.disableWRITE;
}
if( object.enableREAD ) {
delete object.enableREAD;
}
if( object.disableREAD ) {
delete object.disableREAD;
}
if( object.enableDELETE ) {
delete object.enableDELETE;
}
if( object.disableDELETE ) {
delete object.disableDELETE;
}
}
groomBrowserMethods( object ) {
if( object.create ) {
delete object.create;
}
if( object.update ) {
delete object.update;
}
if( object.afterLoad ) {
delete object.afterLoad;
}
}
groomEntry( entry, object ) {
var propertyName = this.getClassNameByEntry( entry );
var propertyValue = this.getObjectByEntry( entry );
this.groomPermissionMethods( object );
this.groomBrowserMethods( object );
this.groomBrowserEvents( object );
this.groomCssProperties( object, propertyName );
this.groomRemainingProperties( object, propertyName, propertyValue );
if( this.isUnifyObject(propertyName, propertyValue ) ) {
this.groomApplicationObject( propertyValue );
}
return object;
}
groomApplicationObject( object ) {
var entries = Object.entries( object );
for( var c = 0; c < entries.length; c++ ) {
var entry = entries[c];
this.groomEntry( entry, object );
}
return object;
}
serializeEntry( entry, serializedObject ) {
var propertyName = this.getClassNameByEntry( entry );
var propertyValue = this.getObjectByEntry( entry );
this.serializeProperty( propertyName, propertyValue, serializedObject );
}
serializeEntries( entries ) {
var serializedObject = new Object();
for( var c = 0; c < entries.length; c++ ) {
var entry = entries[c];
this.serializeEntry( entry, serializedObject );
}
return serializedObject;
}
serialize( object, is_root = true, cut ){
var entries = Object.entries( object );
this.serializeEntries( entries );
return this.createOuterObject( object, serializedObject, is_root );
}
serializeServerProperty( object, propertyName, propertyValue ) {
object[ propertyName ] = propertyValue;
}
serializedUnifyObject( object, propertyName, propertyValue ) {
object[ propertyName ] = this.serialize( propertyValue, false );
}
serializeProperty( propertyName, propertyValue, object ) {
if( this.isServerValue( propertyName, propertyValue ) ) {
this.serializeServerProperty( object, propertyName, propertyValue );
}
if( this.isUnifyObject(propertyName, propertyValue ) ) {
this.serializedUnifyObject( object, propertyName, propertyValue );
}
return object;
}
isArray( array ) {
if( !array ) {
return false;
}
return Array.isArray( array );
}
validateNumber( value ) {
if( typeof value == "number" ) {
return value;
} else {
return false;
}
}
validateString( value ) {
if( typeof value == "string" ) {
return value;
} else {
return false;
}
}
validateValue( value ) {
if( typeof value == "string" || typeof value == "number" || typeof value == "boolean" ) {
return value;
} else {
return false;
}
}
validateBoolean( value ) {
if( typeof value == "boolean" ) {
return value;
} else {
return false;
}
}
validateArray( values ) {
if( !this.isArray( values ) ) {
return false;
}
for( var c = 0; c < values.length; c++ ) {
values[ c ] = this.validateString( values[ c ] );
}
return values;
}
is_allowed_value( value ) {
if( this.is_int( value ) ) {
return true;
}
if( this.is_text( value ) ) {
return true;
}
if( this.is_boolean( value ) ) {
return true;
}
if( this.is_object( value ) ) {
return true;
}
return false;
}
is_float( value ) {
if( typeof value == "number" ) {
return true;
} else {
return false;
}
}
is_number( value ) {
if( typeof value == "number" ) {
return true;
} else {
return false;
}
}
is_object( value ) {
if( typeof value == "object" ) {
return true;
} else {
return false;
}
}
is_text( value ) {
if( typeof value == "string" ) {
return true;
} else {
return false;
}
}
is_string( value ) {
if( typeof value == "string" ) {
return true;
} else {
return false;
}
}
is_boolean() {
if( typeof value == "boolean" ) {
return true;
} else {
return false;
}
}
is_int( value ) {
if( typeof value == "number" ) {
return true;
} else {
return false;
}
}
createOuterObjectWithRoot() {
var objectName = this.getClassName( object );
var output = new Object();
output[ objectName ] = serializedObject;
return output;
}
createOuterObject( object, serializedObject, is_root ) {
if( is_root ) {
return this.createOuterObjectWithRoot( object, serializedObject );
} else {
return serializedObject;
}
}
consoleColors() {
return consoleColors;
}
getFirstObjectFromEntries( entries ) {
var firstChild = entries[0][1];
if( firstChild ) {
return firstChild;
} else {
return object;
}
}
getFirstChild( object ) {
var entries = Object.entries( object );
if( entries[0] ) {
return this.getFirstObjectFromEntries( entries );
}
}
}
String.prototype.replaceAll = function replaceAll( search, replace ) { return this.split( search ).join( replace ); }
export default new tools();