@@ -7,13 +7,15 @@ import * as DOM from 'vs/base/browser/dom';
77import * as dompurify from 'vs/base/browser/dompurify/dompurify' ;
88import { DomEmitter } from 'vs/base/browser/event' ;
99import { createElement , FormattedTextRenderOptions } from 'vs/base/browser/formattedTextRenderer' ;
10+ import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent' ;
1011import { StandardMouseEvent } from 'vs/base/browser/mouseEvent' ;
1112import { renderLabelWithIcons } from 'vs/base/browser/ui/iconLabel/iconLabels' ;
1213import { onUnexpectedError } from 'vs/base/common/errors' ;
1314import { Event } from 'vs/base/common/event' ;
1415import { IMarkdownString , escapeDoubleQuotes , parseHrefAndDimensions , removeMarkdownEscapes , MarkdownStringTrustedOptions } from 'vs/base/common/htmlContent' ;
1516import { markdownEscapeEscapedIcons } from 'vs/base/common/iconLabels' ;
1617import { defaultGenerator } from 'vs/base/common/idGenerator' ;
18+ import { KeyCode } from 'vs/base/common/keyCodes' ;
1719import { Lazy } from 'vs/base/common/lazy' ;
1820import { DisposableStore } from 'vs/base/common/lifecycle' ;
1921import { marked } from 'vs/base/common/marked/marked' ;
@@ -158,15 +160,8 @@ export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRende
158160 }
159161
160162 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 ;
170165 if ( target . tagName !== 'A' ) {
171166 target = target . parentElement ;
172167 if ( ! target || target . tagName !== 'A' ) {
@@ -179,13 +174,29 @@ export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRende
179174 if ( markdown . baseUri ) {
180175 href = resolveWithBaseUri ( URI . from ( markdown . baseUri ) , href ) ;
181176 }
182- options . actionHandler ! . callback ( href , mouseEvent ) ;
177+ options . actionHandler ! . callback ( href , event ) ;
183178 }
184179 } catch ( err ) {
185180 onUnexpectedError ( err ) ;
186181 } 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 ;
188198 }
199+ _activateLink ( keyboardEvent ) ;
189200 } ) ) ;
190201 }
191202
0 commit comments