2020-05-25 15:57:47 +00:00
|
|
|
import * as plugins from './domtools.plugins';
|
2020-05-25 22:14:37 +00:00
|
|
|
import { Stringmap } from '@pushrocks/lik/dist_ts/lik.stringmap';
|
|
|
|
import { FastMap } from '@pushrocks/lik/dist_ts/lik.fastmap';
|
2020-05-27 21:15:38 +00:00
|
|
|
import { TViewport } from './domtools.breakpoints';
|
|
|
|
|
2020-06-28 17:40:03 +00:00
|
|
|
import { Scroller } from './domtools.classes.scroller';
|
2020-07-29 17:32:28 +00:00
|
|
|
import { delayForRandom } from '@pushrocks/smartdelay';
|
2020-09-12 13:11:10 +00:00
|
|
|
import { setupGlobalTheme } from './domtools.css.theme';
|
2020-06-28 17:40:03 +00:00
|
|
|
|
2020-05-27 21:15:38 +00:00
|
|
|
export interface IDomToolsState {
|
|
|
|
virtualViewport: TViewport;
|
|
|
|
}
|
2020-05-25 15:57:47 +00:00
|
|
|
|
|
|
|
export class DomTools {
|
2020-06-03 09:07:31 +00:00
|
|
|
// ======
|
|
|
|
// STATIC
|
|
|
|
// ======
|
|
|
|
/**
|
|
|
|
* setups domtools
|
|
|
|
*/
|
2020-05-25 15:57:47 +00:00
|
|
|
public static async setupDomTools() {
|
|
|
|
let domToolsInstance: DomTools;
|
|
|
|
if (!globalThis.deesDomTools) {
|
|
|
|
globalThis.deesDomTools = new DomTools();
|
|
|
|
domToolsInstance = globalThis.deesDomTools;
|
2020-09-12 13:11:10 +00:00
|
|
|
|
|
|
|
// lets setup theming
|
|
|
|
setupGlobalTheme(domToolsInstance);
|
|
|
|
|
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();
|
|
|
|
} 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.
|
|
|
|
*/
|
|
|
|
public static getGlobalDomToolsSync() {
|
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-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',
|
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 = {
|
|
|
|
smartdelay: plugins.smartdelay
|
|
|
|
};
|
|
|
|
|
2020-06-28 16:59:14 +00:00
|
|
|
public scroller: plugins.SweetScroll;
|
|
|
|
|
2020-06-03 09:07:31 +00:00
|
|
|
private actionSetVirtualViewport = this.domToolsStatePart.createAction<TViewport>(
|
|
|
|
async (statePart, payload) => {
|
|
|
|
const currentState = statePart.getState();
|
|
|
|
currentState.virtualViewport = payload;
|
|
|
|
return currentState;
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
2020-05-25 15:57:47 +00:00
|
|
|
public domToolsReady = plugins.smartpromise.defer();
|
|
|
|
public domReady = plugins.smartpromise.defer();
|
|
|
|
public globalStylesReady = plugins.smartpromise.defer();
|
|
|
|
|
2020-06-28 15:49:46 +00:00
|
|
|
constructor() {
|
|
|
|
// lets care about third party stuff
|
2020-06-28 16:59:14 +00:00
|
|
|
this.domToolsReady.promise.then(() => {
|
|
|
|
this.scroller = new plugins.SweetScroll({
|
|
|
|
/* some options */
|
|
|
|
});
|
|
|
|
});
|
2020-05-25 15:57:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private runOnceTrackerStringMap = new Stringmap();
|
|
|
|
private runOnceResultMap = new FastMap();
|
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
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
public setVirtualViewport(environmentArg: TViewport) {
|
2020-05-27 21:59:28 +00:00
|
|
|
this.domToolsStatePart.dispatchAction(this.actionSetVirtualViewport, environmentArg);
|
|
|
|
}
|
2020-06-28 15:49:46 +00:00
|
|
|
|
|
|
|
public async setWebsiteInfo(optionsArg: plugins.websetup.IWebSetupConstructorOptions) {
|
|
|
|
const websetup = new plugins.websetup.WebSetup(optionsArg);
|
|
|
|
await websetup.setup();
|
|
|
|
}
|
2020-05-27 21:15:38 +00:00
|
|
|
}
|