Friendiiverse/App/Utils.js

202 lines
5.1 KiB
JavaScript
Raw Normal View History

function ForceList(Item) {
return (Array.isArray(Item) ? Item : [Item]);
};
function RndId() {
2023-04-23 19:46:01 +02:00
return `${Date.now()}${Math.random() + Math.random()}`;
};
2023-04-25 23:35:34 +02:00
function RndHtmlId(Tag) {
return `Rnd-${Tag}-${RndId().replace('.', '-')}`;
};
2023-04-23 19:46:01 +02:00
2023-04-25 15:00:41 +02:00
function UrlBase(Url) {
var Lower = Url.toLowerCase();
var Domain = UrlDomain(Url);
if (Lower.startsWith('http://')) return `http://${Domain}`;
else
if (Lower.startsWith('https://')) return `https://${Domain}`;
else
return `//${Domain}`;
};
2023-04-23 19:46:01 +02:00
function UrlDomain(Url) {
return Url.split('//')[1].split('/')[0];
};
function FuncName(Fun) {
Fun = Fun.toString();
var Name = Fun.split(' ')[1].split('(')[0].split('{')[0];
var Hash = Fun.hashCode();
return `f:${Name} (${Fun.hashCode()})`;
};
function CallFun(f, a, b, c, d) {
if (typeof(f) === 'function') {
f(a, b, c, d);
};
};
function LogDebug(Data, Status) {
if (Debug) {
if (!Status) {
Status = 'l';
};
for (var i=0; i<Data.length; i++) {
try {
Data[i] = JSON.parse(Data[i]);
} catch(_){};
};
console[{l: "log", e: "error"}[Status.toLowerCase()]](FuncName(LogDebug.caller), Data);
};
};
2023-04-20 22:08:38 +02:00
function IsObj(Item) {
2023-04-26 15:33:51 +02:00
return typeof(Item) === 'object';
2023-04-20 22:08:38 +02:00
};
2023-04-20 18:13:47 +02:00
function CopyObj(Obj) {
return JSON.parse(JSON.stringify(Obj));
};
2023-04-23 00:48:14 +02:00
function ExtrimObj(Obj) {
Obj = CopyObj(Obj);
Object.keys(Obj).forEach(function(Key){
Obj[Key] = undefined;
});
return Obj;
};
2023-04-26 15:33:51 +02:00
function UrlObj(Val) {
if (IsObj(Val)) {
return Obj;
} else
if (typeof(Val) === 'string') {
// TODO: fetch from Internet if key missing in cache
return ApiCache.Urls[Val];
};
};
2023-04-20 22:08:38 +02:00
function B64Obj(Obj) {
return btoa(JSON.stringify(Obj));
};
function UnB64Obj(Obj) {
return JSON.parse(atob(Obj));
};
// Transform JSON tree into a new using a template schema
2023-04-20 00:19:19 +02:00
// DEVNOTE: Unsafe, should check for colliding "__" keys from input tree and act accordingly
function JsonTransformA(TreesOld, SchemaCurr, SchemaRoot) {
if (Array.isArray(TreesOld)) {
var ListNew = [];
ForceList(TreesOld).forEach(function(TreeOld){
ListNew.push(JsonTransformCycleA(TreeOld, SchemaCurr, SchemaRoot));
});
return ListNew;
} else {
return JsonTransformCycleA(TreesOld, SchemaCurr, SchemaRoot);
};
};
function JsonTransformCycleA(TreeOld, SchemaCurr, SchemaRoot) {
var TreeNew = {};
Object.keys(TreeOld).forEach(function(KeyOld){
var Content = TreeOld[KeyOld];
2023-04-20 22:08:38 +02:00
var KeyNew = ((IsObj(SchemaCurr) && KeyOld in SchemaCurr) ? SchemaCurr[KeyOld] : KeyOld);
if (IsObj(Content) && Content !== null) {
if (Array.isArray(Content)) {
// Lists
2023-04-20 00:19:19 +02:00
/* var ListNew = [];
Content.forEach(function(Value){
ListNew.push(JsonTransform(Value, KeyNew));
});
2023-04-20 00:19:19 +02:00
TreeNew[KeyNew] = ListNew;*/
} else {
// Dicts
2023-04-20 00:19:19 +02:00
// Strange bug, in this context we can't assign new value to child of the object, we use a variable
NameKeyNew = KeyNew.__;
if (!NameKeyNew) {
NameKeyNew = KeyOld;
};
TreeNew[NameKeyNew] = JsonTransformA(Content, SchemaRoot[NameKeyNew], SchemaRoot);
if (NameKeyNew !== KeyOld) {
TreeNew[SchemaRoot[NameKeyNew].__] = TreeNew[NameKeyNew];
delete TreeNew[NameKeyNew];
};
};
} else {
// Values
TreeNew[KeyNew] = Content;
};
});
return TreeNew;
};
2023-04-23 00:48:14 +02:00
2023-04-20 15:17:00 +02:00
function JsonTransformB(TreesOld, SchemaNew, NodeNew, TypeOld) {
2023-04-25 00:55:20 +02:00
LogDebug([TreesOld, SchemaNew, NodeNew, TypeOld]);
2023-04-20 15:17:00 +02:00
if (Array.isArray(TreesOld)) {
2023-04-26 15:33:51 +02:00
// List of values
2023-04-20 15:17:00 +02:00
var ListNew = [];
ForceList(TreesOld).forEach(function(TreeOld){
ListNew.push(JsonTransformCycleB(TreeOld, SchemaNew, NodeNew, TypeOld));
});
return ListNew;
} else {
2023-04-26 15:33:51 +02:00
// Object
2023-04-25 00:55:20 +02:00
if (TreesOld) {
return JsonTransformCycleB(TreesOld, SchemaNew, NodeNew, TypeOld);
};
2023-04-20 15:17:00 +02:00
};
2023-04-20 00:19:19 +02:00
};
2023-04-20 15:17:00 +02:00
function JsonTransformCycleB(TreeOld, SchemaNew, NodeNew, TypeOld) {
2023-04-20 18:13:47 +02:00
var TreeNew = CopyObj(NodeNew);
Object.keys(TreeNew).forEach(function(KeyNew){
if (TypeOld in TreeNew[KeyNew]) {
var KeyOld = TreeNew[KeyNew][TypeOld];
2023-04-20 15:17:00 +02:00
var ObjOld = TreeOld[KeyOld];
2023-04-20 22:08:38 +02:00
if (IsObj(KeyOld)) {
2023-04-23 00:48:14 +02:00
// Object in SchemaNew / Deep nested children in TreeOld
Object.keys(KeyOld).forEach(function(KeyObj){
2023-04-25 15:00:41 +02:00
//if (SchemaNew.__All__) {
// TreeNew.__All__ = SchemaNew.__All__;
//};
2023-04-23 00:48:14 +02:00
if (KeyObj === '__Eval__') {
eval(KeyOld[KeyObj]);
2023-04-23 19:46:01 +02:00
} else
if (KeyObj === '__EvalSet__') {
TreeNew[KeyNew] = eval(KeyOld[KeyObj]);
2023-04-26 15:33:51 +02:00
} else
if (KeyObj === '__OldOr__') {
var Keys = KeyOld[KeyObj];
for (var i=0; i<Keys.length; i++) {
var Key = TreeOld[Keys[i]];
if (Key !== undefined) {
TreeNew[KeyNew] = Key;
return;
};
};
2023-04-23 00:48:14 +02:00
};
});
2023-04-20 15:17:00 +02:00
} else {
2023-04-23 00:48:14 +02:00
// Value in SchemaNew / Direct children in TreeOld
2023-04-20 22:08:38 +02:00
if (IsObj(ObjOld)) {
2023-04-20 15:17:00 +02:00
TreeNew[KeyNew] = JsonTransformB(ObjOld, SchemaNew, SchemaNew[KeyNew], TypeOld);
} else {
TreeNew[KeyNew] = ObjOld;
};
};
};
2023-04-20 00:19:19 +02:00
});
2023-04-23 00:48:14 +02:00
TreeNew.__TreeOld__ = TreeOld;
2023-04-20 00:19:19 +02:00
return TreeNew;
};
2023-04-26 15:33:51 +02:00
// https://stackoverflow.com/a/7616484
String.prototype.hashCode = function() {
var hash = 0, i, chr;
if (this.length === 0) return hash;
for (i = 0; i < this.length; i++) {
chr = this.charCodeAt(i);
hash = ((hash << 5) - hash) + chr;
hash |= 0; // Convert to 32bit integer
};
return Number(hash).toString(16).padStart(2, 0);
};