|
|
|
@ -1,11 +1,16 @@
|
|
|
|
|
import { ContentSecurityStrategy, CONTENT_SECURITY_STRATEGY } from './content-security.strategy';
|
|
|
|
|
import { DomStrategy, DOM_STRATEGY } from './dom.strategy';
|
|
|
|
|
|
|
|
|
|
export type ElementOptions<T extends HTMLScriptElement | HTMLStyleElement = any> = Partial<{
|
|
|
|
|
[key in keyof T]: T[key];
|
|
|
|
|
}>;
|
|
|
|
|
|
|
|
|
|
export abstract class ContentStrategy<T extends HTMLScriptElement | HTMLStyleElement = any> {
|
|
|
|
|
constructor(
|
|
|
|
|
public content: string,
|
|
|
|
|
protected domStrategy: DomStrategy = DOM_STRATEGY.AppendToHead(),
|
|
|
|
|
protected contentSecurityStrategy: ContentSecurityStrategy = CONTENT_SECURITY_STRATEGY.None(),
|
|
|
|
|
protected options: ElementOptions<T> = {},
|
|
|
|
|
) {}
|
|
|
|
|
|
|
|
|
|
abstract createElement(): T;
|
|
|
|
@ -13,6 +18,10 @@ export abstract class ContentStrategy<T extends HTMLScriptElement | HTMLStyleEle
|
|
|
|
|
insertElement(): T {
|
|
|
|
|
const element = this.createElement();
|
|
|
|
|
|
|
|
|
|
if (this.options && Object.keys(this.options).length > 0) {
|
|
|
|
|
Object.keys(this.options).forEach(key => (element[key] = this.options[key]));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.contentSecurityStrategy.applyCSP(element);
|
|
|
|
|
this.domStrategy.insertElement(element);
|
|
|
|
|
|
|
|
|
@ -39,16 +48,16 @@ export class ScriptContentStrategy extends ContentStrategy<HTMLScriptElement> {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const CONTENT_STRATEGY = {
|
|
|
|
|
AppendScriptToBody(content: string) {
|
|
|
|
|
return new ScriptContentStrategy(content, DOM_STRATEGY.AppendToBody());
|
|
|
|
|
AppendScriptToBody(content: string, options?: ElementOptions<HTMLScriptElement>) {
|
|
|
|
|
return new ScriptContentStrategy(content, DOM_STRATEGY.AppendToBody(), undefined, options);
|
|
|
|
|
},
|
|
|
|
|
AppendScriptToHead(content: string) {
|
|
|
|
|
return new ScriptContentStrategy(content, DOM_STRATEGY.AppendToHead());
|
|
|
|
|
AppendScriptToHead(content: string, options?: ElementOptions<HTMLScriptElement>) {
|
|
|
|
|
return new ScriptContentStrategy(content, DOM_STRATEGY.AppendToHead(), undefined, options);
|
|
|
|
|
},
|
|
|
|
|
AppendStyleToHead(content: string) {
|
|
|
|
|
return new StyleContentStrategy(content, DOM_STRATEGY.AppendToHead());
|
|
|
|
|
AppendStyleToHead(content: string, options?: ElementOptions<HTMLStyleElement>) {
|
|
|
|
|
return new StyleContentStrategy(content, DOM_STRATEGY.AppendToHead(), undefined, options);
|
|
|
|
|
},
|
|
|
|
|
PrependStyleToHead(content: string) {
|
|
|
|
|
return new StyleContentStrategy(content, DOM_STRATEGY.PrependToHead());
|
|
|
|
|
PrependStyleToHead(content: string, options?: ElementOptions<HTMLStyleElement>) {
|
|
|
|
|
return new StyleContentStrategy(content, DOM_STRATEGY.PrependToHead(), undefined, options);
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|