diff --git a/src/vs/base/browser/htmlContentRenderer.ts b/src/vs/base/browser/htmlContentRenderer.ts index 5e0c45a5628..ff348241c42 100644 --- a/src/vs/base/browser/htmlContentRenderer.ts +++ b/src/vs/base/browser/htmlContentRenderer.ts @@ -12,6 +12,8 @@ import { IMouseEvent } from 'vs/base/browser/mouseEvent'; import { IDisposable } from 'vs/base/common/lifecycle'; import { onUnexpectedError } from 'vs/base/common/errors'; import { URI } from 'vs/base/common/uri'; +import { parse } from 'vs/base/common/marshalling'; +import { cloneAndChange } from 'vs/base/common/objects'; export interface IContentActionHandler { callback: (content: string, event?: IMouseEvent) => void; @@ -53,10 +55,37 @@ export function renderFormattedText(formattedText: string, options: RenderOption export function renderMarkdown(markdown: IMarkdownString, options: RenderOptions = {}): HTMLElement { const element = createElement(options); + const _uriMassage = function (part: string): string { + let data: any; + try { + data = parse(decodeURIComponent(part)); + } catch (e) { + // ignore + } + if (!data) { + return part; + } + data = cloneAndChange(data, value => { + if (markdown.uris[value]) { + return URI.revive(markdown.uris[value]); + } else { + return undefined; + } + }); + return encodeURIComponent(JSON.stringify(data)); + }; + const _href = function (href: string): string { const data = markdown.uris && markdown.uris[href]; + if (!data) { + return href; + } + let uri = URI.revive(data); + if (uri.query) { + uri = uri.with({ query: _uriMassage(uri.query) }); + } if (data) { - href = URI.revive(data).toString(true); + href = uri.toString(true); } return href; }; diff --git a/src/vs/workbench/api/node/extHostTypeConverters.ts b/src/vs/workbench/api/node/extHostTypeConverters.ts index e50f4755d58..f4426f74c52 100644 --- a/src/vs/workbench/api/node/extHostTypeConverters.ts +++ b/src/vs/workbench/api/node/extHostTypeConverters.ts @@ -11,7 +11,7 @@ import { EditorViewColumn } from 'vs/workbench/api/shared/editor'; import { IDecorationOptions, IThemeDecorationRenderOptions, IDecorationRenderOptions, IContentDecorationRenderOptions } from 'vs/editor/common/editorCommon'; import { EndOfLineSequence, TrackedRangeStickiness } from 'vs/editor/common/model'; import * as vscode from 'vscode'; -import { URI } from 'vs/base/common/uri'; +import { URI, UriComponents } from 'vs/base/common/uri'; import { ProgressLocation as MainProgressLocation } from 'vs/platform/progress/common/progress'; import { SaveReason } from 'vs/workbench/services/textfile/common/textfiles'; import { IPosition } from 'vs/editor/common/core/position'; @@ -25,6 +25,8 @@ import { ACTIVE_GROUP, SIDE_GROUP } from 'vs/workbench/services/editor/common/ed import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/node/extHostDocumentsAndEditors'; import { isString, isNumber } from 'vs/base/common/types'; import * as marked from 'vs/base/common/marked/marked'; +import { parse } from 'vs/base/common/marshalling'; +import { cloneAndChange } from 'vs/base/common/objects'; export interface PositionLike { line: number; @@ -227,7 +229,9 @@ export namespace MarkdownString { let renderer = new marked.Renderer(); renderer.image = renderer.link = (href: string): string => { try { - res.uris[href] = URI.parse(href, true); + let uri = URI.parse(href, true); + uri = uri.with({ query: _uriMassage(uri.query, res.uris) }); + res.uris[href] = uri; } catch (e) { // ignore } @@ -238,6 +242,31 @@ export namespace MarkdownString { return res; } + function _uriMassage(part: string, bucket: { [n: string]: UriComponents }): string { + if (!part) { + return part; + } + let data: any; + try { + data = parse(decodeURIComponent(part)); + } catch (e) { + // ignore + } + if (!data) { + return part; + } + data = cloneAndChange(data, value => { + if (value instanceof URI) { + let key = `__uri_${Math.random().toString(16).slice(2, 8)}`; + bucket[key] = value; + return key; + } else { + return undefined; + } + }); + return encodeURIComponent(JSON.stringify(data)); + } + export function to(value: htmlContent.IMarkdownString): vscode.MarkdownString { const ret = new htmlContent.MarkdownString(value.value); ret.isTrusted = value.isTrusted;