dees-domtools/ts/domtools.classes.domtools.ts

186 lines
5.8 KiB
TypeScript
Raw Permalink Normal View History

2022-03-16 12:39:50 +00:00
import * as plugins from './domtools.plugins.js';
2023-08-27 11:33:36 +00:00
import { type TViewport } from './domtools.css.breakpoints.js';
2022-03-16 12:39:50 +00:00
import { Scroller } from './domtools.classes.scroller.js';
2023-08-20 15:10:10 +00:00
import { WebSetup } from '@push.rocks/websetup';
2022-03-16 12:39:50 +00:00
import { ThemeManager } from './domtools.classes.thememanager.js';
2022-04-21 20:53:58 +00:00
import { Keyboard } from './domtools.classes.keyboard.js';
2020-06-28 17:40:03 +00:00
2020-05-27 21:15:38 +00:00
export interface IDomToolsState {
virtualViewport: TViewport;
2022-01-14 17:20:45 +00:00
jwt: string;
2020-05-27 21:15:38 +00:00
}
2020-05-25 15:57:47 +00:00
2022-04-21 20:53:58 +00:00
export interface IDomToolsContructorOptions {
ignoreGlobal?: boolean;
}
2020-05-25 15:57:47 +00:00
export class DomTools {
2020-06-03 09:07:31 +00:00
// ======
// STATIC
// ======
/**
* setups domtools
*/
2022-04-21 20:53:58 +00:00
public static async setupDomTools(optionsArg: IDomToolsContructorOptions = {}) {
2020-05-25 15:57:47 +00:00
let domToolsInstance: DomTools;
2022-04-21 20:53:58 +00:00
if (!globalThis.deesDomTools && !optionsArg.ignoreGlobal) {
globalThis.deesDomTools = new DomTools(optionsArg);
2020-05-25 15:57:47 +00:00
domToolsInstance = globalThis.deesDomTools;
2020-09-12 13:11:10 +00:00
2020-05-25 15:57:47 +00:00
// lets make sure the dom is ready
const readyStateChangedFunc = () => {
if (document.readyState === 'interactive' || document.readyState === 'complete') {
2020-05-25 16:11:59 +00:00
domToolsInstance.elements.headElement = document.querySelector('head');
domToolsInstance.elements.bodyElement = document.querySelector('body');
2020-05-25 15:57:47 +00:00
domToolsInstance.domReady.resolve();
}
};
document.addEventListener('readystatechange', readyStateChangedFunc);
domToolsInstance.domToolsReady.resolve();
2022-04-21 20:53:58 +00:00
} else if (optionsArg.ignoreGlobal) {
domToolsInstance = new DomTools(optionsArg);
2020-05-25 15:57:47 +00:00
} else {
domToolsInstance = globalThis.deesDomTools;
}
await domToolsInstance.domToolsReady.promise;
return domToolsInstance;
2020-05-23 16:55:36 +00:00
}
2020-05-25 15:57:47 +00:00
2020-07-27 18:23:47 +00:00
/**
* if you can, use the static asysnc .setupDomTools() function instead since it is safer to use.
*/
2020-09-16 13:57:16 +00:00
public static getGlobalDomToolsSync(): DomTools {
2020-07-27 17:11:00 +00:00
const globalDomTools: DomTools = globalThis.deesDomTools;
if (!globalDomTools) {
2020-07-27 18:23:47 +00:00
throw new Error('You tried to access domtools synchronously too early');
2020-07-27 17:11:00 +00:00
}
return globalThis.deesDomTools;
}
2020-06-03 09:07:31 +00:00
// ========
// INSTANCE
// ========
2020-06-28 15:49:46 +00:00
// elements
public elements: {
headElement: HTMLElement;
bodyElement: HTMLElement;
} = {
headElement: null,
bodyElement: null,
};
2020-11-05 18:08:42 +00:00
public websetup: WebSetup = new WebSetup({
metaObject: {
2020-11-23 20:41:26 +00:00
title: 'loading...',
},
2020-11-05 18:08:42 +00:00
});
2020-11-04 18:35:45 +00:00
2020-05-25 16:11:59 +00:00
public smartstate = new plugins.smartstate.Smartstate();
2020-05-27 21:59:28 +00:00
public domToolsStatePart = this.smartstate.getStatePart<IDomToolsState>('domtools', {
2020-06-03 09:07:31 +00:00
virtualViewport: 'native',
2022-04-21 20:53:58 +00:00
jwt: null,
2020-05-27 21:59:28 +00:00
});
2020-06-03 10:34:09 +00:00
public router = new plugins.smartrouter.SmartRouter({
2020-06-28 15:49:46 +00:00
debug: false,
2020-05-27 21:59:28 +00:00
});
2020-05-25 16:11:59 +00:00
2020-07-29 17:32:28 +00:00
public convenience = {
2021-09-13 18:35:33 +00:00
typedrequest: plugins.typedrequest,
2020-09-12 13:14:17 +00:00
smartdelay: plugins.smartdelay,
2022-12-31 11:12:58 +00:00
smartjson: plugins.smartjson,
2023-01-02 16:25:17 +00:00
smarturl: plugins.smarturl,
2020-07-29 17:32:28 +00:00
};
2020-10-06 22:08:26 +00:00
public deesComms = new plugins.deesComms.DeesComms();
2020-11-23 20:41:26 +00:00
public scroller = new plugins.SweetScroll({
/* some options */
}); // TODO: switch to scroller class
public themeManager = new ThemeManager(this);
2022-04-20 21:56:09 +00:00
public keyboard = new Keyboard(document.body);
2021-11-21 15:14:27 +00:00
2020-05-25 15:57:47 +00:00
public domToolsReady = plugins.smartpromise.defer();
public domReady = plugins.smartpromise.defer();
public globalStylesReady = plugins.smartpromise.defer();
2022-04-21 20:53:58 +00:00
constructor(optionsArg: IDomToolsContructorOptions) {}
2020-05-25 15:57:47 +00:00
2022-12-31 10:34:04 +00:00
private runOnceTrackerStringMap = new plugins.lik.Stringmap();
private runOnceResultMap = new plugins.lik.FastMap();
2021-11-26 14:26:15 +00:00
2020-05-25 16:22:05 +00:00
/**
* run a function once and always get the Promise of the first execution
2020-06-28 15:49:46 +00:00
* @param identifierArg the indentifier arg identifies functions. functions with the same identifier are considered equal
* @param funcArg the actual func arg to run
2020-05-25 16:22:05 +00:00
*/
2020-05-25 15:57:47 +00:00
public async runOnce<T>(identifierArg: string, funcArg: () => Promise<T>) {
const runningId = `${identifierArg}+runningCheck`;
2020-05-27 21:15:38 +00:00
if (!this.runOnceTrackerStringMap.checkString(identifierArg)) {
2020-05-25 15:57:47 +00:00
this.runOnceTrackerStringMap.addString(identifierArg);
this.runOnceTrackerStringMap.addString(runningId);
const result = await funcArg();
this.runOnceResultMap.addToMap(identifierArg, result);
this.runOnceTrackerStringMap.removeString(runningId);
}
2020-05-27 21:15:38 +00:00
return await this.runOnceTrackerStringMap.registerUntilTrue(
2020-06-03 09:07:31 +00:00
(stringMap) => {
2020-05-27 21:15:38 +00:00
return !stringMap.includes(runningId);
},
() => {
return this.runOnceResultMap.getByKey(identifierArg);
}
);
2020-05-25 15:57:47 +00:00
}
2020-06-28 15:49:46 +00:00
// setStuff
2021-11-26 14:26:15 +00:00
/**
* allows to set global styles
* @param stylesText the css text you want to set
*/
2020-06-28 15:49:46 +00:00
public async setGlobalStyles(stylesText: string) {
await this.domReady.promise;
const styleElement = document.createElement('style');
styleElement.type = 'text/css';
styleElement.appendChild(document.createTextNode(stylesText));
this.elements.headElement.appendChild(styleElement);
}
2022-04-22 07:25:10 +00:00
/**
* allows to set global styles
* @param stylesText the css text you want to set
*/
2023-04-05 14:46:13 +00:00
public async setExternalScript(scriptLinkArg: string) {
2022-04-22 07:25:10 +00:00
await this.domReady.promise;
const done = plugins.smartpromise.defer();
2023-04-05 14:46:13 +00:00
const script = document.createElement('script');
2022-04-22 07:25:10 +00:00
script.src = scriptLinkArg;
2023-04-05 14:46:13 +00:00
script.addEventListener('load', function () {
2022-04-22 07:25:10 +00:00
done.resolve();
});
2022-04-22 07:37:50 +00:00
const parentNode = document.head || document.body;
parentNode.append(script);
2022-04-22 07:25:10 +00:00
await done.promise;
}
2021-11-26 14:26:15 +00:00
/**
* allows setting external css files
* @param cssLinkArg a url to an external stylesheet
*/
2020-12-01 17:31:37 +00:00
public async setExternalCss(cssLinkArg: string) {
const cssTag = document.createElement('link');
cssTag.rel = 'stylesheet';
cssTag.crossOrigin = 'anonymous';
cssTag.href = cssLinkArg;
document.head.append(cssTag);
}
2021-11-26 14:26:15 +00:00
/**
* allows setting of website infos
* @param optionsArg the website info
*/
2020-06-28 15:49:46 +00:00
public async setWebsiteInfo(optionsArg: plugins.websetup.IWebSetupConstructorOptions) {
2020-11-05 20:08:07 +00:00
await this.websetup.setup(optionsArg);
2020-11-04 18:35:45 +00:00
await this.websetup.readyPromise;
2020-06-28 15:49:46 +00:00
}
2020-05-27 21:15:38 +00:00
}