Merge from vscode 8e0f348413f4f616c23a88ae30030efa85811973 (#6381)

* Merge from vscode 8e0f348413f4f616c23a88ae30030efa85811973

* disable strict null check
This commit is contained in:
Anthony Dresser
2019-07-15 22:35:46 -07:00
committed by GitHub
parent f720ec642f
commit 0b7e7ddbf9
2406 changed files with 59140 additions and 35464 deletions

View File

@@ -1,32 +0,0 @@
{
"registrations": [
{
"component": {
"type": "git",
"git": {
"name": "textmate/markdown.tmbundle",
"repositoryUrl": "https://github.com/textmate/markdown.tmbundle",
"commitHash": "11cf764606cb2cde54badb5d0e5a0758a8871c4b"
}
},
"licenseDetail": [
"Copyright (c) markdown.tmbundle authors",
"",
"If not otherwise specified (see below), files in this repository fall under the following license:",
"",
"Permission to copy, use, modify, sell and distribute this",
"software is granted. This software is provided \"as is\" without",
"express or implied warranty, and with no claim as to its",
"suitability for any purpose.",
"",
"An exception is made for files in readable text which contain their own license information,",
"or files where an accompanying file exists (in the same directory) with a \"-license\" suffix added",
"to the base-name name of the original file, and an extension of txt, html, or similar. For example",
"\"tidy\" is accompanied by \"tidy-license.txt\"."
],
"license": "TextMate Bundle License",
"version": "0.0.0"
}
],
"version": 1
}

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.icon-canvas-transparent,.icon-vs-out{fill:#f6f6f6;}.icon-canvas-transparent{opacity:0;}.icon-vs-bg{fill:#424242;}.icon-vs-action-blue{fill:#00539c;}</style></defs><title>SwitchToPreview_16x</title><g id="canvas"><path class="icon-canvas-transparent" d="M16,0V16H0V0Z"/></g><g id="outline" style="display: none;"><path class="icon-vs-out" d="M16,4V16H5V9.121l-1.939,1.94A1.5,1.5,0,0,1,.939,8.939L3.446,6.433A4.4,4.4,0,0,1,3,4.5,4.488,4.488,0,0,1,11.949,4Z" style="display: none;"/></g><g id="iconBg"><path class="icon-vs-bg" d="M12,10h1v3H12Zm0-3h-.762a4.5,4.5,0,0,1-.944,1H12Zm-2,6h1V11H10Zm2-8h-.051a4.485,4.485,0,0,1-.225,1H14v8H7V8.972a4.4,4.4,0,0,1-1-.237V15h9V5ZM9,12H8v1H9Zm1-3H8v1h2Z"/></g><g id="colorAction"><path class="icon-vs-action-blue" d="M7.5,1A3.5,3.5,0,0,0,4,4.5a3.463,3.463,0,0,0,.707,2.086L1.646,9.646a.5.5,0,0,0,.708.708l3.06-3.061A3.463,3.463,0,0,0,7.5,8a3.5,3.5,0,0,0,0-7Zm0,6A2.5,2.5,0,1,1,10,4.5,2.5,2.5,0,0,1,7.5,7Z"/></g></svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.icon-canvas-transparent,.icon-vs-out{fill:#f6f6f6;}.icon-canvas-transparent{opacity:0;}.icon-vs-bg{fill:#424242;}.icon-vs-action-blue{fill:#00539c;}</style></defs><title>PreviewInRightPanel_16x</title><g id="canvas"><path class="icon-canvas-transparent" d="M16,0V16H0V0Z"/></g><g id="outline" style="display: none;"><path class="icon-vs-out" d="M16,1V15H10.121l-.56.561a1.5,1.5,0,0,1-2.122,0A1.469,1.469,0,0,1,7.1,15H0V1Z" style="display: none;"/></g><g id="iconBg"><path class="icon-vs-bg" d="M1,2V14H7.1a1.469,1.469,0,0,1,.341-.561L9,11.88V5h5V7.351a3.515,3.515,0,0,1,1,.707V2ZM7,13H2V5H7Z"/></g><g id="colorAction"><path class="icon-vs-action-blue" d="M12.5,8a2.5,2.5,0,0,0-2.084,3.877l-2.27,2.269a.5.5,0,0,0,.708.708l2.269-2.27A2.5,2.5,0,1,0,12.5,8Zm0,4A1.5,1.5,0,1,1,14,10.5,1.5,1.5,0,0,1,12.5,12Z"/></g></svg>

Before

Width:  |  Height:  |  Size: 890 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.icon-canvas-transparent,.icon-vs-out{fill:#252526;}.icon-canvas-transparent{opacity:0;}.icon-vs-bg{fill:#c5c5c5;}.icon-vs-action-blue{fill:#75beff;}</style></defs><title>PreviewInRightPanel_16x</title><g id="canvas"><path class="icon-canvas-transparent" d="M16,0V16H0V0Z"/></g><g id="outline" style="display: none;"><path class="icon-vs-out" d="M16,1V15H10.121l-.56.561a1.5,1.5,0,0,1-2.122,0A1.469,1.469,0,0,1,7.1,15H0V1Z" style="display: none;"/></g><g id="iconBg"><path class="icon-vs-bg" d="M1,2V14H7.1a1.469,1.469,0,0,1,.341-.561L9,11.88V5h5V7.351a3.515,3.515,0,0,1,1,.707V2ZM7,13H2V5H7Z"/></g><g id="colorAction"><path class="icon-vs-action-blue" d="M12.5,8a2.5,2.5,0,0,0-2.084,3.877l-2.27,2.269a.5.5,0,0,0,.708.708l2.269-2.27A2.5,2.5,0,1,0,12.5,8Zm0,4A1.5,1.5,0,1,1,14,10.5,1.5,1.5,0,0,1,12.5,12Z"/></g></svg>

Before

Width:  |  Height:  |  Size: 889 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.icon-canvas-transparent,.icon-vs-out{fill:#252526;}.icon-canvas-transparent{opacity:0;}.icon-vs-bg{fill:#c5c5c5;}.icon-vs-action-blue{fill:#75beff;}</style></defs><title>SwitchToPreview_16x</title><g id="canvas"><path class="icon-canvas-transparent" d="M16,0V16H0V0Z"/></g><g id="outline" style="display: none;"><path class="icon-vs-out" d="M16,4V16H5V9.121l-1.939,1.94A1.5,1.5,0,0,1,.939,8.939L3.446,6.433A4.4,4.4,0,0,1,3,4.5,4.488,4.488,0,0,1,11.949,4Z" style="display: none;"/></g><g id="iconBg"><path class="icon-vs-bg" d="M12,10h1v3H12Zm0-3h-.762a4.5,4.5,0,0,1-.944,1H12Zm-2,6h1V11H10Zm2-8h-.051a4.485,4.485,0,0,1-.225,1H14v8H7V8.972a4.4,4.4,0,0,1-1-.237V15h9V5ZM9,12H8v1H9Zm1-3H8v1h2Z"/></g><g id="colorAction"><path class="icon-vs-action-blue" d="M7.5,1A3.5,3.5,0,0,0,4,4.5a3.463,3.463,0,0,0,.707,2.086L1.646,9.646a.5.5,0,0,0,.708.708l3.06-3.061A3.463,3.463,0,0,0,7.5,8a3.5,3.5,0,0,0,0-7Zm0,6A2.5,2.5,0,1,1,10,4.5,2.5,2.5,0,0,1,7.5,7Z"/></g></svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -1,3 +0,0 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
<!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
]><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><polygon fill="#656565" points="10,2 7.414,2 8.414,3 9,3 9,3.586 9,4 9,4.414 9,6 12,6 12,13 4,13 4,8 3,8 3,14 13,14 13,5"/><polygon fill="#00539C" points="5,1 3,1 5,3 1,3 1,5 5,5 3,7 5,7 8,4"/></svg>

Before

Width:  |  Height:  |  Size: 417 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><polygon fill="#C5C5C5" points="10,2 7.414,2 8.414,3 9,3 9,3.586 9,4 9,4.414 9,6 12,6 12,13 4,13 4,8 3,8 3,14 13,14 13,5"/><polygon fill="#75BEFF" points="5,1 3,1 5,3 1,3 1,5 5,5 3,7 5,7 8,4"/></svg>

Before

Width:  |  Height:  |  Size: 262 B

File diff suppressed because one or more lines are too long

View File

@@ -4,10 +4,10 @@
*--------------------------------------------------------------------------------------------*/
html, body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "Ubuntu", "Droid Sans", sans-serif;
font-size: 14px;
font-family: var(--vscode-markdown-font-family, -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "Ubuntu", "Droid Sans", sans-serif);
font-size: var(--vscode-markdown-font-size, 14px);
padding: 0 26px;
line-height: 22px;
line-height: var(--vscode-markdown-line-height, 22px);
word-wrap: break-word;
}
@@ -135,7 +135,6 @@ h3 code,
h4 code,
h5 code,
h6 code {
font-size: inherit;
line-height: auto;
}
@@ -168,8 +167,8 @@ blockquote {
code {
font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", "Courier New", monospace, "Droid Sans Fallback";
font-size: 1rem;
line-height: 1.357rem;
font-size: 1em;
line-height: 1.357em;
}
body.wordWrap pre {

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M2 2L1 3V13L2 14H14L15 13V3L14 2H2ZM2 13V3H14V13H2ZM12 5H4V6H12V5ZM3 4V7H13V4H3ZM7 9H3V8H7V9ZM3 12H7V11H3V12ZM12 9H10V11H12V9ZM9 8V12H13V8H9Z" fill="#C5C5C5"/>
</svg>

After

Width:  |  Height:  |  Size: 312 B

View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M2 2L1 3V13L2 14H14L15 13V3L14 2H2ZM2 13V3H14V13H2ZM12 5H4V6H12V5ZM3 4V7H13V4H3ZM7 9H3V8H7V9ZM3 12H7V11H3V12ZM12 9H10V11H12V9ZM9 8V12H13V8H9Z" fill="#424242"/>
</svg>

After

Width:  |  Height:  |  Size: 312 B

View File

@@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.219 8.35484C11.6063 8.12309 12.049 8.00047 12.5003 8C12.8904 7.99939 13.2753 8.0901 13.6241 8.26486C13.9729 8.43963 14.276 8.6936 14.5091 9.00646C14.7421 9.31933 14.8987 9.6824 14.9664 10.0666C15.034 10.4509 15.0108 10.8456 14.8985 11.2192C14.7863 11.5929 14.5882 11.9351 14.32 12.2184C14.0518 12.5018 13.7211 12.7185 13.3542 12.8511C12.9873 12.9837 12.5944 13.0287 12.207 12.9823C11.8197 12.9359 11.4485 12.7995 11.1233 12.584L8.7683 14.9399L8.06055 14.2322L10.4163 11.877C10.1677 11.5003 10.0258 11.0634 10.0054 10.6126C9.98511 10.1618 10.0872 9.71384 10.3009 9.31634C10.5145 8.91885 10.8318 8.58659 11.219 8.35484ZM11.667 11.7472C11.9136 11.912 12.2036 12 12.5003 12C12.8981 12 13.2797 11.842 13.561 11.5607C13.8423 11.2794 14.0003 10.8978 14.0003 10.5C14.0003 10.2033 13.9123 9.91332 13.7475 9.66665C13.5827 9.41997 13.3484 9.22772 13.0743 9.11418C12.8002 9.00065 12.4986 8.97095 12.2077 9.02883C11.9167 9.0867 11.6494 9.22956 11.4396 9.43934C11.2299 9.64912 11.087 9.9164 11.0291 10.2074C10.9712 10.4983 11.001 10.7999 11.1145 11.074C11.228 11.3481 11.4203 11.5824 11.667 11.7472Z" fill="#C5C5C5"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M13 1L14 2V7.33573C13.6829 7.18584 13.3457 7.08481 13 7.03533V2L8 2L8 12.8787L6.87837 14H2L1 13V2L2 1H13ZM9.70794 14H9.70785L10 13.7077V13.7079L9.70794 14ZM13 10.5174C13.0002 10.5116 13.0003 10.5058 13.0003 10.5C13.0003 10.4942 13.0002 10.4884 13 10.4826V10.5174ZM2 2L7 2L7 13H2L2 2Z" fill="#C5C5C5"/>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.219 8.35484C11.6063 8.12309 12.049 8.00047 12.5003 8C12.8904 7.99939 13.2753 8.0901 13.6241 8.26486C13.9729 8.43963 14.276 8.6936 14.5091 9.00646C14.7421 9.31933 14.8987 9.6824 14.9664 10.0666C15.034 10.4509 15.0108 10.8456 14.8985 11.2192C14.7863 11.5929 14.5882 11.9351 14.32 12.2184C14.0518 12.5018 13.7211 12.7185 13.3542 12.8511C12.9873 12.9837 12.5944 13.0287 12.207 12.9823C11.8197 12.9359 11.4485 12.7995 11.1233 12.584L8.7683 14.9399L8.06055 14.2322L10.4163 11.877C10.1677 11.5003 10.0258 11.0634 10.0054 10.6126C9.98511 10.1618 10.0872 9.71384 10.3009 9.31634C10.5145 8.91885 10.8318 8.58659 11.219 8.35484ZM11.667 11.7472C11.9136 11.912 12.2036 12 12.5003 12C12.8981 12 13.2797 11.842 13.561 11.5607C13.8423 11.2794 14.0003 10.8978 14.0003 10.5C14.0003 10.2033 13.9123 9.91332 13.7475 9.66665C13.5827 9.41997 13.3484 9.22772 13.0743 9.11418C12.8002 9.00065 12.4986 8.97095 12.2077 9.02883C11.9167 9.0867 11.6494 9.22956 11.4396 9.43934C11.2299 9.64912 11.087 9.9164 11.0291 10.2074C10.9712 10.4983 11.001 10.7999 11.1145 11.074C11.228 11.3481 11.4203 11.5824 11.667 11.7472Z" fill="#424242"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M13 1L14 2V7.33573C13.6829 7.18584 13.3457 7.08481 13 7.03533V2L8 2L8 12.8787L6.87837 14H2L1 13V2L2 1H13ZM9.70794 14H9.70785L10 13.7077V13.7079L9.70794 14ZM13 10.5174C13.0002 10.5116 13.0003 10.5058 13.0003 10.5C13.0003 10.4942 13.0002 10.4884 13 10.4826V10.5174ZM2 2L7 2L7 13H2L2 2Z" fill="#424242"/>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.06065 3.85356L5.91421 6L5.2071 5.29289L6.49999 4H3.5C3.10218 4 2.72064 4.15804 2.43934 4.43934C2.15804 4.72065 2 5.10218 2 5.5C2 5.89783 2.15804 6.27936 2.43934 6.56066C2.72064 6.84197 3.10218 7 3.5 7H4V8H3.5C2.83696 8 2.20107 7.73661 1.73223 7.26777C1.26339 6.79893 1 6.16305 1 5.5C1 4.83696 1.26339 4.20108 1.73223 3.73224C2.20107 3.2634 2.83696 3 3.5 3H6.49999L6.49999 3H6.49996L6 2.50004V2.50001L5.2071 1.70711L5.91421 1L8.06065 3.14645L8.06065 3.85356ZM5 6.50003L5.91421 7.41424L6 7.32845V14H14V7H10V3H9.06065V2.73227L8.32838 2H11.2L11.5 2.1L14.9 5.6L15 6V14.5L14.5 15H5.5L5 14.5V9.00003V6.50003ZM11 3V6H13.9032L11 3Z" fill="#C5C5C5"/>
</svg>

After

Width:  |  Height:  |  Size: 796 B

View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.06065 3.85356L5.91421 6L5.2071 5.29289L6.49999 4H3.5C3.10218 4 2.72064 4.15804 2.43934 4.43934C2.15804 4.72065 2 5.10218 2 5.5C2 5.89783 2.15804 6.27936 2.43934 6.56066C2.72064 6.84197 3.10218 7 3.5 7H4V8H3.5C2.83696 8 2.20107 7.73661 1.73223 7.26777C1.26339 6.79893 1 6.16305 1 5.5C1 4.83696 1.26339 4.20108 1.73223 3.73224C2.20107 3.2634 2.83696 3 3.5 3H6.49999L6.49999 3H6.49996L6 2.50004V2.50001L5.2071 1.70711L5.91421 1L8.06065 3.14645L8.06065 3.85356ZM5 6.50003L5.91421 7.41424L6 7.32845V14H14V7H10V3H9.06065V2.73227L8.32838 2H11.2L11.5 2.1L14.9 5.6L15 6V14.5L14.5 15H5.5L5 14.5V9.00003V6.50003ZM11 3V6H13.9032L11 3Z" fill="#424242"/>
</svg>

After

Width:  |  Height:  |  Size: 796 B

View File

@@ -4,7 +4,9 @@
"description": "%description%",
"version": "1.0.0",
"icon": "icon.png",
"publisher": "vscode",
"publisher": "vscode",
"enableProposedApi": true,
"license": "MIT",
"aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217",
"engines": {
"vscode": "^1.20.0"
@@ -32,8 +34,8 @@
"title": "%markdown.preview.title%",
"category": "Markdown",
"icon": {
"light": "./media/Preview.svg",
"dark": "./media/Preview_inverse.svg"
"light": "./media/preview-light.svg",
"dark": "./media/preview-dark.svg"
}
},
{
@@ -41,8 +43,8 @@
"title": "%markdown.previewSide.title%",
"category": "Markdown",
"icon": {
"light": "./media/PreviewOnRightPane_16x.svg",
"dark": "./media/PreviewOnRightPane_16x_dark.svg"
"light": "./media/preview-right-light.svg",
"dark": "./media/preview-right-dark.svg"
}
},
{
@@ -50,8 +52,8 @@
"title": "%markdown.showLockedPreviewToSide.title%",
"category": "Markdown",
"icon": {
"light": "./media/PreviewOnRightPane_16x.svg",
"dark": "./media/PreviewOnRightPane_16x_dark.svg"
"light": "./media/preview-right-light.svg",
"dark": "./media/preview-right-dark.svg"
}
},
{
@@ -59,8 +61,8 @@
"title": "%markdown.showSource.title%",
"category": "Markdown",
"icon": {
"light": "./media/ViewSource.svg",
"dark": "./media/ViewSource_inverse.svg"
"light": "./media/view-source-light.svg",
"dark": "./media/view-source-dark.svg"
}
},
{
@@ -313,7 +315,7 @@
"build-preview": "webpack --mode development"
},
"dependencies": {
"highlight.js": "9.13.1",
"highlight.js": "9.15.8",
"markdown-it": "^8.4.2",
"markdown-it-front-matter": "^0.1.2",
"vscode-extension-telemetry": "0.1.1",
@@ -323,7 +325,7 @@
"@types/highlight.js": "9.12.3",
"@types/lodash.throttle": "^4.1.3",
"@types/markdown-it": "0.0.2",
"@types/node": "^10.12.21",
"@types/node": "^10.14.8",
"lodash.throttle": "^4.1.1",
"mocha-junit-reporter": "^1.17.0",
"mocha-multi-reporters": "^1.1.7",

View File

@@ -19,7 +19,7 @@ const settings = getSettings();
const vscode = acquireVsCodeApi();
// Set VS Code state
let state = getData('data-state');
let state = getData<{ line: number }>('data-state');
vscode.setState(state);
const messaging = createPosterForVsCode(vscode);
@@ -131,8 +131,8 @@ document.addEventListener('click', event => {
if (node.getAttribute('href').startsWith('#')) {
break;
}
if (node.href.startsWith('file://') || node.href.startsWith('vscode-resource:')) {
const [path, fragment] = node.href.replace(/^(file:\/\/|vscode-resource:)/i, '').split('#');
if (node.href.startsWith('file://') || node.href.startsWith('vscode-resource:') || node.href.startsWith(settings.webviewResourceRoot)) {
const [path, fragment] = node.href.replace(/^(file:\/\/|vscode-resource:)/i, '').replace(new RegExp(`^${escapeRegExp(settings.webviewResourceRoot)}`)).split('#');
messaging.postMessage('clickLink', { path, fragment });
event.preventDefault();
event.stopPropagation();
@@ -157,4 +157,8 @@ if (settings.scrollEditorWithPreview) {
}
}
}, 50));
}
function escapeRegExp(text: string) {
return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
}

View File

@@ -4,18 +4,19 @@
*--------------------------------------------------------------------------------------------*/
export interface PreviewSettings {
source: string;
line: number;
lineCount: number;
scrollPreviewWithEditor?: boolean;
scrollEditorWithPreview: boolean;
disableSecurityWarnings: boolean;
doubleClickToSwitchToEditor: boolean;
readonly source: string;
readonly line: number;
readonly lineCount: number;
readonly scrollPreviewWithEditor?: boolean;
readonly scrollEditorWithPreview: boolean;
readonly disableSecurityWarnings: boolean;
readonly doubleClickToSwitchToEditor: boolean;
readonly webviewResourceRoot: string;
}
let cachedSettings: PreviewSettings | undefined = undefined;
export function getData(key: string): PreviewSettings {
export function getData<T = {}>(key: string): T {
const element = document.getElementById('vscode-markdown-preview-data');
if (element) {
const data = element.getAttribute(key);

View File

@@ -5,17 +5,20 @@
import * as path from 'path';
import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import { OpenDocumentLinkCommand } from '../commands/openDocumentLink';
import { getUriForLinkWithKnownExternalScheme } from '../util/links';
function normalizeLink(
const localize = nls.loadMessageBundle();
function parseLink(
document: vscode.TextDocument,
link: string,
base: string
): vscode.Uri {
): { uri: vscode.Uri, tooltip?: string } {
const externalSchemeUri = getUriForLinkWithKnownExternalScheme(link);
if (externalSchemeUri) {
return externalSchemeUri;
return { uri: externalSchemeUri };
}
// Assume it must be an relative or absolute file path
@@ -34,7 +37,10 @@ function normalizeLink(
resourcePath = base ? path.join(base, tempUri.path) : tempUri.path;
}
return OpenDocumentLinkCommand.createCommandUri(resourcePath, tempUri.fragment);
return {
uri: OpenDocumentLinkCommand.createCommandUri(resourcePath, tempUri.fragment),
tooltip: localize('documentLink.tooltip', 'Follow link')
};
}
function matchAll(
@@ -61,18 +67,21 @@ function extractDocumentLink(
const linkStart = document.positionAt(offset);
const linkEnd = document.positionAt(offset + link.length);
try {
return new vscode.DocumentLink(
const { uri, tooltip } = parseLink(document, link, base);
const documentLink = new vscode.DocumentLink(
new vscode.Range(linkStart, linkEnd),
normalizeLink(document, link, base));
uri);
documentLink.tooltip = tooltip;
return documentLink;
} catch (e) {
return undefined;
}
}
export default class LinkProvider implements vscode.DocumentLinkProvider {
private readonly linkPattern = /(\[((!\[[^\]]*?\]\(\s*)([^\s\(\)]+?)\s*\)\]|[^\]]*\])\(\s*)(([^\s\(\)]|\(\S*?\))+)\s*(".*?")?\)/g;
private readonly referenceLinkPattern = /(\[([^\]]+)\]\[\s*?)([^\s\]]*?)\]/g;
private readonly definitionPattern = /^([\t ]*\[([^\]]+)\]:\s*)(\S+)/gm;
private readonly linkPattern = /(\[((!\[[^\]]*?\]\(\s*)([^\s\(\)]+?)\s*\)\]|(?:\\\]|[^\]])*\])\(\s*)(([^\s\(\)]|\(\S*?\))+)\s*(".*?")?\)/g;
private readonly referenceLinkPattern = /(\[((?:\\\]|[^\]])+)\]\[\s*?)([^\s\]]*?)\]/g;
private readonly definitionPattern = /^([\t ]*\[((?:\\\]|[^\]])+)\]:\s*)(\S+)/gm;
public provideDocumentLinks(
document: vscode.TextDocument,
@@ -144,11 +153,10 @@ export default class LinkProvider implements vscode.DocumentLinkProvider {
}
}
for (const definition of Array.from(definitions.values())) {
for (const definition of definitions.values()) {
try {
results.push(new vscode.DocumentLink(
definition.linkRange,
normalizeLink(document, definition.link, base)));
const { uri } = parseLink(document, definition.link, base);
results.push(new vscode.DocumentLink(definition.linkRange, uri));
} catch (e) {
// noop
}

View File

@@ -16,6 +16,7 @@ import { MarkdownPreviewConfigurationManager } from './previewConfig';
import { MarkdownContributionProvider, MarkdownContributions } from '../markdownExtensions';
import { isMarkdownFile } from '../util/file';
import { resolveLinkToMarkdownFile } from '../commands/openDocumentLink';
import { WebviewResourceProvider, normalizeResource } from '../util/resources';
const localize = nls.loadMessageBundle();
interface WebviewMessage {
@@ -345,8 +346,8 @@ export class MarkdownPreview extends Disposable {
private get iconPath() {
const root = path.join(this._contributionProvider.extensionPath, 'media');
return {
light: vscode.Uri.file(path.join(root, 'Preview.svg')),
dark: vscode.Uri.file(path.join(root, 'Preview_inverse.svg'))
light: vscode.Uri.file(path.join(root, 'preview-light.svg')),
dark: vscode.Uri.file(path.join(root, 'preview-dark.svg'))
};
}
@@ -388,31 +389,46 @@ export class MarkdownPreview extends Disposable {
}
private async doUpdate(): Promise<void> {
const resource = this._resource;
if (this._disposed) {
return;
}
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;
}
const pendingVersion = new PreviewDocumentVersion(resource, document.version);
if (this._disposed) {
return;
}
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) {
const content = await this._contentProvider.provideTextDocumentContent(document, this._previewConfigurations, this.line, this.state);
if (this._resource === markdownResource) {
const self = this;
const resourceProvider: WebviewResourceProvider = {
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);
// Another call to `doUpdate` may have happened.
// Make sure we are still updating for the correct document
if (this.currentVersion && this.currentVersion.equals(pendingVersion)) {
@@ -432,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

@@ -3,17 +3,17 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import * as path from 'path';
import { MarkdownEngine } from '../markdownEngine';
import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
import { Logger } from '../logger';
import { ContentSecurityPolicyArbiter, MarkdownPreviewSecurityLevel } from '../security';
import { MarkdownPreviewConfigurationManager, MarkdownPreviewConfiguration } from './previewConfig';
import { MarkdownEngine } from '../markdownEngine';
import { MarkdownContributionProvider } from '../markdownExtensions';
import { ContentSecurityPolicyArbiter, MarkdownPreviewSecurityLevel } from '../security';
import { WebviewResourceProvider } from '../util/resources';
import { MarkdownPreviewConfiguration, MarkdownPreviewConfigurationManager } from './previewConfig';
const localize = nls.loadMessageBundle();
/**
* Strings used inside the markdown preview.
@@ -35,8 +35,8 @@ const previewStrings = {
'Content Disabled Security Warning')
};
function escapeAttribute(value: string): string {
return value.replace(/"/g, '&quot;');
function escapeAttribute(value: string | vscode.Uri): string {
return value.toString().replace(/"/g, '&quot;');
}
export class MarkdownContentProvider {
@@ -50,6 +50,7 @@ export class MarkdownContentProvider {
public async provideTextDocumentContent(
markdownDocument: vscode.TextDocument,
resourceProvider: WebviewResourceProvider,
previewConfigurations: MarkdownPreviewConfigurationManager,
initialLine: number | undefined = undefined,
state?: any
@@ -63,18 +64,19 @@ export class MarkdownContentProvider {
scrollPreviewWithEditor: config.scrollPreviewWithEditor,
scrollEditorWithPreview: config.scrollEditorWithPreview,
doubleClickToSwitchToEditor: config.doubleClickToSwitchToEditor,
disableSecurityWarnings: this.cspArbiter.shouldDisableSecurityWarnings()
disableSecurityWarnings: this.cspArbiter.shouldDisableSecurityWarnings(),
webviewResourceRoot: resourceProvider.toWebviewResource(markdownDocument.uri).toString(),
};
this.logger.log('provideTextDocumentContent', initialData);
// Content Security Policy
const nonce = new Date().getTime() + '' + new Date().getMilliseconds();
const csp = this.getCspForResource(sourceUri, nonce);
const csp = this.getCsp(resourceProvider, sourceUri, nonce);
const body = await this.engine.render(markdownDocument);
return `<!DOCTYPE html>
<html>
<html style="${escapeAttribute(this.getSettingsOverrideStyles(config))}">
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
${csp}
@@ -82,14 +84,14 @@ export class MarkdownContentProvider {
data-settings="${escapeAttribute(JSON.stringify(initialData))}"
data-strings="${escapeAttribute(JSON.stringify(previewStrings))}"
data-state="${escapeAttribute(JSON.stringify(state || {}))}">
<script src="${this.extensionResourcePath('pre.js')}" nonce="${nonce}"></script>
${this.getStyles(sourceUri, nonce, config, state)}
<base href="${markdownDocument.uri.with({ scheme: 'vscode-resource' }).toString(true)}">
<script src="${this.extensionResourcePath(resourceProvider, 'pre.js')}" nonce="${nonce}"></script>
${this.getStyles(resourceProvider, sourceUri, config, state)}
<base href="${resourceProvider.toWebviewResource(markdownDocument.uri)}">
</head>
<body class="vscode-body ${config.scrollBeyondLastLine ? 'scrollBeyondLastLine' : ''} ${config.wordWrap ? 'wordWrap' : ''} ${config.markEditorSelection ? 'showEditorSelection' : ''}">
${body}
<div class="code-line" data-line="${markdownDocument.lineCount}"></div>
${this.getScripts(nonce)}
${this.getScripts(resourceProvider, nonce)}
</body>
</html>`;
}
@@ -107,13 +109,13 @@ export class MarkdownContentProvider {
</html>`;
}
private extensionResourcePath(mediaFile: string): string {
return vscode.Uri.file(this.context.asAbsolutePath(path.join('media', mediaFile)))
.with({ scheme: 'vscode-resource' })
.toString();
private extensionResourcePath(resourceProvider: WebviewResourceProvider, mediaFile: string): string {
const webviewResource = resourceProvider.toWebviewResource(
vscode.Uri.file(this.context.asAbsolutePath(path.join('media', mediaFile))));
return webviewResource.toString();
}
private fixHref(resource: vscode.Uri, href: string): string {
private fixHref(resourceProvider: WebviewResourceProvider, resource: vscode.Uri, href: string): string {
if (!href) {
return href;
}
@@ -124,42 +126,36 @@ export class MarkdownContentProvider {
// Assume it must be a local file
if (path.isAbsolute(href)) {
return vscode.Uri.file(href)
.with({ scheme: 'vscode-resource' })
.toString();
return resourceProvider.toWebviewResource(vscode.Uri.file(href)).toString();
}
// Use a workspace relative path if there is a workspace
const root = vscode.workspace.getWorkspaceFolder(resource);
if (root) {
return vscode.Uri.file(path.join(root.uri.fsPath, href))
.with({ scheme: 'vscode-resource' })
.toString();
return resourceProvider.toWebviewResource(vscode.Uri.file(path.join(root.uri.fsPath, href))).toString();
}
// Otherwise look relative to the markdown file
return vscode.Uri.file(path.join(path.dirname(resource.fsPath), href))
.with({ scheme: 'vscode-resource' })
.toString();
return resourceProvider.toWebviewResource(vscode.Uri.file(path.join(path.dirname(resource.fsPath), href))).toString();
}
private computeCustomStyleSheetIncludes(resource: vscode.Uri, config: MarkdownPreviewConfiguration): string {
if (Array.isArray(config.styles)) {
return config.styles.map(style => {
return `<link rel="stylesheet" class="code-user-style" data-source="${escapeAttribute(style)}" href="${escapeAttribute(this.fixHref(resource, style))}" type="text/css" media="screen">`;
}).join('\n');
private computeCustomStyleSheetIncludes(resourceProvider: WebviewResourceProvider, resource: vscode.Uri, config: MarkdownPreviewConfiguration): string {
if (!Array.isArray(config.styles)) {
return '';
}
return '';
const out: string[] = [];
for (const style of config.styles) {
out.push(`<link rel="stylesheet" class="code-user-style" data-source="${escapeAttribute(style)}" href="${escapeAttribute(this.fixHref(resourceProvider, resource, style))}" type="text/css" media="screen">`);
}
return out.join('\n');
}
private getSettingsOverrideStyles(nonce: string, config: MarkdownPreviewConfiguration): string {
return `<style nonce="${nonce}">
html, body {
${config.fontFamily ? `font-family: ${config.fontFamily};` : ''}
${isNaN(config.fontSize) ? '' : `font-size: ${config.fontSize}px;`}
${isNaN(config.lineHeight) ? '' : `line-height: ${config.lineHeight};`}
}
</style>`;
private getSettingsOverrideStyles(config: MarkdownPreviewConfiguration): string {
return [
config.fontFamily ? `--vscode-markdown-font-family: ${config.fontFamily};` : '',
isNaN(config.fontSize) ? '' : `--vscode-markdown-font-size: ${config.fontSize}px;`,
isNaN(config.lineHeight) ? '' : `--vscode-markdown-line-height: ${config.lineHeight};`,
].join(' ');
}
private getImageStabilizerStyles(state?: any) {
@@ -177,37 +173,47 @@ export class MarkdownContentProvider {
return ret;
}
private getStyles(resource: vscode.Uri, nonce: string, config: MarkdownPreviewConfiguration, state?: any): string {
const baseStyles = this.contributionProvider.contributions.previewStyles
.map(resource => `<link rel="stylesheet" type="text/css" href="${escapeAttribute(resource.toString())}">`)
.join('\n');
private getStyles(resourceProvider: WebviewResourceProvider, resource: vscode.Uri, config: MarkdownPreviewConfiguration, state?: any): string {
const baseStyles: string[] = [];
for (const resource of this.contributionProvider.contributions.previewStyles) {
baseStyles.push(`<link rel="stylesheet" type="text/css" href="${escapeAttribute(resourceProvider.toWebviewResource(resource))}">`);
}
return `${baseStyles}
${this.getSettingsOverrideStyles(nonce, config)}
${this.computeCustomStyleSheetIncludes(resource, config)}
return `${baseStyles.join('\n')}
${this.computeCustomStyleSheetIncludes(resourceProvider, resource, config)}
${this.getImageStabilizerStyles(state)}`;
}
private getScripts(nonce: string): string {
return this.contributionProvider.contributions.previewScripts
.map(resource => `<script async src="${escapeAttribute(resource.toString())}" nonce="${nonce}" charset="UTF-8"></script>`)
.join('\n');
private getScripts(resourceProvider: WebviewResourceProvider, nonce: string): string {
const out: string[] = [];
for (const resource of this.contributionProvider.contributions.previewScripts) {
out.push(`<script async
src="${escapeAttribute(resourceProvider.toWebviewResource(resource))}"
nonce="${nonce}"
charset="UTF-8"></script>`);
}
return out.join('\n');
}
private getCspForResource(resource: vscode.Uri, nonce: string): string {
private getCsp(
provider: WebviewResourceProvider,
resource: vscode.Uri,
nonce: string
): string {
const rule = provider.cspSource;
switch (this.cspArbiter.getSecurityLevelForResource(resource)) {
case MarkdownPreviewSecurityLevel.AllowInsecureContent:
return `<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src vscode-resource: http: https: data:; media-src vscode-resource: http: https: data:; script-src 'nonce-${nonce}'; style-src vscode-resource: 'unsafe-inline' http: https: data:; font-src vscode-resource: http: https: data:;">`;
return `<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src 'self' ${rule} http: https: data:; media-src 'self' ${rule} http: https: data:; script-src 'nonce-${nonce}'; style-src 'self' ${rule} 'unsafe-inline' http: https: data:; font-src 'self' ${rule} http: https: data:;">`;
case MarkdownPreviewSecurityLevel.AllowInsecureLocalContent:
return `<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src vscode-resource: https: data: http://localhost:* http://127.0.0.1:*; media-src vscode-resource: https: data: http://localhost:* http://127.0.0.1:*; script-src 'nonce-${nonce}'; style-src vscode-resource: 'unsafe-inline' https: data: http://localhost:* http://127.0.0.1:*; font-src vscode-resource: https: data: http://localhost:* http://127.0.0.1:*;">`;
return `<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src 'self' ${rule} https: data: http://localhost:* http://127.0.0.1:*; media-src 'self' ${rule} https: data: http://localhost:* http://127.0.0.1:*; script-src 'nonce-${nonce}'; style-src 'self' ${rule} 'unsafe-inline' https: data: http://localhost:* http://127.0.0.1:*; font-src 'self' ${rule} https: data: http://localhost:* http://127.0.0.1:*;">`;
case MarkdownPreviewSecurityLevel.AllowScriptsAndAllContent:
return '';
case MarkdownPreviewSecurityLevel.Strict:
default:
return `<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src vscode-resource: https: data:; media-src vscode-resource: https: data:; script-src 'nonce-${nonce}'; style-src vscode-resource: 'unsafe-inline' https: data:; font-src vscode-resource: https: data:;">`;
return `<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src 'self' ${rule} https: data:; media-src 'self' ${rule} https: data:; script-src 'nonce-${nonce}'; style-src 'self' ${rule} 'unsafe-inline' https: data:; font-src 'self' ${rule} https: data:;">`;
}
}
}

View File

@@ -234,7 +234,6 @@ export class MarkdownEngine {
return normalizeLink(externalSchemeUri.toString(true));
}
// Assume it must be an relative or absolute file path
// Use a fake scheme to avoid parse warnings
let uri = vscode.Uri.parse(`vscode-resource:${link}`);
@@ -271,7 +270,7 @@ export class MarkdownEngine {
const validateLink = md.validateLink;
md.validateLink = (link: string) => {
// support file:// links
return validateLink(link) || link.indexOf('file:') === 0;
return validateLink(link) || link.startsWith('file:') || /^data:image\/.*?;/.test(link);
};
}

View File

@@ -9,8 +9,7 @@ import { Disposable } from './util/dispose';
import * as arrays from './util/arrays';
const resolveExtensionResource = (extension: vscode.Extension<any>, resourcePath: string): vscode.Uri => {
return vscode.Uri.file(path.join(extension.extensionPath, resourcePath))
.with({ scheme: 'vscode-resource' });
return vscode.Uri.file(path.join(extension.extensionPath, resourcePath));
};
const resolveExtensionResources = (extension: vscode.Extension<any>, resourcePaths: unknown): vscode.Uri[] => {

View File

@@ -72,6 +72,14 @@ suite('markdown.DocumentLinkProvider', () => {
assertRangeEqual(link.range, new vscode.Range(0, 6, 0, 25));
});
// #35245
test('Should handle links with escaped characters in name', () => {
const links = getLinksForFile('a [b\\]](./file)');
assert.strictEqual(links.length, 1);
const [link] = links;
assertRangeEqual(link.range, new vscode.Range(0, 8, 0, 14));
});
test('Should handle links with balanced parens', () => {
{

View File

@@ -0,0 +1,33 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
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;
}

View File

@@ -29,10 +29,10 @@
resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-0.0.2.tgz#5d9ad19e6e6508cdd2f2596df86fd0aade598660"
integrity sha1-XZrRnm5lCM3S8llt+G/Qqt5ZhmA=
"@types/node@^10.12.21":
version "10.12.21"
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.21.tgz#7e8a0c34cf29f4e17a36e9bd0ea72d45ba03908e"
integrity sha512-CBgLNk4o3XMnqMc0rhb6lc77IwShMEglz05deDcn2lQxyXEZivfwgYJu7SMha9V5XcrP6qZuevTHV/QrN2vjKQ==
"@types/node@^10.14.8":
version "10.14.8"
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.8.tgz#fe444203ecef1162348cd6deb76c62477b2cc6e9"
integrity sha512-I4+DbJEhLEg4/vIy/2gkWDvXBOOtPKV9EnLhYjMoqxcRW+TTZtUftkHktz/a8suoD5mUL7m6ReLrkPvSsCQQmw==
abbrev@1:
version "1.1.1"
@@ -2933,10 +2933,10 @@ he@1.1.1:
resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd"
integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0=
highlight.js@9.13.1:
version "9.13.1"
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.13.1.tgz#054586d53a6863311168488a0f58d6c505ce641e"
integrity sha512-Sc28JNQNDzaH6PORtRLMvif9RSn1mYuOoX3omVjnb0+HbpPygU2ALBI0R/wsiqCb4/fcp07Gdo8g+fhtFrQl6A==
highlight.js@9.15.8:
version "9.15.8"
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.15.8.tgz#f344fda123f36f1a65490e932cf90569e4999971"
integrity sha512-RrapkKQWwE+wKdF73VsOa2RQdIoO3mxwJ4P8mhbI6KYJUraUHRKM5w5zQQKXNk0xNL4UVRdulV9SBJcmzJNzVA==
hmac-drbg@^1.0.0:
version "1.0.1"