@@ -7,13 +7,15 @@ import * as DOM from 'vs/base/browser/dom';
7
7
import * as dompurify from 'vs/base/browser/dompurify/dompurify' ;
8
8
import { DomEmitter } from 'vs/base/browser/event' ;
9
9
import { createElement , FormattedTextRenderOptions } from 'vs/base/browser/formattedTextRenderer' ;
10
+ import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent' ;
10
11
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent' ;
11
12
import { renderLabelWithIcons } from 'vs/base/browser/ui/iconLabel/iconLabels' ;
12
13
import { onUnexpectedError } from 'vs/base/common/errors' ;
13
14
import { Event } from 'vs/base/common/event' ;
14
15
import { IMarkdownString , escapeDoubleQuotes , parseHrefAndDimensions , removeMarkdownEscapes , MarkdownStringTrustedOptions } from 'vs/base/common/htmlContent' ;
15
16
import { markdownEscapeEscapedIcons } from 'vs/base/common/iconLabels' ;
16
17
import { defaultGenerator } from 'vs/base/common/idGenerator' ;
18
+ import { KeyCode } from 'vs/base/common/keyCodes' ;
17
19
import { Lazy } from 'vs/base/common/lazy' ;
18
20
import { DisposableStore } from 'vs/base/common/lifecycle' ;
19
21
import { marked } from 'vs/base/common/marked/marked' ;
@@ -158,15 +160,8 @@ export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRende
158
160
}
159
161
160
162
if ( options . actionHandler ) {
161
- const onClick = options . actionHandler . disposables . add ( new DomEmitter ( element , 'click' ) ) ;
162
- const onAuxClick = options . actionHandler . disposables . add ( new DomEmitter ( element , 'auxclick' ) ) ;
163
- options . actionHandler . disposables . add ( Event . any ( onClick . event , onAuxClick . event ) ( e => {
164
- const mouseEvent = new StandardMouseEvent ( e ) ;
165
- if ( ! mouseEvent . leftButton && ! mouseEvent . middleButton ) {
166
- return ;
167
- }
168
-
169
- let target : HTMLElement | null = mouseEvent . target ;
163
+ const _activateLink = function ( event : StandardMouseEvent | StandardKeyboardEvent ) : void {
164
+ let target : HTMLElement | null = event . target ;
170
165
if ( target . tagName !== 'A' ) {
171
166
target = target . parentElement ;
172
167
if ( ! target || target . tagName !== 'A' ) {
@@ -179,13 +174,29 @@ export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRende
179
174
if ( markdown . baseUri ) {
180
175
href = resolveWithBaseUri ( URI . from ( markdown . baseUri ) , href ) ;
181
176
}
182
- options . actionHandler ! . callback ( href , mouseEvent ) ;
177
+ options . actionHandler ! . callback ( href , event ) ;
183
178
}
184
179
} catch ( err ) {
185
180
onUnexpectedError ( err ) ;
186
181
} finally {
187
- mouseEvent . preventDefault ( ) ;
182
+ event . preventDefault ( ) ;
183
+ }
184
+ } ;
185
+ const onClick = options . actionHandler . disposables . add ( new DomEmitter ( element , 'click' ) ) ;
186
+ const onAuxClick = options . actionHandler . disposables . add ( new DomEmitter ( element , 'auxclick' ) ) ;
187
+ options . actionHandler . disposables . add ( Event . any ( onClick . event , onAuxClick . event ) ( e => {
188
+ const mouseEvent = new StandardMouseEvent ( e ) ;
189
+ if ( ! mouseEvent . leftButton && ! mouseEvent . middleButton ) {
190
+ return ;
191
+ }
192
+ _activateLink ( mouseEvent ) ;
193
+ } ) ) ;
194
+ options . actionHandler . disposables . add ( DOM . addDisposableListener ( element , 'keydown' , ( e ) => {
195
+ const keyboardEvent = new StandardKeyboardEvent ( e ) ;
196
+ if ( ! keyboardEvent . equals ( KeyCode . Space ) && ! keyboardEvent . equals ( KeyCode . Enter ) ) {
197
+ return ;
188
198
}
199
+ _activateLink ( keyboardEvent ) ;
189
200
} ) ) ;
190
201
}
191
202
0 commit comments