From 432b639d62481fc68c4b1e57571a897ce6323549 Mon Sep 17 00:00:00 2001 From: xiaokuangkuang Date: Wed, 9 Oct 2024 15:06:46 +0800 Subject: [PATCH] feat: supported csp --- src/module.ts | 5 +++++ src/monaco-provider.service.ts | 27 +++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/module.ts b/src/module.ts index a78916b..dace670 100644 --- a/src/module.ts +++ b/src/module.ts @@ -4,6 +4,7 @@ import { NgModule, Optional, SkipSelf, + CSP_NONCE, } from '@angular/core'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; @@ -53,6 +54,10 @@ export class MonacoEditorModule { provide: MonacoEditorConfig, useValue: config, }, + { + provide: CSP_NONCE, + useValue: 'g6oHcXjoYW7NfBS4', + }, ], }; } diff --git a/src/monaco-provider.service.ts b/src/monaco-provider.service.ts index 4f31613..9dbfdd5 100644 --- a/src/monaco-provider.service.ts +++ b/src/monaco-provider.service.ts @@ -18,6 +18,8 @@ export interface Require { }): void; } +const NONCE = 'g6oHcXjoYW7NfBS4'; + /** * Provider for monaco editor. */ @@ -66,6 +68,8 @@ export class MonacoProviderService { } async initMonaco() { + this.initCSPNonce(); + return this._loadingPromise || (this._loadingPromise = this.loadMonaco()); } @@ -148,6 +152,29 @@ export class MonacoProviderService { .find(({ aliases, id }) => aliases?.includes(alias) || id === alias); } + private initCSPNonce() { + const observer = new MutationObserver(mutationsList => { + for (const mutation of mutationsList) { + if (mutation.type === 'childList') { + mutation.addedNodes.forEach(node => { + if ( + (node as HTMLElement).tagName === 'STYLE' && + !(node as HTMLElement).getAttribute('nonce') + ) { + (node as HTMLElement).setAttribute('nonce', NONCE); + } + }); + } + } + }); + + // 监听 标签的变化 + observer.observe(document.head, { childList: true, subtree: true }); + + // 如果 monaco-editor 插入样式到 ,可以监听 标签 + observer.observe(document.body, { childList: true, subtree: true }); + } + /** * Currently monaco-editor is loaded via its own loader and it is RequireJs (amd) spec: */