Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
掘金者说
vscode
提交
82084be1
V
vscode
项目概览
掘金者说
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
82084be1
编写于
3月 14, 2018
作者:
M
Matt Bierner
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Switch to use `vscode-resource` scheme in webviews
Fixes #45784
上级
a2ac383f
变更
19
展开全部
隐藏空白更改
内联
并排
Showing
19 changed file
with
188 addition
and
138 deletion
+188
-138
extensions/markdown/media/index.js
extensions/markdown/media/index.js
+3
-3
extensions/markdown/package.json
extensions/markdown/package.json
+7
-0
extensions/markdown/preview-src/index.ts
extensions/markdown/preview-src/index.ts
+2
-2
extensions/markdown/src/extension.ts
extensions/markdown/src/extension.ts
+6
-5
extensions/markdown/src/features/preview.ts
extensions/markdown/src/features/preview.ts
+8
-4
extensions/markdown/src/features/previewContentProvider.ts
extensions/markdown/src/features/previewContentProvider.ts
+11
-23
extensions/markdown/src/features/previewManager.ts
extensions/markdown/src/features/previewManager.ts
+5
-2
extensions/markdown/src/markdownEngine.ts
extensions/markdown/src/markdownEngine.ts
+7
-13
extensions/markdown/src/markdownExtensions.ts
extensions/markdown/src/markdownExtensions.ts
+92
-53
extensions/markdown/src/test/tableOfContentsProvider.test.ts
extensions/markdown/src/test/tableOfContentsProvider.test.ts
+19
-6
src/vs/vscode.proposed.d.ts
src/vs/vscode.proposed.d.ts
+2
-2
src/vs/workbench/api/electron-browser/mainThreadWebview.ts
src/vs/workbench/api/electron-browser/mainThreadWebview.ts
+1
-2
src/vs/workbench/api/node/extHost.api.impl.ts
src/vs/workbench/api/node/extHost.api.impl.ts
+1
-1
src/vs/workbench/api/node/extHost.protocol.ts
src/vs/workbench/api/node/extHost.protocol.ts
+1
-1
src/vs/workbench/api/node/extHostWebview.ts
src/vs/workbench/api/node/extHostWebview.ts
+3
-2
src/vs/workbench/parts/html/electron-browser/webview.ts
src/vs/workbench/parts/html/electron-browser/webview.ts
+1
-14
src/vs/workbench/parts/update/electron-browser/releaseNotesEditor.ts
...bench/parts/update/electron-browser/releaseNotesEditor.ts
+2
-3
src/vs/workbench/parts/webview/electron-browser/webviewEditor.ts
...workbench/parts/webview/electron-browser/webviewEditor.ts
+10
-1
src/vs/workbench/parts/webview/electron-browser/webviewInput.ts
.../workbench/parts/webview/electron-browser/webviewInput.ts
+7
-1
未找到文件。
extensions/markdown/media/index.js
浏览文件 @
82084be1
此差异已折叠。
点击以展开。
extensions/markdown/package.json
浏览文件 @
82084be1
...
...
@@ -267,6 +267,13 @@
"fileMatch"
:
"package.json"
,
"url"
:
"./schemas/package.schema.json"
}
],
"markdown.previewStyles"
:
[
"./media/markdown.css"
,
"./media/tomorrow.css"
],
"markdown.previewScripts"
:
[
"./media/index.js"
]
},
"scripts"
:
{
...
...
extensions/markdown/preview-src/index.ts
浏览文件 @
82084be1
...
...
@@ -90,8 +90,8 @@ document.addEventListener('click', event => {
if
(
node
.
getAttribute
(
'
href
'
).
startsWith
(
'
#
'
))
{
break
;
}
if
(
node
.
href
.
startsWith
(
'
file://
'
)
||
node
.
href
.
startsWith
(
'
vscode-
workspace-
resource:
'
))
{
const
[
path
,
fragment
]
=
node
.
href
.
replace
(
/^
(
file:
\/\/
|vscode-
workspace-
resource:
)
/i
,
''
).
split
(
'
#
'
);
if
(
node
.
href
.
startsWith
(
'
file://
'
)
||
node
.
href
.
startsWith
(
'
vscode-resource:
'
))
{
const
[
path
,
fragment
]
=
node
.
href
.
replace
(
/^
(
file:
\/\/
|vscode-resource:
)
/i
,
''
).
split
(
'
#
'
);
postCommand
(
'
_markdown.openDocumentLink
'
,
[{
path
,
fragment
}]);
event
.
preventDefault
();
event
.
stopPropagation
();
...
...
extensions/markdown/src/extension.ts
浏览文件 @
82084be1
...
...
@@ -11,7 +11,7 @@ import { Logger } from './logger';
import
{
CommandManager
}
from
'
./commandManager
'
;
import
*
as
commands
from
'
./commands/index
'
;
import
{
loadDefaultTelemetryReporter
}
from
'
./telemetryReporter
'
;
import
{
loadMarkdownExtens
ions
}
from
'
./markdownExtensions
'
;
import
{
getMarkdownExtensionContribut
ions
}
from
'
./markdownExtensions
'
;
import
LinkProvider
from
'
./features/documentLinkProvider
'
;
import
MDDocumentSymbolProvider
from
'
./features/documentSymbolProvider
'
;
import
{
MarkdownContentProvider
}
from
'
./features/previewContentProvider
'
;
...
...
@@ -23,16 +23,17 @@ export function activate(context: vscode.ExtensionContext) {
const
telemetryReporter
=
loadDefaultTelemetryReporter
();
context
.
subscriptions
.
push
(
telemetryReporter
);
const
contributions
=
getMarkdownExtensionContributions
();
const
cspArbiter
=
new
ExtensionContentSecurityPolicyArbiter
(
context
.
globalState
,
context
.
workspaceState
);
const
engine
=
new
MarkdownEngine
();
const
engine
=
new
MarkdownEngine
(
contributions
);
const
logger
=
new
Logger
();
const
selector
=
'
markdown
'
;
const
contentProvider
=
new
MarkdownContentProvider
(
engine
,
context
,
cspArbiter
,
logger
);
loadMarkdownExtensions
(
contentProvider
,
engine
);
const
contentProvider
=
new
MarkdownContentProvider
(
engine
,
context
,
cspArbiter
,
contributions
,
logger
);
const
previewManager
=
new
MarkdownPreviewManager
(
contentProvider
,
logger
);
const
previewManager
=
new
MarkdownPreviewManager
(
contentProvider
,
logger
,
contributions
);
context
.
subscriptions
.
push
(
previewManager
);
context
.
subscriptions
.
push
(
vscode
.
languages
.
registerDocumentSymbolProvider
(
selector
,
new
MDDocumentSymbolProvider
(
engine
)));
...
...
extensions/markdown/src/features/preview.ts
浏览文件 @
82084be1
...
...
@@ -13,6 +13,7 @@ import { disposeAll } from '../util/dispose';
import
*
as
nls
from
'
vscode-nls
'
;
import
{
getVisibleLine
,
MarkdownFileTopmostLineMonitor
}
from
'
../util/topmostLineMonitor
'
;
import
{
MarkdownPreviewConfigurationManager
}
from
'
./previewConfig
'
;
import
{
MarkdownContributions
}
from
'
../markdownExtensions
'
;
const
localize
=
nls
.
loadMessageBundle
();
export
class
MarkdownPreview
{
...
...
@@ -37,7 +38,8 @@ export class MarkdownPreview {
private
readonly
contentProvider
:
MarkdownContentProvider
,
private
readonly
previewConfigurations
:
MarkdownPreviewConfigurationManager
,
private
readonly
logger
:
Logger
,
topmostLineMonitor
:
MarkdownFileTopmostLineMonitor
topmostLineMonitor
:
MarkdownFileTopmostLineMonitor
,
private
readonly
contributions
:
MarkdownContributions
)
{
this
.
uri
=
vscode
.
Uri
.
parse
(
`
${
MarkdownPreview
.
previewScheme
}
:
${
MarkdownPreview
.
previewCount
++
}
`
);
this
.
webview
=
vscode
.
window
.
createWebview
(
...
...
@@ -251,16 +253,18 @@ export class MarkdownPreview {
}
private
getLocalResourceRoots
(
resource
:
vscode
.
Uri
):
vscode
.
Uri
[]
{
const
baseRoots
=
this
.
contributions
.
previewResourceRoots
;
const
folder
=
vscode
.
workspace
.
getWorkspaceFolder
(
resource
);
if
(
folder
)
{
return
[
folder
.
uri
]
;
return
baseRoots
.
concat
(
folder
.
uri
)
;
}
if
(
!
resource
.
scheme
||
resource
.
scheme
===
'
file
'
)
{
return
[
vscode
.
Uri
.
file
(
path
.
dirname
(
resource
.
fsPath
))]
;
return
baseRoots
.
concat
(
vscode
.
Uri
.
file
(
path
.
dirname
(
resource
.
fsPath
)))
;
}
return
[]
;
return
baseRoots
;
}
private
onDidScrollPreview
(
line
:
number
)
{
...
...
extensions/markdown/src/features/previewContentProvider.ts
浏览文件 @
82084be1
...
...
@@ -13,6 +13,7 @@ const localize = nls.loadMessageBundle();
import
{
Logger
}
from
'
../logger
'
;
import
{
ContentSecurityPolicyArbiter
,
MarkdownPreviewSecurityLevel
}
from
'
../security
'
;
import
{
MarkdownPreviewConfigurationManager
,
MarkdownPreviewConfiguration
}
from
'
./previewConfig
'
;
import
{
MarkdownContributions
}
from
'
../markdownExtensions
'
;
/**
* Strings used inside the markdown preview.
...
...
@@ -35,24 +36,14 @@ const previewStrings = {
};
export
class
MarkdownContentProvider
{
private
readonly
extraStyles
:
Array
<
vscode
.
Uri
>
=
[];
private
readonly
extraScripts
:
Array
<
vscode
.
Uri
>
=
[];
constructor
(
private
readonly
engine
:
MarkdownEngine
,
private
readonly
context
:
vscode
.
ExtensionContext
,
private
readonly
cspArbiter
:
ContentSecurityPolicyArbiter
,
private
readonly
extensionPreviewResourceProvider
:
MarkdownContributions
,
private
readonly
logger
:
Logger
)
{
}
public
addScript
(
resource
:
vscode
.
Uri
):
void
{
this
.
extraScripts
.
push
(
resource
);
}
public
addStyle
(
resource
:
vscode
.
Uri
):
void
{
this
.
extraStyles
.
push
(
resource
);
}
public
async
provideTextDocumentContent
(
markdownDocument
:
vscode
.
TextDocument
,
previewConfigurations
:
MarkdownPreviewConfigurationManager
,
...
...
@@ -85,7 +76,7 @@ export class MarkdownContentProvider {
<meta id="vscode-markdown-preview-data" data-settings="
${
JSON
.
stringify
(
initialData
).
replace
(
/"/g
,
'
"
'
)}
" data-strings="
${
JSON
.
stringify
(
previewStrings
).
replace
(
/"/g
,
'
"
'
)}
">
<script src="
${
this
.
extensionResourcePath
(
'
pre.js
'
)}
" nonce="
${
nonce
}
"></script>
${
this
.
getStyles
(
sourceUri
,
nonce
,
config
)}
<base href="
${
markdownDocument
.
uri
.
with
({
scheme
:
'
vscode-
workspace-
resource
'
}).
toString
(
true
)}
">
<base href="
${
markdownDocument
.
uri
.
with
({
scheme
:
'
vscode-resource
'
}).
toString
(
true
)}
">
</head>
<body class="vscode-body
${
config
.
scrollBeyondLastLine
?
'
scrollBeyondLastLine
'
:
''
}
${
config
.
wordWrap
?
'
wordWrap
'
:
''
}
${
config
.
markEditorSelection
?
'
showEditorSelection
'
:
''
}
">
${
body
}
...
...
@@ -97,7 +88,7 @@ export class MarkdownContentProvider {
private
extensionResourcePath
(
mediaFile
:
string
):
string
{
return
vscode
.
Uri
.
file
(
this
.
context
.
asAbsolutePath
(
path
.
join
(
'
media
'
,
mediaFile
)))
.
with
({
scheme
:
'
vscode-
extension-
resource
'
})
.
with
({
scheme
:
'
vscode-resource
'
})
.
toString
();
}
...
...
@@ -115,7 +106,7 @@ export class MarkdownContentProvider {
// Use href as file URI if it is absolute
if
(
path
.
isAbsolute
(
href
)
||
hrefUri
.
scheme
===
'
file
'
)
{
return
vscode
.
Uri
.
file
(
href
)
.
with
({
scheme
:
'
vscode-
workspace-
resource
'
})
.
with
({
scheme
:
'
vscode-resource
'
})
.
toString
();
}
...
...
@@ -123,13 +114,13 @@ export class MarkdownContentProvider {
let
root
=
vscode
.
workspace
.
getWorkspaceFolder
(
resource
);
if
(
root
)
{
return
vscode
.
Uri
.
file
(
path
.
join
(
root
.
uri
.
fsPath
,
href
))
.
with
({
scheme
:
'
vscode-
workspace-
resource
'
})
.
with
({
scheme
:
'
vscode-resource
'
})
.
toString
();
}
// Otherwise look relative to the markdown file
return
vscode
.
Uri
.
file
(
path
.
join
(
path
.
dirname
(
resource
.
fsPath
),
href
))
.
with
({
scheme
:
'
vscode-
workspace-
resource
'
})
.
with
({
scheme
:
'
vscode-resource
'
})
.
toString
();
}
...
...
@@ -153,10 +144,7 @@ export class MarkdownContentProvider {
}
private
getStyles
(
resource
:
vscode
.
Uri
,
nonce
:
string
,
config
:
MarkdownPreviewConfiguration
):
string
{
const
baseStyles
=
[
this
.
extensionResourcePath
(
'
markdown.css
'
),
this
.
extensionResourcePath
(
'
tomorrow.css
'
)
].
concat
(
this
.
extraStyles
.
map
(
resource
=>
resource
.
toString
()));
const
baseStyles
=
this
.
extensionPreviewResourceProvider
.
previewStyles
.
map
(
resource
=>
resource
.
toString
());
return
`
${
baseStyles
.
map
(
href
=>
`<link rel="stylesheet" type="text/css" href="
${
href
}
">`
).
join
(
'
\n
'
)}
${
this
.
getSettingsOverrideStyles
(
nonce
,
config
)}
...
...
@@ -164,7 +152,7 @@ export class MarkdownContentProvider {
}
private
getScripts
(
nonce
:
string
):
string
{
const
scripts
=
[
this
.
extensionResourcePath
(
'
index.js
'
)].
concat
(
this
.
extraScripts
.
map
(
resource
=>
resource
.
toString
()
));
const
scripts
=
this
.
extensionPreviewResourceProvider
.
previewScripts
.
map
(
resource
=>
resource
.
toString
(
));
return
scripts
.
map
(
source
=>
`<script async src="
${
source
}
" nonce="
${
nonce
}
" charset="UTF-8"></script>`
)
.
join
(
'
\n
'
);
...
...
@@ -173,14 +161,14 @@ export class MarkdownContentProvider {
private
getCspForResource
(
resource
:
vscode
.
Uri
,
nonce
:
string
):
string
{
switch
(
this
.
cspArbiter
.
getSecurityLevelForResource
(
resource
))
{
case
MarkdownPreviewSecurityLevel
.
AllowInsecureContent
:
return
`<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src vscode-
workspace-resource: vscode-extension-resource: http: https: data:; media-src vscode-workspace-resource: vscode-extension-resource: http: https: data:; script-src 'nonce-
${
nonce
}
'; style-src vscode-workspace-resource: 'unsafe-inline' http: https: data: vscode-extension-resource:; font-src vscode-workspace-resource: vscode-extension
-resource: http: https: data:;">`
;
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:;">`
;
case
MarkdownPreviewSecurityLevel
.
AllowScriptsAndAllContent
:
return
''
;
case
MarkdownPreviewSecurityLevel
.
Strict
:
default
:
return
`<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src vscode-
workspace-resource: vscode-extension-resource: https: data:; media-src vscode-workspace-resource: vscode-extension-resource: https: data:; script-src 'nonce-
${
nonce
}
'; style-src vscode-workspace-resource: 'unsafe-inline' https: data: vscode-extension-resource:; font-src vscode-workspace-resource: vscode-extension
-resource: https: data:;">`
;
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:;">`
;
}
}
}
extensions/markdown/src/features/previewManager.ts
浏览文件 @
82084be1
...
...
@@ -12,6 +12,7 @@ import { disposeAll } from '../util/dispose';
import
{
MarkdownFileTopmostLineMonitor
}
from
'
../util/topmostLineMonitor
'
;
import
{
isMarkdownFile
}
from
'
../util/file
'
;
import
{
MarkdownPreviewConfigurationManager
}
from
'
./previewConfig
'
;
import
{
MarkdownContributions
}
from
'
../markdownExtensions
'
;
export
class
MarkdownPreviewManager
{
private
static
readonly
markdownPreviewActiveContextKey
=
'
markdownPreviewFocus
'
;
...
...
@@ -24,7 +25,8 @@ export class MarkdownPreviewManager {
public
constructor
(
private
readonly
contentProvider
:
MarkdownContentProvider
,
private
readonly
logger
:
Logger
private
readonly
logger
:
Logger
,
private
readonly
contributions
:
MarkdownContributions
)
{
vscode
.
window
.
onDidChangeActiveEditor
(
editor
=>
{
vscode
.
commands
.
executeCommand
(
'
setContext
'
,
MarkdownPreviewManager
.
markdownPreviewActiveContextKey
,
...
...
@@ -122,7 +124,8 @@ export class MarkdownPreviewManager {
this
.
contentProvider
,
this
.
previewConfigurations
,
this
.
logger
,
this
.
topmostLineMonitor
);
this
.
topmostLineMonitor
,
this
.
contributions
);
preview
.
onDispose
(()
=>
{
const
existing
=
this
.
previews
.
indexOf
(
preview
!
);
...
...
extensions/markdown/src/markdownEngine.ts
浏览文件 @
82084be1
...
...
@@ -7,6 +7,7 @@ import * as vscode from 'vscode';
import
*
as
path
from
'
path
'
;
import
{
Slug
}
from
'
./tableOfContentsProvider
'
;
import
{
MarkdownIt
,
Token
}
from
'
markdown-it
'
;
import
{
MarkdownContributions
}
from
'
./markdownExtensions
'
;
const
FrontMatterRegex
=
/^---
\s
*
[^]
*
?(
-
{3}
|
\.{3})\s
*/
;
...
...
@@ -17,15 +18,9 @@ export class MarkdownEngine {
private
currentDocument
?:
vscode
.
Uri
;
private
plugins
:
Array
<
(
md
:
any
)
=>
any
>
=
[];
public
addPlugin
(
factory
:
(
md
:
any
)
=>
any
):
void
{
if
(
this
.
md
)
{
this
.
usePlugin
(
factory
);
}
else
{
this
.
plugins
.
push
(
factory
);
}
}
public
constructor
(
private
readonly
extensionPreviewResourceProvider
:
MarkdownContributions
)
{
}
private
usePlugin
(
factory
:
(
md
:
any
)
=>
any
):
void
{
try
{
...
...
@@ -57,10 +52,9 @@ export class MarkdownEngine {
slugify
:
(
header
:
string
)
=>
Slug
.
fromHeading
(
header
).
value
});
for
(
const
plugin
of
this
.
p
lugins
)
{
this
.
usePlugin
(
plugin
);
for
(
const
plugin
of
this
.
extensionPreviewResourceProvider
.
markdownItP
lugins
)
{
this
.
usePlugin
(
await
plugin
);
}
this
.
plugins
=
[];
for
(
const
renderName
of
[
'
paragraph_open
'
,
'
heading_open
'
,
'
image
'
,
'
code_block
'
,
'
blockquote_open
'
,
'
list_item_open
'
])
{
this
.
addLineNumberRenderer
(
this
.
md
,
renderName
);
...
...
@@ -154,7 +148,7 @@ export class MarkdownEngine {
fragment
:
Slug
.
fromHeading
(
fragment
).
value
});
}
return
normalizeLink
(
uri
.
with
({
scheme
:
'
vscode-
workspace-
resource
'
}).
toString
(
true
));
return
normalizeLink
(
uri
.
with
({
scheme
:
'
vscode-resource
'
}).
toString
(
true
));
}
else
if
(
!
uri
.
scheme
&&
!
uri
.
path
&&
uri
.
fragment
)
{
return
normalizeLink
(
uri
.
with
({
fragment
:
Slug
.
fromHeading
(
uri
.
fragment
).
value
...
...
extensions/markdown/src/markdownExtensions.ts
浏览文件 @
82084be1
...
...
@@ -6,76 +6,115 @@
import
*
as
vscode
from
'
vscode
'
;
import
*
as
path
from
'
path
'
;
import
{
MarkdownContentProvider
}
from
'
./features/previewContentProvider
'
;
import
{
MarkdownEngine
}
from
'
./markdownEngine
'
;
const
resolveExtensionResources
=
(
extension
:
vscode
.
Extension
<
any
>
,
resourcePath
:
string
):
vscode
.
Uri
=>
{
return
vscode
.
Uri
.
file
(
path
.
join
(
extension
.
extensionPath
,
resourcePath
))
.
with
({
scheme
:
'
vscode-
extension-
resource
'
});
.
with
({
scheme
:
'
vscode-resource
'
});
};
export
interface
MarkdownContributions
{
readonly
previewScripts
:
vscode
.
Uri
[];
readonly
previewStyles
:
vscode
.
Uri
[];
readonly
markdownItPlugins
:
Thenable
<
(
md
:
any
)
=>
any
>
[];
readonly
previewResourceRoots
:
vscode
.
Uri
[];
}
export
function
loadMarkdownExtensions
(
contentProvider
:
MarkdownContentProvider
,
engine
:
MarkdownEngine
)
{
for
(
const
extension
of
vscode
.
extensions
.
all
)
{
const
contributes
=
extension
.
packageJSON
&&
extension
.
packageJSON
.
contributes
;
if
(
!
contributes
)
{
continue
;
}
class
MarkdownExtensionContributions
implements
MarkdownContributions
{
private
readonly
_scripts
:
vscode
.
Uri
[]
=
[];
private
readonly
_styles
:
vscode
.
Uri
[]
=
[];
private
readonly
_previewResourceRoots
:
vscode
.
Uri
[]
=
[];
private
readonly
_plugins
:
Thenable
<
(
md
:
any
)
=>
any
>
[]
=
[];
tryLoadPreviewStyles
(
contributes
,
contentProvider
,
extension
);
tryLoadPreviewScripts
(
contributes
,
contentProvider
,
extension
);
tryLoadMarkdownItPlugins
(
contributes
,
extension
,
engine
);
private
_loaded
=
false
;
public
get
previewScripts
():
vscode
.
Uri
[]
{
this
.
ensureLoaded
();
return
this
.
_scripts
;
}
public
get
previewStyles
():
vscode
.
Uri
[]
{
this
.
ensureLoaded
();
return
this
.
_styles
;
}
public
get
previewResourceRoots
():
vscode
.
Uri
[]
{
this
.
ensureLoaded
();
return
this
.
_previewResourceRoots
;
}
public
get
markdownItPlugins
():
Thenable
<
(
md
:
any
)
=>
any
>
[]
{
this
.
ensureLoaded
();
return
this
.
_plugins
;
}
}
function
tryLoadMarkdownItPlugins
(
contributes
:
any
,
extension
:
vscode
.
Extension
<
any
>
,
engine
:
MarkdownEngine
)
{
if
(
contributes
[
'
markdown.markdownItPlugins
'
])
{
extension
.
activate
().
then
(()
=>
{
if
(
extension
.
exports
&&
extension
.
exports
.
extendMarkdownIt
)
{
engine
.
addPlugin
((
md
:
any
)
=>
extension
.
exports
.
extendMarkdownIt
(
md
));
private
ensureLoaded
()
{
if
(
this
.
_loaded
)
{
return
;
}
this
.
_loaded
=
true
;
for
(
const
extension
of
vscode
.
extensions
.
all
)
{
const
contributes
=
extension
.
packageJSON
&&
extension
.
packageJSON
.
contributes
;
if
(
!
contributes
)
{
continue
;
}
this
.
tryLoadPreviewStyles
(
contributes
,
extension
);
this
.
tryLoadPreviewScripts
(
contributes
,
extension
);
this
.
tryLoadMarkdownItPlugins
(
contributes
,
extension
);
if
(
contributes
[
'
markdown.previewScripts
'
]
||
contributes
[
'
markdown.previewStyles
'
])
{
this
.
_previewResourceRoots
.
push
(
vscode
.
Uri
.
file
(
extension
.
extensionPath
));
}
}
);
}
}
}
function
tryLoadPreviewScripts
(
contributes
:
any
,
contentProvider
:
MarkdownContentProvider
,
extension
:
vscode
.
Extension
<
any
>
)
{
const
scripts
=
contributes
[
'
markdown.previewScripts
'
];
if
(
scripts
&&
Array
.
isArray
(
scripts
))
{
for
(
const
script
of
scripts
)
{
try
{
contentProvider
.
addScript
(
resolveExtensionResources
(
extension
,
script
));
}
catch
(
e
)
{
// noop
private
tryLoadMarkdownItPlugins
(
contributes
:
any
,
extension
:
vscode
.
Extension
<
any
>
)
{
if
(
contributes
[
'
markdown.markdownItPlugins
'
])
{
this
.
_plugins
.
push
(
extension
.
activate
().
then
(()
=>
{
if
(
extension
.
exports
&&
extension
.
exports
.
extendMarkdownIt
)
{
return
(
md
:
any
)
=>
extension
.
exports
.
extendMarkdownIt
(
md
);
}
return
(
md
:
any
)
=>
md
;
}));
}
}
private
tryLoadPreviewScripts
(
contributes
:
any
,
extension
:
vscode
.
Extension
<
any
>
)
{
const
scripts
=
contributes
[
'
markdown.previewScripts
'
];
if
(
scripts
&&
Array
.
isArray
(
scripts
))
{
for
(
const
script
of
scripts
)
{
try
{
this
.
_scripts
.
push
(
resolveExtensionResources
(
extension
,
script
));
}
catch
(
e
)
{
// noop
}
}
}
}
}
function
tryLoadPreviewStyles
(
contributes
:
any
,
contentProvider
:
MarkdownContentProvider
,
extension
:
vscode
.
Extension
<
any
>
)
{
const
styles
=
contributes
[
'
markdown.previewStyles
'
];
if
(
styles
&&
Array
.
isArray
(
styles
)
)
{
for
(
const
style
of
styles
)
{
try
{
contentProvider
.
addStyle
(
resolveExtensionResources
(
extension
,
style
));
}
catch
(
e
)
{
// noop
private
tryLoadPreviewStyles
(
contributes
:
any
,
extension
:
vscode
.
Extension
<
any
>
)
{
const
styles
=
contributes
[
'
markdown.previewStyles
'
];
if
(
styles
&&
Array
.
isArray
(
styles
))
{
for
(
const
style
of
styles
)
{
try
{
this
.
_styles
.
push
(
resolveExtensionResources
(
extension
,
style
));
}
catch
(
e
)
{
// noop
}
}
}
}
}
export
function
getMarkdownExtensionContributions
():
MarkdownContributions
{
return
new
MarkdownExtensionContributions
();
}
\ No newline at end of file
extensions/markdown/src/test/tableOfContentsProvider.test.ts
浏览文件 @
82084be1
...
...
@@ -9,13 +9,14 @@ import 'mocha';
import
{
TableOfContentsProvider
}
from
'
../tableOfContentsProvider
'
;
import
{
MarkdownEngine
}
from
'
../markdownEngine
'
;
import
{
MarkdownContributions
}
from
'
../markdownExtensions
'
;
const
testFileName
=
vscode
.
Uri
.
parse
(
'
test.md
'
);
suite
(
'
markdown.TableOfContentsProvider
'
,
()
=>
{
test
(
'
Lookup should not return anything for empty document
'
,
async
()
=>
{
const
doc
=
new
InMemoryDocument
(
testFileName
,
''
);
const
provider
=
new
TableOfContentsProvider
(
new
Markdown
Engine
(),
doc
);
const
provider
=
new
TableOfContentsProvider
(
newEngine
(),
doc
);
assert
.
strictEqual
(
await
provider
.
lookup
(
''
),
undefined
);
assert
.
strictEqual
(
await
provider
.
lookup
(
'
foo
'
),
undefined
);
...
...
@@ -23,7 +24,7 @@ suite('markdown.TableOfContentsProvider', () => {
test
(
'
Lookup should not return anything for document with no headers
'
,
async
()
=>
{
const
doc
=
new
InMemoryDocument
(
testFileName
,
'
a *b*
\n
c
'
);
const
provider
=
new
TableOfContentsProvider
(
new
Markdown
Engine
(),
doc
);
const
provider
=
new
TableOfContentsProvider
(
newEngine
(),
doc
);
assert
.
strictEqual
(
await
provider
.
lookup
(
''
),
undefined
);
assert
.
strictEqual
(
await
provider
.
lookup
(
'
foo
'
),
undefined
);
...
...
@@ -33,7 +34,7 @@ suite('markdown.TableOfContentsProvider', () => {
test
(
'
Lookup should return basic #header
'
,
async
()
=>
{
const
doc
=
new
InMemoryDocument
(
testFileName
,
`# a\nx\n# c`
);
const
provider
=
new
TableOfContentsProvider
(
new
Markdown
Engine
(),
doc
);
const
provider
=
new
TableOfContentsProvider
(
newEngine
(),
doc
);
{
const
entry
=
await
provider
.
lookup
(
'
a
'
);
...
...
@@ -52,7 +53,7 @@ suite('markdown.TableOfContentsProvider', () => {
test
(
'
Lookups should be case in-sensitive
'
,
async
()
=>
{
const
doc
=
new
InMemoryDocument
(
testFileName
,
`# fOo\n`
);
const
provider
=
new
TableOfContentsProvider
(
new
Markdown
Engine
(),
doc
);
const
provider
=
new
TableOfContentsProvider
(
newEngine
(),
doc
);
assert
.
strictEqual
((
await
provider
.
lookup
(
'
fOo
'
))
!
.
line
,
0
);
assert
.
strictEqual
((
await
provider
.
lookup
(
'
foo
'
))
!
.
line
,
0
);
...
...
@@ -61,7 +62,7 @@ suite('markdown.TableOfContentsProvider', () => {
test
(
'
Lookups should ignore leading and trailing white-space, and collapse internal whitespace
'
,
async
()
=>
{
const
doc
=
new
InMemoryDocument
(
testFileName
,
`# f o o \n`
);
const
provider
=
new
TableOfContentsProvider
(
new
Markdown
Engine
(),
doc
);
const
provider
=
new
TableOfContentsProvider
(
newEngine
(),
doc
);
assert
.
strictEqual
((
await
provider
.
lookup
(
'
f o o
'
))
!
.
line
,
0
);
assert
.
strictEqual
((
await
provider
.
lookup
(
'
f o o
'
))
!
.
line
,
0
);
...
...
@@ -76,7 +77,7 @@ suite('markdown.TableOfContentsProvider', () => {
test
(
'
should normalize special characters #44779
'
,
async
()
=>
{
const
doc
=
new
InMemoryDocument
(
testFileName
,
`# Indentação\n`
);
const
provider
=
new
TableOfContentsProvider
(
new
Markdown
Engine
(),
doc
);
const
provider
=
new
TableOfContentsProvider
(
newEngine
(),
doc
);
assert
.
strictEqual
((
await
provider
.
lookup
(
'
indentacao
'
))
!
.
line
,
0
);
});
...
...
@@ -136,3 +137,15 @@ class InMemoryDocument implements vscode.TextDocument {
throw
new
Error
(
'
Method not implemented.
'
);
}
}
function
newEngine
():
MarkdownEngine
{
return
new
MarkdownEngine
(
new
class
implements
MarkdownContributions
{
readonly
previewScripts
:
vscode
.
Uri
[]
=
[];
readonly
previewStyles
:
vscode
.
Uri
[]
=
[];
readonly
previewResourceRoots
:
vscode
.
Uri
[]
=
[];
readonly
markdownItPlugins
:
Promise
<
(
md
:
any
)
=>
any
>
[]
=
[];
});
}
src/vs/vscode.proposed.d.ts
浏览文件 @
82084be1
...
...
@@ -519,9 +519,9 @@ declare module 'vscode' {
readonly
retainContextWhenHidden
?:
boolean
;
/**
* Root paths from which the webview can load local (filesystem) resources using the `vscode-
workspace-
resource:` scheme.
* Root paths from which the webview can load local (filesystem) resources using the `vscode-resource:` scheme.
*
* Default to the root folders of the current workspace.
* Default to the root folders of the current workspace
plus the extension's install directory
.
*
* Pass in an empty array to disallow access to any local resources.
*/
...
...
src/vs/workbench/api/electron-browser/mainThreadWebview.ts
浏览文件 @
82084be1
...
...
@@ -2,7 +2,6 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'
use strict
'
;
import
*
as
map
from
'
vs/base/common/map
'
;
import
{
MainThreadWebviewsShape
,
MainContext
,
IExtHostContext
,
ExtHostContext
,
ExtHostWebviewsShape
,
WebviewHandle
}
from
'
vs/workbench/api/node/extHost.protocol
'
;
...
...
@@ -47,7 +46,7 @@ export class MainThreadWebviews implements MainThreadWebviewsShape {
this
.
_toDispose
=
dispose
(
this
.
_toDispose
);
}
$createWebview
(
handle
:
WebviewHandle
,
uri
:
URI
,
title
:
string
,
column
:
Position
,
options
:
vscode
.
WebviewOptions
):
void
{
$createWebview
(
handle
:
WebviewHandle
,
uri
:
URI
,
title
:
string
,
column
:
Position
,
options
:
vscode
.
WebviewOptions
,
extensionFolderPath
:
string
):
void
{
const
webviewInput
=
new
WebviewInput
(
URI
.
revive
(
uri
),
title
,
options
,
''
,
{
onMessage
:
message
=>
this
.
_proxy
.
$onMessage
(
handle
,
message
),
onDidChangePosition
:
position
=>
this
.
_proxy
.
$onDidChangePosition
(
handle
,
position
),
...
...
src/vs/workbench/api/node/extHost.api.impl.ts
浏览文件 @
82084be1
...
...
@@ -413,7 +413,7 @@ export function createApiFactory(
return
extHostDecorations
.
registerDecorationProvider
(
provider
,
extension
.
id
);
}),
createWebview
:
proposedApiFunction
(
extension
,
(
uri
:
vscode
.
Uri
,
title
:
string
,
column
:
vscode
.
ViewColumn
,
options
:
vscode
.
WebviewOptions
)
=>
{
return
extHostWebviews
.
createWebview
(
uri
,
title
,
column
,
options
);
return
extHostWebviews
.
createWebview
(
uri
,
title
,
column
,
options
,
extension
.
extensionFolderPath
);
}),
onDidChangeActiveEditor
:
proposedApiFunction
(
extension
,
(
listener
,
thisArg
?,
disposables
?)
=>
{
return
extHostDocumentsAndEditors
.
onDidChangeActiveEditor
(
listener
,
thisArg
,
disposables
);
...
...
src/vs/workbench/api/node/extHost.protocol.ts
浏览文件 @
82084be1
...
...
@@ -345,7 +345,7 @@ export interface MainThreadTelemetryShape extends IDisposable {
export
type
WebviewHandle
=
number
;
export
interface
MainThreadWebviewsShape
extends
IDisposable
{
$createWebview
(
handle
:
WebviewHandle
,
uri
:
URI
,
title
:
string
,
column
:
EditorPosition
,
options
:
vscode
.
WebviewOptions
):
void
;
$createWebview
(
handle
:
WebviewHandle
,
uri
:
URI
,
title
:
string
,
column
:
EditorPosition
,
options
:
vscode
.
WebviewOptions
,
extensionFolderPath
:
string
):
void
;
$disposeWebview
(
handle
:
WebviewHandle
):
void
;
$show
(
handle
:
WebviewHandle
,
column
:
EditorPosition
):
void
;
$setTitle
(
handle
:
WebviewHandle
,
value
:
string
):
void
;
...
...
src/vs/workbench/api/node/extHostWebview.ts
浏览文件 @
82084be1
...
...
@@ -132,10 +132,11 @@ export class ExtHostWebviews implements ExtHostWebviewsShape {
uri
:
vscode
.
Uri
,
title
:
string
,
viewColumn
:
vscode
.
ViewColumn
,
options
:
vscode
.
WebviewOptions
options
:
vscode
.
WebviewOptions
,
extensionFolderPath
:
string
):
vscode
.
Webview
{
const
handle
=
ExtHostWebviews
.
handlePool
++
;
this
.
_proxy
.
$createWebview
(
handle
,
uri
,
title
,
typeConverters
.
fromViewColumn
(
viewColumn
),
options
);
this
.
_proxy
.
$createWebview
(
handle
,
uri
,
title
,
typeConverters
.
fromViewColumn
(
viewColumn
),
options
,
extensionFolderPath
);
const
webview
=
new
ExtHostWebview
(
handle
,
this
.
_proxy
,
uri
,
viewColumn
,
options
);
this
.
_webviews
.
set
(
handle
,
webview
);
...
...
src/vs/workbench/parts/html/electron-browser/webview.ts
浏览文件 @
82084be1
...
...
@@ -3,8 +3,6 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'
use strict
'
;
import
URI
from
'
vs/base/common/uri
'
;
import
{
IDisposable
,
dispose
}
from
'
vs/base/common/lifecycle
'
;
import
Event
,
{
Emitter
}
from
'
vs/base/common/event
'
;
...
...
@@ -328,17 +326,7 @@ export class Webview {
appRootUri
]);
const
extensionPaths
=
[
URI
.
file
(
this
.
_environmentService
.
extensionsPath
),
appRootUri
,
];
if
(
this
.
_environmentService
.
extensionDevelopmentPath
)
{
extensionPaths
.
push
(
URI
.
file
(
this
.
_environmentService
.
extensionDevelopmentPath
));
}
registerFileProtocol
(
contents
,
'
vscode-extension-resource
'
,
()
=>
extensionPaths
);
registerFileProtocol
(
contents
,
'
vscode-workspace-resource
'
,
()
=>
registerFileProtocol
(
contents
,
'
vscode-resource
'
,
()
=>
(
this
.
_options
.
localResourceRoots
||
[])
);
}
...
...
@@ -443,7 +431,6 @@ function registerFileProtocol(
callback
({
path
:
normalizedPath
});
return
;
}
}
callback
({
error
:
'
Cannot load resource outside of protocol root
'
});
},
(
error
)
=>
{
...
...
src/vs/workbench/parts/update/electron-browser/releaseNotesEditor.ts
浏览文件 @
82084be1
...
...
@@ -12,7 +12,7 @@ import { tokenizeToString } from 'vs/editor/common/modes/textToHtmlTokenizer';
import
{
IMode
,
TokenizationRegistry
}
from
'
vs/editor/common/modes
'
;
import
{
generateTokensCSSForColorMap
}
from
'
vs/editor/common/modes/supports/tokenization
'
;
import
{
IWorkbenchEditorService
}
from
'
vs/workbench/services/editor/common/editorService
'
;
import
{
ServicesAccessor
,
IInstantiationService
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
ServicesAccessor
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
KeybindingIO
}
from
'
vs/workbench/services/keybinding/common/keybindingIO
'
;
import
{
IKeybindingService
}
from
'
vs/platform/keybinding/common/keybinding
'
;
import
{
IRequestService
}
from
'
vs/platform/request/node/request
'
;
...
...
@@ -56,7 +56,6 @@ export class ReleaseNotesManager {
public
constructor
(
@
IEditorGroupService
private
readonly
_editorGroupService
:
IEditorGroupService
,
@
IEnvironmentService
private
readonly
_environmentService
:
IEnvironmentService
,
@
IInstantiationService
private
readonly
_instantiationService
:
IInstantiationService
,
@
IKeybindingService
private
readonly
_keybindingService
:
IKeybindingService
,
@
IModeService
private
readonly
_modeService
:
IModeService
,
@
IOpenerService
private
readonly
_openerService
:
IOpenerService
,
...
...
@@ -85,7 +84,7 @@ export class ReleaseNotesManager {
}
}
else
{
const
uri
=
URI
.
parse
(
'
release-notes:
'
+
version
);
this
.
_currentReleaseNotes
=
this
.
_instantiationService
.
createInstance
(
WebviewInput
,
uri
,
title
,
{
tryRestoreScrollPosition
:
true
},
html
,
{
this
.
_currentReleaseNotes
=
new
WebviewInput
(
uri
,
title
,
{
tryRestoreScrollPosition
:
true
},
html
,
{
onDidClickLink
:
uri
=>
this
.
onDidClickLink
(
uri
),
onDispose
:
()
=>
{
this
.
_currentReleaseNotes
=
undefined
;
}
},
this
.
_partService
);
...
...
src/vs/workbench/parts/webview/electron-browser/webviewEditor.ts
浏览文件 @
82084be1
...
...
@@ -22,6 +22,7 @@ import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace
import
DOM
=
require
(
'
vs/base/browser/dom
'
);
import
Event
,
{
Emitter
}
from
'
vs/base/common/event
'
;
import
{
WebviewInput
}
from
'
vs/workbench/parts/webview/electron-browser/webviewInput
'
;
import
URI
from
'
vs/base/common/uri
'
;
export
class
WebviewEditor
extends
BaseWebviewEditor
{
...
...
@@ -162,7 +163,7 @@ export class WebviewEditor extends BaseWebviewEditor {
allowSvgs
:
true
,
enableWrappedPostMessage
:
true
,
useSameOriginForRoot
:
false
,
localResourceRoots
:
(
input
&&
input
.
options
.
localResourceRoots
)
||
this
.
_contextService
.
getWorkspace
().
folders
.
map
(
x
=>
x
.
uri
)
localResourceRoots
:
input
.
options
.
localResourceRoots
||
this
.
getDefaultLocalResourceRoots
(
)
};
input
.
setHtml
(
input
.
html
);
...
...
@@ -173,6 +174,14 @@ export class WebviewEditor extends BaseWebviewEditor {
this
.
doUpdateContainer
();
}
private
getDefaultLocalResourceRoots
():
URI
[]
{
const
rootPaths
=
this
.
_contextService
.
getWorkspace
().
folders
.
map
(
x
=>
x
.
uri
);
if
((
this
.
input
as
WebviewInput
).
extensionFolderPath
)
{
rootPaths
.
push
((
this
.
input
as
WebviewInput
).
extensionFolderPath
);
}
return
rootPaths
;
}
private
getWebview
(
input
:
WebviewInput
):
Webview
{
if
(
this
.
_webview
)
{
return
this
.
_webview
;
...
...
src/vs/workbench/parts/webview/electron-browser/webviewInput.ts
浏览文件 @
82084be1
...
...
@@ -40,6 +40,7 @@ export class WebviewInput extends EditorInput {
private
_webviewDisposables
:
IDisposable
[]
=
[];
private
_position
?:
Position
;
private
_scrollYPercentage
:
number
=
0
;
public
readonly
extensionFolderPath
:
URI
|
undefined
;
constructor
(
resource
:
URI
,
...
...
@@ -47,7 +48,8 @@ export class WebviewInput extends EditorInput {
options
:
WebviewInputOptions
,
html
:
string
,
events
:
WebviewEvents
,
partService
:
IPartService
partService
:
IPartService
,
extensionFolderPath
?:
string
)
{
super
();
this
.
_resource
=
resource
;
...
...
@@ -56,6 +58,10 @@ export class WebviewInput extends EditorInput {
this
.
_html
=
html
;
this
.
_events
=
events
;
if
(
extensionFolderPath
)
{
this
.
extensionFolderPath
=
URI
.
file
(
extensionFolderPath
);
}
const
id
=
WebviewInput
.
handlePool
++
;
this
.
_container
=
document
.
createElement
(
'
div
'
);
this
.
_container
.
id
=
`webview-
${
id
}
`
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录