Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
28c5b1f6
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,发现更多精彩内容 >>
提交
28c5b1f6
编写于
5月 22, 2017
作者:
A
Alex Dima
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Generate screen reader explanations for cursor movements
上级
d7b5d345
变更
5
展开全部
隐藏空白更改
内联
并排
Showing
5 changed file
with
1212 addition
and
7 deletion
+1212
-7
src/vs/editor/common/controller/accGenerator.ts
src/vs/editor/common/controller/accGenerator.ts
+194
-0
src/vs/editor/common/controller/cursor.ts
src/vs/editor/common/controller/cursor.ts
+15
-2
src/vs/editor/common/view/viewEvents.ts
src/vs/editor/common/view/viewEvents.ts
+6
-1
src/vs/editor/contrib/wordOperations/common/wordOperations.ts
...vs/editor/contrib/wordOperations/common/wordOperations.ts
+3
-1
src/vs/editor/test/common/controller/cursor.test.ts
src/vs/editor/test/common/controller/cursor.test.ts
+994
-3
未找到文件。
src/vs/editor/common/controller/accGenerator.ts
0 → 100644
浏览文件 @
28c5b1f6
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'
use strict
'
;
import
{
Position
}
from
'
vs/editor/common/core/position
'
;
import
*
as
nls
from
'
vs/nls
'
;
import
{
Range
}
from
'
vs/editor/common/core/range
'
;
import
{
IModel
}
from
"
vs/editor/common/editorCommon
"
;
import
{
Selection
}
from
'
vs/editor/common/core/selection
'
;
export
class
ScreenReaderMessageGenerator
{
public
static
xSelected
(
x
:
string
):
string
{
return
nls
.
localize
(
{
key
:
'
x.selected
'
,
comment
:
[
'
A piece of text was added to the selection (this should be a message suitable for a Screen Reader).
'
]
},
"
{0}
\n
Selected
"
,
x
);
}
public
static
xUnselected
(
x
:
string
):
string
{
return
nls
.
localize
(
{
key
:
'
x.unselected
'
,
comment
:
[
'
A piece of text was removed from the selection (this should be a message suitable for a Screen Reader).
'
]
},
"
{0}
\n
Unselected
"
,
x
);
}
public
static
xCharsSelected
(
x
:
number
):
string
{
return
nls
.
localize
(
{
key
:
'
x.chars.selected
'
,
comment
:
[
'
A large number of characters were added to the selection (this should be a message suitable for a Screen Reader).
'
]
},
"
{0}
\n
Characters selected
"
,
x
);
}
public
static
xCharsUnselected
(
x
:
number
):
string
{
return
nls
.
localize
(
{
key
:
'
x.chars.unselected
'
,
comment
:
[
'
A large number of characters were removed from the selection (this should be a message suitable for a Screen Reader).
'
]
},
"
{0}
\n
Characters unselected
"
,
x
);
}
public
static
generateMessage
(
source
:
string
,
model
:
IModel
,
oldModelId
:
number
,
oldSelection
:
Selection
,
newModelId
:
number
,
newSelection
:
Selection
):
string
{
if
(
oldModelId
===
newModelId
)
{
return
this
.
_cursorChangeMessage
(
source
,
model
,
oldSelection
,
newSelection
);
}
return
'
TODO
'
;
}
private
static
_cursorChangeMessage
(
source
:
string
,
model
:
IModel
,
oldSelection
:
Selection
,
newSelection
:
Selection
):
string
{
if
(
oldSelection
.
equalsRange
(
newSelection
))
{
return
''
;
}
if
(
oldSelection
.
isEmpty
())
{
if
(
newSelection
.
isEmpty
())
{
// ...[]... => ...[]...
return
this
.
_cursorMoveMessage
(
source
,
model
,
oldSelection
.
getPosition
(),
newSelection
.
getPosition
());
}
// ...[]... => ...[x]...:
return
this
.
_cursorSelectedMessage
(
model
,
newSelection
);
}
if
(
newSelection
.
isEmpty
())
{
if
(
oldSelection
.
containsPosition
(
newSelection
.
getPosition
()))
{
// ...a[xy]b... => ...a[]xyb... or ...ax[]yb... or ...axy[]b...
return
this
.
_cursorUnselectedMessage
(
model
,
oldSelection
);
}
// moved away from the old selection and collapsed it
return
this
.
_cursorMoveMessage
(
source
,
model
,
oldSelection
.
getPosition
(),
newSelection
.
getPosition
())
+
'
\n
'
+
this
.
_cursorUnselectedMessage
(
model
,
oldSelection
);
}
// ...[x]... => ...[y]...
if
(
newSelection
.
getStartPosition
().
equals
(
oldSelection
.
getStartPosition
()))
{
// ...a[x]... => ...a[y]...
if
(
newSelection
.
getEndPosition
().
isBefore
(
oldSelection
.
getEndPosition
()))
{
// ...a[xy]... => ...a[x]y...
return
this
.
_cursorUnselectedMessage
(
model
,
new
Range
(
newSelection
.
endLineNumber
,
newSelection
.
endColumn
,
oldSelection
.
endLineNumber
,
oldSelection
.
endColumn
));
}
// ...a[x]y... => ...a[xy]...
return
this
.
_cursorSelectedMessage
(
model
,
new
Range
(
oldSelection
.
endLineNumber
,
oldSelection
.
endColumn
,
newSelection
.
endLineNumber
,
newSelection
.
endColumn
));
}
if
(
newSelection
.
getEndPosition
().
equals
(
oldSelection
.
getEndPosition
()))
{
// ...[x]a... => ...[y]a...
if
(
newSelection
.
getStartPosition
().
isBefore
(
oldSelection
.
getStartPosition
()))
{
// ...y[x]a... => ...[yx]a...
return
this
.
_cursorSelectedMessage
(
model
,
new
Range
(
newSelection
.
startLineNumber
,
newSelection
.
startColumn
,
oldSelection
.
startLineNumber
,
oldSelection
.
startColumn
));
}
// ...[yx]a... => ...y[x]a...
return
this
.
_cursorUnselectedMessage
(
model
,
new
Range
(
oldSelection
.
startLineNumber
,
oldSelection
.
startColumn
,
newSelection
.
startLineNumber
,
newSelection
.
startColumn
));
}
// weird jump
return
this
.
_cursorSelectedMessage
(
model
,
newSelection
)
+
'
\n
'
+
this
.
_cursorUnselectedMessage
(
model
,
oldSelection
);
}
private
static
_cursorMoveMessage
(
source
:
string
,
model
:
IModel
,
oldPosition
:
Position
,
newPosition
:
Position
):
string
{
if
(
source
===
'
moveWordCommand
'
)
{
return
model
.
getValueInRange
(
new
Range
(
oldPosition
.
lineNumber
,
oldPosition
.
column
,
newPosition
.
lineNumber
,
newPosition
.
column
));
}
const
oldLineNumber
=
oldPosition
.
lineNumber
;
const
oldColumn
=
oldPosition
.
column
;
const
newLineNumber
=
newPosition
.
lineNumber
;
const
newColumn
=
newPosition
.
column
;
// check going down via right arrow
if
(
newLineNumber
===
oldLineNumber
+
1
&&
newColumn
===
1
&&
oldColumn
===
model
.
getLineMaxColumn
(
oldLineNumber
))
{
return
this
.
_cursorCharMessage
(
model
,
newPosition
);
}
// check going up via up arrow
if
(
newLineNumber
===
oldLineNumber
-
1
&&
newColumn
===
model
.
getLineMaxColumn
(
newLineNumber
)
&&
oldColumn
===
1
)
{
return
this
.
_cursorCharMessage
(
model
,
newPosition
);
}
const
lineCount
=
model
.
getLineCount
();
if
(
oldLineNumber
!==
newLineNumber
)
{
if
(
newLineNumber
===
lineCount
)
{
// Last line does not have an EOL
return
model
.
getLineContent
(
newLineNumber
);
}
return
model
.
getLineContent
(
newLineNumber
)
+
model
.
getEOL
();
}
return
this
.
_cursorCharMessage
(
model
,
newPosition
);
}
private
static
_cursorCharMessage
(
model
:
IModel
,
position
:
Position
):
string
{
const
lineNumber
=
position
.
lineNumber
;
const
column
=
position
.
column
;
const
maxLineColumn
=
model
.
getLineMaxColumn
(
lineNumber
);
if
(
column
===
maxLineColumn
)
{
const
lineCount
=
model
.
getLineCount
();
if
(
lineNumber
===
lineCount
)
{
// At the end of the file
return
''
;
}
return
model
.
getEOL
();
}
return
model
.
getLineContent
(
lineNumber
).
charAt
(
column
-
1
);
}
private
static
_cursorSelectedMessage
(
model
:
IModel
,
range
:
Range
):
string
{
const
valueLength
=
model
.
getValueLengthInRange
(
range
);
if
(
valueLength
>
512
)
{
return
this
.
xCharsSelected
(
valueLength
);
}
return
this
.
xSelected
(
model
.
getValueInRange
(
range
));
}
private
static
_cursorUnselectedMessage
(
model
:
IModel
,
range
:
Range
):
string
{
const
valueLength
=
model
.
getValueLengthInRange
(
range
);
if
(
valueLength
>
512
)
{
return
this
.
xCharsUnselected
(
valueLength
);
}
return
this
.
xUnselected
(
model
.
getValueInRange
(
range
));
}
}
src/vs/editor/common/controller/cursor.ts
浏览文件 @
28c5b1f6
...
@@ -21,6 +21,7 @@ import { CursorChangeReason } from 'vs/editor/common/controller/cursorEvents';
...
@@ -21,6 +21,7 @@ import { CursorChangeReason } from 'vs/editor/common/controller/cursorEvents';
import
{
IViewModel
}
from
"
vs/editor/common/viewModel/viewModel
"
;
import
{
IViewModel
}
from
"
vs/editor/common/viewModel/viewModel
"
;
import
*
as
viewEvents
from
'
vs/editor/common/view/viewEvents
'
;
import
*
as
viewEvents
from
'
vs/editor/common/view/viewEvents
'
;
import
Event
,
{
Emitter
}
from
'
vs/base/common/event
'
;
import
Event
,
{
Emitter
}
from
'
vs/base/common/event
'
;
import
{
ScreenReaderMessageGenerator
}
from
"
vs/editor/common/controller/accGenerator
"
;
function
containsLineMappingChanged
(
events
:
viewEvents
.
ViewEvent
[]):
boolean
{
function
containsLineMappingChanged
(
events
:
viewEvents
.
ViewEvent
[]):
boolean
{
for
(
let
i
=
0
,
len
=
events
.
length
;
i
<
len
;
i
++
)
{
for
(
let
i
=
0
,
len
=
events
.
length
;
i
<
len
;
i
++
)
{
...
@@ -56,7 +57,7 @@ export class CursorStateChangedEvent {
...
@@ -56,7 +57,7 @@ export class CursorStateChangedEvent {
/**
/**
* A snapshot of the cursor and the model state
* A snapshot of the cursor and the model state
*/
*/
class
CursorModelState
{
export
class
CursorModelState
{
public
readonly
modelVersionId
:
number
;
public
readonly
modelVersionId
:
number
;
public
readonly
cursorState
:
CursorState
[];
public
readonly
cursorState
:
CursorState
[];
...
@@ -380,8 +381,20 @@ export class Cursor extends viewEvents.ViewEventEmitter implements ICursors {
...
@@ -380,8 +381,20 @@ export class Cursor extends viewEvents.ViewEventEmitter implements ICursors {
const
selections
=
this
.
_cursors
.
getSelections
();
const
selections
=
this
.
_cursors
.
getSelections
();
const
viewSelections
=
this
.
_cursors
.
getViewSelections
();
const
viewSelections
=
this
.
_cursors
.
getViewSelections
();
let
screenReaderMessage
:
string
=
null
;
if
(
oldState
)
{
screenReaderMessage
=
ScreenReaderMessageGenerator
.
generateMessage
(
source
,
this
.
_model
,
oldState
.
modelVersionId
,
oldState
.
cursorState
[
0
].
modelState
.
selection
,
newState
.
modelVersionId
,
newState
.
cursorState
[
0
].
modelState
.
selection
);
}
// Let the view get the event first.
// Let the view get the event first.
this
.
_emit
([
new
viewEvents
.
ViewCursorStateChangedEvent
(
viewSelections
,
isInEditableRange
)]);
this
.
_emit
([
new
viewEvents
.
ViewCursorStateChangedEvent
(
viewSelections
,
isInEditableRange
,
screenReaderMessage
)]);
// Only after the view has been notified, let the rest of the world know...
// Only after the view has been notified, let the rest of the world know...
this
.
_onDidChange
.
fire
(
new
CursorStateChangedEvent
(
selections
,
source
||
'
keyboard
'
,
reason
));
this
.
_onDidChange
.
fire
(
new
CursorStateChangedEvent
(
selections
,
source
||
'
keyboard
'
,
reason
));
...
...
src/vs/editor/common/view/viewEvents.ts
浏览文件 @
28c5b1f6
...
@@ -70,10 +70,15 @@ export class ViewCursorStateChangedEvent {
...
@@ -70,10 +70,15 @@ export class ViewCursorStateChangedEvent {
* Is the primary cursor in the editable range?
* Is the primary cursor in the editable range?
*/
*/
public
readonly
isInEditableRange
:
boolean
;
public
readonly
isInEditableRange
:
boolean
;
/**
* A message that can be presented to screen readers.
*/
public
readonly
screenReaderMessage
:
string
;
constructor
(
selections
:
Selection
[],
isInEditableRange
:
boolean
)
{
constructor
(
selections
:
Selection
[],
isInEditableRange
:
boolean
,
screenReaderMessage
:
string
)
{
this
.
selections
=
selections
;
this
.
selections
=
selections
;
this
.
isInEditableRange
=
isInEditableRange
;
this
.
isInEditableRange
=
isInEditableRange
;
this
.
screenReaderMessage
=
screenReaderMessage
;
}
}
}
}
...
...
src/vs/editor/contrib/wordOperations/common/wordOperations.ts
浏览文件 @
28c5b1f6
...
@@ -15,6 +15,8 @@ import { Range } from 'vs/editor/common/core/range';
...
@@ -15,6 +15,8 @@ import { Range } from 'vs/editor/common/core/range';
import
{
WordNavigationType
,
WordOperations
}
from
'
vs/editor/common/controller/cursorWordOperations
'
;
import
{
WordNavigationType
,
WordOperations
}
from
'
vs/editor/common/controller/cursorWordOperations
'
;
import
{
ReplaceCommand
}
from
'
vs/editor/common/commands/replaceCommand
'
;
import
{
ReplaceCommand
}
from
'
vs/editor/common/commands/replaceCommand
'
;
import
{
getMapForWordSeparators
,
WordCharacterClassifier
}
from
"
vs/editor/common/controller/wordCharacterClassifier
"
;
import
{
getMapForWordSeparators
,
WordCharacterClassifier
}
from
"
vs/editor/common/controller/wordCharacterClassifier
"
;
import
{
CursorState
}
from
"
vs/editor/common/controller/cursorCommon
"
;
import
{
CursorChangeReason
}
from
"
vs/editor/common/controller/cursorEvents
"
;
export
interface
MoveWordOptions
extends
ICommandOptions
{
export
interface
MoveWordOptions
extends
ICommandOptions
{
inSelectionMode
:
boolean
;
inSelectionMode
:
boolean
;
...
@@ -44,7 +46,7 @@ export abstract class MoveWordCommand extends EditorCommand {
...
@@ -44,7 +46,7 @@ export abstract class MoveWordCommand extends EditorCommand {
return
this
.
_moveTo
(
sel
,
outPosition
,
this
.
_inSelectionMode
);
return
this
.
_moveTo
(
sel
,
outPosition
,
this
.
_inSelectionMode
);
});
});
editor
.
setSelections
(
result
);
editor
.
_getCursors
().
setStates
(
'
moveWordCommand
'
,
CursorChangeReason
.
NotSet
,
result
.
map
(
r
=>
CursorState
.
fromModelSelection
(
r
))
);
if
(
result
.
length
===
1
)
{
if
(
result
.
length
===
1
)
{
const
pos
=
new
Position
(
result
[
0
].
positionLineNumber
,
result
[
0
].
positionColumn
);
const
pos
=
new
Position
(
result
[
0
].
positionLineNumber
,
result
[
0
].
positionColumn
);
editor
.
revealPosition
(
pos
,
false
,
true
);
editor
.
revealPosition
(
pos
,
false
,
true
);
...
...
src/vs/editor/test/common/controller/cursor.test.ts
浏览文件 @
28c5b1f6
此差异已折叠。
点击以展开。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录