Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
a1b377e4
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,发现更多精彩内容 >>
提交
a1b377e4
编写于
12月 06, 2017
作者:
R
Ramya Achutha Rao
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Skip emmet when open tag is not closed even when no parent node #35128
上级
cd292288
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
113 addition
and
33 deletion
+113
-33
extensions/emmet/src/abbreviationActions.ts
extensions/emmet/src/abbreviationActions.ts
+24
-20
extensions/emmet/src/test/abbreviationAction.test.ts
extensions/emmet/src/test/abbreviationAction.test.ts
+89
-13
未找到文件。
extensions/emmet/src/abbreviationActions.ts
浏览文件 @
a1b377e4
...
...
@@ -217,12 +217,12 @@ function fallbackTab(): Thenable<boolean | undefined> {
* @param abbreviationRange The range of the abbreviation for which given position is being validated
*/
export
function
isValidLocationForEmmetAbbreviation
(
document
:
vscode
.
TextDocument
,
currentNode
:
Node
|
null
,
syntax
:
string
,
position
:
vscode
.
Position
,
abbreviationRange
:
vscode
.
Range
):
boolean
{
// Continue validation only if the file was parse-able and the currentNode has been found
if
(
!
currentNode
)
{
return
true
;
}
if
(
isStyleSheet
(
syntax
))
{
// Continue validation only if the file was parse-able and the currentNode has been found
if
(
!
currentNode
)
{
return
true
;
}
// If current node is a rule or at-rule, then perform additional checks to ensure
// emmet suggestions are not provided in the rule selector
if
(
currentNode
.
type
!==
'
rule
'
&&
currentNode
.
type
!==
'
at-rule
'
)
{
...
...
@@ -253,24 +253,28 @@ export function isValidLocationForEmmetAbbreviation(document: vscode.TextDocumen
const
endAngle
=
'
>
'
;
const
escape
=
'
\\
'
;
const
currentHtmlNode
=
<
HtmlNode
>
currentNode
;
const
innerRange
=
getInnerRange
(
currentHtmlNode
);
let
start
=
new
vscode
.
Position
(
0
,
0
);
// Fix for https://github.com/Microsoft/vscode/issues/28829
if
(
!
innerRange
||
!
innerRange
.
contains
(
position
))
{
return
false
;
}
if
(
currentHtmlNode
)
{
const
innerRange
=
getInnerRange
(
currentHtmlNode
);
// Fix for https://github.com/Microsoft/vscode/issues/35128
// Find the position up till where we will backtrack looking for unescaped < or >
// to decide if current position is valid for emmet expansion
let
start
=
innerRange
.
start
;
let
lastChildBeforePosition
=
currentHtmlNode
.
firstChild
;
while
(
lastChildBeforePosition
)
{
if
(
lastChildBeforePosition
.
end
.
isAfter
(
position
))
{
break
;
// Fix for https://github.com/Microsoft/vscode/issues/28829
if
(
!
innerRange
||
!
innerRange
.
contains
(
position
))
{
return
false
;
}
// Fix for https://github.com/Microsoft/vscode/issues/35128
// Find the position up till where we will backtrack looking for unescaped < or >
// to decide if current position is valid for emmet expansion
start
=
innerRange
.
start
;
let
lastChildBeforePosition
=
currentHtmlNode
.
firstChild
;
while
(
lastChildBeforePosition
)
{
if
(
lastChildBeforePosition
.
end
.
isAfter
(
position
))
{
break
;
}
start
=
lastChildBeforePosition
.
end
;
lastChildBeforePosition
=
lastChildBeforePosition
.
nextSibling
;
}
start
=
lastChildBeforePosition
.
end
;
lastChildBeforePosition
=
lastChildBeforePosition
.
nextSibling
;
}
let
textToBackTrack
=
document
.
getText
(
new
vscode
.
Range
(
start
.
line
,
start
.
character
,
abbreviationRange
.
start
.
line
,
abbreviationRange
.
start
.
character
));
...
...
extensions/emmet/src/test/abbreviationAction.test.ts
浏览文件 @
a1b377e4
...
...
@@ -42,7 +42,7 @@ const scssContents = `
p40
}
}
`
`
;
const
htmlContents
=
`
<body class="header">
...
...
@@ -128,6 +128,36 @@ suite('Tests for Expand Abbreviations (HTML)', () => {
return
testHtmlCompletionProvider
(
new
Selection
(
3
,
23
,
3
,
23
),
'
img
'
,
'
<img src=
\
"
\
" alt=
\
"
\
">
'
);
});
test
(
'
Expand snippets when no parent node (HTML)
'
,
()
=>
{
return
withRandomFileEditor
(
'
img
'
,
'
html
'
,
(
editor
,
doc
)
=>
{
editor
.
selection
=
new
Selection
(
0
,
3
,
0
,
3
);
return
expandEmmetAbbreviation
(
null
).
then
(()
=>
{
assert
.
equal
(
editor
.
document
.
getText
(),
'
<img src=
\
"
\
" alt=
\
"
\
">
'
);
return
Promise
.
resolve
();
});
});
});
test
(
'
Expand snippets when no parent node in completion list (HTML)
'
,
()
=>
{
return
withRandomFileEditor
(
'
img
'
,
'
html
'
,
(
editor
,
doc
)
=>
{
editor
.
selection
=
new
Selection
(
0
,
3
,
0
,
3
);
const
cancelSrc
=
new
CancellationTokenSource
();
const
completionPromise
=
completionProvider
.
provideCompletionItems
(
editor
.
document
,
editor
.
selection
.
active
,
cancelSrc
.
token
);
if
(
!
completionPromise
)
{
assert
.
equal
(
!
completionPromise
,
false
,
`Got unexpected undefined instead of a completion promise`
);
return
Promise
.
resolve
();
}
return
completionPromise
.
then
(
completionList
=>
{
assert
.
equal
(
completionList
&&
completionList
.
items
&&
completionList
.
items
.
length
>
0
,
true
);
if
(
completionList
)
{
assert
.
equal
(
completionList
.
items
[
0
].
label
,
'
img
'
);
assert
.
equal
((
<
string
>
completionList
.
items
[
0
].
documentation
||
''
).
replace
(
/
\|
/g
,
''
),
'
<img src=
\
"
\
" alt=
\
"
\
">
'
);
}
return
Promise
.
resolve
();
});
});
});
test
(
'
Expand abbreviation (HTML)
'
,
()
=>
{
return
testExpandAbbreviation
(
'
html
'
,
new
Selection
(
5
,
25
,
5
,
25
),
'
ul>li
'
,
'
<ul>
\n\t\t\t
<li></li>
\n\t\t
</ul>
'
);
});
...
...
@@ -157,7 +187,7 @@ suite('Tests for Expand Abbreviations (HTML)', () => {
});
test
(
'
Expand abbreviation with numbered repeaters in completion list (HTML)
'
,
()
=>
{
return
testHtmlCompletionProvider
(
new
Selection
(
7
,
33
,
7
,
33
),
'
ul>li.item$*2
'
,
'
<ul>
\n\t
<li class="item1"></li>
\n\t
<li class="item2"></li>
\n
</ul>
'
);
return
testHtmlCompletionProvider
(
new
Selection
(
7
,
33
,
7
,
33
),
'
ul>li.item$*2
'
,
'
<ul>
\n\t
<li class="item1"></li>
\n\t
<li class="item2"></li>
\n
</ul>
'
);
});
test
(
'
Expand abbreviation with numbered repeaters with offset (HTML)
'
,
()
=>
{
...
...
@@ -165,7 +195,7 @@ suite('Tests for Expand Abbreviations (HTML)', () => {
});
test
(
'
Expand abbreviation with numbered repeaters with offset in completion list (HTML)
'
,
()
=>
{
return
testHtmlCompletionProvider
(
new
Selection
(
8
,
36
,
8
,
36
),
'
ul>li.item$@44*2
'
,
'
<ul>
\n\t
<li class="item44"></li>
\n\t
<li class="item45"></li>
\n
</ul>
'
);
return
testHtmlCompletionProvider
(
new
Selection
(
8
,
36
,
8
,
36
),
'
ul>li.item$@44*2
'
,
'
<ul>
\n\t
<li class="item44"></li>
\n\t
<li class="item45"></li>
\n
</ul>
'
);
});
test
(
'
Expand abbreviation with numbered repeaters in groups (HTML)
'
,
()
=>
{
...
...
@@ -201,19 +231,65 @@ suite('Tests for Expand Abbreviations (HTML)', () => {
});
test
(
'
No expanding text inside open tag (HTML)
'
,
()
=>
{
return
testExpandAbbreviation
(
'
html
'
,
new
Selection
(
2
,
4
,
2
,
4
),
''
,
''
,
true
);
return
withRandomFileEditor
(
htmlContents
,
'
html
'
,
(
editor
,
doc
)
=>
{
editor
.
selection
=
new
Selection
(
2
,
4
,
2
,
4
);
return
expandEmmetAbbreviation
(
null
).
then
(()
=>
{
assert
.
equal
(
editor
.
document
.
getText
(),
htmlContents
);
return
Promise
.
resolve
();
});
});
});
test
(
'
No expanding text inside open tag in completion list (HTML)
'
,
()
=>
{
return
testHtmlCompletionProvider
(
new
Selection
(
2
,
4
,
2
,
4
),
''
,
''
,
true
);
return
withRandomFileEditor
(
htmlContents
,
'
html
'
,
(
editor
,
doc
)
=>
{
editor
.
selection
=
new
Selection
(
2
,
4
,
2
,
4
);
const
cancelSrc
=
new
CancellationTokenSource
();
const
completionPromise
=
completionProvider
.
provideCompletionItems
(
editor
.
document
,
editor
.
selection
.
active
,
cancelSrc
.
token
);
assert
.
equal
(
!
completionPromise
,
true
,
`Got unexpected comapletion promise instead of undefined`
);
return
Promise
.
resolve
();
});
});
test
(
'
No expanding text inside open tag when there is no closing tag (HTML)
'
,
()
=>
{
return
testExpandAbbreviation
(
'
html
'
,
new
Selection
(
9
,
8
,
9
,
8
),
''
,
''
,
true
);
return
withRandomFileEditor
(
htmlContents
,
'
html
'
,
(
editor
,
doc
)
=>
{
editor
.
selection
=
new
Selection
(
9
,
8
,
9
,
8
);
return
expandEmmetAbbreviation
(
null
).
then
(()
=>
{
assert
.
equal
(
editor
.
document
.
getText
(),
htmlContents
);
return
Promise
.
resolve
();
});
});
});
test
(
'
No expanding text inside open tag when there is no closing tag in completion list (HTML)
'
,
()
=>
{
return
testHtmlCompletionProvider
(
new
Selection
(
9
,
8
,
9
,
8
),
''
,
''
,
true
);
return
withRandomFileEditor
(
htmlContents
,
'
html
'
,
(
editor
,
doc
)
=>
{
editor
.
selection
=
new
Selection
(
9
,
8
,
9
,
8
);
const
cancelSrc
=
new
CancellationTokenSource
();
const
completionPromise
=
completionProvider
.
provideCompletionItems
(
editor
.
document
,
editor
.
selection
.
active
,
cancelSrc
.
token
);
assert
.
equal
(
!
completionPromise
,
true
,
`Got unexpected comapletion promise instead of undefined`
);
return
Promise
.
resolve
();
});
});
test
(
'
No expanding text inside open tag when there is no closing tag when there is no parent node (HTML)
'
,
()
=>
{
const
fileContents
=
'
<img s
'
;
return
withRandomFileEditor
(
fileContents
,
'
html
'
,
(
editor
,
doc
)
=>
{
editor
.
selection
=
new
Selection
(
0
,
6
,
0
,
6
);
return
expandEmmetAbbreviation
(
null
).
then
(()
=>
{
assert
.
equal
(
editor
.
document
.
getText
(),
fileContents
);
return
Promise
.
resolve
();
});
});
});
test
(
'
No expanding text in completion list inside open tag when there is no closing tag when there is no parent node (HTML)
'
,
()
=>
{
const
fileContents
=
'
<img s
'
;
return
withRandomFileEditor
(
fileContents
,
'
html
'
,
(
editor
,
doc
)
=>
{
editor
.
selection
=
new
Selection
(
0
,
6
,
0
,
6
);
const
cancelSrc
=
new
CancellationTokenSource
();
const
completionPromise
=
completionProvider
.
provideCompletionItems
(
editor
.
document
,
editor
.
selection
.
active
,
cancelSrc
.
token
);
assert
.
equal
(
!
completionPromise
,
true
,
`Got unexpected comapletion promise instead of undefined`
);
return
Promise
.
resolve
();
});
});
test
(
'
Expand css when inside style tag (HTML)
'
,
()
=>
{
...
...
@@ -251,7 +327,7 @@ suite('Tests for Expand Abbreviations (HTML)', () => {
const
emmetCompletionItem
=
completionList
.
items
[
0
];
assert
.
equal
(
emmetCompletionItem
.
label
,
expandedText
,
`Label of completion item doesnt match.`
);
assert
.
equal
((
<
string
>
emmetCompletionItem
.
documentation
||
''
).
replace
(
/
\|
/g
,
''
),
expandedText
,
`Docs of completion item doesnt match.`
);
assert
.
equal
(
emmetCompletionItem
.
filterText
,
abbreviation
,
`FilterText of completion item doesnt match.`
)
assert
.
equal
(
emmetCompletionItem
.
filterText
,
abbreviation
,
`FilterText of completion item doesnt match.`
)
;
return
Promise
.
resolve
();
});
});
...
...
@@ -304,8 +380,8 @@ suite('Tests for Expand Abbreviations (CSS)', () => {
return
withRandomFileEditor
(
cssContents
,
'
css
'
,
(
editor
,
doc
)
=>
{
editor
.
selection
=
new
Selection
(
3
,
1
,
3
,
4
);
const
cancelSrc
=
new
CancellationTokenSource
();
const
completionPromise1
=
completionProvider
.
provideCompletionItems
(
editor
.
document
,
new
Position
(
3
,
4
),
cancelSrc
.
token
);
const
completionPromise2
=
completionProvider
.
provideCompletionItems
(
editor
.
document
,
new
Position
(
5
,
4
),
cancelSrc
.
token
);
const
completionPromise1
=
completionProvider
.
provideCompletionItems
(
editor
.
document
,
new
Position
(
3
,
4
),
cancelSrc
.
token
);
const
completionPromise2
=
completionProvider
.
provideCompletionItems
(
editor
.
document
,
new
Position
(
5
,
4
),
cancelSrc
.
token
);
if
(
!
completionPromise1
||
!
completionPromise2
)
{
assert
.
equal
(
1
,
2
,
`Problem with expanding m10`
);
return
Promise
.
resolve
();
...
...
@@ -390,7 +466,7 @@ m10
background:
}
}
`
`
;
return
withRandomFileEditor
(
scssContentsNoExpand
,
'
scss
'
,
(
editor
,
doc
)
=>
{
editor
.
selections
=
[
...
...
@@ -413,7 +489,7 @@ m10
background:
}
}
`
`
;
return
withRandomFileEditor
(
scssContentsNoExpand
,
'
scss
'
,
(
editor
,
doc
)
=>
{
editor
.
selection
=
new
Selection
(
1
,
3
,
1
,
3
);
// outside rule
...
...
@@ -431,7 +507,7 @@ m10
assert
.
equal
(
1
,
2
,
`m10 gets expanded in invalid location (n the value part of property value)`
);
}
return
Promise
.
resolve
();
})
})
;
}
return
Promise
.
resolve
();
});
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录