Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | 11x 11x 11x 11x 31x 31x 31x | import { DOCUMENT } from '@angular/common';
import { Inject, Injectable, Renderer2, RendererFactory2 } from '@angular/core';
import { Observable, Observer } from 'rxjs';
import { Attribute } from 'ish-core/models/attribute/attribute.model';
interface ScriptType {
src: string;
loaded: boolean;
}
interface ScriptLoaderOption {
/**
* optionally set a type if it is not a classic Javascript file, e.g. 'module'
*/
type?: string;
/**
* integrity hash and crossOrigin to 'anonymous' (parameter 'crossorigin' ignored in that case)
*/
integrity?: string;
/**
* optional value for crossOrigin attribute in script tag
*/
crossorigin?: string;
/**
* optional script html element (data) attributes, e.g. <script src="..." data-foo="bar">
*/
attributes?: Attribute<string>[];
}
@Injectable({ providedIn: 'root' })
export class ScriptLoaderService {
private registeredScripts: ScriptType[] = [];
private renderer: Renderer2;
constructor(private rendererFactory: RendererFactory2, @Inject(DOCUMENT) private document: Document) {
// Get an instance of Renderer2
this.renderer = this.rendererFactory.createRenderer(undefined, undefined);
}
/**
* load a script, if it has not already been loaded
*
* @param url script url, e.g. https://pptest.payengine.de/bridge/1.0/payengine.min.js
* @param options a set of optional parameters to configure script handling optionally set a type if it is not a classic Javascript file, e.g. 'module'
* @returns Observable<ScriptType>
*/
load(url: string, options?: ScriptLoaderOption): Observable<ScriptType> {
return new Observable<ScriptType>((observer: Observer<ScriptType>) => {
let script = this.registeredScripts.find(s => s.src === url);
Iif (!script) {
script = { src: url, loaded: false };
this.registeredScripts.push(script);
}
// Complete if already loaded
if (script?.loaded) {
observer.next(script);
observer.complete();
} else {
// Load the script
const scriptElement = this.renderer.createElement('script');
scriptElement.src = url;
scriptElement.async = true;
Iif (options?.type) {
scriptElement.type = options.type;
}
Iif (options?.crossorigin) {
scriptElement.crossOrigin = options.crossorigin;
}
Iif (options?.integrity) {
scriptElement.integrity = options.integrity;
scriptElement.crossOrigin = 'anonymous'; // required to be 'anonymous' if integrity is given
}
Iif (options?.attributes?.length) {
for (const attr of options.attributes) {
this.renderer.setAttribute(scriptElement, attr.name, attr.value);
}
}
scriptElement.onload = () => {
script.loaded = true;
observer.next(script);
observer.complete();
};
scriptElement.onerror = () => {
observer.error(`Could not load script ${script.src}`);
};
// insert script as html body child
this.renderer.appendChild(this.document.body, scriptElement);
}
});
}
}
|