Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
cac27d27
V
vscode
项目概览
xxadev
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
cac27d27
编写于
6月 14, 2019
作者:
M
Matt Bierner
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Enable basic iframe webviews prototype in the web
上级
e1c930e1
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
82 addition
and
198 deletion
+82
-198
src/vs/workbench/contrib/webview/browser/pre/index.html
src/vs/workbench/contrib/webview/browser/pre/index.html
+55
-0
src/vs/workbench/contrib/webview/browser/webviewElement.ts
src/vs/workbench/contrib/webview/browser/webviewElement.ts
+6
-183
src/vs/workbench/contrib/webview/browser/webviewService.ts
src/vs/workbench/contrib/webview/browser/webviewService.ts
+16
-6
src/vs/workbench/contrib/webview/electron-browser/webviewService.ts
...kbench/contrib/webview/electron-browser/webviewService.ts
+2
-5
src/vs/workbench/workbench.web.main.ts
src/vs/workbench/workbench.web.main.ts
+3
-4
未找到文件。
src/vs/workbench/contrib/webview/browser/pre/index.html
0 → 100644
浏览文件 @
cac27d27
<!DOCTYPE html>
<html
lang=
"en"
>
<head>
<meta
charset=
"UTF-8"
>
<meta
http-equiv=
"Content-Security-Policy"
content=
"default-src *; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'"
/>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1.0"
>
<meta
http-equiv=
"X-UA-Compatible"
content=
"ie=edge"
>
<title>
Virtual Document
</title>
</head>
<body>
<script
src=
"main.js"
></script>
<script>
(
function
()
{
const
id
=
document
.
location
.
search
.
match
(
/
\b
id=
([\w\-]
+
)
/
)[
1
];
const
handlers
=
{};
const
postMessageToVsCode
=
(
channel
,
data
)
=>
{
window
.
parent
.
postMessage
({
target
:
id
,
channel
,
data
},
'
*
'
);
};
window
.
addEventListener
(
'
message
'
,
(
e
)
=>
{
if
(
e
.
origin
===
'
TODO - Does this come from the inner iframe we created?
'
)
{
postMessageToVsCode
(
e
.
data
.
command
,
e
.
data
.
data
);
return
;
}
const
channel
=
e
.
data
.
channel
;
const
handler
=
handlers
[
channel
];
if
(
handler
)
{
handler
(
e
,
e
.
data
.
args
);
}
else
{
console
.
log
(
'
no handler for
'
,
e
);
}
});
createWebviewManager
({
origin
:
document
.
location
.
href
,
postMessage
:
(
channel
,
data
)
=>
{
postMessageToVsCode
(
channel
,
data
);
},
onMessage
:
(
channel
,
handler
)
=>
{
handlers
[
channel
]
=
handler
;
},
preProcessHtml
:
(
text
)
=>
{
return
text
.
replace
(
/
(?:[
"'
])
vscode-resource:
([^\s
'"
]
+
)(?:[
"'
])
/gi
,
'
/resource?path=$1
'
);
}
});
}());
</script>
</body>
</html>
src/vs/workbench/contrib/webview/browser/webviewElement.ts
浏览文件 @
cac27d27
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import
{
Emitter
}
from
'
vs/base/common/event
'
;
import
{
URI
}
from
'
vs/base/common/uri
'
;
...
...
@@ -14,70 +14,8 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import
{
Disposable
}
from
'
vs/base/common/lifecycle
'
;
import
{
areWebviewInputOptionsEqual
}
from
'
vs/workbench/contrib/webview/browser/webviewEditorService
'
;
import
{
addDisposableListener
,
addClass
}
from
'
vs/base/browser/dom
'
;
import
{
createServer
}
from
'
http
'
;
import
*
as
fs
from
'
fs
'
;
import
*
as
path
from
'
path
'
;
import
{
startsWith
}
from
'
vs/base/common/strings
'
;
import
{
getWebviewThemeData
}
from
'
vs/workbench/contrib/webview/common/themeing
'
;
import
{
IConfigurationService
}
from
'
vs/platform/configuration/common/configuration
'
;
import
{
getWebviewContentMimeType
}
from
'
vs/workbench/contrib/webview/common/mimeTypes
'
;
const
SERVER_RESOURCE_ROOT_PATH
=
'
/resource/
'
;
class
Server
{
public
static
make
(
id
:
string
,
fileService
:
IFileService
):
Promise
<
Server
>
{
let
address
=
''
;
return
new
Promise
<
Server
>
((
resolve
,
reject
)
=>
{
const
server
=
createServer
((
req
,
res
)
=>
{
if
(
req
.
url
===
'
/
'
)
{
res
.
writeHead
(
200
,
{
'
Content-Type
'
:
'
text/html
'
});
res
.
write
(
getHtml
(
id
,
address
));
res
.
end
();
return
;
}
if
(
req
.
url
===
'
/main.js
'
)
{
res
.
writeHead
(
200
,
{
'
Content-Type
'
:
'
text/html
'
});
res
.
write
(
fs
.
readFileSync
(
path
.
join
(
__dirname
.
replace
(
'
file:
'
,
''
),
'
pre
'
,
'
main.js
'
)));
res
.
end
();
return
;
}
if
(
req
.
url
&&
startsWith
(
req
.
url
,
SERVER_RESOURCE_ROOT_PATH
))
{
const
path
=
URI
.
file
(
req
.
url
.
replace
(
SERVER_RESOURCE_ROOT_PATH
,
'
/
'
));
res
.
writeHead
(
200
,
{
'
Content-Type
'
:
getWebviewContentMimeType
(
path
)
});
fileService
.
readFile
(
path
).
then
(
result
=>
{
res
.
write
(
result
.
value
.
buffer
);
}).
finally
(()
=>
{
res
.
end
();
});
return
;
}
res
.
writeHead
(
404
);
res
.
end
();
return
;
});
server
.
on
(
'
error
'
,
reject
);
const
l
=
server
.
listen
(()
=>
{
server
.
removeListener
(
'
error
'
,
reject
);
address
=
`http://localhost:
${
l
.
address
().
port
}
`
;
resolve
(
new
Server
(
server
,
l
.
address
().
port
));
});
});
}
private
constructor
(
public
readonly
server
:
import
(
'
http
'
).
Server
,
public
readonly
port
:
number
)
{
}
dispose
()
{
this
.
server
.
close
();
}
}
interface
WebviewContent
{
readonly
html
:
string
;
...
...
@@ -94,10 +32,9 @@ export class IFrameWebview extends Disposable implements Webview {
private
_focused
=
false
;
private
readonly
id
:
string
;
private
readonly
server
:
Promise
<
Server
>
;
constructor
(
private
readonly
_options
:
WebviewOptions
,
_options
:
WebviewOptions
,
contentOptions
:
WebviewContentOptions
,
@
IInstantiationService
instantiationService
:
IInstantiationService
,
@
IThemeService
themeService
:
IThemeService
,
...
...
@@ -118,16 +55,11 @@ export class IFrameWebview extends Disposable implements Webview {
this
.
element
=
document
.
createElement
(
'
iframe
'
);
this
.
element
.
sandbox
.
add
(
'
allow-scripts
'
);
this
.
element
.
sandbox
.
add
(
'
allow-same-origin
'
);
this
.
element
.
setAttribute
(
'
src
'
,
''
);
this
.
element
.
setAttribute
(
'
src
'
,
`/src/vs/workbench/contrib/webview/browser/pre/index.html?id=
${
this
.
id
}
`
);
this
.
element
.
style
.
border
=
'
none
'
;
this
.
element
.
style
.
width
=
'
100%
'
;
this
.
element
.
style
.
height
=
'
100%
'
;
this
.
server
=
Server
.
make
(
this
.
id
,
fileService
);
this
.
server
.
then
(
async
server
=>
{
this
.
element
.
setAttribute
(
'
src
'
,
`http://localhost:
${
server
.
port
}
`
);
});
this
.
_register
(
addDisposableListener
(
window
,
'
message
'
,
e
=>
{
if
(
!
e
||
!
e
.
data
||
e
.
data
.
target
!==
this
.
id
)
{
return
;
...
...
@@ -241,7 +173,7 @@ export class IFrameWebview extends Disposable implements Webview {
private
handleFocusChange
(
isFocused
:
boolean
):
void
{
this
.
_focused
=
isFocused
;
if
(
isF
ocused
)
{
if
(
this
.
_f
ocused
)
{
this
.
_onDidFocus
.
fire
();
}
}
...
...
@@ -332,112 +264,3 @@ export class IFrameWebview extends Disposable implements Webview {
}
}
function
getHtml
(
id
:
string
,
origin
:
string
):
any
{
return
`<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" content="default-src *; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Virtual Document</title>
</head>
<body>
<script src="/main.js"></script>
<script>
(function() {
const handlers = {};
const postMessageToVsCode = (channel, data) => {
window.parent.postMessage({ target: '
${
id
}
', channel, data }, '*');
};
window.addEventListener('message', (e) => {
if (e.origin === '
${
origin
}
') {
postMessageToVsCode(e.data.command, e.data.data);
return;
}
const channel = e.data.channel;
const handler = handlers[channel];
if (handler) {
handler(e, e.data.args);
} else {
console.log('no handler for ', e);
}
});
createWebviewManager({
origin: '
${
origin
}
',
postMessage: (channel, data) => {
postMessageToVsCode(channel, data);
},
onMessage: (channel, handler) => {
handlers[channel] = handler;
},
preProcessHtml: (text) => {
return text.replace(/vscode-resource:(?=\\S)/gi, '
${
SERVER_RESOURCE_ROOT_PATH
}
');
},
injectHtml: (newDocument) => {
return;
const defaultScript = newDocument.createElement('script');
defaultScript.textContent =
\`
(function(){
const regexp = new RegExp('^vscode-resource:/', 'g');
const observer = new MutationObserver(handleMutation);
observer.observe(document, { subtree: true, childList: true });
handleChildNodeMutation(document.head.querySelector('base'));
document.head.childNodes.forEach(handleChildNodeMutation);
if (document.body) {
document.body.childNodes.forEach(handleChildNodeMutation);
}
function handleMutation(records) {
for (const record of records) {
if (record.target.nodeName === 'HEAD' && record.type === 'childList') {
handleChildNodeMutation(document.head.querySelector('base'));
record.addedNodes.forEach(handleChildNodeMutation);
} else {
handleChildNodeMutation(record.target);
}
}
}
function handleChildNodeMutation(node) {
if (!node) {
return;
}
if (node.nodeName === 'LINK' || node.nodeName === 'BASE') {
handleStyleNode(node, 'href');
return;
}
if (node.nodeName === 'SCRIPT') {
handleStyleNode(node, 'src');
return;
}
}
function handleStyleNode(target, property) {
if (!target[property]) {
return;
}
const match = target[property].match(regexp);
if (!match) {
return;
}
target.setAttribute(property, target[property].replace(regexp, '
${
origin
}
'));
}
}())
\`
;
newDocument.head.prepend(defaultScript);
}
});
}());
</script>
</body>
</html>`
;
}
src/vs/workbench/contrib/webview/browser/webviewService.ts
浏览文件 @
cac27d27
...
...
@@ -3,13 +3,23 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import
{
I
WebviewService
,
Webview
,
WebviewContentOptions
,
WebviewOptions
}
from
'
vs/workbench/contrib/webview/common/webview
'
;
export
class
NullWebviewService
implements
IWebviewService
{
import
{
I
InstantiationService
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
IFrameWebview
as
WebviewElement
}
from
'
vs/workbench/contrib/webview/browser/webviewElement
'
;
import
{
IWebviewService
,
WebviewOptions
,
WebviewContentOptions
,
Webview
}
from
'
vs/workbench/contrib/webview/common/webview
'
;
export
class
WebviewService
implements
IWebviewService
{
_serviceBrand
:
any
;
createWebview
(
_options
:
WebviewOptions
,
_contentOptions
:
WebviewContentOptions
):
Webview
{
throw
new
Error
(
'
not supported
'
);
constructor
(
@
IInstantiationService
private
readonly
_instantiationService
:
IInstantiationService
,
)
{
}
createWebview
(
options
:
WebviewOptions
,
contentOptions
:
WebviewContentOptions
):
Webview
{
return
this
.
_instantiationService
.
createInstance
(
WebviewElement
,
options
,
contentOptions
);
}
}
}
\ No newline at end of file
src/vs/workbench/contrib/webview/electron-browser/webviewService.ts
浏览文件 @
cac27d27
...
...
@@ -4,8 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import
{
IInstantiationService
}
from
'
vs/platform/instantiation/common/instantiation
'
;
// import { WebviewElement } from 'vs/workbench/contrib/webview/electron-browser/webviewElement';
import
{
IFrameWebview
as
WebviewElement
}
from
'
vs/workbench/contrib/webview/browser/webviewElement
'
;
import
{
WebviewElement
}
from
'
vs/workbench/contrib/webview/electron-browser/webviewElement
'
;
import
{
IWebviewService
,
WebviewOptions
,
WebviewContentOptions
,
Webview
}
from
'
vs/workbench/contrib/webview/common/webview
'
;
export
class
WebviewService
implements
IWebviewService
{
...
...
@@ -19,10 +18,8 @@ export class WebviewService implements IWebviewService {
options
:
WebviewOptions
,
contentOptions
:
WebviewContentOptions
):
Webview
{
const
element
=
this
.
_instantiationService
.
createInstance
(
WebviewElement
,
return
this
.
_instantiationService
.
createInstance
(
WebviewElement
,
options
,
contentOptions
);
return
element
;
}
}
\ No newline at end of file
src/vs/workbench/workbench.web.main.ts
浏览文件 @
cac27d27
...
...
@@ -247,13 +247,12 @@ import 'vs/workbench/contrib/markers/browser/markers.contribution';
import
'
vs/workbench/contrib/url/common/url.contribution
'
;
// Webview
// import 'vs/workbench/contrib/webview/browser/webview.contribution';
// import 'vs/workbench/contrib/webview/electron-browser/webview.contribution';
import
'
vs/workbench/contrib/webview/browser/webview.contribution
'
;
import
{
IWebviewService
}
from
'
vs/workbench/contrib/webview/common/webview
'
;
import
{
Null
WebviewService
}
from
'
vs/workbench/contrib/webview/browser/webviewService
'
;
import
{
WebviewService
}
from
'
vs/workbench/contrib/webview/browser/webviewService
'
;
import
{
IWebviewEditorService
,
WebviewEditorService
}
from
'
vs/workbench/contrib/webview/browser/webviewEditorService
'
;
registerSingleton
(
IWebviewService
,
Null
WebviewService
,
true
);
registerSingleton
(
IWebviewService
,
WebviewService
,
true
);
registerSingleton
(
IWebviewEditorService
,
WebviewEditorService
,
true
);
// Extensions Management
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录