Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
掘金者说
vscode
提交
1ac7165c
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,发现更多精彩内容 >>
提交
1ac7165c
编写于
6月 17, 2019
作者:
M
Matt Bierner
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Handle multiple clients in the webview service worker
上级
6cfe053d
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
93 addition
and
25 deletion
+93
-25
src/vs/workbench/contrib/webview/browser/pre/main.js
src/vs/workbench/contrib/webview/browser/pre/main.js
+3
-3
src/vs/workbench/contrib/webview/browser/pre/service-worker.js
...s/workbench/contrib/webview/browser/pre/service-worker.js
+90
-22
未找到文件。
src/vs/workbench/contrib/webview/browser/pre/main.js
浏览文件 @
1ac7165c
...
...
@@ -123,8 +123,6 @@
navigator
.
serviceWorker
.
register
(
'
service-worker.js
'
);
navigator
.
serviceWorker
.
ready
.
then
(
registration
=>
{
registration
.
active
.
postMessage
(
'
ping
'
);
host
.
onMessage
(
'
loaded-resource
'
,
event
=>
{
registration
.
active
.
postMessage
({
channel
:
'
loaded-resource
'
,
data
:
event
.
data
.
args
});
});
...
...
@@ -232,6 +230,8 @@
};
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
const
ID
=
document
.
location
.
search
.
match
(
/
\b
id=
([\w
-
]
+
)
/
)[
1
];
if
(
!
document
.
body
)
{
return
;
}
...
...
@@ -363,7 +363,7 @@
// seeing the service worker applying properly.
// Fake load an empty on the correct origin and then write real html
// into it to get around this.
newFrame
.
src
=
'
/fake.html
'
;
newFrame
.
src
=
`/fake.html?id=
${
ID
}
`
;
}
newFrame
.
style
.
cssText
=
'
display: block; margin: 0; overflow: hidden; position: absolute; width: 100%; height: 100%; visibility: hidden
'
;
document
.
body
.
appendChild
(
newFrame
);
...
...
src/vs/workbench/contrib/webview/browser/pre/service-worker.js
浏览文件 @
1ac7165c
...
...
@@ -2,15 +2,72 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// Listen for messages from clients.
const
resolvedPaths
=
new
Map
();
/**
* Root path for resources
*/
const
resourceRoot
=
'
/vscode-resource
'
;
/**
* @typedef {{resolve: () => void, promise: Promise<Response> }} ResourcePathEntry
*/
/**
* Map of requested paths to responses.
*/
const
resourceRequestManager
=
new
class
ResourceRequestManager
{
constructor
()
{
/** @type {Map<string, ResourcePathEntry>} */
this
.
map
=
new
Map
();
}
/**
* @param {string} webviewId
* @param {string} path
* @return {ResourcePathEntry | undefined}
*/
get
(
webviewId
,
path
)
{
return
this
.
map
.
get
(
this
.
_key
(
webviewId
,
path
));
}
/**
* @param {string} webviewId
* @param {string} path
* @return {boolean}
*/
has
(
webviewId
,
path
)
{
return
this
.
map
.
has
(
this
.
_key
(
webviewId
,
path
));
}
/**
* @param {string} webviewId
* @param {string} path
* @param {ResourcePathEntry} entry
*/
set
(
webviewId
,
path
,
entry
)
{
this
.
map
.
set
(
this
.
_key
(
webviewId
,
path
),
entry
);
}
/**
* @param {string} webviewId
* @param {string} path
* @return {string}
*/
_key
(
webviewId
,
path
)
{
return
`
${
webviewId
}
@@@
${
path
}
`
;
}
}();
const
notFoundResponse
=
new
Response
(
'
Not Found
'
,
{
status
:
404
,
});
self
.
addEventListener
(
'
message
'
,
(
event
)
=>
{
switch
(
event
.
data
.
channel
)
{
case
'
loaded-resource
'
:
{
const
webviewId
=
getWebviewIdForClient
(
event
.
source
);
const
data
=
event
.
data
.
data
;
const
target
=
reso
lvedPaths
.
get
(
data
.
path
);
const
target
=
reso
urceRequestManager
.
get
(
webviewId
,
data
.
path
);
if
(
!
target
)
{
console
.
log
(
'
Loaded unknown resource
'
,
data
.
path
);
return
;
...
...
@@ -20,19 +77,16 @@ self.addEventListener('message', (event) => {
target
.
resolve
(
new
Response
(
data
.
data
,
{
status
:
200
,
headers
:
{
'
Content-Type
'
:
data
.
mime
},
})
.
clone
()
);
}));
}
else
{
target
.
resolve
(
new
Response
(
'
Not Found
'
,
{
status
:
404
,
}).
clone
());
target
.
resolve
(
notFoundResponse
.
clone
());
}
return
;
}
return
;
}
});
var
clients
;
const
resourceRoot
=
'
/vscode-resource
'
;
console
.
log
(
'
Unknown message
'
)
;
})
;
self
.
addEventListener
(
'
fetch
'
,
(
event
)
=>
{
const
requestUrl
=
new
URL
(
event
.
request
.
url
);
...
...
@@ -42,36 +96,44 @@ self.addEventListener('fetch', (event) => {
}
event
.
respondWith
((
async
()
=>
{
const
client
=
await
self
.
clients
.
get
(
event
.
clientId
);
if
(
!
client
)
{
console
.
log
(
'
Could not find inner client for request
'
);
return
notFoundResponse
.
clone
();
}
const
webviewId
=
getWebviewIdForClient
(
client
);
const
resourcePath
=
requestUrl
.
pathname
.
replace
(
resourceRoot
,
''
);
const
existing
=
reso
lvedPaths
.
get
(
resourcePath
);
const
existing
=
reso
urceRequestManager
.
get
(
webviewId
,
resourcePath
);
if
(
existing
)
{
return
existing
.
promise
.
then
(
r
=>
r
.
clone
());
}
const
allClients
=
await
clients
.
matchAll
({
includeUncontrolled
:
true
});
const
allClients
=
await
self
.
clients
.
matchAll
({
includeUncontrolled
:
true
});
if
(
resourceRequestManager
.
has
(
webviewId
,
resourcePath
))
{
// Someone else added it in the meantime
return
resourceRequestManager
.
get
(
resourceRequestManager
).
promise
.
then
(
r
=>
r
.
clone
());
}
// Find parent iframe
for
(
const
client
of
allClients
)
{
const
clientUrl
=
new
URL
(
client
.
url
);
if
(
clientUrl
.
pathname
===
'
/
'
)
{
if
(
clientUrl
.
pathname
===
'
/
'
&&
clientUrl
.
search
.
match
(
new
RegExp
(
'
\\
bid=
'
+
webviewId
))
)
{
client
.
postMessage
({
channel
:
'
load-resource
'
,
path
:
resourcePath
});
if
(
resolvedPaths
.
has
(
resourcePath
))
{
// Someone else added it in the mean time
return
resolvedPaths
.
get
(
resolvedPaths
).
promise
;
}
let
resolve
;
const
promise
=
new
Promise
(
r
=>
resolve
=
r
);
reso
lvedPaths
.
set
(
resourcePath
,
{
resolve
,
promise
});
reso
urceRequestManager
.
set
(
webviewId
,
resourcePath
,
{
resolve
,
promise
});
return
promise
.
then
(
r
=>
r
.
clone
());
}
}
console
.
log
(
'
Could not find parent client for request
'
);
return
notFoundResponse
.
clone
();
})());
});
...
...
@@ -82,3 +144,9 @@ self.addEventListener('install', (event) => {
self
.
addEventListener
(
'
activate
'
,
(
event
)
=>
{
event
.
waitUntil
(
self
.
clients
.
claim
());
// Become available to all pages
});
function
getWebviewIdForClient
(
client
)
{
const
requesterClientUrl
=
new
URL
(
client
.
url
);
return
requesterClientUrl
.
search
.
match
(
/
\b
id=
([
a-z0-9-
]
+
)
/i
)[
1
];
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录