UNPKG

@kwiz/common

Version:

KWIZ common utilities and helpers for M365 platform

171 lines (154 loc) 7.6 kB
import { isDebug } from "../helpers/debug"; import { noop } from "../helpers/objects"; import { isNotEmptyArray, isNullOrEmptyString, isNullOrUndefined } from "../helpers/typecheckers"; import { IKnownScript, ksGlobal } from "../types/knownscript.types"; import Sod from "./sod"; export interface IScriptUtils { /** @deprecated - use wrapFunction instead from helpers/functions */ wrapFunction3?: (originalFunction: () => void, instance: any, doBefore: () => void, doAfter: () => void) => void; loadKnownScript: (script: IKnownScript) => void; loadKnownScript_Sync: (script: IKnownScript) => void; ensureScript: (scriptUrl: string, global: ksGlobal, callback: () => void, sodName: string) => void; ensureScripts: (scripts: { scriptUrl: string; global: ksGlobal; sodName: string; }[], callback: () => void) => void; } export default class script implements IScriptUtils { private static instance: script = null; public isRtl = false; public static get Instance() { if (script.instance === null) { //share single instance between all imports if (typeof (window as any).kSingleScripts !== 'undefined') script.instance = (window as any).kSingleScripts;//a global instance already exists, use it else { script.instance = new script(); (window as any).kSingleScripts = script.instance;//place this instance in the global namespace for others to reuse } } return script.instance; } public async loadKnownScript(knownScript: IKnownScript) { var promisesDependencies: Promise<any>[] = []; (knownScript.dependencies || []).forEach(dep => { promisesDependencies.push(this.loadKnownScript(dep)); }); if (promisesDependencies.length > 0) await Promise.all(promisesDependencies); return new Promise((resolve, reject) => { this.ensureKnownScriptInternal(knownScript, () => { resolve(Sod.getGlobal(knownScript.global)); }); }); } public loadKnownScript_Sync(knownScript: IKnownScript) { try { if (isNotEmptyArray(knownScript.dependencies)) { (knownScript.dependencies || []).forEach(dep => { this.loadKnownScript_Sync(dep) }); } } catch { } this.ensureKnownScriptInternal(knownScript, noop, true); return Sod.getGlobal(knownScript.global); } private ensureKnownScriptInternal(knownScript: IKnownScript, callback: () => void, sync = false) { let url = isDebug() && !knownScript.forceMin ? knownScript.url.replace('.min.js', '.js') : knownScript.url; if (url[0] === '/') url = "https://apps.kwizcom.com" + url; if (sync === true) this.ensureScriptSync(url, knownScript.global, callback, knownScript.sodName); else this.ensureScript(url, knownScript.global, callback, knownScript.sodName); let cssFiles = this.isRtl === true && !isNullOrUndefined(knownScript.rtlCss) ? knownScript.rtlCss : knownScript.css; if (!isNullOrUndefined(cssFiles)) cssFiles.forEach(css => { if (!isNullOrEmptyString(css)) { let cssurl = isDebug() && !knownScript.forceMin ? css.replace('.min.css', '.css') : css; if (cssurl[0] === '/') cssurl = "https://apps.kwizcom.com" + cssurl; let knownStyles = document.getElementsByClassName("kwizcom_known_css"); let found = false; for (let si = 0; si < knownStyles.length; si++) { let elm: HTMLLinkElement = knownStyles[si] as HTMLLinkElement; if (elm.href && elm.href.toLowerCase() === cssurl.toLowerCase()) { found = true; break; } } if (!found) { let link = document.createElement("link"); link.rel = "stylesheet"; link.className = "kwizcom_known_css"; link.type = "text/css"; link.href = cssurl; document.head.appendChild(link); } } }); } public loadCss(cssUrl: string) { let knownStyles = document.getElementsByClassName("kwizcom_known_css"); let found = false; for (let si = 0; si < knownStyles.length; si++) { let elm: HTMLLinkElement = knownStyles[si] as HTMLLinkElement; if (elm.href && elm.href.toLowerCase() === cssUrl.toLowerCase()) { found = true; break; } } if (!found) { let link = document.createElement("link"); link.rel = "stylesheet"; link.className = "kwizcom_known_css"; link.type = "text/css"; link.href = cssUrl; document.head.appendChild(link); } } public ensureScriptSync(scriptUrl: string, global: ksGlobal, callback?: () => void, sodName?: string) { //in IE there is no promise, we cannot use any async functions return Sod.ensureScriptNoPromise(scriptUrl, global, callback, sodName, true); } public async ensureScript(scriptUrl: string, global: ksGlobal, callback?: () => void, sodName?: string) { return Sod.ensureScript(scriptUrl, global, callback, sodName, false); } /** ensure a collection of scripts and call the callback when they are all done */ public async ensureScripts(scripts: { scriptUrl: string; global: ksGlobal; sodName: string; }[], callback: () => void) { let promises: Promise<void>[] = []; let length = scripts.length; let finished = 0; let onFinished = typeof (callback) !== "function" ? null : () => { finished++; if (finished === length)//all finished callback(); }; scripts.forEach(scr => { promises.push(Sod.ensureScript(scr.scriptUrl, scr.global, onFinished, scr.sodName)); }); return Promise.all(promises); } private _WrapFunctionArr: any[] = []; /** @deprecated - use wrapFunction instead from helpers/functions */ public wrapFunction3(originalFunction: () => void, instance: any, doBefore: () => void, doAfter: () => void) { try { if (instance !== null) { originalFunction.bind(instance); } var idx = this._WrapFunctionArr.length; this._WrapFunctionArr[idx] = originalFunction; originalFunction = function (...args: any[]) { if (typeof (doBefore) === "function") { doBefore.apply(instance, args); } var returnValue = this._WrapFunctionArr[idx].apply(instance, args); if (typeof (doAfter) === "function") { doAfter.apply(instance, args); } return returnValue; }; if (instance !== null) { originalFunction.bind(instance); } } catch (e) { if (isDebug()) console.log('unhandled error in wrapFunction3'); } } }