Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
掘金者说
vscode
提交
94125f91
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,发现更多精彩内容 >>
提交
94125f91
编写于
3月 21, 2018
作者:
J
Joao Moreno
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
url handlers
fixes #34404
上级
241f82af
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
104 addition
and
156 deletion
+104
-156
src/vs/code/electron-main/app.ts
src/vs/code/electron-main/app.ts
+10
-3
src/vs/code/electron-main/launch.ts
src/vs/code/electron-main/launch.ts
+36
-22
src/vs/code/electron-main/windows.ts
src/vs/code/electron-main/windows.ts
+2
-2
src/vs/platform/url/common/urlIpc.ts
src/vs/platform/url/common/urlIpc.ts
+34
-1
src/vs/platform/url/common/urlService.ts
src/vs/platform/url/common/urlService.ts
+9
-3
src/vs/platform/url/electron-main/electronUrlListener.ts
src/vs/platform/url/electron-main/electronUrlListener.ts
+2
-92
src/vs/platform/windows/electron-main/windows.ts
src/vs/platform/windows/electron-main/windows.ts
+1
-1
src/vs/platform/windows/electron-main/windowsService.ts
src/vs/platform/windows/electron-main/windowsService.ts
+3
-25
src/vs/workbench/electron-browser/main.ts
src/vs/workbench/electron-browser/main.ts
+7
-7
未找到文件。
src/vs/code/electron-main/app.ts
浏览文件 @
94125f91
...
...
@@ -29,7 +29,7 @@ import { IStateService } from 'vs/platform/state/common/state';
import
{
IEnvironmentService
}
from
'
vs/platform/environment/common/environment
'
;
import
{
IConfigurationService
}
from
'
vs/platform/configuration/common/configuration
'
;
import
{
IURLService
}
from
'
vs/platform/url/common/url
'
;
import
{
URLHandlerChannelClient
}
from
'
vs/platform/url/common/urlIpc
'
;
import
{
URLHandlerChannelClient
,
URLServiceChannel
}
from
'
vs/platform/url/common/urlIpc
'
;
import
{
ITelemetryService
}
from
'
vs/platform/telemetry/common/telemetry
'
;
import
{
NullTelemetryService
}
from
'
vs/platform/telemetry/common/telemetryUtils
'
;
import
{
ITelemetryAppenderChannel
,
TelemetryAppenderClient
}
from
'
vs/platform/telemetry/common/telemetryIpc
'
;
...
...
@@ -59,7 +59,7 @@ import { IssueChannel } from 'vs/platform/issue/common/issueIpc';
import
{
IssueService
}
from
'
vs/platform/issue/electron-main/issueService
'
;
import
{
LogLevelSetterChannel
}
from
'
vs/platform/log/common/logIpc
'
;
import
{
setUnexpectedErrorHandler
}
from
'
vs/base/common/errors
'
;
import
{
ElectronURLListener
}
from
'
vs/platform/url/electron-main/
urlService
'
;
import
{
ElectronURLListener
}
from
'
vs/platform/url/electron-main/
electronUrlListener
'
;
export
class
CodeApplication
{
...
...
@@ -369,6 +369,10 @@ export class CodeApplication {
this
.
electronIpcServer
.
registerChannel
(
'
windows
'
,
windowsChannel
);
this
.
sharedProcessClient
.
done
(
client
=>
client
.
registerChannel
(
'
windows
'
,
windowsChannel
));
const
urlService
=
accessor
.
get
(
IURLService
);
const
urlChannel
=
new
URLServiceChannel
(
urlService
);
this
.
electronIpcServer
.
registerChannel
(
'
url
'
,
urlChannel
);
// Log level management
const
logLevelChannel
=
new
LogLevelSetterChannel
(
accessor
.
get
(
ILogService
));
this
.
electronIpcServer
.
registerChannel
(
'
loglevel
'
,
logLevelChannel
);
...
...
@@ -381,13 +385,16 @@ export class CodeApplication {
this
.
windowsMainService
=
accessor
.
get
(
IWindowsMainService
);
// TODO@Joao: unfold this
const
args
=
this
.
environmentService
.
args
;
const
urlService
=
accessor
.
get
(
IURLService
);
// Create a URL handler which forwards to the last active window
const
activeWindowManager
=
new
ActiveWindowManager
(
windowsService
);
const
urlHandlerChannel
=
this
.
electronIpcServer
.
getChannel
(
'
urlHandler
'
,
{
route
:
()
=>
activeWindowManager
.
activeClientId
});
const
multiplexURLHandler
=
new
URLHandlerChannelClient
(
urlHandlerChannel
);
// Register the multiple URL handker
urlService
.
registerHandler
(
multiplexURLHandler
);
// Watch Electron URLs and forward them to the UrlService
const
urls
=
args
[
'
open-url
'
]
?
args
.
_urls
:
[];
const
urlListener
=
new
ElectronURLListener
(
urls
,
urlService
,
this
.
windowsMainService
);
this
.
toDispose
.
push
(
urlListener
);
...
...
src/vs/code/electron-main/launch.ts
浏览文件 @
94125f91
...
...
@@ -40,6 +40,24 @@ export interface IMainProcessInfo {
windows
:
IWindowInfo
[];
}
function
parseOpenUrl
(
args
:
ParsedArgs
):
URI
[]
{
if
(
args
[
'
open-url
'
]
&&
args
.
_urls
&&
args
.
_urls
.
length
>
0
)
{
// --open-url must contain -- followed by the url(s)
// process.argv is used over args._ as args._ are resolved to file paths at this point
return
args
.
_urls
.
map
(
url
=>
{
try
{
return
URI
.
parse
(
url
);
}
catch
(
err
)
{
return
null
;
}
})
.
filter
(
uri
=>
!!
uri
);
}
return
[];
}
export
interface
ILaunchService
{
_serviceBrand
:
any
;
start
(
args
:
ParsedArgs
,
userEnv
:
IProcessEnvironment
):
TPromise
<
void
>
;
...
...
@@ -119,8 +137,25 @@ export class LaunchService implements ILaunchService {
public
start
(
args
:
ParsedArgs
,
userEnv
:
IProcessEnvironment
):
TPromise
<
void
>
{
this
.
logService
.
trace
(
'
Received data from other instance:
'
,
args
,
userEnv
);
const
urlsToOpen
=
parseOpenUrl
(
args
);
// Check early for open-url which is handled in URL service
if
(
this
.
shouldOpenUrl
(
args
))
{
if
(
urlsToOpen
.
length
)
{
let
whenWindowReady
=
TPromise
.
as
<
any
>
(
null
);
// Create a window if there is none
if
(
this
.
windowsMainService
.
getWindowCount
()
===
0
)
{
const
window
=
this
.
windowsMainService
.
openNewWindow
(
OpenContext
.
DESKTOP
)[
0
];
whenWindowReady
=
window
.
ready
();
}
// Make sure a window is open, ready to receive the url event
whenWindowReady
.
then
(()
=>
{
for
(
const
url
of
urlsToOpen
)
{
this
.
urlService
.
open
(
url
);
}
});
return
TPromise
.
as
(
null
);
}
...
...
@@ -128,27 +163,6 @@ export class LaunchService implements ILaunchService {
return
this
.
startOpenWindow
(
args
,
userEnv
);
}
private
shouldOpenUrl
(
args
:
ParsedArgs
):
boolean
{
if
(
args
[
'
open-url
'
]
&&
args
.
_urls
&&
args
.
_urls
.
length
>
0
)
{
// --open-url must contain -- followed by the url(s)
// process.argv is used over args._ as args._ are resolved to file paths at this point
args
.
_urls
.
map
(
url
=>
{
try
{
return
URI
.
parse
(
url
);
}
catch
(
err
)
{
return
null
;
}
})
.
filter
(
uri
=>
!!
uri
)
.
forEach
(
uri
=>
this
.
urlService
.
open
(
uri
));
return
true
;
}
return
false
;
}
private
startOpenWindow
(
args
:
ParsedArgs
,
userEnv
:
IProcessEnvironment
):
TPromise
<
void
>
{
const
context
=
!!
userEnv
[
'
VSCODE_CLI
'
]
?
OpenContext
.
CLI
:
OpenContext
.
DESKTOP
;
let
usedWindows
:
ICodeWindow
[];
...
...
src/vs/code/electron-main/windows.ts
浏览文件 @
94125f91
...
...
@@ -1374,8 +1374,8 @@ export class WindowsManager implements IWindowsMainService {
return
getLastActiveWindow
(
WindowsManager
.
WINDOWS
);
}
public
openNewWindow
(
context
:
OpenContext
):
void
{
this
.
open
({
context
,
cli
:
this
.
environmentService
.
args
,
forceNewWindow
:
true
,
forceEmpty
:
true
});
public
openNewWindow
(
context
:
OpenContext
):
ICodeWindow
[]
{
return
this
.
open
({
context
,
cli
:
this
.
environmentService
.
args
,
forceNewWindow
:
true
,
forceEmpty
:
true
});
}
public
waitForWindowCloseOrLoad
(
windowId
:
number
):
TPromise
<
void
>
{
...
...
src/vs/platform/url/common/urlIpc.ts
浏览文件 @
94125f91
...
...
@@ -7,8 +7,41 @@
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
{
IChannel
}
from
'
vs/base/parts/ipc/common/ipc
'
;
import
{
IURLHandler
}
from
'
./url
'
;
import
{
IURLHandler
,
IURLService
}
from
'
./url
'
;
import
URI
from
'
vs/base/common/uri
'
;
import
{
IDisposable
}
from
'
vs/base/common/lifecycle
'
;
export
interface
IURLServiceChannel
extends
IChannel
{
call
(
command
:
'
open
'
,
url
:
string
):
TPromise
<
boolean
>
;
call
(
command
:
string
,
arg
?:
any
):
TPromise
<
any
>
;
}
export
class
URLServiceChannel
implements
IURLServiceChannel
{
constructor
(
private
service
:
IURLService
)
{
}
call
(
command
:
string
,
arg
?:
any
):
TPromise
<
any
>
{
switch
(
command
)
{
case
'
open
'
:
return
this
.
service
.
open
(
URI
.
revive
(
arg
));
}
return
undefined
;
}
}
export
class
URLServiceChannelClient
implements
IURLService
{
_serviceBrand
:
any
;
constructor
(
private
channel
:
IChannel
)
{
}
open
(
url
:
URI
):
TPromise
<
boolean
,
any
>
{
return
this
.
channel
.
call
(
'
open
'
,
url
.
toJSON
());
}
registerHandler
(
handler
:
IURLHandler
):
IDisposable
{
throw
new
Error
(
'
Not implemented.
'
);
}
}
export
interface
IURLHandlerChannel
extends
IChannel
{
call
(
command
:
'
handleURL
'
,
arg
:
any
):
TPromise
<
boolean
>
;
...
...
src/vs/platform/url/common/urlService.ts
浏览文件 @
94125f91
...
...
@@ -38,11 +38,17 @@ export class URLService implements IURLService {
}
}
export
class
ForwardingURLHandler
implements
IURLHandler
{
export
class
RelayURLService
extends
URLService
implements
IURLHandler
{
constructor
(@
IURLService
private
urlService
:
IURLService
)
{
}
constructor
(
private
urlService
:
IURLService
)
{
super
();
}
handleURL
(
uri
:
URI
):
TPromise
<
boolean
>
{
async
open
(
uri
:
URI
):
TPromise
<
boolean
>
{
return
this
.
urlService
.
open
(
uri
);
}
handleURL
(
uri
:
URI
):
TPromise
<
boolean
>
{
return
super
.
open
(
uri
);
}
}
\ No newline at end of file
src/vs/platform/url/electron-main/
urlService
.ts
→
src/vs/platform/url/electron-main/
electronUrlListener
.ts
浏览文件 @
94125f91
...
...
@@ -6,14 +6,11 @@
'
use strict
'
;
import
{
mapEvent
,
fromNodeEventEmitter
,
filterEvent
}
from
'
vs/base/common/event
'
;
import
{
IURLService
,
IURLHandler
}
from
'
vs/platform/url/common/url
'
;
import
{
IURLService
}
from
'
vs/platform/url/common/url
'
;
import
product
from
'
vs/platform/node/product
'
;
import
{
app
}
from
'
electron
'
;
import
URI
from
'
vs/base/common/uri
'
;
import
{
ILogService
}
from
'
vs/platform/log/common/log
'
;
import
{
IDisposable
,
dispose
,
toDisposable
}
from
'
vs/base/common/lifecycle
'
;
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
{
Limiter
}
from
'
vs/base/common/async
'
;
import
{
IDisposable
,
dispose
}
from
'
vs/base/common/lifecycle
'
;
import
{
IWindowsMainService
}
from
'
vs/platform/windows/electron-main/windows
'
;
import
{
ReadyState
}
from
'
vs/platform/windows/common/windows
'
;
...
...
@@ -25,93 +22,6 @@ function uriFromRawUrl(url: string): URI | null {
}
}
export
class
URLService
implements
IURLService
{
_serviceBrand
:
any
;
private
buffer
:
URI
[];
private
handlers
:
IURLHandler
[]
=
[];
private
handlerLimiter
=
new
Limiter
<
void
>
(
1
);
private
disposables
:
IDisposable
[]
=
[];
constructor
(
initial
:
string
|
string
[],
@
ILogService
private
logService
:
ILogService
)
{
const
globalBuffer
=
(
global
.
getOpenUrls
()
||
[])
as
string
[];
const
rawBuffer
=
[
...(
typeof
initial
===
'
string
'
?
[
initial
]
:
initial
),
...
globalBuffer
];
this
.
buffer
=
rawBuffer
.
map
(
uriFromRawUrl
).
filter
(
uri
=>
!!
uri
);
app
.
setAsDefaultProtocolClient
(
product
.
urlProtocol
,
process
.
execPath
,
[
'
--open-url
'
,
'
--
'
]);
const
onOpenElectronUrl
=
mapEvent
(
fromNodeEventEmitter
(
app
,
'
open-url
'
,
(
event
:
Electron
.
Event
,
url
:
string
)
=>
({
event
,
url
})),
({
event
,
url
})
=>
{
// always prevent default and return the url as string
event
.
preventDefault
();
return
url
;
});
const
onOpenUrl
=
filterEvent
(
mapEvent
(
onOpenElectronUrl
,
uriFromRawUrl
),
uri
=>
!!
uri
);
onOpenUrl
(
this
.
openURI
,
this
,
this
.
disposables
);
}
open
(
uri
:
URI
):
TPromise
<
boolean
>
{
// const uri = uriFromRawUrl(url);
// if (!uri) {
// return ;
// }
return
this
.
openURI
(
uri
);
}
private
async
openURI
(
uri
:
URI
,
handlers
=
this
.
handlers
):
TPromise
<
boolean
>
{
this
.
logService
.
trace
(
'
urlService#handleURI
'
,
uri
.
toString
());
for
(
const
handler
of
handlers
)
{
if
(
await
handler
.
handleURL
(
uri
))
{
return
true
;
}
}
return
false
;
}
private
async
flushBuffer
(
handler
:
IURLHandler
):
TPromise
<
void
>
{
const
buffer
=
[...
this
.
buffer
];
for
(
const
uri
of
buffer
)
{
if
(
await
handler
.
handleURL
(
uri
))
{
this
.
buffer
.
splice
(
this
.
buffer
.
indexOf
(
uri
,
1
));
}
}
}
registerHandler
(
handler
:
IURLHandler
):
IDisposable
{
this
.
handlers
.
push
(
handler
);
this
.
handlerLimiter
.
queue
(()
=>
this
.
flushBuffer
(
handler
));
return
toDisposable
(()
=>
{
const
index
=
this
.
handlers
.
indexOf
(
handler
);
if
(
index
===
-
1
)
{
return
;
}
this
.
handlers
.
splice
(
index
,
1
);
});
}
dispose
():
void
{
this
.
disposables
=
dispose
(
this
.
disposables
);
}
}
export
class
ElectronURLListener
{
private
buffer
:
URI
[]
=
[];
...
...
src/vs/platform/windows/electron-main/windows.ts
浏览文件 @
94125f91
...
...
@@ -107,7 +107,7 @@ export interface IWindowsMainService {
focusLastActive
(
cli
:
ParsedArgs
,
context
:
OpenContext
):
ICodeWindow
;
getLastActiveWindow
():
ICodeWindow
;
waitForWindowCloseOrLoad
(
windowId
:
number
):
TPromise
<
void
>
;
openNewWindow
(
context
:
OpenContext
):
void
;
openNewWindow
(
context
:
OpenContext
):
ICodeWindow
[]
;
sendToFocused
(
channel
:
string
,
...
args
:
any
[]):
void
;
sendToAll
(
channel
:
string
,
payload
:
any
,
windowIdsToIgnore
?:
number
[]):
void
;
getFocusedWindow
():
ICodeWindow
;
...
...
src/vs/platform/windows/electron-main/windowsService.ts
浏览文件 @
94125f91
...
...
@@ -489,40 +489,18 @@ export class WindowsService implements IWindowsService, IURLHandler, IDisposable
async
handleURL
(
uri
:
URI
):
TPromise
<
boolean
>
{
// Catch file URLs
if
(
uri
.
authority
===
Schemas
.
file
&&
!!
uri
.
path
)
{
this
.
openFileForURI
(
URI
.
file
(
uri
.
fsPath
));
return
true
;
}
// Catch extension URLs when there are no windows open
if
(
uri
=>
/^extension/
.
test
(
uri
.
path
)
&&
this
.
windowsMainService
.
getWindowCount
()
===
0
)
{
this
.
openExtensionForURI
(
uri
);
return
true
;
return
this
.
openFileForURI
(
URI
.
file
(
uri
.
fsPath
));
}
return
false
;
}
private
openFileForURI
(
uri
:
URI
):
TPromise
<
void
>
{
private
async
openFileForURI
(
uri
:
URI
):
TPromise
<
boolean
>
{
const
cli
=
assign
(
Object
.
create
(
null
),
this
.
environmentService
.
args
,
{
goto
:
true
});
const
pathsToOpen
=
[
uri
.
fsPath
];
this
.
windowsMainService
.
open
({
context
:
OpenContext
.
API
,
cli
,
pathsToOpen
});
return
TPromise
.
as
(
null
);
}
/**
* This should only fire whenever an extension URL is open
* and there are no windows to handle it.
*/
private
async
openExtensionForURI
(
uri
:
URI
):
TPromise
<
void
>
{
const
cli
=
assign
(
Object
.
create
(
null
),
this
.
environmentService
.
args
);
const
window
=
await
this
.
windowsMainService
.
open
({
context
:
OpenContext
.
API
,
cli
})[
0
];
if
(
!
window
)
{
return
;
}
window
.
win
.
show
();
return
true
;
}
dispose
():
void
{
...
...
src/vs/workbench/electron-browser/main.ts
浏览文件 @
94125f91
...
...
@@ -36,18 +36,17 @@ import { Client as ElectronIPCClient } from 'vs/base/parts/ipc/electron-browser/
import
{
webFrame
}
from
'
electron
'
;
import
{
UpdateChannelClient
}
from
'
vs/platform/update/common/updateIpc
'
;
import
{
IUpdateService
}
from
'
vs/platform/update/common/update
'
;
import
{
URLHandlerChannel
}
from
'
vs/platform/url/common/urlIpc
'
;
import
{
URLHandlerChannel
,
URLServiceChannelClient
}
from
'
vs/platform/url/common/urlIpc
'
;
import
{
IURLService
}
from
'
vs/platform/url/common/url
'
;
import
{
WorkspacesChannelClient
}
from
'
vs/platform/workspaces/common/workspacesIpc
'
;
import
{
IWorkspacesService
}
from
'
vs/platform/workspaces/common/workspaces
'
;
import
{
createSpdLogService
}
from
'
vs/platform/log/node/spdlogService
'
;
import
*
as
fs
from
'
fs
'
;
import
{
ConsoleLogService
,
MultiplexLogService
,
ILogService
}
from
'
vs/platform/log/common/log
'
;
import
{
IssueChannelClient
}
from
'
vs/platform/issue/common/issueIpc
'
;
import
{
IIssueService
}
from
'
vs/platform/issue/common/issue
'
;
import
{
LogLevelSetterChannelClient
,
FollowerLogService
}
from
'
vs/platform/log/common/logIpc
'
;
import
{
URLService
,
ForwardingURLHandler
}
from
'
vs/platform/url/common/urlService
'
;
import
{
RelayURLService
}
from
'
vs/platform/url/common/urlService
'
;
gracefulFs
.
gracefulify
(
fs
);
// enable gracefulFs
...
...
@@ -217,11 +216,12 @@ function createMainProcessServices(mainProcessClient: ElectronIPCClient, configu
const
updateChannel
=
mainProcessClient
.
getChannel
(
'
update
'
);
serviceCollection
.
set
(
IUpdateService
,
new
SyncDescriptor
(
UpdateChannelClient
,
updateChannel
));
const
localUrlService
=
new
URLService
();
serviceCollection
.
set
(
IURLService
,
localUrlService
);
const
urlChannel
=
mainProcessClient
.
getChannel
(
'
url
'
);
const
mainUrlService
=
new
URLServiceChannelClient
(
urlChannel
);
const
urlService
=
new
RelayURLService
(
mainUrlService
);
serviceCollection
.
set
(
IURLService
,
urlService
);
const
urlHandler
=
new
ForwardingURLHandler
(
localUrlService
);
const
urlHandlerChannel
=
new
URLHandlerChannel
(
urlHandler
);
const
urlHandlerChannel
=
new
URLHandlerChannel
(
urlService
);
mainProcessClient
.
registerChannel
(
'
urlHandler
'
,
urlHandlerChannel
);
const
issueChannel
=
mainProcessClient
.
getChannel
(
'
issue
'
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录