diff --git a/resources/snippetview/snippetview.html b/resources/snippetview/snippetview.html
index a3416499b..4e2531f28 100644
--- a/resources/snippetview/snippetview.html
+++ b/resources/snippetview/snippetview.html
@@ -3,17 +3,17 @@
diff --git a/src/extras/math-preview-panel.ts b/src/extras/math-preview-panel.ts
index 6e9e6dde0..5180fd571 100644
--- a/src/extras/math-preview-panel.ts
+++ b/src/extras/math-preview-panel.ts
@@ -31,7 +31,7 @@ class MathPreviewPanelSerializer implements vscode.WebviewPanelSerializer {
enableScripts: true,
localResourceRoots: [resourcesFolder(lw.extensionRoot)]
}
- panel.webview.html = getHtml(panel.webview)
+ panel.webview.html = getHtml()
logger.log('Math preview panel: restored')
return Promise.resolve()
}
@@ -66,7 +66,7 @@ function open() {
}
)
initializePanel(panel)
- panel.webview.html = getHtml(panel.webview)
+ panel.webview.html = getHtml()
const configuration = vscode.workspace.getConfiguration('latex-workshop')
const editorGroup = configuration.get('mathpreviewpanel.editorGroup') as string
if (activeDocument) {
@@ -130,13 +130,21 @@ function clearCache() {
state.prevMacros = undefined
}
-function getHtml(webview: vscode.Webview) {
- const jsPath = vscode.Uri.file(path.join(lw.extensionRoot, './resources/mathpreviewpanel/mathpreview.js'))
- const jsPathSrc = webview.asWebviewUri(jsPath)
+let serverHandlerInserted = false
+function getHtml() {
+ if (serverHandlerInserted === false) {
+ lw.server.setHandler((url: string) => {
+ if (url.startsWith('/mathpreviewpanel/')) {
+ return path.resolve(lw.extensionRoot, 'resources')
+ }
+ return undefined
+ })
+ serverHandlerInserted = true
+ }
return `
-
+
-
+
diff --git a/src/extras/snippet-view.ts b/src/extras/snippet-view.ts
index d258a1473..c4128abf0 100644
--- a/src/extras/snippet-view.ts
+++ b/src/extras/snippet-view.ts
@@ -2,7 +2,6 @@ import * as vscode from 'vscode'
import { readFileSync } from 'fs'
import * as path from 'path'
import { lw } from '../lw'
-import { replaceWebviewPlaceholders } from '../utils/webview'
export {
state,
@@ -81,7 +80,19 @@ function receive(message: SnippetViewResult) {
}
class SnippetViewProvider implements vscode.WebviewViewProvider {
+ private serverHandlerInserted = false
+
public resolveWebviewView(webviewView: vscode.WebviewView) {
+ if (this.serverHandlerInserted === false) {
+ lw.server.setHandler((url: string) => {
+ if (url.startsWith('/snippetview/')) {
+ return path.resolve(lw.extensionRoot, 'resources')
+ }
+ return undefined
+ })
+ this.serverHandlerInserted = true
+ }
+
state.view = webviewView
webviewView.webview.options = {
@@ -93,9 +104,8 @@ class SnippetViewProvider implements vscode.WebviewViewProvider {
})
const webviewSourcePath = path.join(lw.extensionRoot, 'resources', 'snippetview', 'snippetview.html')
- let webviewHtml = readFileSync(webviewSourcePath, { encoding: 'utf8' })
- webviewHtml = replaceWebviewPlaceholders(webviewHtml, state.view.webview)
- webviewView.webview.html = webviewHtml
+ webviewView.webview.html = readFileSync(webviewSourcePath, { encoding: 'utf8' })
+ .replaceAll('%PORT%', lw.server.getPort().toString())
webviewView.webview.onDidReceiveMessage((e: SnippetViewResult) => {
state.callbacks.forEach((cb) => void cb(e))
diff --git a/src/preview/server.ts b/src/preview/server.ts
index 62c4563fc..d28f203bd 100644
--- a/src/preview/server.ts
+++ b/src/preview/server.ts
@@ -11,6 +11,7 @@ const logger = lw.log('Server')
export {
getPort,
getUrl,
+ setHandler,
initialize,
// initialized
}
@@ -52,9 +53,11 @@ const state: {
httpServer: http.Server,
wsServer?: WsServer,
address?: AddressInfo,
- validOriginUri?: vscode.Uri
+ validOriginUri?: vscode.Uri,
+ handlers: ((url: string) => string | undefined)[]
} = {
httpServer: initialize(),
+ handlers: []
// initialized
}
@@ -76,6 +79,10 @@ async function getUrl(pdfUri: vscode.Uri): Promise<{url: string, uri: vscode.Uri
return { url, uri: vscode.Uri.parse(url, true) }
}
+function setHandler(newHandler: (url: string) => string | undefined) {
+ state.handlers.push(newHandler)
+}
+
function getValidOrigin(): string {
if (state.validOriginUri) {
return `${state.validOriginUri.scheme}://${state.validOriginUri.authority}`
@@ -144,7 +151,7 @@ function checkHttpOrigin(req: http.IncomingMessage, response: http.ServerRespons
return true
}
const reqOrigin = req.headers['origin']
- if (reqOrigin !== undefined && reqOrigin !== validOrigin) {
+ if (reqOrigin !== undefined && !reqOrigin.startsWith('vscode-webview:') && reqOrigin !== validOrigin) {
logger.log(`Origin in http request is invalid: ${JSON.stringify(req.headers)}`)
logger.log(`Valid origin: ${validOrigin}`)
response.writeHead(403)
@@ -155,7 +162,7 @@ function checkHttpOrigin(req: http.IncomingMessage, response: http.ServerRespons
}
}
-function sendOkResponse(response: http.ServerResponse, content: Buffer, contentType: string) {
+function sendOkResponse(response: http.ServerResponse, content: Buffer, contentType: string, cors: boolean = true) {
//
// Headers to enable site isolation.
// - https://fetch.spec.whatwg.org/#cross-origin-resource-policy-header
@@ -170,7 +177,7 @@ function sendOkResponse(response: http.ServerResponse, content: Buffer, contentT
response.writeHead(200, {
'Content-Type': contentType,
'Content-Length': content.length,
- ...sameOriginPolicyHeaders
+ ...(cors ? sameOriginPolicyHeaders : {'Access-Control-Allow-Origin': '*'})
})
response.end(content)
}
@@ -209,13 +216,20 @@ async function handler(request: http.IncomingMessage, response: http.ServerRespo
}
let root: string
if (request.url.startsWith('/build/') || request.url.startsWith('/cmaps/') || request.url.startsWith('/standard_fonts/')) {
- root = path.resolve(`${lw.extensionRoot}/node_modules/pdfjs-dist`)
+ root = path.resolve(lw.extensionRoot, 'node_modules', 'pdfjs-dist')
} else if (request.url.startsWith('/out/viewer/') || request.url.startsWith('/viewer/')) {
// For requests to /out/viewer/*.js and requests to /viewer/*.ts.
// The latter is for debugging with sourcemap.
root = path.resolve(lw.extensionRoot)
} else {
- root = path.resolve(`${lw.extensionRoot}/viewer`)
+ root = path.resolve(lw.extensionRoot, 'viewer')
+ }
+ for (const overrideHandler of state.handlers) {
+ const overrideRoot = overrideHandler(request.url)
+ if (overrideRoot !== undefined) {
+ root = overrideRoot
+ break
+ }
}
//
// Prevent directory traversal attack.
@@ -276,7 +290,7 @@ async function handler(request: http.IncomingMessage, response: http.ServerRespo
}
response.end()
} else {
- sendOkResponse(response, content, contentType)
+ sendOkResponse(response, content, contentType, false)
}
})
}
diff --git a/src/utils/webview.ts b/src/utils/webview.ts
index 3ed82f3a9..4b2a0377e 100644
--- a/src/utils/webview.ts
+++ b/src/utils/webview.ts
@@ -1,25 +1,4 @@
import * as vscode from 'vscode'
-import { lw } from '../lw'
-
-const logger = lw.log('Util', 'Webview')
-
-let pathLogged = false
-export function replaceWebviewPlaceholders(content: string, webview: vscode.Webview): string {
- const extensionRootUri = vscode.Uri.file(lw.extensionRoot)
- const resourcesFolderUri = webview.asWebviewUri(vscode.Uri.joinPath(extensionRootUri, 'resources'))
- const resourcesFolderLink = resourcesFolderUri.toString()
- const pdfjsDistUri = webview.asWebviewUri(vscode.Uri.joinPath(extensionRootUri, 'node_modules', 'pdfjs-dist'))
- const pdfjsDistLink = pdfjsDistUri.toString()
- if (!pathLogged) {
- pathLogged = true
- logger.log(`%VSCODE_RES% = ${resourcesFolderLink} .`)
- logger.log(`%VSCODE_PDFJS_DIST% = ${pdfjsDistLink} .`)
- logger.log(`%VSCODE_CSP% = ${webview.cspSource} .`)
- }
- return content.replace(/%VSCODE_RES%/g, resourcesFolderLink)
- .replace(/%VSCODE_PDFJS_DIST%/g, pdfjsDistLink)
- .replace(/%VSCODE_CSP%/g, webview.cspSource)
-}
function getMoveCommands(tabEditorGroup: string) {
if (tabEditorGroup === 'left') {