diff --git a/src/Environment.ts b/src/Environment.ts index b7973c31d..8fc76ec4e 100644 --- a/src/Environment.ts +++ b/src/Environment.ts @@ -54,6 +54,7 @@ import { Logger } from '@src/Logger'; import { LeftHandTapEffectInfo } from './rendering/effects/LeftHandTapEffectInfo'; import { CapellaImporter } from './importer/CapellaImporter'; import { ResizeObserverPolyfill } from './platform/javascript/ResizeObserverPolyfill'; +import { WebPlatform } from './platform/javascript/WebPlatform'; export class LayoutEngineFactory { public readonly vertical: boolean; @@ -86,12 +87,12 @@ export class RenderEngineFactory { */ export class Environment { /** - * The font size of the music font in pixel. + * The font size of the music font in pixel. */ public static readonly MusicFontSize = 34; /** - * The scaling factor to use when rending raster graphics for sharper rendering on high-dpi displays. + * The scaling factor to use when rending raster graphics for sharper rendering on high-dpi displays. */ public static HighDpiFactor = 1; @@ -158,12 +159,15 @@ export class Environment { try { Environment._globalThis = globalThis; } catch (e) { - // global this not available + // globalThis not available } if (typeof Environment._globalThis === 'undefined') { Environment._globalThis = self; } + if (typeof Environment._globalThis === 'undefined') { + Environment._globalThis = global; + } if (typeof Environment._globalThis === 'undefined') { Environment._globalThis = window; } @@ -175,6 +179,11 @@ export class Environment { return this._globalThis; } + /** + * @target web + */ + public static webPlatform: WebPlatform = Environment.detectWebPlatform(); + /** * @target web */ @@ -183,9 +192,7 @@ export class Environment { /** * @target web */ - public static bravuraFontChecker: FontLoadingChecker = new FontLoadingChecker( - 'alphaTab' - ); + public static bravuraFontChecker: FontLoadingChecker = new FontLoadingChecker('alphaTab'); /** * @target web @@ -200,8 +207,8 @@ export class Environment { public static throttle(action: () => void, delay: number): () => void { let timeoutId: number = 0; return () => { - window.clearTimeout(timeoutId); - timeoutId = window.setTimeout(action, delay); + Environment.globalThis.clearTimeout(timeoutId); + timeoutId = Environment.globalThis.setTimeout(action, delay); }; } @@ -209,7 +216,7 @@ export class Environment { * @target web */ private static detectScriptFile(): string | null { - if (Environment.isRunningInWorker) { + if (Environment.isRunningInWorker || Environment.webPlatform !== WebPlatform.Browser) { return null; } return (document.currentScript as HTMLScriptElement).src; @@ -448,19 +455,39 @@ export class Environment { * @target web */ public static platformInit(): void { - Environment.registerJQueryPlugin(); - if (!Environment.isRunningInWorker) { + if (Environment.isRunningInWorker) { + AlphaTabWebWorker.init(); + AlphaSynthWebWorker.init(); + } else if (Environment.webPlatform === WebPlatform.Browser) { + Environment.registerJQueryPlugin(); Environment.HighDpiFactor = window.devicePixelRatio; // ResizeObserver API does not yet exist so long on Safari (only start 2020 with iOS Safari 13.7 and Desktop 13.1) - // so we better add a polyfill for it - if(!('ResizeObserver' in globalThis)) { + // so we better add a polyfill for it + if (!('ResizeObserver' in globalThis)) { (globalThis as any).ResizeObserver = ResizeObserverPolyfill; } - } else { - AlphaTabWebWorker.init(); - AlphaSynthWebWorker.init(); } } + + /** + * @target web + */ + private static detectWebPlatform(): WebPlatform { + try { + // Credit of the node.js detection goes to + // https://github.com/iliakan/detect-node + // MIT License + // Copyright (c) 2017 Ilya Kantor + // tslint:disable-next-line: strict-type-predicates + if (Object.prototype.toString.call(typeof process !== 'undefined' ? process : 0) === '[object process]') { + return WebPlatform.NodeJs; + } + } catch (e) { + // no node.js + } + + return WebPlatform.Browser; + } } -Environment.platformInit(); \ No newline at end of file +Environment.platformInit(); diff --git a/src/platform/javascript/AlphaSynthWebAudioOutput.ts b/src/platform/javascript/AlphaSynthWebAudioOutput.ts index c79a079a1..e8435b70d 100644 --- a/src/platform/javascript/AlphaSynthWebAudioOutput.ts +++ b/src/platform/javascript/AlphaSynthWebAudioOutput.ts @@ -37,7 +37,7 @@ export class AlphaSynthWebAudioOutput implements ISynthOutput { if (ctx.state === 'suspended') { let resume = () => { ctx.resume(); - window.setTimeout(() => { + Environment.globalThis.setTimeout(() => { if (ctx.state === 'running') { document.body.removeEventListener('touchend', resume, false); document.body.removeEventListener('click', resume, false); diff --git a/src/platform/javascript/AlphaTabWebWorker.ts b/src/platform/javascript/AlphaTabWebWorker.ts index 2942744bf..4fa6dfd46 100644 --- a/src/platform/javascript/AlphaTabWebWorker.ts +++ b/src/platform/javascript/AlphaTabWebWorker.ts @@ -21,7 +21,7 @@ export class AlphaTabWebWorker { } public static init(): void { - Environment.globalThis.alphaTabWebWorker = new AlphaTabWebWorker(Environment.globalThis as IWorkerScope); + (Environment.globalThis as any).alphaTabWebWorker = new AlphaTabWebWorker(Environment.globalThis as IWorkerScope); } private handleMessage(e: MessageEvent): void { diff --git a/src/platform/javascript/BrowserUiFacade.ts b/src/platform/javascript/BrowserUiFacade.ts index f69ef7e3c..dc17a4175 100644 --- a/src/platform/javascript/BrowserUiFacade.ts +++ b/src/platform/javascript/BrowserUiFacade.ts @@ -25,6 +25,9 @@ import { BrowserMouseEventArgs } from '@src/platform/javascript/BrowserMouseEven import { Cursors } from '@src/platform/Cursors'; import { JsonConverter } from '@src/model/JsonConverter'; import { SettingsSerializer } from '@src/generated/SettingsSerializer'; +import { WebPlatform } from './WebPlatform'; +import { AlphaTabError } from '@src/AlphaTabError'; +import { AlphaTabErrorType } from '@src/alphatab'; /** * @target web @@ -81,6 +84,11 @@ export class BrowserUiFacade implements IUiFacade { } public constructor(rootElement: HTMLElement) { + if(Environment.webPlatform !== WebPlatform.Browser) { + throw new AlphaTabError(AlphaTabErrorType.General, + 'Usage of AlphaTabApi is only possible in browser environments. For usage in node use the Low Level APIs' + ); + } rootElement.classList.add('alphaTab'); this.rootContainer = new HtmlElementContainer(rootElement); this.areWorkersSupported = 'Worker' in window; diff --git a/src/platform/javascript/WebPlatform.ts b/src/platform/javascript/WebPlatform.ts new file mode 100644 index 000000000..53155f6dd --- /dev/null +++ b/src/platform/javascript/WebPlatform.ts @@ -0,0 +1,8 @@ +/** + * Lists all web specific platforms alphaTab might run in + * like browser, nodejs. + */ +export enum WebPlatform { + Browser, + NodeJs +}