Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
9736b536
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,发现更多精彩内容 >>
提交
9736b536
编写于
3月 11, 2016
作者:
J
João Moreno
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #3971 from joaomoreno/extensions
Extension status bar improvements & polish
上级
eac772f3
8c898984
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
257 addition
and
107 deletion
+257
-107
src/vs/base/common/errors.ts
src/vs/base/common/errors.ts
+5
-0
src/vs/workbench/parts/extensions/common/extensions.ts
src/vs/workbench/parts/extensions/common/extensions.ts
+5
-2
src/vs/workbench/parts/extensions/common/extensionsUtil.ts
src/vs/workbench/parts/extensions/common/extensionsUtil.ts
+35
-0
src/vs/workbench/parts/extensions/common/vsoGalleryService.ts
...vs/workbench/parts/extensions/common/vsoGalleryService.ts
+0
-0
src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts
...ts/extensions/electron-browser/extensions.contribution.ts
+3
-2
src/vs/workbench/parts/extensions/electron-browser/extensionsQuickOpen.ts
.../parts/extensions/electron-browser/extensionsQuickOpen.ts
+7
-17
src/vs/workbench/parts/extensions/electron-browser/extensionsWidgets.ts
...ch/parts/extensions/electron-browser/extensionsWidgets.ts
+140
-54
src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension.ts
...tensions/electron-browser/extensionsWorkbenchExtension.ts
+5
-6
src/vs/workbench/parts/extensions/electron-browser/media/extensions.css
...ch/parts/extensions/electron-browser/media/extensions.css
+48
-17
src/vs/workbench/parts/extensions/node/extensionsService.ts
src/vs/workbench/parts/extensions/node/extensionsService.ts
+9
-9
未找到文件。
src/vs/base/common/errors.ts
浏览文件 @
9736b536
...
...
@@ -13,6 +13,7 @@ import strings = require('vs/base/common/strings');
import
{
IAction
}
from
'
vs/base/common/actions
'
;
import
{
IXHRResponse
}
from
'
vs/base/common/http
'
;
import
Severity
from
'
vs/base/common/severity
'
;
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
export
interface
ErrorListenerCallback
{
(
error
:
any
):
void
;
...
...
@@ -88,6 +89,10 @@ export function onUnexpectedError(e: any): void {
}
}
export
function
onUnexpectedPromiseError
<
T
>
(
promise
:
TPromise
<
T
>
):
TPromise
<
T
>
{
return
promise
.
then
<
T
>
(
null
,
onUnexpectedError
);
}
export
interface
IConnectionErrorData
{
status
:
number
;
statusText
?:
string
;
...
...
src/vs/workbench/parts/extensions/common/extensions.ts
浏览文件 @
9736b536
...
...
@@ -5,6 +5,7 @@
'
use strict
'
;
import
nls
=
require
(
'
vs/nls
'
);
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
Event
from
'
vs/base/common/event
'
;
import
{
createDecorator
,
ServiceIdentifier
}
from
'
vs/platform/instantiation/common/instantiation
'
;
...
...
@@ -52,7 +53,7 @@ export interface IGalleryService {
export
interface
IExtensionsService
{
serviceId
:
ServiceIdentifier
<
any
>
;
onInstallExtension
:
Event
<
IExtensionManifest
>
;
onDidInstallExtension
:
Event
<
IExtension
>
;
onDidInstallExtension
:
Event
<
{
extension
:
IExtension
;
error
?:
Error
;
}
>
;
onUninstallExtension
:
Event
<
IExtension
>
;
onDidUninstallExtension
:
Event
<
IExtension
>
;
...
...
@@ -67,4 +68,6 @@ export var IExtensionTipsService = createDecorator<IExtensionTipsService>('exten
export
interface
IExtensionTipsService
{
serviceId
:
ServiceIdentifier
<
any
>
;
getRecommendations
():
TPromise
<
IExtension
[]
>
;
}
\ No newline at end of file
}
export
var
commandCategory
=
nls
.
localize
(
'
extensionsCategory
'
,
"
Extensions
"
);
\ No newline at end of file
src/vs/workbench/parts/extensions/common/extensionsUtil.ts
0 → 100644
浏览文件 @
9736b536
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import
{
ServicesAccessor
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
IExtension
,
IExtensionsService
,
IGalleryService
}
from
'
vs/workbench/parts/extensions/common/extensions
'
;
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
*
as
semver
from
'
semver
'
;
'
use strict
'
;
export
function
extensionEquals
(
one
:
IExtension
,
other
:
IExtension
):
boolean
{
return
one
.
publisher
===
other
.
publisher
&&
one
.
name
===
other
.
name
;
}
export
function
getOutdatedExtensions
(
accessor
:
ServicesAccessor
):
TPromise
<
IExtension
[]
>
{
const
extensionsService
=
accessor
.
get
(
IExtensionsService
);
const
galleryService
=
accessor
.
get
(
IGalleryService
);
if
(
!
galleryService
.
isEnabled
())
{
return
TPromise
.
as
([]);
}
return
TPromise
.
join
<
any
>
([
galleryService
.
query
(),
extensionsService
.
getInstalled
()])
.
then
(
result
=>
{
const
available
=
result
[
0
];
const
installed
=
result
[
1
];
return
available
.
filter
(
extension
=>
{
const
local
=
installed
.
filter
(
local
=>
extensionEquals
(
local
,
extension
))[
0
];
return
local
&&
semver
.
lt
(
local
.
version
,
extension
.
version
);
});
});
}
\ No newline at end of file
src/vs/workbench/parts/extensions/
node
/vsoGalleryService.ts
→
src/vs/workbench/parts/extensions/
common
/vsoGalleryService.ts
浏览文件 @
9736b536
文件已移动
src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts
浏览文件 @
9736b536
...
...
@@ -3,12 +3,13 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import
'
vs/css!./media/extensions
'
;
import
platform
=
require
(
'
vs/platform/platform
'
);
import
{
registerSingleton
}
from
'
vs/platform/instantiation/common/extensions
'
;
import
statusbar
=
require
(
'
vs/workbench/browser/parts/statusbar/statusbar
'
);
import
{
ExtensionsStatusbarItem
}
from
'
vs/workbench/parts/extensions/electron-browser/extensionsWidgets
'
;
import
{
IGalleryService
}
from
'
vs/workbench/parts/extensions/common/extensions
'
;
import
{
GalleryService
}
from
'
vs/workbench/parts/extensions/
node
/vsoGalleryService
'
;
import
{
GalleryService
}
from
'
vs/workbench/parts/extensions/
common
/vsoGalleryService
'
;
import
{
IWorkbenchContributionsRegistry
,
Extensions
as
WorkbenchExtensions
}
from
'
vs/workbench/common/contributions
'
;
import
{
ExtensionsWorkbenchExtension
}
from
'
vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension
'
;
...
...
@@ -24,5 +25,5 @@ registerSingleton(IGalleryService, GalleryService);
(
<
statusbar
.
IStatusbarRegistry
>
platform
.
Registry
.
as
(
statusbar
.
Extensions
.
Statusbar
)).
registerStatusbarItem
(
new
statusbar
.
StatusbarItemDescriptor
(
ExtensionsStatusbarItem
,
statusbar
.
StatusbarAlignment
.
LEFT
,
10
/* Low Priority */
10
000
));
src/vs/workbench/parts/extensions/electron-browser/extensionsQuickOpen.ts
浏览文件 @
9736b536
...
...
@@ -3,8 +3,6 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import
'
vs/css!./media/extensions
'
;
import
nls
=
require
(
'
vs/nls
'
);
import
{
IDisposable
,
disposeAll
}
from
'
vs/base/common/lifecycle
'
;
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
...
...
@@ -24,9 +22,9 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import
{
IWorkspaceContextService
}
from
'
vs/workbench/services/workspace/common/contextService
'
;
import
{
HighlightedLabel
}
from
'
vs/base/browser/ui/highlightedlabel/highlightedLabel
'
;
import
{
Action
}
from
'
vs/base/common/actions
'
;
import
*
as
semver
from
'
semver
'
;
import
{
ActionBar
}
from
'
vs/base/browser/ui/actionbar/actionbar
'
;
import
{
shell
}
from
'
electron
'
;
import
{
extensionEquals
,
getOutdatedExtensions
}
from
'
vs/workbench/parts/extensions/common/extensionsUtil
'
;
const
$
=
dom
.
emmet
;
...
...
@@ -76,10 +74,6 @@ function getHighlights(input: string, extension: IExtension): IHighlights {
return
{
id
,
name
,
displayName
,
description
};
}
function
extensionEquals
(
one
:
IExtension
,
other
:
IExtension
):
boolean
{
return
one
.
publisher
===
other
.
publisher
&&
one
.
name
===
other
.
name
;
}
function
extensionEntryCompare
(
one
:
IExtensionEntry
,
other
:
IExtensionEntry
):
number
{
const
oneInstallCount
=
one
.
extension
.
galleryInformation
?
one
.
extension
.
galleryInformation
.
installCount
:
0
;
const
otherInstallCount
=
other
.
extension
.
galleryInformation
?
other
.
extension
.
galleryInformation
.
installCount
:
0
;
...
...
@@ -263,7 +257,7 @@ class Renderer implements IRenderer<IExtensionEntry> {
updateActions
();
data
.
disposables
=
disposeAll
(
data
.
disposables
);
data
.
disposables
.
push
(
this
.
extensionsService
.
onDidInstallExtension
(
e
=>
onExtensionStateChange
(
e
,
ExtensionState
.
Installed
)));
data
.
disposables
.
push
(
this
.
extensionsService
.
onDidInstallExtension
(
e
=>
onExtensionStateChange
(
e
.
extension
,
ExtensionState
.
Installed
)));
data
.
disposables
.
push
(
this
.
extensionsService
.
onDidUninstallExtension
(
e
=>
onExtensionStateChange
(
e
,
ExtensionState
.
Uninstalled
)));
data
.
displayName
.
set
(
extension
.
displayName
,
entry
.
highlights
.
displayName
);
...
...
@@ -480,8 +474,7 @@ class OutdatedExtensionsModel implements IModel<IExtensionEntry> {
public
entries
:
IExtensionEntry
[];
constructor
(
private
galleryExtensions
:
IExtension
[],
private
localExtensions
:
IExtension
[],
private
outdatedExtensions
:
IExtension
[],
@
IInstantiationService
instantiationService
:
IInstantiationService
)
{
this
.
renderer
=
instantiationService
.
createInstance
(
Renderer
);
...
...
@@ -490,12 +483,9 @@ class OutdatedExtensionsModel implements IModel<IExtensionEntry> {
}
public
set
input
(
input
:
string
)
{
this
.
entries
=
this
.
gallery
Extensions
this
.
entries
=
this
.
outdated
Extensions
.
map
(
extension
=>
({
extension
,
highlights
:
getHighlights
(
input
.
trim
(),
extension
)
}))
.
filter
(({
extension
,
highlights
})
=>
{
const
local
=
this
.
localExtensions
.
filter
(
local
=>
extensionEquals
(
local
,
extension
))[
0
];
return
local
&&
semver
.
lt
(
local
.
version
,
extension
.
version
)
&&
!!
highlights
;
})
.
filter
(({
highlights
})
=>
!!
highlights
)
.
map
(({
extension
,
highlights
}:
{
extension
:
IExtension
,
highlights
:
IHighlights
})
=>
({
extension
,
highlights
,
...
...
@@ -525,8 +515,8 @@ export class OutdatedExtensionsHandler extends QuickOpenHandler {
getResults
(
input
:
string
):
TPromise
<
IModel
<
IExtensionEntry
>>
{
if
(
!
this
.
modelPromise
)
{
this
.
telemetryService
.
publicLog
(
'
extensionGallery:open
'
);
this
.
modelPromise
=
TPromise
.
join
<
any
>
([
this
.
galleryService
.
query
(),
this
.
extensionsService
.
getInstalled
()]
)
.
then
(
result
=>
this
.
instantiationService
.
createInstance
(
OutdatedExtensionsModel
,
result
[
0
],
result
[
1
]
));
this
.
modelPromise
=
this
.
instantiationService
.
invokeFunction
(
getOutdatedExtensions
)
.
then
(
outdated
=>
this
.
instantiationService
.
createInstance
(
OutdatedExtensionsModel
,
outdated
));
}
return
this
.
modelPromise
.
then
(
model
=>
{
...
...
src/vs/workbench/parts/extensions/electron-browser/extensionsWidgets.ts
浏览文件 @
9736b536
...
...
@@ -5,80 +5,166 @@
import
nls
=
require
(
'
vs/nls
'
);
import
Severity
from
'
vs/base/common/severity
'
;
import
dom
=
require
(
'
vs/base/browser/dom
'
);
import
lifecycle
=
require
(
'
vs/base/common/lifecycle
'
);
import
{
onUnexpectedError
}
from
'
vs/base/common/errors
'
;
import
{
ThrottledDelayer
}
from
'
vs/base/common/async
'
;
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
{
emmet
as
$
,
append
,
toggleClass
}
from
'
vs/base/browser/dom
'
;
import
{
IDisposable
,
combinedDispose
}
from
'
vs/base/common/lifecycle
'
;
import
{
onUnexpectedPromiseError
}
from
'
vs/base/common/errors
'
;
import
{
assign
}
from
'
vs/base/common/objects
'
;
import
{
Action
}
from
'
vs/base/common/actions
'
;
import
statusbar
=
require
(
'
vs/workbench/browser/parts/statusbar/statusbar
'
);
import
{
IExtensionService
,
I
ExtensionsStatus
}
from
'
vs/platform/extensions/common/extensions
'
;
import
{
IExtensionService
,
I
Message
}
from
'
vs/platform/extensions/common/extensions
'
;
import
{
IInstantiationService
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
IMessageService
,
CloseAction
}
from
'
vs/platform/message/common/message
'
;
import
{
UninstallAction
}
from
'
vs/workbench/parts/extensions/electron-browser/extensionsActions
'
;
import
{
IExtensionsService
}
from
'
vs/workbench/parts/extensions/common/extensions
'
;
import
{
IExtensionsService
,
commandCategory
,
IExtension
,
IExtensionManifest
}
from
'
vs/workbench/parts/extensions/common/extensions
'
;
import
{
IQuickOpenService
}
from
'
vs/workbench/services/quickopen/common/quickOpenService
'
;
import
{
getOutdatedExtensions
}
from
'
vs/workbench/parts/extensions/common/extensionsUtil
'
;
var
$
=
dom
.
emmet
;
interface
IState
{
errors
:
IMessage
[];
installing
:
IExtensionManifest
[];
outdated
:
IExtension
[];
}
const
InitialState
:
IState
=
{
errors
:
[],
installing
:
[],
outdated
:
[]
};
function
extensionEquals
(
one
:
IExtensionManifest
,
other
:
IExtensionManifest
):
boolean
{
return
one
.
publisher
===
other
.
publisher
&&
one
.
name
===
other
.
name
;
}
const
OutdatedPeriod
=
5
*
60
*
1000
;
// every 5 minutes
export
class
ExtensionsStatusbarItem
implements
statusbar
.
IStatusbarItem
{
private
toDispose
:
lifecycle
.
IDisposable
[];
private
domNode
:
HTMLElement
;
private
status
:
{
[
id
:
string
]:
IExtensionsStatus
};
private
container
:
HTMLElement
;
private
messageCount
:
number
;
private
state
:
IState
=
InitialState
;
private
outdatedDelayer
=
new
ThrottledDelayer
<
void
>
(
OutdatedPeriod
);
constructor
(
@
IExtensionService
extensionService
:
IExtensionService
,
@
IExtensionService
private
extensionService
:
IExtensionService
,
@
IMessageService
private
messageService
:
IMessageService
,
@
IExtensionsService
protected
extensionsService
:
IExtensionsService
,
@
IInstantiationService
protected
instantiationService
:
IInstantiationService
@
IInstantiationService
protected
instantiationService
:
IInstantiationService
,
@
IQuickOpenService
protected
quickOpenService
:
IQuickOpenService
)
{}
render
(
container
:
HTMLElement
):
IDisposable
{
this
.
domNode
=
append
(
container
,
$
(
'
a.extensions-statusbar
'
));
append
(
this
.
domNode
,
$
(
'
.icon
'
));
this
.
domNode
.
onclick
=
()
=>
this
.
onClick
();
this
.
checkErrors
();
this
.
checkOutdated
();
const
disposables
=
[];
this
.
extensionsService
.
onInstallExtension
(
this
.
onInstallExtension
,
this
,
disposables
);
this
.
extensionsService
.
onDidInstallExtension
(
this
.
onDidInstallExtension
,
this
,
disposables
);
this
.
extensionsService
.
onDidUninstallExtension
(
this
.
onDidUninstallExtension
,
this
,
disposables
);
return
combinedDispose
(...
disposables
);
}
)
{
this
.
toDispose
=
[];
this
.
messageCount
=
0
;
private
updateState
(
obj
:
any
):
void
{
this
.
state
=
assign
(
this
.
state
,
obj
);
this
.
onStateChange
();
}
private
get
hasErrors
()
{
return
this
.
state
.
errors
.
length
>
0
;
}
private
get
isInstalling
()
{
return
this
.
state
.
installing
.
length
>
0
;
}
private
get
hasUpdates
()
{
return
this
.
state
.
outdated
.
length
>
0
;
}
private
onStateChange
():
void
{
toggleClass
(
this
.
domNode
,
'
has-errors
'
,
this
.
hasErrors
);
toggleClass
(
this
.
domNode
,
'
is-installing
'
,
!
this
.
hasErrors
&&
this
.
isInstalling
);
toggleClass
(
this
.
domNode
,
'
has-updates
'
,
!
this
.
hasErrors
&&
!
this
.
isInstalling
&&
this
.
hasUpdates
);
if
(
this
.
hasErrors
)
{
const
singular
=
nls
.
localize
(
'
oneIssue
'
,
"
Extensions (1 issue)
"
);
const
plural
=
nls
.
localize
(
'
multipleIssues
'
,
"
Extensions ({0} issues)
"
,
this
.
state
.
errors
.
length
);
this
.
domNode
.
title
=
this
.
state
.
errors
.
length
>
1
?
plural
:
singular
;
}
else
if
(
this
.
isInstalling
)
{
this
.
domNode
.
title
=
nls
.
localize
(
'
extensionsInstalling
'
,
"
Extensions ({0} installing...)
"
,
this
.
state
.
installing
.
length
);
}
else
if
(
this
.
hasUpdates
)
{
const
singular
=
nls
.
localize
(
'
oneUpdate
'
,
"
Extensions (1 update available)
"
);
const
plural
=
nls
.
localize
(
'
multipleUpdates
'
,
"
Extensions ({0} updates available)
"
,
this
.
state
.
outdated
.
length
);
this
.
domNode
.
title
=
this
.
state
.
outdated
.
length
>
1
?
plural
:
singular
;
}
else
{
this
.
domNode
.
title
=
nls
.
localize
(
'
extensions
'
,
"
Extensions
"
);
}
}
extensionService
.
onReady
().
then
(()
=>
{
this
.
status
=
extensionService
.
getExtensionsStatus
();
Object
.
keys
(
this
.
status
).
forEach
(
key
=>
{
this
.
messageCount
+=
this
.
status
[
key
].
messages
.
filter
(
message
=>
message
.
type
>
Severity
.
Info
).
length
;
private
onClick
():
void
{
if
(
this
.
hasErrors
)
{
this
.
showErrors
(
this
.
state
.
errors
);
this
.
updateState
({
errors
:
[]
});
}
else
if
(
this
.
hasUpdates
)
{
this
.
quickOpenService
.
show
(
`ext update `
);
}
else
{
this
.
quickOpenService
.
show
(
`>
${
commandCategory
}
: `
);
}
}
private
showErrors
(
errors
:
IMessage
[]):
void
{
const
promise
=
onUnexpectedPromiseError
(
this
.
extensionsService
.
getInstalled
());
promise
.
done
(
installed
=>
{
errors
.
forEach
(
m
=>
{
const
extension
=
installed
.
filter
(
ext
=>
ext
.
path
===
m
.
source
).
pop
();
const
actions
=
[
CloseAction
];
const
name
=
(
extension
&&
extension
.
name
)
||
m
.
source
;
const
message
=
`
${
name
}
:
${
m
.
message
}
`
;
if
(
extension
)
{
const
actionLabel
=
nls
.
localize
(
'
uninstall
'
,
"
Uninstall
"
);
actions
.
push
(
new
Action
(
'
extensions.uninstall2
'
,
actionLabel
,
null
,
true
,
()
=>
this
.
instantiationService
.
createInstance
(
UninstallAction
).
run
(
extension
)));
}
this
.
messageService
.
show
(
m
.
type
,
{
message
,
actions
});
});
this
.
render
(
this
.
container
);
});
}
public
render
(
container
:
HTMLElement
):
lifecycle
.
IDisposable
{
this
.
container
=
container
;
if
(
this
.
messageCount
>
0
)
{
this
.
domNode
=
dom
.
append
(
container
,
$
(
'
a.extensions-statusbar
'
));
const
issueLabel
=
this
.
messageCount
>
1
?
nls
.
localize
(
'
issues
'
,
"
issues
"
)
:
nls
.
localize
(
'
issue
'
,
"
issue
"
);
const
extensionLabel
=
nls
.
localize
(
'
extension
'
,
"
extension
"
);
this
.
domNode
.
title
=
`
${
this
.
messageCount
}
${
extensionLabel
}
${
issueLabel
}
`
;
this
.
domNode
.
textContent
=
`
${
this
.
messageCount
}
${
issueLabel
}
`
;
this
.
toDispose
.
push
(
dom
.
addDisposableListener
(
this
.
domNode
,
'
click
'
,
()
=>
{
this
.
extensionsService
.
getInstalled
().
done
(
installed
=>
{
Object
.
keys
(
this
.
status
).
forEach
(
key
=>
{
this
.
status
[
key
].
messages
.
forEach
(
m
=>
{
if
(
m
.
type
>
Severity
.
Info
)
{
const
extension
=
installed
.
filter
(
ext
=>
ext
.
path
===
m
.
source
).
pop
();
const
actions
=
[
CloseAction
];
const
name
=
(
extension
&&
extension
.
name
)
||
m
.
source
;
const
message
=
`
${
name
}
:
${
m
.
message
}
`
;
if
(
extension
)
{
const
actionLabel
=
nls
.
localize
(
'
uninstall
'
,
"
Uninstall
"
);
actions
.
push
(
new
Action
(
'
extensions.uninstall2
'
,
actionLabel
,
null
,
true
,
()
=>
this
.
instantiationService
.
createInstance
(
UninstallAction
).
run
(
extension
)));
}
this
.
messageService
.
show
(
m
.
type
,
{
message
,
actions
});
}
});
});
},
onUnexpectedError
);
}));
}
private
onInstallExtension
(
manifest
:
IExtensionManifest
):
void
{
const
installing
=
[...
this
.
state
.
installing
,
manifest
];
this
.
updateState
({
installing
});
}
private
onDidInstallExtension
({
extension
}:
{
extension
:
IExtension
;
}):
void
{
const
installing
=
this
.
state
.
installing
.
filter
(
e
=>
!
extensionEquals
(
extension
,
e
));
this
.
updateState
({
installing
});
this
.
outdatedDelayer
.
trigger
(()
=>
this
.
checkOutdated
(),
0
);
}
return
{
dispose
:
()
=>
lifecycle
.
disposeAll
(
this
.
toDispose
)
};
private
onDidUninstallExtension
():
void
{
this
.
outdatedDelayer
.
trigger
(()
=>
this
.
checkOutdated
(),
0
);
}
private
checkErrors
():
void
{
const
promise
=
onUnexpectedPromiseError
(
this
.
extensionService
.
onReady
());
promise
.
done
(()
=>
{
const
status
=
this
.
extensionService
.
getExtensionsStatus
();
const
errors
=
Object
.
keys
(
status
)
.
map
(
k
=>
status
[
k
].
messages
)
.
reduce
((
r
,
m
)
=>
r
.
concat
(
m
),
[])
.
filter
(
m
=>
m
.
type
>
Severity
.
Info
);
this
.
updateState
({
errors
});
});
}
private
checkOutdated
():
TPromise
<
void
>
{
return
this
.
instantiationService
.
invokeFunction
(
getOutdatedExtensions
)
.
then
(
null
,
_
=>
[])
// ignore errors
.
then
(
outdated
=>
{
this
.
updateState
({
outdated
});
// repeat this later
this
.
outdatedDelayer
.
trigger
(()
=>
this
.
checkOutdated
());
});
}
}
\ No newline at end of file
src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension.ts
浏览文件 @
9736b536
...
...
@@ -8,7 +8,7 @@ import errors = require('vs/base/common/errors');
import
platform
=
require
(
'
vs/platform/platform
'
);
import
{
Promise
}
from
'
vs/base/common/winjs.base
'
;
import
{
IWorkbenchContribution
}
from
'
vs/workbench/common/contributions
'
;
import
{
IExtensionsService
,
IGalleryService
,
IExtensionTipsService
}
from
'
vs/workbench/parts/extensions/common/extensions
'
;
import
{
IExtensionsService
,
IGalleryService
,
IExtensionTipsService
,
commandCategory
}
from
'
vs/workbench/parts/extensions/common/extensions
'
;
import
{
IInstantiationService
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
IMessageService
}
from
'
vs/platform/message/common/message
'
;
import
Severity
from
'
vs/base/common/severity
'
;
...
...
@@ -46,9 +46,8 @@ export class ExtensionsWorkbenchExtension implements IWorkbenchContribution {
// add service
instantiationService
.
addSingleton
(
IExtensionTipsService
,
this
.
instantiationService
.
createInstance
(
ExtensionTipsService
));
const
extensionsCategory
=
nls
.
localize
(
'
extensionsCategory
'
,
"
Extensions
"
);
const
actionRegistry
=
(
<
wbaregistry
.
IWorkbenchActionRegistry
>
platform
.
Registry
.
as
(
wbaregistry
.
Extensions
.
WorkbenchActions
));
actionRegistry
.
registerWorkbenchAction
(
new
SyncActionDescriptor
(
ListExtensionsAction
,
ListExtensionsAction
.
ID
,
ListExtensionsAction
.
LABEL
),
extensions
Category
);
actionRegistry
.
registerWorkbenchAction
(
new
SyncActionDescriptor
(
ListExtensionsAction
,
ListExtensionsAction
.
ID
,
ListExtensionsAction
.
LABEL
),
command
Category
);
(
<
IQuickOpenRegistry
>
platform
.
Registry
.
as
(
Extensions
.
Quickopen
)).
registerQuickOpenHandler
(
new
QuickOpenHandlerDescriptor
(
...
...
@@ -62,7 +61,7 @@ export class ExtensionsWorkbenchExtension implements IWorkbenchContribution {
if
(
galleryService
.
isEnabled
())
{
this
.
instantiationService
.
invokeFunction
(
checkForLegacyExtensionNeeds
);
actionRegistry
.
registerWorkbenchAction
(
new
SyncActionDescriptor
(
InstallExtensionAction
,
InstallExtensionAction
.
ID
,
InstallExtensionAction
.
LABEL
),
extensions
Category
);
actionRegistry
.
registerWorkbenchAction
(
new
SyncActionDescriptor
(
InstallExtensionAction
,
InstallExtensionAction
.
ID
,
InstallExtensionAction
.
LABEL
),
command
Category
);
(
<
IQuickOpenRegistry
>
platform
.
Registry
.
as
(
Extensions
.
Quickopen
)).
registerQuickOpenHandler
(
new
QuickOpenHandlerDescriptor
(
...
...
@@ -73,7 +72,7 @@ export class ExtensionsWorkbenchExtension implements IWorkbenchContribution {
)
);
actionRegistry
.
registerWorkbenchAction
(
new
SyncActionDescriptor
(
ListOutdatedExtensionsAction
,
ListOutdatedExtensionsAction
.
ID
,
ListOutdatedExtensionsAction
.
LABEL
),
extensions
Category
);
actionRegistry
.
registerWorkbenchAction
(
new
SyncActionDescriptor
(
ListOutdatedExtensionsAction
,
ListOutdatedExtensionsAction
.
ID
,
ListOutdatedExtensionsAction
.
LABEL
),
command
Category
);
(
<
IQuickOpenRegistry
>
platform
.
Registry
.
as
(
Extensions
.
Quickopen
)).
registerQuickOpenHandler
(
new
QuickOpenHandlerDescriptor
(
...
...
@@ -85,7 +84,7 @@ export class ExtensionsWorkbenchExtension implements IWorkbenchContribution {
);
// add extension tips services
actionRegistry
.
registerWorkbenchAction
(
new
SyncActionDescriptor
(
ListSuggestedExtensionsAction
,
ListSuggestedExtensionsAction
.
ID
,
ListSuggestedExtensionsAction
.
LABEL
),
extensions
Category
);
actionRegistry
.
registerWorkbenchAction
(
new
SyncActionDescriptor
(
ListSuggestedExtensionsAction
,
ListSuggestedExtensionsAction
.
ID
,
ListSuggestedExtensionsAction
.
LABEL
),
command
Category
);
(
<
IQuickOpenRegistry
>
platform
.
Registry
.
as
(
Extensions
.
Quickopen
)).
registerQuickOpenHandler
(
new
QuickOpenHandlerDescriptor
(
...
...
src/vs/workbench/parts/extensions/electron-browser/media/extensions.css
浏览文件 @
9736b536
...
...
@@ -135,23 +135,54 @@
/* Status bar */
.monaco-shell
.extensions-statusbar
{
padding
:
0
5px
0
25px
;
line-height
:
22px
;
background
:
url('extensions-status.svg')
center
center
no-repeat
;
background-size
:
14px
;
background-position
:
4px
50%
;
}
.monaco-shell
.extensions-suggestions
{
padding
:
0
5px
0
5px
;
-webkit-transition
:
visibility
250ms
cubic-bezier
(
0.175
,
0.885
,
0.32
,
1.275
);
transition
:
visibility
250ms
cubic-bezier
(
0.175
,
0.885
,
0.32
,
1.275
);
}
.monaco-shell
.extensions-suggestions
>
.octicon
{
font-size
:
14px
;
position
:
relative
;
padding
:
0
5px
;
width
:
14px
;
}
.monaco-shell
.extensions-suggestions.disabled
{
display
:
none
;
.monaco-shell
.extensions-statusbar
>
.icon
{
background
:
url('extensions-status.svg')
center
center
no-repeat
;
background-size
:
14px
;
width
:
14px
;
height
:
100%
;
}
.monaco-shell
.extensions-statusbar.has-updates
::after
{
content
:
''
;
width
:
6px
;
height
:
6px
;
background-color
:
#39A71E
;
position
:
absolute
;
top
:
2px
;
right
:
3px
;
border-radius
:
10px
;
border
:
1px
solid
white
;
}
.monaco-shell
.extensions-statusbar.has-errors
::after
{
content
:
''
;
width
:
6px
;
height
:
6px
;
background-color
:
#CC6633
;
position
:
absolute
;
top
:
2px
;
right
:
3px
;
border-radius
:
10px
;
border
:
1px
solid
white
;
}
@keyframes
shake
{
from
{
transform
:
rotate
(
0deg
);
}
30
%
{
transform
:
rotate
(
0deg
);
}
40
%
{
transform
:
rotate
(
-20deg
);
}
48
%
{
transform
:
rotate
(
10deg
);
}
52
%
{
transform
:
rotate
(
-10deg
);
}
60
%
{
transform
:
rotate
(
20deg
);
}
70
%
{
transform
:
rotate
(
0deg
);
}
to
{
transform
:
rotate
(
0deg
);
}
}
.monaco-shell
.extensions-statusbar.is-installing
.icon
{
animation
:
2s
ease-in-out
infinite
shake
;
opacity
:
0.7
;
}
\ No newline at end of file
src/vs/workbench/parts/extensions/node/extensionsService.ts
浏览文件 @
9736b536
...
...
@@ -92,10 +92,10 @@ export class ExtensionsService implements IExtensionsService {
private
obsoleteFileLimiter
:
Limiter
<
void
>
;
private
_onInstallExtension
=
new
Emitter
<
IExtensionManifest
>
();
@
ServiceEvent
onInstallExtension
:
Event
<
IExtension
>
=
this
.
_onInstallExtension
.
event
;
@
ServiceEvent
onInstallExtension
:
Event
<
IExtension
Manifest
>
=
this
.
_onInstallExtension
.
event
;
private
_onDidInstallExtension
=
new
Emitter
<
IExtension
>
();
@
ServiceEvent
onDidInstallExtension
:
Event
<
IExtension
>
=
this
.
_onDidInstallExtension
.
event
;
private
_onDidInstallExtension
=
new
Emitter
<
{
extension
:
IExtension
;
error
?:
Error
;
}
>
();
@
ServiceEvent
onDidInstallExtension
:
Event
<
{
extension
:
IExtension
;
error
?:
Error
;
}
>
=
this
.
_onDidInstallExtension
.
event
;
private
_onUninstallExtension
=
new
Emitter
<
IExtension
>
();
@
ServiceEvent
onUninstallExtension
:
Event
<
IExtension
>
=
this
.
_onUninstallExtension
.
event
;
...
...
@@ -129,6 +129,8 @@ export class ExtensionsService implements IExtensionsService {
return
TPromise
.
wrapError
(
new
Error
(
nls
.
localize
(
'
missingGalleryInformation
'
,
"
Gallery information is missing
"
)));
}
this
.
_onInstallExtension
.
fire
(
extension
);
return
this
.
getLastValidExtensionVersion
(
extension
,
extension
.
galleryInformation
.
versions
).
then
(
versionInfo
=>
{
const
version
=
versionInfo
.
version
;
const
url
=
versionInfo
.
downloadUrl
;
...
...
@@ -139,13 +141,11 @@ export class ExtensionsService implements IExtensionsService {
return
this
.
request
(
url
)
.
then
(
opts
=>
download
(
zipPath
,
opts
))
.
then
(()
=>
validate
(
zipPath
,
extension
,
version
))
.
then
(
manifest
=>
{
this
.
_onInstallExtension
.
fire
(
manifest
);
return
manifest
;
})
.
then
(
manifest
=>
extract
(
zipPath
,
extensionPath
,
{
sourcePath
:
'
extension
'
,
overwrite
:
true
}).
then
(()
=>
manifest
))
.
then
(
manifest
=>
{
manifest
=
assign
({
__metadata
:
galleryInformation
},
manifest
);
return
pfs
.
writeFile
(
manifestPath
,
JSON
.
stringify
(
manifest
,
null
,
'
\t
'
));
})
.
then
(()
=>
{
this
.
_onDidInstallExtension
.
fire
(
extension
);
return
extension
;
});
.
then
(
manifest
=>
assign
({
__metadata
:
galleryInformation
},
manifest
))
.
then
(
manifest
=>
pfs
.
writeFile
(
manifestPath
,
JSON
.
stringify
(
manifest
,
null
,
'
\t
'
)))
.
then
(()
=>
{
this
.
_onDidInstallExtension
.
fire
({
extension
});
return
extension
;
})
.
then
(
null
,
error
=>
{
this
.
_onDidInstallExtension
.
fire
({
extension
,
error
});
return
TPromise
.
wrapError
(
error
);
});
});
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录