diff --git a/examples/Assets/script.js b/examples/Assets/script.js new file mode 100644 index 0000000000..adfa13d65d --- /dev/null +++ b/examples/Assets/script.js @@ -0,0 +1,3 @@ +var h1 = document.createElement('h1'); +h1.appendChild(document.createTextNode('Hello from JavaScript!')); +document.body.appendChild(h1); \ No newline at end of file diff --git a/examples/Assets/style.css b/examples/Assets/style.css new file mode 100644 index 0000000000..976559bafc --- /dev/null +++ b/examples/Assets/style.css @@ -0,0 +1,4 @@ +body { + color: white; + background-color: cornflowerblue; +} \ No newline at end of file diff --git a/examples/ContentViewTest.ps1 b/examples/ContentViewTest.ps1 new file mode 100644 index 0000000000..21055149d5 --- /dev/null +++ b/examples/ContentViewTest.ps1 @@ -0,0 +1,8 @@ +$params = @{ + HtmlBodyContent = "Testing JavaScript and CSS paths..." + JavaScriptPaths = ".\Assets\script.js" + StyleSheetPaths = ".\Assets\style.css" +} + +$view = New-VSCodeHtmlContentView -Title "Test View" -ShowInColumn Two +Set-VSCodeHtmlContentView -View $view @params \ No newline at end of file diff --git a/src/features/CustomViews.ts b/src/features/CustomViews.ts index 35f5b3a0a7..97e9cd447f 100644 --- a/src/features/CustomViews.ts +++ b/src/features/CustomViews.ts @@ -50,7 +50,7 @@ export class CustomViewsFeature implements IFeature { args => { this.contentProvider.setHtmlContentView( args.id, - args.htmlBodyContent); + args.htmlContent); }); languageClient.onRequest( @@ -119,7 +119,7 @@ class PowerShellContentProvider implements vscode.TextDocumentContentProvider { ) } - public setHtmlContentView(id: string, content: string) { + public setHtmlContentView(id: string, content: HtmlContent) { let uriString = this.getUri(id); let view: CustomView = this.viewIndex[uriString]; @@ -160,7 +160,11 @@ abstract class CustomView { class HtmlContentView extends CustomView { - private htmlContent: string = ""; + private htmlContent: HtmlContent = { + bodyContent: "", + javaScriptPaths: [], + styleSheetPaths: [] + }; constructor( id: string, @@ -169,17 +173,49 @@ class HtmlContentView extends CustomView { super(id, title, CustomViewType.HtmlContent); } - setContent(htmlContent: string) { + setContent(htmlContent: HtmlContent) { this.htmlContent = htmlContent; } appendContent(content: string) { - this.htmlContent += content; + this.htmlContent.bodyContent += content; } getContent(): string { - // Return an HTML page which disables JavaScript in content by default - return `
${this.htmlContent}`; + var styleSrc = "none"; + var styleTags = ""; + + function getNonce(): number { + return Math.floor(Math.random() * 100000) + 100000; + } + + if (this.htmlContent.styleSheetPaths && + this.htmlContent.styleSheetPaths.length > 0) { + styleSrc = ""; + this.htmlContent.styleSheetPaths.forEach( + p => { + var nonce = getNonce(); + styleSrc += `'nonce-${nonce}' `; + styleTags += `\n`; + }); + } + + var scriptSrc = "none"; + var scriptTags = ""; + + if (this.htmlContent.javaScriptPaths && + this.htmlContent.javaScriptPaths.length > 0) { + scriptSrc = ""; + this.htmlContent.javaScriptPaths.forEach( + p => { + var nonce = getNonce(); + scriptSrc += `'nonce-${nonce}' `; + scriptTags += `\n`; + }); + } + + // Return an HTML page with the specified content + return `${styleTags}\n${this.htmlContent.bodyContent}\n${scriptTags}`; } } @@ -226,9 +262,15 @@ namespace SetHtmlContentViewRequest { 'powerShell/setHtmlViewContent'); } +interface HtmlContent { + bodyContent: string; + javaScriptPaths: string[]; + styleSheetPaths: string[]; +} + interface SetHtmlContentViewRequestArguments { id: string; - htmlBodyContent: string; + htmlContent: HtmlContent; } namespace AppendHtmlOutputViewRequest {