Files
owl/src/utils.ts
T

104 lines
2.5 KiB
TypeScript
Raw Normal View History

/**
* Owl Utils
*
* We have here a small collection of utility functions:
*
2019-05-10 20:50:14 +02:00
* - whenReady
* - loadJS
* - loadFile
* - escape
* - debounce
*/
import { browser } from "./browser";
2019-07-25 13:24:57 +02:00
export function whenReady(fn?: any) {
2020-04-21 15:08:53 +02:00
return new Promise(function (resolve) {
if (document.readyState !== "loading") {
resolve();
} else {
document.addEventListener("DOMContentLoaded", resolve, false);
}
2020-04-21 15:08:53 +02:00
}).then(fn || function () {});
2019-05-10 20:50:14 +02:00
}
const loadedScripts: { [key: string]: Promise<void> } = {};
export function loadJS(url: string): Promise<void> {
if (url in loadedScripts) {
return loadedScripts[url];
}
2020-04-21 15:08:53 +02:00
const promise: Promise<void> = new Promise(function (resolve, reject) {
2019-05-10 20:50:14 +02:00
const script = document.createElement("script");
script.type = "text/javascript";
script.src = url;
2020-04-21 15:08:53 +02:00
script.onload = function () {
2019-05-10 20:50:14 +02:00
resolve();
};
2020-04-21 15:08:53 +02:00
script.onerror = function () {
2019-05-10 20:50:14 +02:00
reject(`Error loading file '${url}'`);
};
const head = document.head || document.getElementsByTagName("head")[0];
head.appendChild(script);
});
loadedScripts[url] = promise;
return promise;
}
export async function loadFile(url: string): Promise<string> {
const result = await browser.fetch(url);
2019-05-10 20:50:14 +02:00
if (!result.ok) {
throw new Error("Error while fetching xml templates");
}
return await result.text();
2019-05-10 20:50:14 +02:00
}
2019-01-16 11:28:05 +01:00
export function escape(str: string | number | undefined): string {
if (str === undefined) {
return "";
}
if (typeof str === "number") {
return String(str);
}
2019-12-12 12:18:08 +01:00
const p = document.createElement("p");
p.textContent = str;
return p.innerHTML;
2019-01-16 11:28:05 +01:00
}
2019-01-30 12:34:45 +01:00
/**
* Returns a function, that, as long as it continues to be invoked, will not
* be triggered. The function will be called after it stops being called for
* N milliseconds. If `immediate` is passed, trigger the function on the
* leading edge, instead of the trailing.
*
* Inspired by https://davidwalsh.name/javascript-debounce-function
*/
export function debounce(func: Function, wait: number, immediate?: boolean): Function {
2019-01-30 12:34:45 +01:00
let timeout;
2020-04-21 15:08:53 +02:00
return function (this: any) {
2019-01-30 12:34:45 +01:00
const context = this;
const args = arguments;
function later() {
timeout = null;
if (!immediate) {
func.apply(context, args);
}
}
const callNow = immediate && !timeout;
browser.clearTimeout(timeout);
timeout = browser.setTimeout(later, wait);
2019-01-30 12:34:45 +01:00
if (callNow) {
func.apply(context, args);
}
};
}
export function shallowEqual(p1, p2): boolean {
2019-09-04 22:48:37 +02:00
for (let k in p1) {
if (p1[k] !== p2[k]) {
2019-09-04 22:48:37 +02:00
return false;
}
2019-09-04 22:48:37 +02:00
}
return true;
}