Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
411d8d06
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,体验更适合开发者的 AI 搜索 >>
提交
411d8d06
编写于
3月 18, 2017
作者:
A
Alex Dima
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Prepare KeybindingService for dispatching based on `code`
上级
0f927b79
变更
18
隐藏空白更改
内联
并排
Showing
18 changed file
with
166 addition
and
85 deletion
+166
-85
src/vs/base/browser/keyboardEvent.ts
src/vs/base/browser/keyboardEvent.ts
+5
-2
src/vs/base/parts/tree/browser/treeDefaults.ts
src/vs/base/parts/tree/browser/treeDefaults.ts
+1
-1
src/vs/editor/browser/standalone/simpleServices.ts
src/vs/editor/browser/standalone/simpleServices.ts
+15
-5
src/vs/editor/contrib/suggest/test/common/suggestModel.test.ts
...s/editor/contrib/suggest/test/common/suggestModel.test.ts
+2
-2
src/vs/editor/test/browser/standalone/simpleServices.test.ts
src/vs/editor/test/browser/standalone/simpleServices.test.ts
+11
-10
src/vs/editor/test/common/mocks/mockCodeEditor.ts
src/vs/editor/test/common/mocks/mockCodeEditor.ts
+2
-2
src/vs/monaco.d.ts
src/vs/monaco.d.ts
+1
-0
src/vs/platform/actions/test/common/menuService.test.ts
src/vs/platform/actions/test/common/menuService.test.ts
+2
-2
src/vs/platform/keybinding/common/abstractKeybindingService.ts
...s/platform/keybinding/common/abstractKeybindingService.ts
+25
-20
src/vs/platform/keybinding/common/keybinding.ts
src/vs/platform/keybinding/common/keybinding.ts
+19
-5
src/vs/platform/keybinding/common/keybindingsRegistry.ts
src/vs/platform/keybinding/common/keybindingsRegistry.ts
+6
-6
src/vs/platform/keybinding/common/usLayoutResolvedKeybinding.ts
.../platform/keybinding/common/usLayoutResolvedKeybinding.ts
+3
-0
src/vs/platform/keybinding/test/common/abstractKeybindingService.test.ts
.../keybinding/test/common/abstractKeybindingService.test.ts
+36
-16
src/vs/platform/keybinding/test/common/mockKeybindingService.ts
.../platform/keybinding/test/common/mockKeybindingService.ts
+15
-4
src/vs/workbench/parts/preferences/browser/keybindingWidgets.ts
.../workbench/parts/preferences/browser/keybindingWidgets.ts
+1
-1
src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts
...bench/parts/terminal/electron-browser/terminalInstance.ts
+1
-2
src/vs/workbench/parts/terminal/test/electron-browser/terminalInstance.test.ts
...s/terminal/test/electron-browser/terminalInstance.test.ts
+3
-3
src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts
...services/keybinding/electron-browser/keybindingService.ts
+18
-4
未找到文件。
src/vs/base/browser/keyboardEvent.ts
浏览文件 @
411d8d06
...
...
@@ -174,11 +174,12 @@ export interface IKeyboardEvent {
readonly
altKey
:
boolean
;
readonly
metaKey
:
boolean
;
readonly
keyCode
:
KeyCode
;
readonly
code
:
string
;
/**
* @internal
*/
to
Runtime
Keybinding
():
SimpleKeybinding
;
toKeybinding
():
SimpleKeybinding
;
equals
(
keybinding
:
number
):
boolean
;
preventDefault
():
void
;
...
...
@@ -200,6 +201,7 @@ export class StandardKeyboardEvent implements IKeyboardEvent {
public
readonly
altKey
:
boolean
;
public
readonly
metaKey
:
boolean
;
public
readonly
keyCode
:
KeyCode
;
public
readonly
code
:
string
;
private
_asKeybinding
:
number
;
private
_asRuntimeKeybinding
:
SimpleKeybinding
;
...
...
@@ -215,6 +217,7 @@ export class StandardKeyboardEvent implements IKeyboardEvent {
this
.
altKey
=
e
.
altKey
;
this
.
metaKey
=
e
.
metaKey
;
this
.
keyCode
=
extractKeyCode
(
e
);
this
.
code
=
e
.
code
;
// console.info(e.type + ": keyCode: " + e.keyCode + ", which: " + e.which + ", charCode: " + e.charCode + ", detail: " + e.detail + " ====> " + this.keyCode + ' -- ' + KeyCode[this.keyCode]);
...
...
@@ -241,7 +244,7 @@ export class StandardKeyboardEvent implements IKeyboardEvent {
}
}
public
to
Runtime
Keybinding
():
SimpleKeybinding
{
public
toKeybinding
():
SimpleKeybinding
{
return
this
.
_asRuntimeKeybinding
;
}
...
...
src/vs/base/parts/tree/browser/treeDefaults.ts
浏览文件 @
411d8d06
...
...
@@ -264,7 +264,7 @@ export class DefaultController implements _.IController {
}
private
onKey
(
bindings
:
KeybindingDispatcher
,
tree
:
_
.
ITree
,
event
:
IKeyboardEvent
):
boolean
{
var
handler
=
bindings
.
dispatch
(
event
.
to
Runtime
Keybinding
());
var
handler
=
bindings
.
dispatch
(
event
.
toKeybinding
());
if
(
handler
)
{
if
(
handler
(
tree
,
event
))
{
event
.
preventDefault
();
...
...
src/vs/editor/browser/standalone/simpleServices.ts
浏览文件 @
411d8d06
...
...
@@ -14,7 +14,7 @@ import { ICommandService, ICommand, ICommandEvent, ICommandHandler, CommandsRegi
import
{
AbstractKeybindingService
}
from
'
vs/platform/keybinding/common/abstractKeybindingService
'
;
import
{
USLayoutResolvedKeybinding
}
from
'
vs/platform/keybinding/common/usLayoutResolvedKeybinding
'
;
import
{
KeybindingResolver
}
from
'
vs/platform/keybinding/common/keybindingResolver
'
;
import
{
IKeybindingEvent
,
KeybindingSource
}
from
'
vs/platform/keybinding/common/keybinding
'
;
import
{
IKeybindingEvent
,
KeybindingSource
,
IKeyboardEvent
}
from
'
vs/platform/keybinding/common/keybinding
'
;
import
{
ContextKeyExpr
,
IContextKeyService
}
from
'
vs/platform/contextkey/common/contextkey
'
;
import
{
IConfirmation
,
IMessageService
}
from
'
vs/platform/message/common/message
'
;
import
*
as
editorCommon
from
'
vs/editor/common/editorCommon
'
;
...
...
@@ -32,7 +32,7 @@ import { KeybindingsRegistry, IKeybindingItem } from 'vs/platform/keybinding/com
import
{
MenuId
,
IMenu
,
IMenuService
}
from
'
vs/platform/actions/common/actions
'
;
import
{
Menu
}
from
'
vs/platform/actions/common/menu
'
;
import
{
ITelemetryService
,
ITelemetryExperiments
,
ITelemetryInfo
}
from
'
vs/platform/telemetry/common/telemetry
'
;
import
{
ResolvedKeybinding
,
Keybinding
,
createKeybinding
}
from
'
vs/base/common/keyCodes
'
;
import
{
ResolvedKeybinding
,
Keybinding
,
createKeybinding
,
SimpleKeybinding
}
from
'
vs/base/common/keyCodes
'
;
import
{
ResolvedKeybindingItem
}
from
'
vs/platform/keybinding/common/resolvedKeybindingItem
'
;
import
{
OS
}
from
'
vs/base/common/platform
'
;
...
...
@@ -323,7 +323,7 @@ export class StandaloneKeybindingService extends AbstractKeybindingService {
this
.
toDispose
.
push
(
dom
.
addDisposableListener
(
domNode
,
dom
.
EventType
.
KEY_DOWN
,
(
e
:
KeyboardEvent
)
=>
{
let
keyEvent
=
new
StandardKeyboardEvent
(
e
);
let
shouldPreventDefault
=
this
.
_dispatch
(
keyEvent
.
toRuntimeKeybinding
()
,
keyEvent
.
target
);
let
shouldPreventDefault
=
this
.
_dispatch
(
keyEvent
,
keyEvent
.
target
);
if
(
shouldPreventDefault
)
{
keyEvent
.
preventDefault
();
}
...
...
@@ -387,7 +387,7 @@ export class StandaloneKeybindingService extends AbstractKeybindingService {
const
item
=
items
[
i
];
const
when
=
(
item
.
when
?
item
.
when
.
normalize
()
:
null
);
const
keybinding
=
item
.
keybinding
;
const
resolvedKeybinding
=
(
keybinding
?
this
.
_createResolved
Keybinding
(
keybinding
)
:
null
);
const
resolvedKeybinding
=
(
keybinding
?
this
.
resolve
Keybinding
(
keybinding
)
:
null
);
result
[
resultLen
++
]
=
new
ResolvedKeybindingItem
(
resolvedKeybinding
,
item
.
command
,
item
.
commandArgs
,
when
,
isDefault
);
}
...
...
@@ -395,10 +395,20 @@ export class StandaloneKeybindingService extends AbstractKeybindingService {
return
result
;
}
p
rotected
_createResolved
Keybinding
(
kb
:
Keybinding
):
ResolvedKeybinding
{
p
ublic
resolve
Keybinding
(
kb
:
Keybinding
):
ResolvedKeybinding
{
return
new
USLayoutResolvedKeybinding
(
kb
,
OS
);
}
public
resolveKeyboardEvent
(
keyboardEvent
:
IKeyboardEvent
):
ResolvedKeybinding
{
let
keybinding
=
new
SimpleKeybinding
(
keyboardEvent
.
ctrlKey
,
keyboardEvent
.
shiftKey
,
keyboardEvent
.
altKey
,
keyboardEvent
.
metaKey
,
keyboardEvent
.
keyCode
);
return
this
.
resolveKeybinding
(
keybinding
);
}
}
export
class
SimpleConfigurationService
implements
IConfigurationService
{
...
...
src/vs/editor/contrib/suggest/test/common/suggestModel.test.ts
浏览文件 @
411d8d06
...
...
@@ -17,12 +17,12 @@ import { MockCodeEditor, MockScopeLocation } from 'vs/editor/test/common/mocks/m
import
{
ServiceCollection
}
from
'
vs/platform/instantiation/common/serviceCollection
'
;
import
{
InstantiationService
}
from
'
vs/platform/instantiation/common/instantiationService
'
;
import
{
IContextKeyService
}
from
'
vs/platform/contextkey/common/contextkey
'
;
import
{
Mock
Keybinding
Service
}
from
'
vs/platform/keybinding/test/common/mockKeybindingService
'
;
import
{
Mock
ContextKey
Service
}
from
'
vs/platform/keybinding/test/common/mockKeybindingService
'
;
import
{
ITelemetryService
}
from
'
vs/platform/telemetry/common/telemetry
'
;
import
{
NullTelemetryService
}
from
'
vs/platform/telemetry/common/telemetryUtils
'
;
function
createMockEditor
(
model
:
Model
):
MockCodeEditor
{
const
contextKeyService
=
new
Mock
Keybinding
Service
();
const
contextKeyService
=
new
Mock
ContextKey
Service
();
const
telemetryService
=
NullTelemetryService
;
const
instantiationService
=
new
InstantiationService
(
new
ServiceCollection
(
[
IContextKeyService
,
contextKeyService
],
...
...
src/vs/editor/test/browser/standalone/simpleServices.test.ts
浏览文件 @
411d8d06
...
...
@@ -9,17 +9,14 @@ import { ContextKeyService } from 'vs/platform/contextkey/browser/contextKeyServ
import
{
SimpleConfigurationService
,
SimpleMessageService
,
StandaloneKeybindingService
,
StandaloneCommandService
}
from
'
vs/editor/browser/standalone/simpleServices
'
;
import
{
InstantiationService
}
from
'
vs/platform/instantiation/common/instantiationService
'
;
import
{
ServiceCollection
}
from
'
vs/platform/instantiation/common/serviceCollection
'
;
import
{
KeyCode
,
SimpleKeybinding
}
from
'
vs/base/common/keyCodes
'
;
import
{
IKeyboardEvent
}
from
'
vs/base/browser/keyboardEvent
'
;
import
{
KeyCode
}
from
'
vs/base/common/keyCodes
'
;
import
{
IKeyboardEvent
}
from
"
vs/platform/keybinding/common/keybinding
"
;
suite
(
'
StandaloneKeybindingService
'
,
()
=>
{
class
TestStandaloneKeybindingService
extends
StandaloneKeybindingService
{
public
dispatch
(
e
:
IKeyboardEvent
):
void
{
let
shouldPreventDefault
=
super
.
_dispatch
(
e
.
toRuntimeKeybinding
(),
e
.
target
);
if
(
shouldPreventDefault
)
{
e
.
preventDefault
();
}
public
testDispatch
(
e
:
IKeyboardEvent
):
void
{
super
.
_dispatch
(
e
,
null
);
}
}
...
...
@@ -45,9 +42,13 @@ suite('StandaloneKeybindingService', () => {
commandInvoked
=
true
;
},
null
);
keybindingService
.
dispatch
(
<
any
>
{
toRuntimeKeybinding
:
()
=>
new
SimpleKeybinding
(
false
,
false
,
false
,
false
,
KeyCode
.
F9
),
preventDefault
:
()
=>
{
}
keybindingService
.
testDispatch
({
ctrlKey
:
false
,
shiftKey
:
false
,
altKey
:
false
,
metaKey
:
false
,
keyCode
:
KeyCode
.
F9
,
code
:
null
});
assert
.
ok
(
commandInvoked
,
'
command invoked
'
);
...
...
src/vs/editor/test/common/mocks/mockCodeEditor.ts
浏览文件 @
411d8d06
...
...
@@ -8,7 +8,7 @@ import { EventEmitter, IEventEmitter } from 'vs/base/common/eventEmitter';
import
{
ServiceCollection
}
from
'
vs/platform/instantiation/common/serviceCollection
'
;
import
{
InstantiationService
}
from
'
vs/platform/instantiation/common/instantiationService
'
;
import
{
IContextKeyService
,
IContextKeyServiceTarget
}
from
'
vs/platform/contextkey/common/contextkey
'
;
import
{
Mock
Keybinding
Service
}
from
'
vs/platform/keybinding/test/common/mockKeybindingService
'
;
import
{
Mock
ContextKey
Service
}
from
'
vs/platform/keybinding/test/common/mockKeybindingService
'
;
import
{
CommonCodeEditor
}
from
'
vs/editor/common/commonCodeEditor
'
;
import
{
CommonEditorConfiguration
}
from
'
vs/editor/common/config/commonEditorConfig
'
;
import
{
Cursor
}
from
'
vs/editor/common/controller/cursor
'
;
...
...
@@ -87,7 +87,7 @@ export function withMockCodeEditor(text: string[], options: editorCommon.ICodeEd
export
function
mockCodeEditor
(
text
:
string
[],
options
:
editorCommon
.
ICodeEditorWidgetCreationOptions
):
CommonCodeEditor
{
let
contextKeyService
=
new
Mock
Keybinding
Service
();
let
contextKeyService
=
new
Mock
ContextKey
Service
();
let
services
=
new
ServiceCollection
();
services
.
set
(
IContextKeyService
,
contextKeyService
);
...
...
src/vs/monaco.d.ts
浏览文件 @
411d8d06
...
...
@@ -380,6 +380,7 @@ declare module monaco {
readonly
altKey
:
boolean
;
readonly
metaKey
:
boolean
;
readonly
keyCode
:
KeyCode
;
readonly
code
:
string
;
equals
(
keybinding
:
number
):
boolean
;
preventDefault
():
void
;
stopPropagation
():
void
;
...
...
src/vs/platform/actions/test/common/menuService.test.ts
浏览文件 @
411d8d06
...
...
@@ -9,7 +9,7 @@ import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions';
import
{
MenuService
}
from
'
vs/platform/actions/common/menuService
'
;
import
{
IDisposable
,
dispose
}
from
'
vs/base/common/lifecycle
'
;
import
{
NullCommandService
}
from
'
vs/platform/commands/common/commands
'
;
import
{
Mock
Keybinding
Service
}
from
'
vs/platform/keybinding/test/common/mockKeybindingService
'
;
import
{
Mock
ContextKey
Service
}
from
'
vs/platform/keybinding/test/common/mockKeybindingService
'
;
import
{
AbstractExtensionService
,
ActivatedExtension
}
from
'
vs/platform/extensions/common/abstractExtensionService
'
;
// --- service instances
...
...
@@ -26,7 +26,7 @@ const extensionService = new class extends AbstractExtensionService<ActivatedExt
}
}(
true
);
const
contextKeyService
=
new
class
extends
Mock
Keybinding
Service
{
const
contextKeyService
=
new
class
extends
Mock
ContextKey
Service
{
contextMatchesRules
()
{
return
true
;
}
...
...
src/vs/platform/keybinding/common/abstractKeybindingService.ts
浏览文件 @
411d8d06
...
...
@@ -5,12 +5,12 @@
'
use strict
'
;
import
*
as
nls
from
'
vs/nls
'
;
import
{
ResolvedKeybinding
,
Keybinding
,
SimpleKeybinding
}
from
'
vs/base/common/keyCodes
'
;
import
{
ResolvedKeybinding
,
Keybinding
}
from
'
vs/base/common/keyCodes
'
;
import
{
IDisposable
,
dispose
}
from
'
vs/base/common/lifecycle
'
;
import
Severity
from
'
vs/base/common/severity
'
;
import
{
ICommandService
}
from
'
vs/platform/commands/common/commands
'
;
import
{
KeybindingResolver
,
IResolveResult
}
from
'
vs/platform/keybinding/common/keybindingResolver
'
;
import
{
IKeybindingEvent
,
IKeybindingService
,
IKeybindingItem2
,
KeybindingSource
}
from
'
vs/platform/keybinding/common/keybinding
'
;
import
{
IKeybindingEvent
,
IKeybindingService
,
IKeybindingItem2
,
KeybindingSource
,
IKeyboardEvent
}
from
'
vs/platform/keybinding/common/keybinding
'
;
import
{
IContextKeyService
,
IContextKeyServiceTarget
}
from
'
vs/platform/contextkey/common/contextkey
'
;
import
{
IStatusbarService
}
from
'
vs/platform/statusbar/common/statusbar
'
;
import
{
IMessageService
}
from
'
vs/platform/message/common/message
'
;
...
...
@@ -56,16 +56,13 @@ export abstract class AbstractKeybindingService implements IKeybindingService {
this
.
toDispose
=
dispose
(
this
.
toDispose
);
}
protected
abstract
_getResolver
():
KeybindingResolver
;
protected
abstract
_createResolvedKeybinding
(
kb
:
Keybinding
):
ResolvedKeybinding
;
get
onDidUpdateKeybindings
():
Event
<
IKeybindingEvent
>
{
return
this
.
_onDidUpdateKeybindings
?
this
.
_onDidUpdateKeybindings
.
event
:
Event
.
None
;
// Sinon stubbing walks properties on prototype
}
p
ublic
resolveKeybinding
(
keybinding
:
Keybinding
):
ResolvedKeybinding
{
return
this
.
_createResolvedKeybinding
(
keybinding
)
;
}
p
rotected
abstract
_getResolver
():
KeybindingResolver
;
public
abstract
resolveKeybinding
(
keybinding
:
Keybinding
):
ResolvedKeybinding
;
public
abstract
resolveKeyboardEvent
(
keyboardEvent
:
IKeyboardEvent
):
ResolvedKeybinding
;
public
getDefaultKeybindings
():
string
{
return
''
;
...
...
@@ -96,32 +93,40 @@ export abstract class AbstractKeybindingService implements IKeybindingService {
return
result
.
resolvedKeybinding
;
}
public
resolve
(
keybinding
:
SimpleKeybinding
,
target
:
IContextKeyServiceTarget
):
IResolveResult
{
if
(
keybinding
.
isModifierKey
())
{
public
softDispatch
(
e
:
IKeyboardEvent
,
target
:
IContextKeyServiceTarget
):
IResolveResult
{
const
keybinding
=
this
.
resolveKeyboardEvent
(
e
);
if
(
keybinding
.
isChord
())
{
console
.
warn
(
'
Unexpected keyboard event mapped to a chord
'
);
return
null
;
}
const
[
firstPart
,]
=
keybinding
.
getDispatchParts
();
if
(
firstPart
===
null
)
{
// cannot be dispatched, probably only modifier keys
return
null
;
}
const
contextValue
=
this
.
_contextKeyService
.
getContextValue
(
target
);
const
currentChord
=
this
.
_currentChord
?
this
.
_currentChord
.
keypress
:
null
;
const
resolvedKeybinding
=
this
.
_createResolvedKeybinding
(
keybinding
);
const
[
firstPart
,]
=
resolvedKeybinding
.
getDispatchParts
();
// We know for a fact the chordPart is null since we're using a single keypress
return
this
.
_getResolver
().
resolve
(
contextValue
,
currentChord
,
firstPart
);
}
protected
_dispatch
(
keybinding
:
SimpleKeybinding
,
target
:
IContextKeyServiceTarget
):
boolean
{
// Check modifier key here and cancel early, it's also checked in resolve as the function
// is used externally.
protected
_dispatch
(
e
:
IKeyboardEvent
,
target
:
IContextKeyServiceTarget
):
boolean
{
let
shouldPreventDefault
=
false
;
if
(
keybinding
.
isModifierKey
())
{
const
keybinding
=
this
.
resolveKeyboardEvent
(
e
);
if
(
keybinding
.
isChord
())
{
console
.
warn
(
'
Unexpected keyboard event mapped to a chord
'
);
return
null
;
}
const
[
firstPart
,]
=
keybinding
.
getDispatchParts
();
if
(
firstPart
===
null
)
{
// cannot be dispatched, probably only modifier keys
return
shouldPreventDefault
;
}
const
contextValue
=
this
.
_contextKeyService
.
getContextValue
(
target
);
const
currentChord
=
this
.
_currentChord
?
this
.
_currentChord
.
keypress
:
null
;
const
resolvedKeybinding
=
this
.
_createResolvedKeybinding
(
keybinding
);
const
[
firstPart
,]
=
resolvedKeybinding
.
getDispatchParts
();
const
keypressLabel
=
resolvedKeybinding
.
getLabel
();
const
keypressLabel
=
keybinding
.
getLabel
();
const
resolveResult
=
this
.
_getResolver
().
resolve
(
contextValue
,
currentChord
,
firstPart
);
if
(
resolveResult
&&
resolveResult
.
enterChord
)
{
...
...
src/vs/platform/keybinding/common/keybinding.ts
浏览文件 @
411d8d06
...
...
@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
'
use strict
'
;
import
{
ResolvedKeybinding
,
Keybinding
,
SimpleKeybinding
}
from
'
vs/base/common/keyCodes
'
;
import
{
ResolvedKeybinding
,
Keybinding
,
KeyCode
}
from
'
vs/base/common/keyCodes
'
;
import
{
createDecorator
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
ContextKeyExpr
,
IContextKeyServiceTarget
}
from
'
vs/platform/contextkey/common/contextkey
'
;
import
{
IResolveResult
}
from
'
vs/platform/keybinding/common/keybindingResolver
'
;
...
...
@@ -34,6 +34,15 @@ export interface IKeybindingEvent {
keybindings
?:
IUserFriendlyKeybinding
[];
}
export
interface
IKeyboardEvent
{
readonly
ctrlKey
:
boolean
;
readonly
shiftKey
:
boolean
;
readonly
altKey
:
boolean
;
readonly
metaKey
:
boolean
;
readonly
keyCode
:
KeyCode
;
readonly
code
:
string
;
}
export
let
IKeybindingService
=
createDecorator
<
IKeybindingService
>
(
'
keybindingService
'
);
export
interface
IKeybindingService
{
...
...
@@ -43,9 +52,12 @@ export interface IKeybindingService {
resolveKeybinding
(
keybinding
:
Keybinding
):
ResolvedKeybinding
;
getDefaultKeybindings
():
str
ing
;
resolveKeyboardEvent
(
keyboardEvent
:
IKeyboardEvent
):
ResolvedKeybind
ing
;
getKeybindings
():
IKeybindingItem2
[];
/**
* Resolve and dispatch `keyboardEvent`, but do not invoke the command or change inner state.
*/
softDispatch
(
keyboardEvent
:
IKeyboardEvent
,
target
:
IContextKeyServiceTarget
):
IResolveResult
;
/**
* Look up keybindings for a command.
...
...
@@ -59,8 +71,10 @@ export interface IKeybindingService {
*/
lookupKeybinding
(
commandId
:
string
):
ResolvedKeybinding
;
customKeybindingsCount
():
number
;
getDefaultKeybindings
():
string
;
resolve
(
keybinding
:
SimpleKeybinding
,
target
:
IContextKeyServiceTarget
):
IResolveResult
;
getKeybindings
():
IKeybindingItem2
[];
customKeybindingsCount
():
number
;
}
src/vs/platform/keybinding/common/keybindingsRegistry.ts
浏览文件 @
411d8d06
...
...
@@ -157,17 +157,17 @@ class KeybindingsRegistryImpl implements IKeybindingsRegistry {
}
}
private
registerDefaultKeybinding
(
k
eybinding
:
number
,
commandId
:
string
,
weight1
:
number
,
weight2
:
number
,
when
:
ContextKeyExpr
):
void
{
const
runtimeKeybinding
=
createKeybinding
(
keybinding
,
OS
);
private
registerDefaultKeybinding
(
k
b
:
number
,
commandId
:
string
,
weight1
:
number
,
weight2
:
number
,
when
:
ContextKeyExpr
):
void
{
const
keybinding
=
createKeybinding
(
kb
,
OS
);
if
(
OS
===
OperatingSystem
.
Windows
)
{
if
(
runtimeK
eybinding
.
type
===
KeybindingType
.
Chord
)
{
this
.
_assertNoCtrlAlt
(
runtimeK
eybinding
.
firstPart
,
commandId
);
if
(
k
eybinding
.
type
===
KeybindingType
.
Chord
)
{
this
.
_assertNoCtrlAlt
(
k
eybinding
.
firstPart
,
commandId
);
}
else
{
this
.
_assertNoCtrlAlt
(
runtimeK
eybinding
,
commandId
);
this
.
_assertNoCtrlAlt
(
k
eybinding
,
commandId
);
}
}
this
.
_keybindings
.
push
({
keybinding
:
runtimeK
eybinding
,
keybinding
:
k
eybinding
,
command
:
commandId
,
commandArgs
:
null
,
when
:
when
,
...
...
src/vs/platform/keybinding/common/usLayoutResolvedKeybinding.ts
浏览文件 @
411d8d06
...
...
@@ -149,6 +149,9 @@ export class USLayoutResolvedKeybinding extends ResolvedKeybinding {
}
public
static
getDispatchStr
(
keybinding
:
SimpleKeybinding
):
string
{
if
(
keybinding
.
isModifierKey
())
{
return
null
;
}
let
result
=
''
;
if
(
keybinding
.
ctrlKey
)
{
...
...
src/vs/platform/keybinding/test/common/abstractKeybindingService.test.ts
浏览文件 @
411d8d06
...
...
@@ -5,7 +5,7 @@
'
use strict
'
;
import
*
as
assert
from
'
assert
'
;
import
{
ResolvedKeybinding
,
KeyCode
,
KeyMod
,
KeyChord
,
Keybinding
,
createKeybinding
,
createSimpleKeybinding
}
from
'
vs/base/common/keyCodes
'
;
import
{
ResolvedKeybinding
,
KeyCode
,
KeyMod
,
KeyChord
,
Keybinding
,
createKeybinding
,
createSimpleKeybinding
,
SimpleKeybinding
}
from
'
vs/base/common/keyCodes
'
;
import
{
AbstractKeybindingService
}
from
'
vs/platform/keybinding/common/abstractKeybindingService
'
;
import
{
USLayoutResolvedKeybinding
}
from
'
vs/platform/keybinding/common/usLayoutResolvedKeybinding
'
;
import
{
IDisposable
}
from
'
vs/base/common/lifecycle
'
;
...
...
@@ -18,6 +18,7 @@ import { IMessageService } from 'vs/platform/message/common/message';
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
{
ResolvedKeybindingItem
}
from
'
vs/platform/keybinding/common/resolvedKeybindingItem
'
;
import
{
OS
}
from
'
vs/base/common/platform
'
;
import
{
IKeyboardEvent
}
from
'
vs/platform/keybinding/common/keybinding
'
;
suite
(
'
AbstractKeybindingService
'
,
()
=>
{
...
...
@@ -39,12 +40,31 @@ suite('AbstractKeybindingService', () => {
return
this
.
_resolver
;
}
p
rotected
_createResolved
Keybinding
(
kb
:
Keybinding
):
ResolvedKeybinding
{
p
ublic
resolve
Keybinding
(
kb
:
Keybinding
):
ResolvedKeybinding
{
return
new
USLayoutResolvedKeybinding
(
kb
,
OS
);
}
public
dispatch
(
keybinding
:
number
):
boolean
{
return
this
.
_dispatch
(
createSimpleKeybinding
(
keybinding
,
OS
),
null
);
public
resolveKeyboardEvent
(
keyboardEvent
:
IKeyboardEvent
):
ResolvedKeybinding
{
let
keybinding
=
new
SimpleKeybinding
(
keyboardEvent
.
ctrlKey
,
keyboardEvent
.
shiftKey
,
keyboardEvent
.
altKey
,
keyboardEvent
.
metaKey
,
keyboardEvent
.
keyCode
);
return
this
.
resolveKeybinding
(
keybinding
);
}
public
testDispatch
(
kb
:
number
):
boolean
{
const
keybinding
=
createSimpleKeybinding
(
kb
,
OS
);
return
this
.
_dispatch
({
ctrlKey
:
keybinding
.
ctrlKey
,
shiftKey
:
keybinding
.
shiftKey
,
altKey
:
keybinding
.
altKey
,
metaKey
:
keybinding
.
metaKey
,
keyCode
:
keybinding
.
keyCode
,
code
:
null
},
null
);
}
}
...
...
@@ -153,7 +173,7 @@ suite('AbstractKeybindingService', () => {
]);
// send Ctrl/Cmd + K
let
shouldPreventDefault
=
kbService
.
d
ispatch
(
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_K
);
let
shouldPreventDefault
=
kbService
.
testD
ispatch
(
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_K
);
assert
.
equal
(
shouldPreventDefault
,
true
);
assert
.
deepEqual
(
executeCommandCalls
,
[]);
assert
.
deepEqual
(
showMessageCalls
,
[]);
...
...
@@ -167,7 +187,7 @@ suite('AbstractKeybindingService', () => {
statusMessageCallsDisposed
=
[];
// send backspace
shouldPreventDefault
=
kbService
.
d
ispatch
(
KeyCode
.
Backspace
);
shouldPreventDefault
=
kbService
.
testD
ispatch
(
KeyCode
.
Backspace
);
assert
.
equal
(
shouldPreventDefault
,
true
);
assert
.
deepEqual
(
executeCommandCalls
,
[]);
assert
.
deepEqual
(
showMessageCalls
,
[]);
...
...
@@ -183,7 +203,7 @@ suite('AbstractKeybindingService', () => {
statusMessageCallsDisposed
=
[];
// send backspace
shouldPreventDefault
=
kbService
.
d
ispatch
(
KeyCode
.
Backspace
);
shouldPreventDefault
=
kbService
.
testD
ispatch
(
KeyCode
.
Backspace
);
assert
.
equal
(
shouldPreventDefault
,
true
);
assert
.
deepEqual
(
executeCommandCalls
,
[{
commandId
:
'
simpleCommand
'
,
...
...
@@ -200,7 +220,7 @@ suite('AbstractKeybindingService', () => {
kbService
.
dispose
();
});
test
(
'
issue #16833: Keybinding service should not
d
ispatch on modifier keys
'
,
()
=>
{
test
(
'
issue #16833: Keybinding service should not
testD
ispatch on modifier keys
'
,
()
=>
{
let
kbService
=
createTestKeybindingService
([
kbItem
(
KeyCode
.
Ctrl
,
'
nope
'
),
...
...
@@ -215,7 +235,7 @@ suite('AbstractKeybindingService', () => {
]);
function
assertIsIgnored
(
keybinding
:
number
):
void
{
let
shouldPreventDefault
=
kbService
.
d
ispatch
(
keybinding
);
let
shouldPreventDefault
=
kbService
.
testD
ispatch
(
keybinding
);
assert
.
equal
(
shouldPreventDefault
,
false
);
assert
.
deepEqual
(
executeCommandCalls
,
[]);
assert
.
deepEqual
(
showMessageCalls
,
[]);
...
...
@@ -252,7 +272,7 @@ suite('AbstractKeybindingService', () => {
currentContextValue
=
{
key1
:
true
};
let
shouldPreventDefault
=
kbService
.
d
ispatch
(
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_K
);
let
shouldPreventDefault
=
kbService
.
testD
ispatch
(
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_K
);
assert
.
equal
(
shouldPreventDefault
,
true
);
assert
.
deepEqual
(
executeCommandCalls
,
[{
commandId
:
'
simpleCommand
'
,
...
...
@@ -268,7 +288,7 @@ suite('AbstractKeybindingService', () => {
// send Ctrl/Cmd + K
currentContextValue
=
{};
shouldPreventDefault
=
kbService
.
d
ispatch
(
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_K
);
shouldPreventDefault
=
kbService
.
testD
ispatch
(
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_K
);
assert
.
equal
(
shouldPreventDefault
,
true
);
assert
.
deepEqual
(
executeCommandCalls
,
[]);
assert
.
deepEqual
(
showMessageCalls
,
[]);
...
...
@@ -283,7 +303,7 @@ suite('AbstractKeybindingService', () => {
// send Ctrl/Cmd + X
currentContextValue
=
{};
shouldPreventDefault
=
kbService
.
d
ispatch
(
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_X
);
shouldPreventDefault
=
kbService
.
testD
ispatch
(
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_X
);
assert
.
equal
(
shouldPreventDefault
,
true
);
assert
.
deepEqual
(
executeCommandCalls
,
[{
commandId
:
'
chordCommand
'
,
...
...
@@ -312,7 +332,7 @@ suite('AbstractKeybindingService', () => {
// send Ctrl/Cmd + K
currentContextValue
=
{};
let
shouldPreventDefault
=
kbService
.
d
ispatch
(
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_K
);
let
shouldPreventDefault
=
kbService
.
testD
ispatch
(
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_K
);
assert
.
equal
(
shouldPreventDefault
,
true
);
assert
.
deepEqual
(
executeCommandCalls
,
[{
commandId
:
'
simpleCommand
'
,
...
...
@@ -330,7 +350,7 @@ suite('AbstractKeybindingService', () => {
currentContextValue
=
{
key1
:
true
};
shouldPreventDefault
=
kbService
.
d
ispatch
(
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_K
);
shouldPreventDefault
=
kbService
.
testD
ispatch
(
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_K
);
assert
.
equal
(
shouldPreventDefault
,
true
);
assert
.
deepEqual
(
executeCommandCalls
,
[{
commandId
:
'
simpleCommand
'
,
...
...
@@ -348,7 +368,7 @@ suite('AbstractKeybindingService', () => {
currentContextValue
=
{
key1
:
true
};
shouldPreventDefault
=
kbService
.
d
ispatch
(
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_X
);
shouldPreventDefault
=
kbService
.
testD
ispatch
(
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_X
);
assert
.
equal
(
shouldPreventDefault
,
false
);
assert
.
deepEqual
(
executeCommandCalls
,
[]);
assert
.
deepEqual
(
showMessageCalls
,
[]);
...
...
@@ -370,7 +390,7 @@ suite('AbstractKeybindingService', () => {
// send Ctrl/Cmd + K
currentContextValue
=
{};
let
shouldPreventDefault
=
kbService
.
d
ispatch
(
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_K
);
let
shouldPreventDefault
=
kbService
.
testD
ispatch
(
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_K
);
assert
.
equal
(
shouldPreventDefault
,
false
);
assert
.
deepEqual
(
executeCommandCalls
,
[{
commandId
:
'
simpleCommand
'
,
...
...
src/vs/platform/keybinding/test/common/mockKeybindingService.ts
浏览文件 @
411d8d06
...
...
@@ -6,7 +6,7 @@
import
{
ResolvedKeybinding
,
Keybinding
,
SimpleKeybinding
}
from
'
vs/base/common/keyCodes
'
;
import
Event
from
'
vs/base/common/event
'
;
import
{
IKeybindingService
,
IKeybindingEvent
,
IKeybindingItem2
}
from
'
vs/platform/keybinding/common/keybinding
'
;
import
{
IKeybindingService
,
IKeybindingEvent
,
IKeybindingItem2
,
IKeyboardEvent
}
from
'
vs/platform/keybinding/common/keybinding
'
;
import
{
IContextKey
,
IContextKeyService
,
IContextKeyServiceTarget
,
ContextKeyExpr
}
from
'
vs/platform/contextkey/common/contextkey
'
;
import
{
IResolveResult
}
from
'
vs/platform/keybinding/common/keybindingResolver
'
;
import
{
USLayoutResolvedKeybinding
}
from
'
vs/platform/keybinding/common/usLayoutResolvedKeybinding
'
;
...
...
@@ -36,7 +36,7 @@ class MockKeybindingContextKey<T> implements IContextKey<T> {
}
}
export
class
Mock
Keybinding
Service
implements
IContextKeyService
{
export
class
Mock
ContextKey
Service
implements
IContextKeyService
{
public
_serviceBrand
:
any
;
public
dispose
():
void
{
}
...
...
@@ -61,7 +61,7 @@ export class MockKeybindingService implements IContextKeyService {
}
}
export
class
MockKeybindingService
2
implements
IKeybindingService
{
export
class
MockKeybindingService
implements
IKeybindingService
{
public
_serviceBrand
:
any
;
public
get
onDidUpdateKeybindings
():
Event
<
IKeybindingEvent
>
{
...
...
@@ -80,6 +80,17 @@ export class MockKeybindingService2 implements IKeybindingService {
return
new
USLayoutResolvedKeybinding
(
keybinding
,
OS
);
}
public
resolveKeyboardEvent
(
keyboardEvent
:
IKeyboardEvent
):
ResolvedKeybinding
{
let
keybinding
=
new
SimpleKeybinding
(
keyboardEvent
.
ctrlKey
,
keyboardEvent
.
shiftKey
,
keyboardEvent
.
altKey
,
keyboardEvent
.
metaKey
,
keyboardEvent
.
keyCode
);
return
this
.
resolveKeybinding
(
keybinding
);
}
public
lookupKeybindings
(
commandId
:
string
):
ResolvedKeybinding
[]
{
return
[];
}
...
...
@@ -92,7 +103,7 @@ export class MockKeybindingService2 implements IKeybindingService {
return
0
;
}
public
resolve
(
keybinding
:
SimpleKeybinding
,
target
:
IContextKeyServiceTarget
):
IResolveResult
{
public
softDispatch
(
keybinding
:
IKeyboardEvent
,
target
:
IContextKeyServiceTarget
):
IResolveResult
{
return
null
;
}
}
src/vs/workbench/parts/preferences/browser/keybindingWidgets.ts
浏览文件 @
411d8d06
...
...
@@ -58,7 +58,7 @@ class KeybindingInputWidget extends Widget {
}
private
printKeybinding
(
keyboardEvent
:
IKeyboardEvent
):
void
{
const
keybinding
=
this
.
keybindingService
.
resolveKeyb
inding
(
keyboardEvent
.
toRuntimeKeybinding
()
);
const
keybinding
=
this
.
keybindingService
.
resolveKeyb
oardEvent
(
keyboardEvent
);
this
.
inputBox
.
value
=
keybinding
.
getUserSettingsLabel
().
toLowerCase
();
this
.
inputBox
.
inputElement
.
title
=
'
keyCode:
'
+
keyboardEvent
.
browserEvent
.
keyCode
;
this
.
_onKeybinding
.
fire
(
keybinding
);
...
...
src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts
浏览文件 @
411d8d06
...
...
@@ -227,8 +227,7 @@ export class TerminalInstance implements ITerminalInstance {
// Skip processing by xterm.js of keyboard events that resolve to commands described
// within commandsToSkipShell
const
standardKeyboardEvent
=
new
StandardKeyboardEvent
(
event
);
const
keybinding
=
standardKeyboardEvent
.
toRuntimeKeybinding
();
const
resolveResult
=
this
.
_keybindingService
.
resolve
(
keybinding
,
standardKeyboardEvent
.
target
);
const
resolveResult
=
this
.
_keybindingService
.
softDispatch
(
standardKeyboardEvent
,
standardKeyboardEvent
.
target
);
if
(
resolveResult
&&
this
.
_skipTerminalCommands
.
some
(
k
=>
k
===
resolveResult
.
commandId
))
{
event
.
preventDefault
();
return
false
;
...
...
src/vs/workbench/parts/terminal/test/electron-browser/terminalInstance.test.ts
浏览文件 @
411d8d06
...
...
@@ -15,7 +15,7 @@ import { TerminalInstance } from 'vs/workbench/parts/terminal/electron-browser/t
import
{
IShellLaunchConfig
}
from
'
vs/workbench/parts/terminal/common/terminal
'
;
import
{
TestInstantiationService
}
from
'
vs/platform/instantiation/test/common/instantiationServiceMock
'
;
import
{
TestMessageService
,
TestContextService
}
from
'
vs/workbench/test/workbenchTestServices
'
;
import
{
Mock
KeybindingService
,
MockKeybindingService2
}
from
'
vs/platform/keybinding/test/common/mockKeybindingService
'
;
import
{
Mock
ContextKeyService
,
MockKeybindingService
}
from
'
vs/platform/keybinding/test/common/mockKeybindingService
'
;
import
{
IKeybindingService
}
from
'
vs/platform/keybinding/common/keybinding
'
;
import
{
IContextKeyService
}
from
'
vs/platform/contextkey/common/contextkey
'
;
...
...
@@ -81,8 +81,8 @@ suite('Workbench - TerminalInstance', () => {
let
configHelper
:
{
config
:
{
cwd
:
string
}
};
setup
(()
=>
{
let
contextKeyService
=
new
Mock
Keybinding
Service
();
let
keybindingService
=
new
MockKeybindingService
2
();
let
contextKeyService
=
new
Mock
ContextKey
Service
();
let
keybindingService
=
new
MockKeybindingService
();
let
terminalFocusContextKey
=
contextKeyService
.
createKey
(
'
test
'
,
false
);
instantiationService
=
new
TestInstantiationService
();
instantiationService
.
stub
(
IMessageService
,
new
TestMessageService
());
...
...
src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts
浏览文件 @
411d8d06
...
...
@@ -18,7 +18,7 @@ import { USLayoutResolvedKeybinding } from 'vs/platform/keybinding/common/usLayo
import
{
IStatusbarService
}
from
'
vs/platform/statusbar/common/statusbar
'
;
import
{
KeybindingResolver
}
from
'
vs/platform/keybinding/common/keybindingResolver
'
;
import
{
ICommandService
}
from
'
vs/platform/commands/common/commands
'
;
import
{
IKeybindingEvent
,
IUserFriendlyKeybinding
,
KeybindingSource
}
from
'
vs/platform/keybinding/common/keybinding
'
;
import
{
IKeybindingEvent
,
IUserFriendlyKeybinding
,
KeybindingSource
,
IKeyboardEvent
}
from
'
vs/platform/keybinding/common/keybinding
'
;
import
{
ContextKeyExpr
,
IContextKeyService
}
from
'
vs/platform/contextkey/common/contextkey
'
;
import
{
IKeybindingRule
,
IKeybindingItem
,
KeybindingsRegistry
}
from
'
vs/platform/keybinding/common/keybindingsRegistry
'
;
import
{
Registry
}
from
'
vs/platform/platform
'
;
...
...
@@ -229,6 +229,9 @@ export class FancyResolvedKeybinding extends ResolvedKeybinding {
}
private
_getDispatchPart
(
keybinding
:
SimpleKeybinding
):
string
{
if
(
keybinding
.
isModifierKey
())
{
return
null
;
}
let
result
=
''
;
if
(
keybinding
.
ctrlKey
)
{
...
...
@@ -291,7 +294,7 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService {
this
.
toDispose
.
push
(
dom
.
addDisposableListener
(
windowElement
,
dom
.
EventType
.
KEY_DOWN
,
(
e
:
KeyboardEvent
)
=>
{
let
keyEvent
=
new
StandardKeyboardEvent
(
e
);
let
shouldPreventDefault
=
this
.
_dispatch
(
keyEvent
.
toRuntimeKeybinding
()
,
keyEvent
.
target
);
let
shouldPreventDefault
=
this
.
_dispatch
(
keyEvent
,
keyEvent
.
target
);
if
(
shouldPreventDefault
)
{
keyEvent
.
preventDefault
();
}
...
...
@@ -339,7 +342,7 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService {
const
item
=
items
[
i
];
const
when
=
(
item
.
when
?
item
.
when
.
normalize
()
:
null
);
const
keybinding
=
item
.
keybinding
;
const
resolvedKeybinding
=
(
keybinding
?
this
.
_createResolved
Keybinding
(
keybinding
)
:
null
);
const
resolvedKeybinding
=
(
keybinding
?
this
.
resolve
Keybinding
(
keybinding
)
:
null
);
result
[
resultLen
++
]
=
new
ResolvedKeybindingItem
(
resolvedKeybinding
,
item
.
command
,
item
.
commandArgs
,
when
,
isDefault
);
}
...
...
@@ -360,10 +363,21 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService {
return
extraUserKeybindings
.
map
((
k
,
i
)
=>
KeybindingIO
.
readKeybindingItem
(
k
,
i
,
OS
));
}
p
rotected
_createResolved
Keybinding
(
kb
:
Keybinding
):
ResolvedKeybinding
{
p
ublic
resolve
Keybinding
(
kb
:
Keybinding
):
ResolvedKeybinding
{
return
new
FancyResolvedKeybinding
(
kb
);
}
public
resolveKeyboardEvent
(
keyboardEvent
:
IKeyboardEvent
):
ResolvedKeybinding
{
let
keybinding
=
new
SimpleKeybinding
(
keyboardEvent
.
ctrlKey
,
keyboardEvent
.
shiftKey
,
keyboardEvent
.
altKey
,
keyboardEvent
.
metaKey
,
keyboardEvent
.
keyCode
);
return
this
.
resolveKeybinding
(
keybinding
);
}
private
_handleKeybindingsExtensionPointUser
(
isBuiltin
:
boolean
,
keybindings
:
ContributedKeyBinding
|
ContributedKeyBinding
[],
collector
:
ExtensionMessageCollector
):
boolean
{
if
(
isContributedKeyBindingsArray
(
keybindings
))
{
let
commandAdded
=
false
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录