Some more small rework and cleanup

This commit is contained in:
WolverinDEV 2021-03-18 18:59:06 +01:00
parent e2be859266
commit 85acd6dd56
11 changed files with 202 additions and 255 deletions

View file

@ -1,6 +1,6 @@
import * as loader from "./loader/loader"; import * as loader from "./loader/loader";
import {Stage} from "./loader/loader"; import {Stage} from "./loader/loader";
import {getUrlParameter} from "./loader/utils"; import {getUrlParameter} from "./loader/Utils";
let overlay: HTMLDivElement; let overlay: HTMLDivElement;
let setupContainer: HTMLDivElement; let setupContainer: HTMLDivElement;

99
loader/app/bootstrap.ts Normal file
View file

@ -0,0 +1,99 @@
import "core-js/stable";
import "./polifill";
import "./css";
import {ApplicationLoader} from "./loader/loader";
import {getUrlParameter} from "./loader/Utils";
/* let the loader register himself at the window first */
const target = getUrlParameter("loader-target") || "app";
console.info("Loading app with loader \"%s\"", target);
let appLoader: ApplicationLoader;
if(target === "empty") {
appLoader = new (require("./targets/empty").default);
} else if(target === "manifest") {
appLoader = new (require("./targets/maifest-target").default);
} else {
appLoader = new (require("./targets/app").default);
}
setTimeout(() => appLoader.execute(), 0);
export {};
if(__build.target === "client") {
/* do this so we don't get a react dev tools warning within the client */
if(!('__REACT_DEVTOOLS_GLOBAL_HOOK__' in window)) {
window.__REACT_DEVTOOLS_GLOBAL_HOOK__ = {};
}
window.__REACT_DEVTOOLS_GLOBAL_HOOK__.inject = function () {};
}
/* Hello World message */
{
const clog = console.log;
const print_security = () => {
{
const css = [
"display: block",
"text-align: center",
"font-size: 42px",
"font-weight: bold",
"-webkit-text-stroke: 2px black",
"color: red"
].join(";");
clog("%c ", "font-size: 100px;");
clog("%cSecurity warning:", css);
}
{
const css = [
"display: block",
"text-align: center",
"font-size: 18px",
"font-weight: bold"
].join(";");
clog("%cPasting anything in here could give attackers access to your data.", css);
clog("%cUnless you understand exactly what you are doing, close this window and stay safe.", css);
clog("%c ", "font-size: 100px;");
}
};
/* print the hello world */
{
const css = [
"display: block",
"text-align: center",
"font-size: 72px",
"font-weight: bold",
"-webkit-text-stroke: 2px black",
"color: #18BC9C"
].join(";");
clog("%cHey, hold on!", css);
}
{
const css = [
"display: block",
"text-align: center",
"font-size: 26px",
"font-weight: bold"
].join(";");
const css_2 = [
"display: block",
"text-align: center",
"font-size: 26px",
"font-weight: bold",
"color: blue"
].join(";");
const display_detect = /./;
display_detect.toString = function() { print_security(); return ""; };
clog("%cLovely to see you using and debugging the TeaSpeak-Web client.", css);
clog("%cIf you have some good ideas or already done some incredible changes,", css);
clog("%cyou'll be may interested to share them here: %chttps://github.com/TeaSpeak/TeaWeb", css, css_2);
clog("%c ", display_detect);
}
}

View file

@ -1,35 +1,14 @@
import "core-js/stable";
import "./polifill";
import "./css";
import * as loader from "./loader/loader";
import {ApplicationLoader} from "./loader/loader";
import {getUrlParameter} from "./loader/utils";
if(window["loader"]) { if(window["loader"]) {
throw "an loader instance has already been defined"; throw "an loader instance has already been defined";
} }
window["loader"] = loader;
/* let the loader register himself at the window first */
const target = getUrlParameter("loader-target") || "app"; export * from "./loader/loader";
console.info("Loading app with loader \"%s\"", target); export * as loaderAnimation from "./animation";
let appLoader: ApplicationLoader; import "./bootstrap";
if(target === "empty") {
appLoader = new (require("./targets/empty").default); /* FIXME: This is glue! */
} else if(target === "manifest") { if(window["loader"]) {
appLoader = new (require("./targets/maifest-target").default); throw "an loader instance has already been defined";
} else {
appLoader = new (require("./targets/app").default);
} }
setTimeout(() => appLoader.execute(), 0); window["loader"] = module.exports;
export {};
if(__build.target === "client") {
/* do this so we don't get a react dev tools warning within the client */
if(!('__REACT_DEVTOOLS_GLOBAL_HOOK__' in window))
window.__REACT_DEVTOOLS_GLOBAL_HOOK__ = {};
window.__REACT_DEVTOOLS_GLOBAL_HOOK__.inject = function () {};
}

View file

@ -1,11 +1,12 @@
import {config, critical_error, SourcePath} from "./loader"; import {config, critical_error, SourcePath} from "./loader";
import {load_parallel, LoadCallback, LoadSyntaxError, ParallelOptions, script_name} from "./utils"; import {executeParallelLoad, LoadCallback, LoadSyntaxError, ParallelOptions} from "./Utils";
let _script_promises: {[key: string]: Promise<void>} = {}; let _script_promises: {[key: string]: Promise<void>} = {};
function load_script_url(url: string) : Promise<void> { function load_script_url(url: string) : Promise<void> {
if(typeof _script_promises[url] === "object") if(typeof _script_promises[url] === "object") {
return _script_promises[url]; return _script_promises[url];
}
return (_script_promises[url] = new Promise((resolve, reject) => { return (_script_promises[url] = new Promise((resolve, reject) => {
const script_tag: HTMLScriptElement = document.createElement("script"); const script_tag: HTMLScriptElement = document.createElement("script");
@ -67,40 +68,18 @@ export interface Options {
cache_tag?: string; cache_tag?: string;
} }
export async function load(path: SourcePath, options: Options) : Promise<void> { export async function loadScript(path: SourcePath, options: Options) : Promise<void> {
if(Array.isArray(path)) { //We have fallback scripts await load_script_url(path + (options.cache_tag || ""));
return load(path[0], options).catch(error => {
if(error instanceof LoadSyntaxError)
return Promise.reject(error);
if(path.length > 1)
return load(path.slice(1), options);
return Promise.reject(error);
});
} else {
const source = typeof(path) === "string" ? {url: path, depends: []} : path;
if(source.url.length == 0) return Promise.resolve();
/* await depends */
for(const depend of source.depends) {
if(!_script_promises[depend])
throw "Missing dependency " + depend;
await _script_promises[depend];
}
await load_script_url(source.url + (options.cache_tag || ""));
}
} }
type MultipleOptions = Options | ParallelOptions; type MultipleOptions = Options | ParallelOptions;
export async function load_multiple(paths: SourcePath[], options: MultipleOptions, callback?: LoadCallback<SourcePath>) : Promise<void> { export async function loadScripts(paths: SourcePath[], options: MultipleOptions, callback?: LoadCallback<SourcePath>) : Promise<void> {
const result = await load_parallel<SourcePath>(paths, e => load(e, options), e => script_name(e, false), options, callback); const result = await executeParallelLoad<SourcePath>(paths, e => loadScript(e, options), e => e, options, callback);
if(result.failed.length > 0) { if(result.failed.length > 0) {
if(config.error) { if(config.error) {
console.error("Failed to load the following scripts:"); console.error("Failed to load the following scripts:");
for(const script of result.failed) { for(const script of result.failed) {
const sname = script_name(script.request, false); const sname = script.request;
if(script.error instanceof LoadSyntaxError) { if(script.error instanceof LoadSyntaxError) {
const source = script.error.source as Error; const source = script.error.source as Error;
if(source.name === "TypeError") { if(source.name === "TypeError") {
@ -126,11 +105,11 @@ export async function load_multiple(paths: SourcePath[], options: MultipleOption
} else if(typeof error === "string") { } else if(typeof error === "string") {
errorMessage = error; errorMessage = error;
} else { } else {
console.error("Script %s loading error: %o", script_name(result.failed[0].request, false), error); console.error("Script %s loading error: %o", result.failed[0].request, error);
errorMessage = "View the browser console for more information!"; errorMessage = "View the browser console for more information!";
} }
critical_error("Failed to load script " + script_name(result.failed[0].request, true), errorMessage); critical_error("Failed to load script " + result.failed[0].request, errorMessage);
} }
throw "failed to load script " + script_name(result.failed[0].request, false) + " (" + errorMessage + ")"; throw "failed to load script " + result.failed[0].request + " (" + errorMessage + ")";
} }
} }

View file

@ -1,18 +1,22 @@
import {config, critical_error, SourcePath} from "./loader"; import {config, critical_error, SourcePath} from "./loader";
import {load_parallel, LoadCallback, LoadSyntaxError, ParallelOptions, script_name} from "./utils"; import {executeParallelLoad, LoadCallback, LoadSyntaxError, ParallelOptions} from "./Utils";
let _style_promises: {[key: string]: Promise<void>} = {}; let loadedStyles: {[key: string]: Promise<void>} = {};
function load_style_url(url: string) : Promise<void> { function load_style_url(url: string) : Promise<void> {
if(typeof _style_promises[url] === "object") if(typeof loadedStyles[url] === "object") {
return _style_promises[url]; return loadedStyles[url];
}
return (_style_promises[url] = new Promise((resolve, reject) => { return (loadedStyles[url] = new Promise((resolve, reject) => {
const tag: HTMLLinkElement = document.createElement("link"); const tag: HTMLLinkElement = document.createElement("link");
let error = false; let error = false;
const error_handler = (event: ErrorEvent) => { const error_handler = (event: ErrorEvent) => {
if(config.verbose) console.log("msg: %o, url: %o, line: %o, col: %o, error: %o", event.message, event.filename, event.lineno, event.colno, event.error); if(config.verbose) {
console.log("msg: %o, url: %o, line: %o, col: %o, error: %o", event.message, event.filename, event.lineno, event.colno, event.error);
}
if(event.filename == tag.href) { //FIXME! if(event.filename == tag.href) { //FIXME!
window.removeEventListener('error', error_handler as any); window.removeEventListener('error', error_handler as any);
@ -42,8 +46,9 @@ function load_style_url(url: string) : Promise<void> {
tag.onerror = error => { tag.onerror = error => {
cleanup(); cleanup();
tag.remove(); tag.remove();
if(config.error) if(config.error) {
console.error("File load error for file %s: %o", url, error); console.error("File load error for file %s: %o", url, error);
}
reject("failed to load file " + url); reject("failed to load file " + url);
}; };
tag.onload = () => { tag.onload = () => {
@ -80,14 +85,14 @@ function load_style_url(url: string) : Promise<void> {
document.getElementById("style").appendChild(tag); document.getElementById("style").appendChild(tag);
tag.href = config.baseUrl + url; tag.href = config.baseUrl + url;
})).then(result => { })).then(() => {
/* cleanup memory */ /* cleanup memory */
_style_promises[url] = Promise.resolve(); /* this promise does not holds the whole script tag and other memory */ loadedStyles[url] = Promise.resolve(); /* this promise does not holds the whole script tag and other memory */
return _style_promises[url]; return loadedStyles[url];
}).catch(error => { }).catch(error => {
/* cleanup memory */ /* cleanup memory */
_style_promises[url] = Promise.reject(error); /* this promise does not holds the whole script tag and other memory */ loadedStyles[url] = Promise.reject(error); /* this promise does not holds the whole script tag and other memory */
return _style_promises[url]; return loadedStyles[url];
}); });
} }
@ -95,39 +100,18 @@ export interface Options {
cache_tag?: string; cache_tag?: string;
} }
export async function load(path: SourcePath, options: Options) : Promise<void> { export async function loadStyle(path: SourcePath, options: Options) : Promise<void> {
if(Array.isArray(path)) { //We have fallback scripts await load_style_url(path + (options.cache_tag || ""));
return load(path[0], options).catch(error => {
if(error instanceof LoadSyntaxError)
return Promise.reject(error);
if(path.length > 1)
return load(path.slice(1), options);
return Promise.reject(error);
});
} else {
const source = typeof(path) === "string" ? {url: path, depends: []} : path;
if(source.url.length == 0) return Promise.resolve();
/* await depends */
for(const depend of source.depends) {
if(!_style_promises[depend])
throw "Missing dependency " + depend;
await _style_promises[depend];
}
await load_style_url(source.url + (options.cache_tag || ""));
}
} }
export type MultipleOptions = Options | ParallelOptions; export type MultipleOptions = Options | ParallelOptions;
export async function load_multiple(paths: SourcePath[], options: MultipleOptions, callback?: LoadCallback<SourcePath>) : Promise<void> { export async function loadStyles(paths: SourcePath[], options: MultipleOptions, callback?: LoadCallback<SourcePath>) : Promise<void> {
const result = await load_parallel<SourcePath>(paths, e => load(e, options), e => script_name(e, false), options, callback); const result = await executeParallelLoad<SourcePath>(paths, e => loadStyle(e, options), e => e, options, callback);
if(result.failed.length > 0) { if(result.failed.length > 0) {
if(config.error) { if(config.error) {
console.error("Failed to load the following style sheets:"); console.error("Failed to load the following style sheets:");
for(const style of result.failed) { for(const style of result.failed) {
const sname = script_name(style.request, false); const sname = style.request;
if(style.error instanceof LoadSyntaxError) { if(style.error instanceof LoadSyntaxError) {
console.log(" - %s: %o", sname, style.error.source); console.log(" - %s: %o", sname, style.error.source);
} else { } else {
@ -136,7 +120,7 @@ export async function load_multiple(paths: SourcePath[], options: MultipleOption
} }
} }
critical_error("Failed to load style " + script_name(result.failed[0].request, true) + " <br>" + "View the browser console for more information!"); critical_error("Failed to load style <code>" + result.failed[0].request + "</code><br>" + "View the browser console for more information!");
throw "failed to load style " + script_name(result.failed[0].request, false); throw "failed to load style " + result.failed[0].request;
} }
} }

View file

@ -1,10 +1,10 @@
import {SourcePath} from "./loader"; import {Options} from "./ScriptLoader";
import {Options} from "./script_loader";
export const getUrlParameter = key => { export const getUrlParameter = key => {
const match = location.search.match(new RegExp("(.*[?&]|^)" + key + "=([^&]+)($|&.*)")); const match = location.search.match(new RegExp("(.*[?&]|^)" + key + "=([^&]+)($|&.*)"));
if(!match) if(!match) {
return undefined; return undefined;
}
return match[2]; return match[2];
}; };
@ -16,24 +16,15 @@ export class LoadSyntaxError {
} }
} }
export function script_name(path: SourcePath, html: boolean) {
if(Array.isArray(path)) {
return path.filter(e => !!e).map(e => script_name(e, html)).join(" or ");
} else if(typeof(path) === "string")
return html ? "<code>" + path + "</code>" : path;
else
return html ? "<code>" + path.url + "</code>" : path.url;
}
export interface ParallelOptions extends Options { export interface ParallelOptions extends Options {
max_parallel_requests?: number maxParallelRequests?: number
} }
export interface ParallelResult<T> { export interface ParallelResult<T> {
succeeded: T[]; succeeded: T[];
failed: { failed: {
request: T, request: T,
error: T error: any
}[], }[],
skipped: T[]; skipped: T[];
@ -41,15 +32,22 @@ export interface ParallelResult<T> {
export type LoadCallback<T> = (entry: T, state: "loading" | "loaded") => void; export type LoadCallback<T> = (entry: T, state: "loading" | "loaded") => void;
export async function load_parallel<T>(requests: T[], executor: (_: T) => Promise<void>, stringify: (_: T) => string, options: ParallelOptions, callback?: LoadCallback<T>) : Promise<ParallelResult<T>> { export async function executeParallelLoad<T>(
requests: T[],
executor: (_: T) => Promise<void>,
stringify: (_: T) => string,
options: ParallelOptions,
callback?: LoadCallback<T>
) : Promise<ParallelResult<T>> {
const result: ParallelResult<T> = { failed: [], succeeded: [], skipped: [] }; const result: ParallelResult<T> = { failed: [], succeeded: [], skipped: [] };
const pendingRequests = requests.slice(0).reverse(); /* we're only able to pop from the back */ const pendingRequests = requests.slice(0).reverse(); /* we're only able to pop from the back */
const currentRequests = {}; const currentRequests = {};
if(typeof callback === "undefined") if(typeof callback === "undefined") {
callback = () => {}; callback = () => {};
}
const maxParallelRequests = typeof options.max_parallel_requests === "number" && options.max_parallel_requests > 0 ? options.max_parallel_requests : Number.MAX_SAFE_INTEGER; const maxParallelRequests = typeof options.maxParallelRequests === "number" && options.maxParallelRequests > 0 ? options.maxParallelRequests : Number.MAX_SAFE_INTEGER;
while (pendingRequests.length > 0) { while (pendingRequests.length > 0) {
while(Object.keys(currentRequests).length < maxParallelRequests) { while(Object.keys(currentRequests).length < maxParallelRequests) {
const element = pendingRequests.pop(); const element = pendingRequests.pop();
@ -60,8 +58,10 @@ export async function load_parallel<T>(requests: T[], executor: (_: T) => Promis
delete currentRequests[name]; delete currentRequests[name];
callback(element, "loaded"); callback(element, "loaded");
}); });
if(pendingRequests.length == 0)
if(pendingRequests.length == 0) {
break; break;
}
} }
/* /*
@ -69,8 +69,9 @@ export async function load_parallel<T>(requests: T[], executor: (_: T) => Promis
* This should also not throw because any errors will be caught before. * This should also not throw because any errors will be caught before.
*/ */
await Promise.race(Object.keys(currentRequests).map(e => currentRequests[e])); await Promise.race(Object.keys(currentRequests).map(e => currentRequests[e]));
if(result.failed.length > 0) if(result.failed.length > 0) {
break; /* finish loading the other requests and than show the error */ break; /* finish loading the other requests and than show the error */
}
} }
await Promise.all(Object.keys(currentRequests).map(e => currentRequests[e])); await Promise.all(Object.keys(currentRequests).map(e => currentRequests[e]));
result.skipped.push(...pendingRequests); result.skipped.push(...pendingRequests);

View file

@ -1,7 +1,5 @@
import * as script_loader from "./script_loader";
import * as style_loader from "./style_loader";
import * as Animation from "../animation"; import * as Animation from "../animation";
import {getUrlParameter} from "./utils"; import {getUrlParameter} from "./Utils";
export interface ApplicationLoader { export interface ApplicationLoader {
execute(); execute();
@ -76,30 +74,9 @@ export enum Stage {
DONE DONE
} }
let cache_tag: string | undefined;
let currentStage: Stage = undefined; let currentStage: Stage = undefined;
const tasks: {[key:number]: InternalTask[]} = {}; const tasks: {[key:number]: InternalTask[]} = {};
/* test if all files shall be load from cache or fetch again */
function loader_cache_tag() {
if(__build.mode === "debug") {
cache_tag = "?_ts=" + Date.now();
return;
}
const cached_version = localStorage.getItem("cached_version");
if(!cached_version || cached_version !== __build.version) {
register_task(Stage.LOADED, {
priority: 0,
name: "cached version updater",
function: async () => {
localStorage.setItem("cached_version", __build.version);
}
});
}
cache_tag = "?_version=" + __build.version;
}
export type ModuleMapping = { export type ModuleMapping = {
application: string, application: string,
modules: { modules: {
@ -174,22 +151,23 @@ export function setCurrentTaskName(taskId: number, name: string) {
} }
export async function execute(customLoadingAnimations: boolean) { export async function execute(customLoadingAnimations: boolean) {
if(!await Animation.initialize(customLoadingAnimations)) if(!await Animation.initialize(customLoadingAnimations)) {
return; return;
}
loader_cache_tag(); const timestampBegin = Date.now();
const load_begin = Date.now();
let begin: number = 0; let begin: number = 0;
let end: number = Date.now(); let end: number = Date.now();
while(currentStage <= Stage.LOADED || typeof(currentStage) === "undefined") { while(currentStage <= Stage.LOADED || typeof currentStage === "undefined") {
let pendingTasks: InternalTask[] = []; let pendingTasks: InternalTask[] = [];
while((tasks[currentStage] || []).length > 0) { while((tasks[currentStage] || []).length > 0) {
if(pendingTasks.length == 0 || pendingTasks[0].priority == tasks[currentStage][0].priority) { if(pendingTasks.length == 0 || pendingTasks[0].priority == tasks[currentStage][0].priority) {
pendingTasks.push(tasks[currentStage].pop()); pendingTasks.push(tasks[currentStage].pop());
} else break; } else {
break;
}
} }
const errors: { const errors: {
@ -282,7 +260,7 @@ export async function execute(customLoadingAnimations: boolean) {
} }
if(config.verbose) if(config.verbose)
console.debug("[loader] finished loader. (Total time: %dms)", Date.now() - load_begin); console.debug("[loader] finished loader. (Total time: %dms)", Date.now() - timestampBegin);
Animation.finalize(config.abortAnimationOnFinish); Animation.finalize(config.abortAnimationOnFinish);
} }
@ -351,79 +329,4 @@ export function critical_error_handler(handler?: ErrorHandler, override?: boolea
} }
/* loaders */ /* loaders */
export type DependSource = { export type SourcePath = string;
url: string;
depends: string[];
}
export type SourcePath = string | DependSource | string[];
export const scripts = script_loader;
export const style = style_loader;
/* Hello World message */
{
const clog = console.log;
const print_security = () => {
{
const css = [
"display: block",
"text-align: center",
"font-size: 42px",
"font-weight: bold",
"-webkit-text-stroke: 2px black",
"color: red"
].join(";");
clog("%c ", "font-size: 100px;");
clog("%cSecurity warning:", css);
}
{
const css = [
"display: block",
"text-align: center",
"font-size: 18px",
"font-weight: bold"
].join(";");
clog("%cPasting anything in here could give attackers access to your data.", css);
clog("%cUnless you understand exactly what you are doing, close this window and stay safe.", css);
clog("%c ", "font-size: 100px;");
}
};
/* print the hello world */
{
const css = [
"display: block",
"text-align: center",
"font-size: 72px",
"font-weight: bold",
"-webkit-text-stroke: 2px black",
"color: #18BC9C"
].join(";");
clog("%cHey, hold on!", css);
}
{
const css = [
"display: block",
"text-align: center",
"font-size: 26px",
"font-weight: bold"
].join(";");
const css_2 = [
"display: block",
"text-align: center",
"font-size: 26px",
"font-weight: bold",
"color: blue"
].join(";");
const display_detect = /./;
display_detect.toString = function() { print_security(); return ""; };
clog("%cLovely to see you using and debugging the TeaSpeak-Web client.", css);
clog("%cIf you have some good ideas or already done some incredible changes,", css);
clog("%cyou'll be may interested to share them here: %chttps://github.com/TeaSpeak/TeaWeb", css, css_2);
clog("%c ", display_detect);
}
}

View file

@ -1,8 +1,9 @@
import * as loader from "./loader/loader"; import * as loader from "./loader/loader";
import {config} from "./loader/loader"; import {config} from "./loader/loader";
import {script_name} from "./loader/utils"; import {loadStyles} from "./loader/StyleLoader";
import {loadScripts} from "./loader/ScriptLoader";
export interface TeaManifest { export interface ApplicationManifest {
version: number; version: number;
chunks: { chunks: {
@ -24,15 +25,17 @@ export interface TeaManifest {
}; };
} }
let manifest: TeaManifest; let manifest: ApplicationManifest;
export async function loadManifest() : Promise<TeaManifest> { export async function loadManifest() : Promise<ApplicationManifest> {
if(manifest) { if(manifest) {
return manifest; return manifest;
} }
try { try {
const response = await fetch(config.baseUrl + "/manifest.json?_date=" + Date.now()); const response = await fetch(config.baseUrl + "/manifest.json?_date=" + Date.now());
if(!response.ok) throw response.status + " " + response.statusText; if(!response.ok) {
throw response.status + " " + response.statusText;
}
manifest = await response.json(); manifest = await response.json();
} catch(error) { } catch(error) {
@ -40,8 +43,10 @@ export async function loadManifest() : Promise<TeaManifest> {
loader.critical_error("Failed to load manifest.json", error); loader.critical_error("Failed to load manifest.json", error);
throw "failed to load manifest.json"; throw "failed to load manifest.json";
} }
if(manifest.version !== 2)
if(manifest.version !== 2) {
throw "invalid manifest version"; throw "invalid manifest version";
}
return manifest; return manifest;
} }
@ -51,30 +56,31 @@ export async function loadManifestTarget(chunkName: string, taskId: number) {
loader.critical_error("Missing entry chunk in manifest.json", "Chunk " + chunkName + " is missing."); loader.critical_error("Missing entry chunk in manifest.json", "Chunk " + chunkName + " is missing.");
throw "missing entry chunk"; throw "missing entry chunk";
} }
loader.module_mapping().push({ loader.module_mapping().push({
application: chunkName, application: chunkName,
modules: manifest.chunks[chunkName].modules modules: manifest.chunks[chunkName].modules
}); });
loader.style.load_multiple(manifest.chunks[chunkName].css_files.map(e => e.file), { await loadStyles(manifest.chunks[chunkName].css_files.map(e => e.file), {
cache_tag: undefined, cache_tag: undefined,
max_parallel_requests: 4 maxParallelRequests: 4
}, (entry, state) => { }, (entry, state) => {
if(state !== "loading") { if (state !== "loading") {
return; return;
} }
loader.setCurrentTaskName(taskId, script_name(entry, false)); loader.setCurrentTaskName(taskId, entry);
}); });
await loader.scripts.load_multiple(manifest.chunks[chunkName].files.map(e => e.file), { await loadScripts(manifest.chunks[chunkName].files.map(e => e.file), {
cache_tag: undefined, cache_tag: undefined,
max_parallel_requests: 4 maxParallelRequests: 4
}, (script, state) => { }, (script, state) => {
if(state !== "loading") { if(state !== "loading") {
return; return;
} }
loader.setCurrentTaskName(taskId, script_name(script, false)); loader.setCurrentTaskName(taskId, script);
}); });
} }

View file

@ -3,21 +3,13 @@ import * as loader from "../loader/loader";
import {ApplicationLoader} from "../loader/loader"; import {ApplicationLoader} from "../loader/loader";
import {loadManifest, loadManifestTarget} from "../maifest"; import {loadManifest, loadManifestTarget} from "../maifest";
/* all javascript loaders */
const loader_javascript = {
load_scripts: async taskId => {
loader.setCurrentTaskName(taskId, "manifest");
await loadManifest();
await loadManifestTarget(__build.entry_chunk_name, taskId);
}
};
loader.register_task(loader.Stage.INITIALIZING, { loader.register_task(loader.Stage.INITIALIZING, {
name: "secure tester", name: "secure tester",
function: async () => { function: async () => {
/* we need https or localhost to use some things like the storage API */ /* we need https or localhost to use some things like the storage API */
if(typeof isSecureContext === "undefined") if(typeof isSecureContext === "undefined") {
(window as any)["isSecureContext"] = location.protocol !== 'https:' || location.hostname === 'localhost'; (window as any)["isSecureContext"] = location.protocol !== 'https:' || location.hostname === 'localhost';
}
if(!isSecureContext) { if(!isSecureContext) {
loader.critical_error("TeaWeb cant run on unsecured sides.", "App requires to be loaded via HTTPS!"); loader.critical_error("TeaWeb cant run on unsecured sides.", "App requires to be loaded via HTTPS!");
@ -28,8 +20,12 @@ loader.register_task(loader.Stage.INITIALIZING, {
}); });
loader.register_task(loader.Stage.JAVASCRIPT, { loader.register_task(loader.Stage.JAVASCRIPT, {
name: "scripts", name: "manifest",
function: loader_javascript.load_scripts, function: async taskId => {
loader.setCurrentTaskName(taskId, "manifest");
await loadManifest();
await loadManifestTarget(__build.entry_chunk_name, taskId);
},
priority: 10 priority: 10
}); });

View file

@ -2,7 +2,7 @@ import "./shared";
import * as loader from "../loader/loader"; import * as loader from "../loader/loader";
import {ApplicationLoader, Stage} from "../loader/loader"; import {ApplicationLoader, Stage} from "../loader/loader";
import {loadManifest, loadManifestTarget} from "../maifest"; import {loadManifest, loadManifestTarget} from "../maifest";
import {getUrlParameter} from "../loader/utils"; import {getUrlParameter} from "../loader/Utils";
export default class implements ApplicationLoader { export default class implements ApplicationLoader {
execute() { execute() {

View file

@ -1,6 +1,6 @@
import * as loader from "../loader/loader"; import * as loader from "../loader/loader";
import {Stage} from "../loader/loader"; import {Stage} from "../loader/loader";
import {BrowserInfo, detect as detectBrowser,} from "detect-browser"; import {detect as detectBrowser} from "detect-browser";
loader.register_task(Stage.SETUP, { loader.register_task(Stage.SETUP, {
name: "app init", name: "app init",