Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
c49d699a
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,发现更多精彩内容 >>
提交
c49d699a
编写于
9月 24, 2020
作者:
R
rebornix
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
comment thread readonly
上级
ee8378e8
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
128 addition
and
60 deletion
+128
-60
src/vs/editor/common/modes.ts
src/vs/editor/common/modes.ts
+2
-0
src/vs/vscode.proposed.d.ts
src/vs/vscode.proposed.d.ts
+10
-0
src/vs/workbench/api/browser/mainThreadComments.ts
src/vs/workbench/api/browser/mainThreadComments.ts
+16
-2
src/vs/workbench/api/common/extHost.protocol.ts
src/vs/workbench/api/common/extHost.protocol.ts
+1
-0
src/vs/workbench/api/common/extHostComments.ts
src/vs/workbench/api/common/extHostComments.ts
+17
-0
src/vs/workbench/contrib/comments/browser/commentThreadWidget.ts
...workbench/contrib/comments/browser/commentThreadWidget.ts
+82
-58
未找到文件。
src/vs/editor/common/modes.ts
浏览文件 @
c49d699a
...
...
@@ -1495,11 +1495,13 @@ export interface CommentThread {
comments
:
Comment
[]
|
undefined
;
onDidChangeComments
:
Event
<
Comment
[]
|
undefined
>
;
collapsibleState
?:
CommentThreadCollapsibleState
;
readOnly
:
boolean
;
input
?:
CommentInput
;
onDidChangeInput
:
Event
<
CommentInput
|
undefined
>
;
onDidChangeRange
:
Event
<
IRange
>
;
onDidChangeLabel
:
Event
<
string
|
undefined
>
;
onDidChangeCollasibleState
:
Event
<
CommentThreadCollapsibleState
|
undefined
>
;
onDidChangeReadOnly
:
Event
<
boolean
>
;
isDisposed
:
boolean
;
}
...
...
src/vs/vscode.proposed.d.ts
浏览文件 @
c49d699a
...
...
@@ -2137,4 +2137,14 @@ declare module 'vscode' {
constructor
(
id
:
string
,
color
?:
ThemeColor
);
}
//#endregion
//#region https://github.com/microsoft/vscode/issues/102665 Comment API @rebornix
export
interface
CommentThread
{
/**
* Whether the thread supports reply.
* Defaults to false.
*/
readOnly
:
boolean
;
}
//#endregion
}
src/vs/workbench/api/browser/mainThreadComments.ts
浏览文件 @
c49d699a
...
...
@@ -84,6 +84,17 @@ export class MainThreadCommentThread implements modes.CommentThread {
return
this
.
_range
;
}
private
readonly
_onDidChangeReadOnly
=
new
Emitter
<
boolean
>
();
get
onDidChangeReadOnly
():
Event
<
boolean
>
{
return
this
.
_onDidChangeReadOnly
.
event
;
}
set
readOnly
(
state
:
boolean
)
{
this
.
_readOnly
=
state
;
this
.
_onDidChangeReadOnly
.
fire
(
this
.
_readOnly
);
}
get
readOnly
()
{
return
this
.
_readOnly
;
}
private
readonly
_onDidChangeRange
=
new
Emitter
<
IRange
>
();
public
onDidChangeRange
=
this
.
_onDidChangeRange
.
event
;
...
...
@@ -112,7 +123,8 @@ export class MainThreadCommentThread implements modes.CommentThread {
public
extensionId
:
string
,
public
threadId
:
string
,
public
resource
:
string
,
private
_range
:
IRange
private
_range
:
IRange
,
private
_readOnly
:
boolean
)
{
this
.
_isDisposed
=
false
;
}
...
...
@@ -126,6 +138,7 @@ export class MainThreadCommentThread implements modes.CommentThread {
if
(
modified
(
'
contextValue
'
))
{
this
.
_contextValue
=
changes
.
contextValue
;
}
if
(
modified
(
'
comments
'
))
{
this
.
_comments
=
changes
.
comments
;
}
if
(
modified
(
'
collapseState
'
))
{
this
.
_collapsibleState
=
changes
.
collapseState
;
}
if
(
modified
(
'
readOnly
'
))
{
this
.
readOnly
=
changes
.
readOnly
!
;
}
}
dispose
()
{
...
...
@@ -214,7 +227,8 @@ export class MainThreadCommentController {
extensionId
,
threadId
,
URI
.
revive
(
resource
).
toString
(),
range
range
,
false
);
this
.
_threads
.
set
(
commentThreadHandle
,
thread
);
...
...
src/vs/workbench/api/common/extHost.protocol.ts
浏览文件 @
c49d699a
...
...
@@ -144,6 +144,7 @@ export type CommentThreadChanges = Partial<{
contextValue
:
string
,
comments
:
modes
.
Comment
[],
collapseState
:
modes
.
CommentThreadCollapsibleState
;
readOnly
:
boolean
;
}
>
;
export
interface
MainThreadCommentsShape
extends
IDisposable
{
...
...
src/vs/workbench/api/common/extHostComments.ts
浏览文件 @
c49d699a
...
...
@@ -219,6 +219,7 @@ type CommentThreadModification = Partial<{
contextValue
:
string
|
undefined
,
comments
:
vscode
.
Comment
[],
collapsibleState
:
vscode
.
CommentThreadCollapsibleState
readOnly
:
boolean
;
}
>
;
export
class
ExtHostCommentThread
implements
vscode
.
CommentThread
{
...
...
@@ -263,6 +264,19 @@ export class ExtHostCommentThread implements vscode.CommentThread {
return
this
.
_range
;
}
private
_readonly
:
boolean
=
false
;
set
readOnly
(
state
:
boolean
)
{
if
(
this
.
_readonly
!==
state
)
{
this
.
_readonly
=
state
;
this
.
modifications
.
readOnly
=
state
;
this
.
_onDidUpdateCommentThread
.
fire
();
}
}
get
readOnly
()
{
return
this
.
_readonly
;
}
private
_label
:
string
|
undefined
;
get
label
():
string
|
undefined
{
...
...
@@ -387,6 +401,9 @@ export class ExtHostCommentThread implements vscode.CommentThread {
if
(
modified
(
'
collapsibleState
'
))
{
formattedModifications
.
collapseState
=
convertToCollapsibleState
(
this
.
_collapseState
);
}
if
(
modified
(
'
readOnly
'
))
{
formattedModifications
.
readOnly
=
this
.
readOnly
;
}
this
.
modifications
=
{};
this
.
_proxy
.
$updateCommentThread
(
...
...
src/vs/workbench/contrib/comments/browser/commentThreadWidget.ts
浏览文件 @
c49d699a
...
...
@@ -61,10 +61,10 @@ export class ReviewZoneWidget extends ZoneWidget implements ICommentThreadWidget
protected
_actionbarWidget
!
:
ActionBar
;
private
_bodyElement
!
:
HTMLElement
;
private
_parentEditor
:
ICodeEditor
;
private
_commentEditor
!
:
ICodeEditor
;
private
_commentEditor
?
:
ICodeEditor
;
private
_commentsElement
!
:
HTMLElement
;
private
_commentElements
:
CommentNode
[]
=
[];
private
_commentForm
!
:
HTMLElement
;
private
_commentForm
?
:
HTMLElement
;
private
_reviewThreadReplyButton
!
:
HTMLElement
;
private
_resizeObserver
:
any
;
private
readonly
_onDidClose
=
new
Emitter
<
ReviewZoneWidget
|
undefined
>
();
...
...
@@ -82,7 +82,7 @@ export class ReviewZoneWidget extends ZoneWidget implements ICommentThreadWidget
private
_contextKeyService
:
IContextKeyService
;
private
_threadIsEmpty
:
IContextKey
<
boolean
>
;
private
_commentThreadContextValue
:
IContextKey
<
string
>
;
private
_commentEditorIsEmpty
!
:
IContextKey
<
boolean
>
;
private
_commentEditorIsEmpty
?
:
IContextKey
<
boolean
>
;
private
_commentFormActions
!
:
CommentFormActions
;
private
_scopedInstatiationService
:
IInstantiationService
;
private
_focusedComment
:
number
|
undefined
=
undefined
;
...
...
@@ -367,8 +367,8 @@ export class ReviewZoneWidget extends ZoneWidget implements ICommentThreadWidget
}
}
if
(
!
this
.
_reviewThreadReplyButton
)
{
this
.
createReplyButton
();
if
(
!
this
.
_reviewThreadReplyButton
&&
this
.
_commentEditor
&&
this
.
_commentForm
)
{
this
.
createReplyButton
(
this
.
_commentEditor
,
this
.
_commentForm
);
}
if
(
this
.
_commentThread
.
comments
&&
this
.
_commentThread
.
comments
.
length
===
0
)
{
...
...
@@ -400,11 +400,11 @@ export class ReviewZoneWidget extends ZoneWidget implements ICommentThreadWidget
}
protected
_onWidth
(
widthInPixel
:
number
):
void
{
this
.
_commentEditor
.
layout
({
height
:
5
*
18
,
width
:
widthInPixel
-
54
/* margin 20px * 10 + scrollbar 14px*/
});
this
.
_commentEditor
?
.
layout
({
height
:
5
*
18
,
width
:
widthInPixel
-
54
/* margin 20px * 10 + scrollbar 14px*/
});
}
protected
_doLayout
(
heightInPixel
:
number
,
widthInPixel
:
number
):
void
{
this
.
_commentEditor
.
layout
({
height
:
5
*
18
,
width
:
widthInPixel
-
54
/* margin 20px * 10 + scrollbar 14px*/
});
this
.
_commentEditor
?
.
layout
({
height
:
5
*
18
,
width
:
widthInPixel
-
54
/* margin 20px * 10 + scrollbar 14px*/
});
}
display
(
lineNumber
:
number
)
{
...
...
@@ -448,6 +448,50 @@ export class ReviewZoneWidget extends ZoneWidget implements ICommentThreadWidget
}
}
// create comment thread only when not readonly
if
(
!
this
.
_commentThread
.
readOnly
)
{
this
.
createCommentForm
();
}
this
.
_resizeObserver
=
new
MutationObserver
(
this
.
_refresh
.
bind
(
this
));
this
.
_resizeObserver
.
observe
(
this
.
_bodyElement
,
{
attributes
:
true
,
childList
:
true
,
characterData
:
true
,
subtree
:
true
});
if
(
this
.
_commentThread
.
collapsibleState
===
modes
.
CommentThreadCollapsibleState
.
Expanded
)
{
this
.
show
({
lineNumber
:
lineNumber
,
column
:
1
},
2
);
}
// If there are no existing comments, place focus on the text area. This must be done after show, which also moves focus.
// if this._commentThread.comments is undefined, it doesn't finish initialization yet, so we don't focus the editor immediately.
if
(
!
this
.
_commentThread
.
readOnly
)
{
if
(
!
this
.
_commentThread
.
comments
||
!
this
.
_commentThread
.
comments
.
length
)
{
this
.
_commentEditor
?.
focus
();
}
else
if
(
this
.
_commentEditor
&&
this
.
_commentEditor
.
getModel
()
!
.
getValueLength
()
>
0
)
{
this
.
expandReplyArea
();
}
}
this
.
_commentThreadDisposables
.
push
(
this
.
_commentThread
.
onDidChangeReadOnly
(()
=>
{
if
(
this
.
_commentForm
)
{
if
(
this
.
_commentThread
.
readOnly
)
{
this
.
_commentForm
.
style
.
display
=
'
none
'
;
}
else
{
this
.
_commentForm
.
style
.
display
=
'
block
'
;
}
}
else
{
if
(
!
this
.
_commentThread
.
readOnly
)
{
this
.
createCommentForm
();
}
}
}));
}
private
createCommentForm
()
{
const
hasExistingComments
=
this
.
_commentThread
.
comments
&&
this
.
_commentThread
.
comments
.
length
>
0
;
this
.
_commentForm
=
dom
.
append
(
this
.
_bodyElement
,
dom
.
$
(
'
.comment-form
'
));
this
.
_commentEditor
=
this
.
_scopedInstatiationService
.
createInstance
(
SimpleCommentEditor
,
this
.
_commentForm
,
SimpleCommentEditor
.
getEditorOptions
(),
this
.
_parentEditor
,
this
);
...
...
@@ -472,62 +516,40 @@ export class ReviewZoneWidget extends ZoneWidget implements ICommentThreadWidget
this
.
_disposables
.
add
(
this
.
_commentEditor
);
this
.
_disposables
.
add
(
this
.
_commentEditor
.
getModel
()
!
.
onDidChangeContent
(()
=>
{
this
.
setCommentEditorDecorations
();
this
.
_commentEditorIsEmpty
.
set
(
!
this
.
_commentEditor
.
getValue
());
this
.
_commentEditorIsEmpty
?.
set
(
!
this
.
_commentEditor
?
.
getValue
());
}));
this
.
createTextModelListener
();
this
.
createTextModelListener
(
this
.
_commentEditor
,
this
.
_commentForm
);
this
.
setCommentEditorDecorations
();
// Only add the additional step of clicking a reply button to expand the textarea when there are existing comments
if
(
hasExistingComments
)
{
this
.
createReplyButton
();
this
.
createReplyButton
(
this
.
_commentEditor
,
this
.
_commentForm
);
}
else
{
if
(
this
.
_commentThread
.
comments
&&
this
.
_commentThread
.
comments
.
length
===
0
)
{
this
.
expandReplyArea
();
}
}
this
.
_error
=
dom
.
append
(
this
.
_commentForm
,
dom
.
$
(
'
.validation-error.hidden
'
));
this
.
_formActions
=
dom
.
append
(
this
.
_commentForm
,
dom
.
$
(
'
.form-actions
'
));
this
.
createCommentWidgetActions
(
this
.
_formActions
,
model
);
this
.
createCommentWidgetActionsListener
();
this
.
_resizeObserver
=
new
MutationObserver
(
this
.
_refresh
.
bind
(
this
));
this
.
_resizeObserver
.
observe
(
this
.
_bodyElement
,
{
attributes
:
true
,
childList
:
true
,
characterData
:
true
,
subtree
:
true
});
if
(
this
.
_commentThread
.
collapsibleState
===
modes
.
CommentThreadCollapsibleState
.
Expanded
)
{
this
.
show
({
lineNumber
:
lineNumber
,
column
:
1
},
2
);
}
// If there are no existing comments, place focus on the text area. This must be done after show, which also moves focus.
// if this._commentThread.comments is undefined, it doesn't finish initialization yet, so we don't focus the editor immediately.
if
(
!
this
.
_commentThread
.
comments
||
!
this
.
_commentThread
.
comments
.
length
)
{
this
.
_commentEditor
.
focus
();
}
else
if
(
this
.
_commentEditor
.
getModel
()
!
.
getValueLength
()
>
0
)
{
this
.
expandReplyArea
();
}
}
private
createTextModelListener
()
{
this
.
_commentThreadDisposables
.
push
(
this
.
_
commentEditor
.
onDidFocusEditorWidget
(()
=>
{
private
createTextModelListener
(
commentEditor
:
ICodeEditor
,
commentForm
:
HTMLElement
)
{
this
.
_commentThreadDisposables
.
push
(
commentEditor
.
onDidFocusEditorWidget
(()
=>
{
this
.
_commentThread
.
input
=
{
uri
:
this
.
_
commentEditor
.
getModel
()
!
.
uri
,
value
:
this
.
_
commentEditor
.
getValue
()
uri
:
commentEditor
.
getModel
()
!
.
uri
,
value
:
commentEditor
.
getValue
()
};
this
.
commentService
.
setActiveCommentThread
(
this
.
_commentThread
);
}));
this
.
_commentThreadDisposables
.
push
(
this
.
_
commentEditor
.
getModel
()
!
.
onDidChangeContent
(()
=>
{
let
modelContent
=
this
.
_
commentEditor
.
getValue
();
if
(
this
.
_commentThread
.
input
&&
this
.
_commentThread
.
input
.
uri
===
this
.
_
commentEditor
.
getModel
()
!
.
uri
&&
this
.
_commentThread
.
input
.
value
!==
modelContent
)
{
this
.
_commentThreadDisposables
.
push
(
commentEditor
.
getModel
()
!
.
onDidChangeContent
(()
=>
{
let
modelContent
=
commentEditor
.
getValue
();
if
(
this
.
_commentThread
.
input
&&
this
.
_commentThread
.
input
.
uri
===
commentEditor
.
getModel
()
!
.
uri
&&
this
.
_commentThread
.
input
.
value
!==
modelContent
)
{
let
newInput
:
modes
.
CommentInput
=
this
.
_commentThread
.
input
;
newInput
.
value
=
modelContent
;
this
.
_commentThread
.
input
=
newInput
;
...
...
@@ -538,20 +560,20 @@ export class ReviewZoneWidget extends ZoneWidget implements ICommentThreadWidget
this
.
_commentThreadDisposables
.
push
(
this
.
_commentThread
.
onDidChangeInput
(
input
=>
{
let
thread
=
this
.
_commentThread
;
if
(
thread
.
input
&&
thread
.
input
.
uri
!==
this
.
_
commentEditor
.
getModel
()
!
.
uri
)
{
if
(
thread
.
input
&&
thread
.
input
.
uri
!==
commentEditor
.
getModel
()
!
.
uri
)
{
return
;
}
if
(
!
input
)
{
return
;
}
if
(
this
.
_
commentEditor
.
getValue
()
!==
input
.
value
)
{
this
.
_
commentEditor
.
setValue
(
input
.
value
);
if
(
commentEditor
.
getValue
()
!==
input
.
value
)
{
commentEditor
.
setValue
(
input
.
value
);
if
(
input
.
value
===
''
)
{
this
.
_pendingComment
=
''
;
this
.
_
commentForm
.
classList
.
remove
(
'
expand
'
);
this
.
_
commentEditor
.
getDomNode
()
!
.
style
.
outline
=
''
;
commentForm
.
classList
.
remove
(
'
expand
'
);
commentEditor
.
getDomNode
()
!
.
style
.
outline
=
''
;
this
.
_error
.
textContent
=
''
;
this
.
_error
.
classList
.
add
(
'
hidden
'
);
}
...
...
@@ -639,7 +661,7 @@ export class ReviewZoneWidget extends ZoneWidget implements ICommentThreadWidget
}
action
.
run
({
thread
:
this
.
_commentThread
,
text
:
this
.
_commentEditor
.
getValue
(),
text
:
this
.
_commentEditor
?
.
getValue
(),
$mid
:
8
});
...
...
@@ -696,23 +718,25 @@ export class ReviewZoneWidget extends ZoneWidget implements ICommentThreadWidget
}
private
expandReplyArea
()
{
if
(
!
this
.
_commentForm
.
classList
.
contains
(
'
expand
'
))
{
this
.
_commentForm
.
classList
.
add
(
'
expand
'
);
this
.
_commentEditor
.
focus
();
if
(
!
this
.
_commentForm
?
.
classList
.
contains
(
'
expand
'
))
{
this
.
_commentForm
?
.
classList
.
add
(
'
expand
'
);
this
.
_commentEditor
?
.
focus
();
}
}
private
hideReplyArea
()
{
this
.
_commentEditor
.
setValue
(
''
);
if
(
this
.
_commentEditor
)
{
this
.
_commentEditor
.
setValue
(
''
);
this
.
_commentEditor
.
getDomNode
()
!
.
style
.
outline
=
''
;
}
this
.
_pendingComment
=
''
;
this
.
_commentForm
.
classList
.
remove
(
'
expand
'
);
this
.
_commentEditor
.
getDomNode
()
!
.
style
.
outline
=
''
;
this
.
_commentForm
?.
classList
.
remove
(
'
expand
'
);
this
.
_error
.
textContent
=
''
;
this
.
_error
.
classList
.
add
(
'
hidden
'
);
}
private
createReplyButton
()
{
this
.
_reviewThreadReplyButton
=
<
HTMLButtonElement
>
dom
.
append
(
this
.
_
commentForm
,
dom
.
$
(
`button.review-thread-reply-button.
${
MOUSE_CURSOR_TEXT_CSS_CLASS_NAME
}
`
));
private
createReplyButton
(
commentEditor
:
ICodeEditor
,
commentForm
:
HTMLElement
)
{
this
.
_reviewThreadReplyButton
=
<
HTMLButtonElement
>
dom
.
append
(
commentForm
,
dom
.
$
(
`button.review-thread-reply-button.
${
MOUSE_CURSOR_TEXT_CSS_CLASS_NAME
}
`
));
this
.
_reviewThreadReplyButton
.
title
=
this
.
_commentOptions
?.
prompt
||
nls
.
localize
(
'
reply
'
,
"
Reply...
"
);
this
.
_reviewThreadReplyButton
.
textContent
=
this
.
_commentOptions
?.
prompt
||
nls
.
localize
(
'
reply
'
,
"
Reply...
"
);
...
...
@@ -720,9 +744,9 @@ export class ReviewZoneWidget extends ZoneWidget implements ICommentThreadWidget
this
.
_disposables
.
add
(
dom
.
addDisposableListener
(
this
.
_reviewThreadReplyButton
,
'
click
'
,
_
=>
this
.
expandReplyArea
()));
this
.
_disposables
.
add
(
dom
.
addDisposableListener
(
this
.
_reviewThreadReplyButton
,
'
focus
'
,
_
=>
this
.
expandReplyArea
()));
this
.
_
commentEditor
.
onDidBlurEditorWidget
(()
=>
{
if
(
this
.
_commentEditor
.
getModel
()
!
.
getValueLength
()
===
0
&&
this
.
_
commentForm
.
classList
.
contains
(
'
expand
'
))
{
this
.
_
commentForm
.
classList
.
remove
(
'
expand
'
);
commentEditor
.
onDidBlurEditorWidget
(()
=>
{
if
(
commentEditor
.
getModel
()
!
.
getValueLength
()
===
0
&&
commentForm
.
classList
.
contains
(
'
expand
'
))
{
commentForm
.
classList
.
remove
(
'
expand
'
);
}
});
}
...
...
@@ -753,7 +777,7 @@ export class ReviewZoneWidget extends ZoneWidget implements ICommentThreadWidget
}
if
(
!
this
.
_commentThread
.
comments
||
!
this
.
_commentThread
.
comments
.
length
)
{
this
.
_commentEditor
.
focus
();
this
.
_commentEditor
?
.
focus
();
}
this
.
_relayout
(
computedLinesNumber
);
...
...
@@ -785,7 +809,7 @@ export class ReviewZoneWidget extends ZoneWidget implements ICommentThreadWidget
}
}];
this
.
_commentEditor
.
setDecorations
(
COMMENTEDITOR_DECORATION_KEY
,
decorations
);
this
.
_commentEditor
?
.
setDecorations
(
COMMENTEDITOR_DECORATION_KEY
,
decorations
);
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录