Make sure we handle loading of markdown resources from UNC workspace correctly

Fixes #48403
This commit is contained in:
Matt Bierner
2019-07-09 15:52:08 -07:00
parent 2f05851c49
commit 4c07744817
3 changed files with 49 additions and 20 deletions

View File

@@ -16,7 +16,7 @@ import { MarkdownPreviewConfigurationManager } from './previewConfig';
import { MarkdownContributionProvider, MarkdownContributions } from '../markdownExtensions';
import { isMarkdownFile } from '../util/file';
import { resolveLinkToMarkdownFile } from '../commands/openDocumentLink';
import { WebviewResourceProvider } from '../util/resources';
import { WebviewResourceProvider, normalizeResource } from '../util/resources';
const localize = nls.loadMessageBundle();
interface WebviewMessage {
@@ -393,14 +393,14 @@ export class MarkdownPreview extends Disposable {
return;
}
const resource = this._resource;
const markdownResource = this._resource;
clearTimeout(this.throttleTimer);
this.throttleTimer = undefined;
let document: vscode.TextDocument;
try {
document = await vscode.workspace.openTextDocument(resource);
document = await vscode.workspace.openTextDocument(markdownResource);
} catch {
await this.showFileNotFoundError();
return;
@@ -410,20 +410,22 @@ export class MarkdownPreview extends Disposable {
return;
}
const pendingVersion = new PreviewDocumentVersion(resource, document.version);
const pendingVersion = new PreviewDocumentVersion(markdownResource, document.version);
if (!this.forceUpdate && this.currentVersion && this.currentVersion.equals(pendingVersion)) {
if (this.line) {
this.updateForView(resource, this.line);
this.updateForView(markdownResource, this.line);
}
return;
}
this.forceUpdate = false;
this.currentVersion = pendingVersion;
if (this._resource === resource) {
if (this._resource === markdownResource) {
const self = this;
const resourceProvider: WebviewResourceProvider = {
toWebviewResource: (resource) => this.editor.webview.toWebviewResource(resource),
toWebviewResource: (resource) => {
return this.editor.webview.toWebviewResource(normalizeResource(markdownResource, resource));
},
get cspSource() { return self.editor.webview.cspSource; }
};
const content = await this._contentProvider.provideTextDocumentContent(document, resourceProvider, this._previewConfigurations, this.line, this.state);
@@ -446,21 +448,19 @@ export class MarkdownPreview extends Disposable {
}
private static getLocalResourceRoots(
resource: vscode.Uri,
base: vscode.Uri,
contributions: MarkdownContributions
): ReadonlyArray<vscode.Uri> {
const baseRoots = contributions.previewResourceRoots;
const baseRoots = Array.from(contributions.previewResourceRoots);
const folder = vscode.workspace.getWorkspaceFolder(resource);
const folder = vscode.workspace.getWorkspaceFolder(base);
if (folder) {
return baseRoots.concat(folder.uri);
baseRoots.push(folder.uri);
} else if (!base.scheme || base.scheme === 'file') {
baseRoots.push(vscode.Uri.file(path.dirname(base.fsPath)));
}
if (!resource.scheme || resource.scheme === 'file') {
return baseRoots.concat(vscode.Uri.file(path.dirname(resource.fsPath)));
}
return baseRoots;
return baseRoots.map(root => normalizeResource(base, root));
}
private onDidScrollPreview(line: number) {

View File

@@ -9,4 +9,25 @@ export interface WebviewResourceProvider {
toWebviewResource(resource: vscode.Uri): vscode.Uri;
readonly cspSource: string;
}
export function normalizeResource(
base: vscode.Uri,
resource: vscode.Uri
): vscode.Uri {
// If we have a windows path and are loading a workspace with an authority,
// make sure we use a unc path with an explicit localhost authority.
//
// Otherwise, the `<base>` rule will insert the authority into the resolved resource
// URI incorrectly.
if (base.authority && !resource.authority) {
const driveMatch = resource.path.match(/^\/(\w):\//);
if (driveMatch) {
return vscode.Uri.file(`\\\\localhost\\${driveMatch[1]}$\\${resource.fsPath.replace(/^\w:\\/, '')}`).with({
fragment: resource.fragment,
query: resource.query
});
}
}
return resource;
}