qcobjects
Version:
QCObjects is an Open-source framework that empowers full-stack developers to make micro-services and micro-frontends into an N-Tier architecture.
524 lines (462 loc) • 17.4 kB
text/typescript
import { IQCObjectsElement, IQCObjectsShadowedElement } from "types";
import { _top } from "./top";
import { _fireAsyncLoad, asyncLoad } from "./asyncLoad";
import { captureFalseTouch } from "./captureFalseTouch";
import { _Cast } from "./Cast";
import { Class } from "./Class";
import { ClassFactory } from "./ClassFactory";
import { Component } from "./Component";
import { ComponentURI } from "./ComponentFactory";
import { componentLoader } from "./componentLoader";
import { CONFIG } from "./CONFIG";
import { _DataStringify } from "./DataStringify";
import { setDefaultProcessors } from "./defaultProcessors";
import { Export } from "./Export";
import { Import } from "./Import";
import { _methods_, _protected_code_ } from "./introspection";
import { isQCObjects_Class, isQCObjects_Object } from "./isQCObjects";
import { logger } from "./Logger";
import { __to_number } from "./mathFunctions";
import { NamespaceRef } from "./NamespaceRef";
import { New } from "./New";
import { ObjectName } from "./ObjectName";
import { Package } from "./Package";
import { is_phonegap, isBrowser } from "./platform";
import { _Ready, ready, Ready } from "./Ready";
import { serviceLoader } from "./serviceLoader";
import { Tag } from "./Tag";
import { Processor } from "./Processor";
import { is_a } from "./is_a";
import { __getType__ } from "./getType";
import { shortCode } from "./shortCode";
import { _DOMCreateElement } from "./DOMCreateElement";
import { ComplexStorageCache } from "./ComplexStorageCache";
import { _super_ } from "./super";
import { waitUntil } from "./waitUntil";
import { subelements } from "./subelements";
import { GlobalSettings } from "./globalSettings";
import loadSDK from "./loadSDK";
import { range } from "./range";
(function __qcobjects__(_top: any) {
if (typeof Object.defineProperty !== "undefined" && typeof _top !== "undefined") {
try {
Object.defineProperty(_top, "__qcobjects__", {
enumerable: true,
configurable: false,
writable: false,
value: __qcobjects__,
});
} catch (e: any) {
logger.debug(`An error ocurred: ${e}`);
if (typeof _top.__qcobjects__ !== "undefined") {
_top.__qcobjects__.loaded = true;
}
}
}
if (typeof _top.__qcobjects__.loaded === "undefined") {
_top.__qcobjects__.loaded = true;
if (isBrowser) {
(Element as unknown as IQCObjectsElement).prototype.subelements = subelements;
(Document as unknown as IQCObjectsElement).prototype.subelements = subelements;
(HTMLElement as unknown as IQCObjectsElement).prototype.subelements = subelements;
if (typeof ShadowRoot !== "undefined") {
(ShadowRoot as unknown as IQCObjectsShadowedElement).prototype.subelements = subelements;
}
}
logger.debugEnabled = false;
logger.infoEnabled = true;
/**
* Basic Type of all elements
*/
if (isBrowser) {
(Element as unknown as IQCObjectsElement).prototype.find = function (tag: string): IQCObjectsElement[] {
const _self = this;
const _oo: IQCObjectsElement[] = [];
const _tags = (document as unknown as IQCObjectsElement).subelements(tag);
_tags.map((_tt, _t) => {
if ((typeof _tags[_t] !== "undefined") && (_tags[_t].parentNode as Element).tagName === _self.parentNode.tagName) {
_oo.push(_Cast(_tt, (new Object())));
}
return _tt;
});
return _oo;
};
}
if (isBrowser) {
Element.prototype.append = function QC_Append(child) {
if (isQCObjects_Object(child) || typeof (child as any).body !== "undefined") {
this.appendChild((child as any).body);
} else {
this.appendChild(child as any);
}
};
/**
* A replacement for direct using of innerHTML
* use: [element].render('content') where 'content' is the string corresponding
* to the DOM to insert in the element
**/
(Element as unknown as IQCObjectsElement).prototype.render = function QC_Render(content: string) {
const _self = this;
const _appendVDOM = (_self: any, content: string): any => {
if (typeof document.implementation.createHTMLDocument !== "undefined") {
const doc = document.implementation.createHTMLDocument("");
doc.body.innerHTML = content;
(doc.body as unknown as IQCObjectsElement).subelements("*").map((element): any => {
return _self.append(element);
});
}
};
if (typeof this.innerHTML !== "undefined") {
try {
this.innerHTML += content;
} catch (e: any) {
logger.debug(`An error ocurred: ${e}`);
_appendVDOM(_self, content);
}
} else {
_appendVDOM(_self, content);
}
};
}
Export(waitUntil);
Export(_super_);
Export(ComplexStorageCache);
Export(ClassFactory);
Export(_DOMCreateElement);
Export(shortCode);
Export(__getType__);
Export(is_a);
Package("com.qcobjects", [Processor]);
if (isBrowser) {
/**
* Adds a Cast functionality to every Element of DOM
*/
(Element as unknown as IQCObjectsElement).prototype.Cast = function QC_Cast<T>(_o: T): T {
const _self: any = this;
return _Cast(_self, _o) as T;
};
}
if (isBrowser) {
window.onload = _Ready;
if (is_phonegap) {
document.addEventListener("deviceready", _Ready, captureFalseTouch as any);
}
} else {
global.onload = _Ready;
}
if (isBrowser) {
window.addEventListener("popstate", function (popStateEvent) {
popStateEvent.stopImmediatePropagation();
popStateEvent.stopPropagation();
Component.route()
.catch((e: any) => { throw new Error(`An error ocurred when trying to load initial routes. ${e}`); });
});
}
Export(serviceLoader);
Export(componentLoader);
Export(ComponentURI);
Export(ObjectName);
Export(_DataStringify);
Export(isQCObjects_Class);
Export(isQCObjects_Object);
Export(NamespaceRef);
/**
* Array math functions
*/
// eslint-disable-next-line no-unused-vars
(Array as any).prototype.unique = function <T>(this: T[]): T[] {
return this.filter(function (value: any, index: any, self: any) {
return self.indexOf(value) === index;
});
};
(Array as any).unique = function <T>(a: Array<T>): T[] {
return (a as any).unique() as T[];
};
(_protected_code_)((Array as any).unique);
(_protected_code_)((Array as any).prototype.unique);
(Array as any).prototype.table = function (): void {
console.table(this);
};
(Array as any).table = function (a: any): void {
a.table();
return;
};
(_protected_code_)((Array as any).table);
(_protected_code_)((Array as any).prototype.table);
(Array as any).prototype.sum = function (): number {
return this.reduce(function (prev: any, current: any) {
return (__to_number(prev)) + (__to_number(current));
}, 0) as number;
};
(Array as any).sum = function (a: any): number {
return a.sum() as number;
};
(_protected_code_)((Array as any).sum);
(_protected_code_)((Array as any).prototype.sum);
(Array as any).prototype.avg = function (): number {
return (this.length < 1) ? (0) : (this.reduce(function (prev: any, current: any) {
return (((__to_number(prev)) + (__to_number(current))) / 2);
})) as number;
};
(Array as any).avg = function (a: any): number {
return a.avg() as number;
};
(_protected_code_)((Array as any).avg);
(_protected_code_)((Array as any).prototype.avg);
(Array as any).prototype.min = function (): number {
return this.reduce(function (prev: number, current: number) {
return (__to_number(prev) <= __to_number(current)) ? (prev) : (current);
}, Infinity) as number;
};
(Array as any).min = function (a: any): number {
return a.min() as number;
};
(_protected_code_)((Array as any).min);
(_protected_code_)((Array as any).prototype.min);
(Array as any).prototype.max = function (): number {
return this.reduce(function (prev: number, current: number) {
return (__to_number(prev) >= __to_number(current)) ? (prev) : (current);
}, 0) as number;
};
(Array as any).max = function (a: any): number {
return a.max() as number;
};
(_protected_code_)((Array as any).max);
(_protected_code_)((Array as any).prototype.max);
(Array as any).prototype.sortBy = function (propName: string, sortAsc = true): Array<any>[] {
const sort_function = (sortAsc) ? (
function (prev: any, current: any) {
return current[propName] < prev[propName] ? 1 : -1;
}
) : (
function (prev: any, current: any) {
return current[propName] > prev[propName] ? 1 : -1;
}
);
return this.sort(sort_function) as Array<any>[];
};
(Array as any).sortBy = function (a: any, propName: string, sortAsc = true): Array<any>[] {
return a.sortBy(propName, sortAsc) as Array<any>[];
};
(_protected_code_)((Array as any).sortBy);
(_protected_code_)((Array as any).prototype.sortBy);
/**
* Extends the Array prototype to include a method that creates a matrix (2D array)
* with specified dimensions and fill value.
*
* @param {number} _length - The number of rows in the matrix.
* @param {any} [_fillValue=0] - The value to fill the matrix with (default is 0).
* @returns {Array<Array<any>>} A 2D array (matrix) filled with the specified value.
*
* @example
* // Create a 3x3 matrix filled with zeros
* const matrix = [].matrix(3);
* console.log(matrix);
* // Output: [0, 0, 0]
*
* @example
* // Create a 2x4 matrix filled with a specific value
* const matrix = [].matrix(2, 5);
* console.log(matrix);
* // Output: [5, 5]
*
* @example
* // Create a 4x2 matrix filled with null values
* const matrix = [].matrix(4, null);
* console.log(matrix);
* // Output: [null, null, null, null]
*/
(Array as any).prototype.matrix = function (_length: number, _fillValue = 0) {
// eslint-disable-next-line no-unused-vars
const x_func = function (x = undefined) {
return _fillValue;
};
return Array.from({
length: _length
}, x_func);
};
/**
* Creates a matrix (2D array) from a given array.
*
* This function extends the Array constructor by adding a static method
* that generates a matrix with specified dimensions and fill value.
*
* @function
* @param {Array} a - The input array used to generate the matrix.
* @param {number} _length - The length of the matrix (number of rows).
* @param {number} [_fillValue=0] - The value to fill the matrix with (default is 0).
* @returns {Array} A 2D array (matrix) created from the input parameters.
*
* @example
* const myMatrix = Array.matrix(2, 5);
* // myMatrix will be [5, 5, 5]
*/
(Array as any).matrix = function <T>(a: any, _length: number, _fillValue = 0): T[] {
return a.matrix(_length, _fillValue) as T[];
};
(_protected_code_)((Array as any).matrix);
(_protected_code_)((Array as any).prototype.matrix);
(Array as any).prototype.matrix2d = function (_length: number, _fillValue = 0) {
// eslint-disable-next-line no-unused-vars
const y_func = function (y: any) {
return _fillValue;
};
// eslint-disable-next-line no-unused-vars
const x_func = function (x: any) {
return Array.from({
length: _length
}, y_func);
};
return Array.from({
length: _length
}, x_func);
};
(Array as any).matrix2d = function <T>(a: any, _length: number, _fillValue = 0): T[][] {
return a.matrix2d(_length, _fillValue) as T[][];
};
(_protected_code_)((Array as any).matrix2d);
(_protected_code_)((Array as any).prototype.matrix2d);
(Array as any).prototype.matrix3d = function (_length: number, _fillValue = 0) {
// eslint-disable-next-line no-unused-vars
const y_func = function (y: any) {
return Array.from({
length: _length
}, function () {
return _fillValue;
});
};
// eslint-disable-next-line no-unused-vars
const x_func = function (x: any) {
return Array.from({
length: _length
}, y_func);
};
return Array.from({
length: _length
}, x_func);
};
(Array as any).matrix3d = function <T>(a: any, _length: number, _fillValue = 0): T[][][] {
return a.matrix3d(_length, _fillValue) as T[][][];
};
(_protected_code_)((Array as any).matrix3d);
(_protected_code_)((Array as any).prototype.matrix3d);
(String as unknown as any).prototype.list = function (): string[] {
const __instance = this;
return range(0, __instance.length - 1).map(function <T>(i: any): T {
return __instance[i] as T;
}) as string[];
};
(_protected_code_)((String as unknown as any).prototype.list);
/**
* End of array math functions
*/
setDefaultProcessors();
/**
* Load every component tag declared in the body
**/
Ready(function () {
if (!CONFIG.get("useSDK")) {
GlobalSettings.__start__()
.catch((e: any) => {
throw Error(e);
});
}
});
/*
Public variables and functions
*/
Export(Export); /* exports the same Export function once */
Export(Import);
Export(Package);
Export(Class);
Export(New);
Export(Tag);
Export(Ready);
Export(ready);
Export(isBrowser);
Export(_methods_);
Export(GlobalSettings);
(loadSDK)();
if (isBrowser) {
asyncLoad(function (): any {
Ready(function () {
/*
* scroll management custom events
* usage: document.addEventListener('percentY90',function(e){console.log(e.detail.percentY)});
* possible events: scrollpercent, defaultscroll, percentY0, percentY25, percentY50, percentY75, percentY90
*/
(function (_top) {
let ticking = false;
const scrollHeight = Math.max(
document.body.scrollHeight, document.documentElement.scrollHeight,
document.body.offsetHeight, document.documentElement.offsetHeight,
document.body.clientHeight, document.documentElement.clientHeight
);
const scrollWidth = Math.max(
document.body.scrollWidth, document.documentElement.scrollWidth,
document.body.offsetWidth, document.documentElement.offsetWidth,
document.body.clientWidth, document.documentElement.clientWidth
);
function scrollDispatcher(event: any) {
const percentY = Math.round(_top.scrollY * 100 / scrollHeight);
const percentX = Math.round(_top.scrollX * 100 / scrollWidth);
const scrollPercentEventEvent = new CustomEvent("scrollpercent", {
detail: {
percentX,
percentY
}
});
event.target.dispatchEvent(scrollPercentEventEvent);
let secondaryEventName = "defaultscroll";
const __valid_scrolls__ = [0, 5, 10, 25, 50, 75, 90, 95, 100];
__valid_scrolls__.filter(function (p) {
return p === percentY;
}).map(function <T>(pY: T): T {
secondaryEventName = "percentY" + percentY.toString();
const secondaryCustomEvent = new CustomEvent(secondaryEventName, {
detail: {
percentX,
percentY
}
});
event.target.dispatchEvent(secondaryCustomEvent);
return pY;
});
}
document.addEventListener("scroll", function (event) {
if (!ticking) {
requestAnimationFrame(function () {
scrollDispatcher(event);
ticking = false;
});
ticking = true;
}
});
})(_top);
});
}, []);
}
if (!isBrowser) {
if (typeof _top.global !== "undefined" && Object.hasOwn(_top.global, "_fireAsyncLoad")) {
_fireAsyncLoad.call(_top);
}
if (typeof _top.global !== "undefined" && Object.hasOwn(_top.global, "onload")) {
_top.global.onload.call(_top);
}
}
/* Freezing Object && Object.prototype to prevent prototype pollution risks */
(function (isBrowser) {
const __freeze__ = function () {
Object.freeze(Object.prototype);
Object.freeze(Object);
};
if (isBrowser && CONFIG.get("secureObjects", false)) {
Ready(function () {
__freeze__();
});
} else if (CONFIG.get("secureObjects", false)) {
__freeze__();
}
})(isBrowser);
}
})(_top);