Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
edf62453
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 搜索 >>
提交
edf62453
编写于
9月 27, 2016
作者:
A
Alex Dima
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Fixes #12329: Prevent that edits produce invalid UTF-16
上级
a2ae3c7e
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
276 addition
and
38 deletion
+276
-38
src/vs/base/common/strings.ts
src/vs/base/common/strings.ts
+7
-9
src/vs/editor/common/controller/cursorMoveHelper.ts
src/vs/editor/common/controller/cursorMoveHelper.ts
+3
-4
src/vs/editor/common/model/textModel.ts
src/vs/editor/common/model/textModel.ts
+71
-20
src/vs/editor/test/common/model/editableTextModel.test.ts
src/vs/editor/test/common/model/editableTextModel.test.ts
+72
-1
src/vs/editor/test/common/model/editableTextModelTestUtils.ts
...vs/editor/test/common/model/editableTextModelTestUtils.ts
+5
-3
src/vs/editor/test/common/model/textModel.test.ts
src/vs/editor/test/common/model/textModel.test.ts
+118
-1
未找到文件。
src/vs/base/common/strings.ts
浏览文件 @
edf62453
...
...
@@ -396,15 +396,13 @@ export function commonSuffixLength(a: string, b: string): number {
// }
// return chrCode;
//}
//export function isLeadSurrogate(chr:string) {
// let chrCode = chr.charCodeAt(0);
// return ;
//}
//
//export function isTrailSurrogate(chr:string) {
// let chrCode = chr.charCodeAt(0);
// return 0xDC00 <= chrCode && chrCode <= 0xDFFF;
//}
export
function
isHighSurrogate
(
charCode
:
number
):
boolean
{
return
(
0xD800
<=
charCode
&&
charCode
<=
0xDBFF
);
}
export
function
isLowSurrogate
(
charCode
:
number
):
boolean
{
return
(
0xDC00
<=
charCode
&&
charCode
<=
0xDFFF
);
}
export
function
isFullWidthCharacter
(
charCode
:
number
):
boolean
{
// Do a cheap trick to better support wrapping of wide characters, treat them as 2 columns
...
...
src/vs/editor/common/controller/cursorMoveHelper.ts
浏览文件 @
edf62453
...
...
@@ -6,6 +6,7 @@
import
{
IPosition
}
from
'
vs/editor/common/editorCommon
'
;
import
{
Selection
}
from
'
vs/editor/common/core/selection
'
;
import
*
as
strings
from
'
vs/base/common/strings
'
;
export
interface
IMoveResult
{
lineNumber
:
number
;
...
...
@@ -51,13 +52,11 @@ export interface IConfiguration {
}
function
isHighSurrogate
(
model
:
ICursorMoveHelperModel
,
lineNumber
:
number
,
column
:
number
)
{
let
code
=
model
.
getLineContent
(
lineNumber
).
charCodeAt
(
column
-
1
);
return
0xD800
<=
code
&&
code
<=
0xDBFF
;
return
strings
.
isHighSurrogate
(
model
.
getLineContent
(
lineNumber
).
charCodeAt
(
column
-
1
));
}
function
isLowSurrogate
(
model
:
ICursorMoveHelperModel
,
lineNumber
:
number
,
column
:
number
)
{
let
code
=
model
.
getLineContent
(
lineNumber
).
charCodeAt
(
column
-
1
);
return
0xDC00
<=
code
&&
code
<=
0xDFFF
;
return
strings
.
isLowSurrogate
(
model
.
getLineContent
(
lineNumber
).
charCodeAt
(
column
-
1
));
}
export
class
CursorMoveHelper
{
...
...
src/vs/editor/common/model/textModel.ts
浏览文件 @
edf62453
...
...
@@ -196,7 +196,7 @@ export class TextModel extends OrderGuaranteeEventEmitter implements editorCommo
}
public
getOffsetAt
(
rawPosition
:
editorCommon
.
IPosition
):
number
{
let
position
=
this
.
validatePosition
(
rawPosition
);
let
position
=
this
.
_validatePosition
(
rawPosition
.
lineNumber
,
rawPosition
.
column
,
false
);
this
.
_ensureLineStarts
();
return
this
.
_lineStarts
.
getAccumulatedValue
(
position
.
lineNumber
-
2
)
+
position
.
column
-
1
;
}
...
...
@@ -611,35 +611,86 @@ export class TextModel extends OrderGuaranteeEventEmitter implements editorCommo
return
lineNumber
;
}
public
validatePosition
(
position
:
editorCommon
.
IPosition
):
Position
{
var
lineNumber
=
position
.
lineNumber
?
position
.
lineNumber
:
1
;
var
column
=
position
.
column
?
position
.
column
:
1
;
/**
* @param strict Do NOT allow a position inside a high-low surrogate pair
*/
private
_validatePosition
(
_lineNumber
:
number
,
_column
:
number
,
strict
:
boolean
):
Position
{
const
lineNumber
=
Math
.
floor
(
typeof
_lineNumber
===
'
number
'
?
_lineNumber
:
1
);
const
column
=
Math
.
floor
(
typeof
_column
===
'
number
'
?
_column
:
1
);
if
(
lineNumber
<
1
)
{
lineNumber
=
1
;
column
=
1
;
return
new
Position
(
1
,
1
);
}
else
if
(
lineNumber
>
this
.
_lines
.
length
)
{
lineNumber
=
this
.
_lines
.
length
;
column
=
this
.
getLineMaxColumn
(
lineNumber
);
if
(
lineNumber
>
this
.
_lines
.
length
)
{
return
new
Position
(
this
.
_lines
.
length
,
this
.
getLineMaxColumn
(
this
.
_lines
.
length
)
);
}
else
{
var
maxColumn
=
this
.
getLineMaxColumn
(
lineNumber
);
if
(
column
<
1
)
{
column
=
1
;
}
else
if
(
column
>
maxColumn
)
{
column
=
maxColumn
;
if
(
column
<=
1
)
{
return
new
Position
(
lineNumber
,
1
);
}
const
maxColumn
=
this
.
getLineMaxColumn
(
lineNumber
);
if
(
column
>=
maxColumn
)
{
return
new
Position
(
lineNumber
,
maxColumn
);
}
if
(
strict
)
{
// If the position would end up in the middle of a high-low surrogate pair,
// we move it to before the pair
// !!At this point, column > 1
const
charCodeBefore
=
this
.
_lines
[
lineNumber
-
1
].
text
.
charCodeAt
(
column
-
2
);
if
(
strings
.
isHighSurrogate
(
charCodeBefore
))
{
return
new
Position
(
lineNumber
,
column
-
1
);
}
}
return
new
Position
(
lineNumber
,
column
);
}
public
validateRange
(
range
:
editorCommon
.
IRange
):
Range
{
var
start
=
this
.
validatePosition
(
new
Position
(
range
.
startLineNumber
,
range
.
startColumn
));
var
end
=
this
.
validatePosition
(
new
Position
(
range
.
endLineNumber
,
range
.
endColumn
));
return
new
Range
(
start
.
lineNumber
,
start
.
column
,
end
.
lineNumber
,
end
.
column
);
public
validatePosition
(
position
:
editorCommon
.
IPosition
):
Position
{
return
this
.
_validatePosition
(
position
.
lineNumber
,
position
.
column
,
true
);
}
public
validateRange
(
_range
:
editorCommon
.
IRange
):
Range
{
const
start
=
this
.
_validatePosition
(
_range
.
startLineNumber
,
_range
.
startColumn
,
false
);
const
end
=
this
.
_validatePosition
(
_range
.
endLineNumber
,
_range
.
endColumn
,
false
);
const
startLineNumber
=
start
.
lineNumber
;
const
startColumn
=
start
.
column
;
const
endLineNumber
=
end
.
lineNumber
;
const
endColumn
=
end
.
column
;
const
startLineText
=
this
.
_lines
[
startLineNumber
-
1
].
text
;
const
endLineText
=
this
.
_lines
[
endLineNumber
-
1
].
text
;
const
charCodeBeforeStart
=
(
startColumn
>
1
?
startLineText
.
charCodeAt
(
startColumn
-
2
)
:
0
);
const
charCodeBeforeEnd
=
(
endColumn
>
1
&&
endColumn
<=
endLineText
.
length
?
endLineText
.
charCodeAt
(
endColumn
-
2
)
:
0
);
const
startInsideSurrogatePair
=
strings
.
isHighSurrogate
(
charCodeBeforeStart
);
const
endInsideSurrogatePair
=
strings
.
isHighSurrogate
(
charCodeBeforeEnd
);
if
(
!
startInsideSurrogatePair
&&
!
endInsideSurrogatePair
)
{
return
new
Range
(
startLineNumber
,
startColumn
,
endLineNumber
,
endColumn
);
}
if
(
startLineNumber
===
endLineNumber
&&
startColumn
===
endColumn
)
{
// do not expand a collapsed range, simply move it to a valid location
return
new
Range
(
startLineNumber
,
startColumn
-
1
,
endLineNumber
,
endColumn
-
1
);
}
if
(
startInsideSurrogatePair
&&
endInsideSurrogatePair
)
{
// expand range at both ends
return
new
Range
(
startLineNumber
,
startColumn
-
1
,
endLineNumber
,
endColumn
+
1
);
}
if
(
startInsideSurrogatePair
)
{
// only expand range at the start
return
new
Range
(
startLineNumber
,
startColumn
-
1
,
endLineNumber
,
endColumn
);
}
// only expand range at the end
return
new
Range
(
startLineNumber
,
startColumn
,
endLineNumber
,
endColumn
+
1
);
}
public
modifyPosition
(
rawPosition
:
editorCommon
.
IPosition
,
offset
:
number
)
:
Position
{
...
...
src/vs/editor/test/common/model/editableTextModel.test.ts
浏览文件 @
edf62453
...
...
@@ -527,7 +527,78 @@ suite('EditorModel - EditableTextModel.applyEdits', () => {
};
}
test
(
'
high-low surrogates 1
'
,
()
=>
{
testApplyEditsWithSyncedModels
(
[
'
📚some
'
,
'
very nice
'
,
'
text
'
],
[
editOp
(
1
,
2
,
1
,
2
,
[
'
a
'
])
],
[
'
a📚some
'
,
'
very nice
'
,
'
text
'
],
/*inputEditsAreInvalid*/
true
);
});
test
(
'
high-low surrogates 2
'
,
()
=>
{
testApplyEditsWithSyncedModels
(
[
'
📚some
'
,
'
very nice
'
,
'
text
'
],
[
editOp
(
1
,
2
,
1
,
3
,
[
'
a
'
])
],
[
'
asome
'
,
'
very nice
'
,
'
text
'
],
/*inputEditsAreInvalid*/
true
);
});
test
(
'
high-low surrogates 3
'
,
()
=>
{
testApplyEditsWithSyncedModels
(
[
'
📚some
'
,
'
very nice
'
,
'
text
'
],
[
editOp
(
1
,
1
,
1
,
2
,
[
'
a
'
])
],
[
'
asome
'
,
'
very nice
'
,
'
text
'
],
/*inputEditsAreInvalid*/
true
);
});
test
(
'
high-low surrogates 4
'
,
()
=>
{
testApplyEditsWithSyncedModels
(
[
'
📚some
'
,
'
very nice
'
,
'
text
'
],
[
editOp
(
1
,
1
,
1
,
3
,
[
'
a
'
])
],
[
'
asome
'
,
'
very nice
'
,
'
text
'
],
/*inputEditsAreInvalid*/
true
);
});
test
(
'
Bug 19872: Undo is funky
'
,
()
=>
{
testApplyEditsWithSyncedModels
(
...
...
src/vs/editor/test/common/model/editableTextModelTestUtils.ts
浏览文件 @
edf62453
...
...
@@ -12,7 +12,7 @@ import {MirrorModel2} from 'vs/editor/common/model/mirrorModel2';
import
{
TextModel
}
from
'
vs/editor/common/model/textModel
'
;
import
{
Position
}
from
'
vs/editor/common/core/position
'
;
export
function
testApplyEditsWithSyncedModels
(
original
:
string
[],
edits
:
editorCommon
.
IIdentifiedSingleEditOperation
[],
expected
:
string
[]):
void
{
export
function
testApplyEditsWithSyncedModels
(
original
:
string
[],
edits
:
editorCommon
.
IIdentifiedSingleEditOperation
[],
expected
:
string
[]
,
inputEditsAreInvalid
:
boolean
=
false
):
void
{
var
originalStr
=
original
.
join
(
'
\n
'
);
var
expectedStr
=
expected
.
join
(
'
\n
'
);
...
...
@@ -31,8 +31,10 @@ export function testApplyEditsWithSyncedModels(original:string[], edits:editorCo
// Assert the inverse edits brought back model to original state
assert
.
deepEqual
(
model
.
getValue
(
editorCommon
.
EndOfLinePreference
.
LF
),
originalStr
);
// Assert the inverse of the inverse edits are the original edits
assert
.
deepEqual
(
inverseInverseEdits
,
edits
);
if
(
!
inputEditsAreInvalid
)
{
// Assert the inverse of the inverse edits are the original edits
assert
.
deepEqual
(
inverseInverseEdits
,
edits
);
}
assertMirrorModels
();
});
...
...
src/vs/editor/test/common/model/textModel.test.ts
浏览文件 @
edf62453
...
...
@@ -437,7 +437,7 @@ suite('Editor Model - TextModel', () => {
test
(
'
validatePosition
'
,
()
=>
{
var
m
=
new
TextModel
([],
TextModel
.
toRawText
(
'
line one
\n
line two
'
,
TextModel
.
DEFAULT_CREATION_OPTIONS
));
let
m
=
new
TextModel
([],
TextModel
.
toRawText
(
'
line one
\n
line two
'
,
TextModel
.
DEFAULT_CREATION_OPTIONS
));
assert
.
deepEqual
(
m
.
validatePosition
(
new
Position
(
0
,
0
)),
new
Position
(
1
,
1
));
assert
.
deepEqual
(
m
.
validatePosition
(
new
Position
(
0
,
1
)),
new
Position
(
1
,
1
));
...
...
@@ -457,6 +457,123 @@ suite('Editor Model - TextModel', () => {
assert
.
deepEqual
(
m
.
validatePosition
(
new
Position
(
30
,
30
)),
new
Position
(
2
,
9
));
assert
.
deepEqual
(
m
.
validatePosition
(
new
Position
(
-
123.123
,
-
0.5
)),
new
Position
(
1
,
1
));
assert
.
deepEqual
(
m
.
validatePosition
(
new
Position
(
Number
.
MIN_VALUE
,
Number
.
MIN_VALUE
)),
new
Position
(
1
,
1
));
assert
.
deepEqual
(
m
.
validatePosition
(
new
Position
(
Number
.
MAX_VALUE
,
Number
.
MAX_VALUE
)),
new
Position
(
2
,
9
));
assert
.
deepEqual
(
m
.
validatePosition
(
new
Position
(
123.23
,
47.5
)),
new
Position
(
2
,
9
));
});
test
(
'
validatePosition around high-low surrogate pairs 1
'
,
()
=>
{
let
m
=
new
TextModel
([],
TextModel
.
toRawText
(
'
a📚b
'
,
TextModel
.
DEFAULT_CREATION_OPTIONS
));
assert
.
deepEqual
(
m
.
validatePosition
(
new
Position
(
0
,
0
)),
new
Position
(
1
,
1
));
assert
.
deepEqual
(
m
.
validatePosition
(
new
Position
(
0
,
1
)),
new
Position
(
1
,
1
));
assert
.
deepEqual
(
m
.
validatePosition
(
new
Position
(
0
,
7
)),
new
Position
(
1
,
1
));
assert
.
deepEqual
(
m
.
validatePosition
(
new
Position
(
1
,
1
)),
new
Position
(
1
,
1
));
assert
.
deepEqual
(
m
.
validatePosition
(
new
Position
(
1
,
2
)),
new
Position
(
1
,
2
));
assert
.
deepEqual
(
m
.
validatePosition
(
new
Position
(
1
,
3
)),
new
Position
(
1
,
2
));
assert
.
deepEqual
(
m
.
validatePosition
(
new
Position
(
1
,
4
)),
new
Position
(
1
,
4
));
assert
.
deepEqual
(
m
.
validatePosition
(
new
Position
(
1
,
5
)),
new
Position
(
1
,
5
));
assert
.
deepEqual
(
m
.
validatePosition
(
new
Position
(
1
,
30
)),
new
Position
(
1
,
5
));
assert
.
deepEqual
(
m
.
validatePosition
(
new
Position
(
2
,
0
)),
new
Position
(
1
,
5
));
assert
.
deepEqual
(
m
.
validatePosition
(
new
Position
(
2
,
1
)),
new
Position
(
1
,
5
));
assert
.
deepEqual
(
m
.
validatePosition
(
new
Position
(
2
,
2
)),
new
Position
(
1
,
5
));
assert
.
deepEqual
(
m
.
validatePosition
(
new
Position
(
2
,
30
)),
new
Position
(
1
,
5
));
assert
.
deepEqual
(
m
.
validatePosition
(
new
Position
(
-
123.123
,
-
0.5
)),
new
Position
(
1
,
1
));
assert
.
deepEqual
(
m
.
validatePosition
(
new
Position
(
Number
.
MIN_VALUE
,
Number
.
MIN_VALUE
)),
new
Position
(
1
,
1
));
assert
.
deepEqual
(
m
.
validatePosition
(
new
Position
(
Number
.
MAX_VALUE
,
Number
.
MAX_VALUE
)),
new
Position
(
1
,
5
));
assert
.
deepEqual
(
m
.
validatePosition
(
new
Position
(
123.23
,
47.5
)),
new
Position
(
1
,
5
));
});
test
(
'
validatePosition around high-low surrogate pairs 2
'
,
()
=>
{
let
m
=
new
TextModel
([],
TextModel
.
toRawText
(
'
a📚📚b
'
,
TextModel
.
DEFAULT_CREATION_OPTIONS
));
assert
.
deepEqual
(
m
.
validatePosition
(
new
Position
(
1
,
1
)),
new
Position
(
1
,
1
));
assert
.
deepEqual
(
m
.
validatePosition
(
new
Position
(
1
,
2
)),
new
Position
(
1
,
2
));
assert
.
deepEqual
(
m
.
validatePosition
(
new
Position
(
1
,
3
)),
new
Position
(
1
,
2
));
assert
.
deepEqual
(
m
.
validatePosition
(
new
Position
(
1
,
4
)),
new
Position
(
1
,
4
));
assert
.
deepEqual
(
m
.
validatePosition
(
new
Position
(
1
,
5
)),
new
Position
(
1
,
4
));
assert
.
deepEqual
(
m
.
validatePosition
(
new
Position
(
1
,
6
)),
new
Position
(
1
,
6
));
assert
.
deepEqual
(
m
.
validatePosition
(
new
Position
(
1
,
7
)),
new
Position
(
1
,
7
));
});
test
(
'
validateRange around high-low surrogate pairs 1
'
,
()
=>
{
let
m
=
new
TextModel
([],
TextModel
.
toRawText
(
'
a📚b
'
,
TextModel
.
DEFAULT_CREATION_OPTIONS
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
0
,
0
,
0
,
1
)),
new
Range
(
1
,
1
,
1
,
1
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
0
,
0
,
0
,
7
)),
new
Range
(
1
,
1
,
1
,
1
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
1
,
1
,
1
)),
new
Range
(
1
,
1
,
1
,
1
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
1
,
1
,
2
)),
new
Range
(
1
,
1
,
1
,
2
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
1
,
1
,
3
)),
new
Range
(
1
,
1
,
1
,
4
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
1
,
1
,
4
)),
new
Range
(
1
,
1
,
1
,
4
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
1
,
1
,
5
)),
new
Range
(
1
,
1
,
1
,
5
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
2
,
1
,
2
)),
new
Range
(
1
,
2
,
1
,
2
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
2
,
1
,
3
)),
new
Range
(
1
,
2
,
1
,
4
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
2
,
1
,
4
)),
new
Range
(
1
,
2
,
1
,
4
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
2
,
1
,
5
)),
new
Range
(
1
,
2
,
1
,
5
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
3
,
1
,
3
)),
new
Range
(
1
,
2
,
1
,
2
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
3
,
1
,
4
)),
new
Range
(
1
,
2
,
1
,
4
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
3
,
1
,
5
)),
new
Range
(
1
,
2
,
1
,
5
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
4
,
1
,
4
)),
new
Range
(
1
,
4
,
1
,
4
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
4
,
1
,
5
)),
new
Range
(
1
,
4
,
1
,
5
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
5
,
1
,
5
)),
new
Range
(
1
,
5
,
1
,
5
));
});
test
(
'
validateRange around high-low surrogate pairs 2
'
,
()
=>
{
let
m
=
new
TextModel
([],
TextModel
.
toRawText
(
'
a📚📚b
'
,
TextModel
.
DEFAULT_CREATION_OPTIONS
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
0
,
0
,
0
,
1
)),
new
Range
(
1
,
1
,
1
,
1
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
0
,
0
,
0
,
7
)),
new
Range
(
1
,
1
,
1
,
1
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
1
,
1
,
1
)),
new
Range
(
1
,
1
,
1
,
1
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
1
,
1
,
2
)),
new
Range
(
1
,
1
,
1
,
2
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
1
,
1
,
3
)),
new
Range
(
1
,
1
,
1
,
4
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
1
,
1
,
4
)),
new
Range
(
1
,
1
,
1
,
4
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
1
,
1
,
5
)),
new
Range
(
1
,
1
,
1
,
6
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
1
,
1
,
6
)),
new
Range
(
1
,
1
,
1
,
6
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
1
,
1
,
7
)),
new
Range
(
1
,
1
,
1
,
7
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
2
,
1
,
2
)),
new
Range
(
1
,
2
,
1
,
2
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
2
,
1
,
3
)),
new
Range
(
1
,
2
,
1
,
4
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
2
,
1
,
4
)),
new
Range
(
1
,
2
,
1
,
4
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
2
,
1
,
5
)),
new
Range
(
1
,
2
,
1
,
6
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
2
,
1
,
6
)),
new
Range
(
1
,
2
,
1
,
6
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
2
,
1
,
7
)),
new
Range
(
1
,
2
,
1
,
7
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
3
,
1
,
3
)),
new
Range
(
1
,
2
,
1
,
2
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
3
,
1
,
4
)),
new
Range
(
1
,
2
,
1
,
4
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
3
,
1
,
5
)),
new
Range
(
1
,
2
,
1
,
6
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
3
,
1
,
6
)),
new
Range
(
1
,
2
,
1
,
6
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
3
,
1
,
7
)),
new
Range
(
1
,
2
,
1
,
7
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
4
,
1
,
4
)),
new
Range
(
1
,
4
,
1
,
4
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
4
,
1
,
5
)),
new
Range
(
1
,
4
,
1
,
6
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
4
,
1
,
6
)),
new
Range
(
1
,
4
,
1
,
6
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
4
,
1
,
7
)),
new
Range
(
1
,
4
,
1
,
7
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
5
,
1
,
5
)),
new
Range
(
1
,
4
,
1
,
4
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
5
,
1
,
6
)),
new
Range
(
1
,
4
,
1
,
6
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
5
,
1
,
7
)),
new
Range
(
1
,
4
,
1
,
7
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
6
,
1
,
6
)),
new
Range
(
1
,
6
,
1
,
6
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
6
,
1
,
7
)),
new
Range
(
1
,
6
,
1
,
7
));
assert
.
deepEqual
(
m
.
validateRange
(
new
Range
(
1
,
7
,
1
,
7
)),
new
Range
(
1
,
7
,
1
,
7
));
});
test
(
'
modifyPosition
'
,
()
=>
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录