Notifications: cannot navigate into link via keybindings (fix #163086) (#167980)

This commit is contained in:
Benjamin Pasero 2022-12-06 07:28:32 +01:00 committed by GitHub
parent e79a401ba5
commit 9df51e1cdd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 28 additions and 15 deletions

View file

@ -825,6 +825,12 @@ export interface EventLike {
stopPropagation(): void;
}
export function isEventLike(obj: unknown): obj is EventLike {
const candidate = obj as EventLike | undefined;
return !!(candidate && typeof candidate.preventDefault === 'function' && typeof candidate.stopPropagation === 'function');
}
export const EventHelper = {
stop: <T extends EventLike>(e: T, cancelBubble?: boolean): T => {
e.preventDefault();

View file

@ -196,7 +196,7 @@ export function registerNotificationCommands(center: INotificationsCenterControl
weight: KeybindingWeight.WorkbenchContrib,
when: ContextKeyExpr.and(NotificationFocusedContext, NotificationsToastsVisibleContext),
primary: KeyCode.DownArrow,
handler: (accessor) => {
handler: () => {
toasts.focusNext();
}
});
@ -207,7 +207,7 @@ export function registerNotificationCommands(center: INotificationsCenterControl
weight: KeybindingWeight.WorkbenchContrib,
when: ContextKeyExpr.and(NotificationFocusedContext, NotificationsToastsVisibleContext),
primary: KeyCode.UpArrow,
handler: (accessor) => {
handler: () => {
toasts.focusPrevious();
}
});
@ -219,7 +219,7 @@ export function registerNotificationCommands(center: INotificationsCenterControl
when: ContextKeyExpr.and(NotificationFocusedContext, NotificationsToastsVisibleContext),
primary: KeyCode.PageUp,
secondary: [KeyCode.Home],
handler: (accessor) => {
handler: () => {
toasts.focusFirst();
}
});
@ -231,7 +231,7 @@ export function registerNotificationCommands(center: INotificationsCenterControl
when: ContextKeyExpr.and(NotificationFocusedContext, NotificationsToastsVisibleContext),
primary: KeyCode.PageDown,
secondary: [KeyCode.End],
handler: (accessor) => {
handler: () => {
toasts.focusLast();
}
});

View file

@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { IListVirtualDelegate, IListRenderer } from 'vs/base/browser/ui/list/list';
import { clearNode, addDisposableListener, EventType, EventHelper, $, EventLike } from 'vs/base/browser/dom';
import { clearNode, addDisposableListener, EventType, EventHelper, $, isEventLike } from 'vs/base/browser/dom';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import { URI } from 'vs/base/common/uri';
import { localize } from 'vs/nls';
@ -26,6 +26,8 @@ import { DomEmitter } from 'vs/base/browser/event';
import { Gesture, EventType as GestureEventType } from 'vs/base/browser/touch';
import { Event } from 'vs/base/common/event';
import { defaultButtonStyles, defaultProgressBarStyles } from 'vs/platform/theme/browser/defaultStyles';
import { KeyCode } from 'vs/base/common/keyCodes';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
export class NotificationsListDelegate implements IListVirtualDelegate<INotificationViewItem> {
@ -150,20 +152,30 @@ class NotificationMessageRenderer {
title = node.href;
}
const anchor = $('a', { href: node.href, title: title, }, node.label);
const anchor = $('a', { href: node.href, title, tabIndex: 0 }, node.label);
if (actionHandler) {
const onPointer = (e: EventLike) => {
EventHelper.stop(e, true);
const handleOpen = (e: unknown) => {
if (isEventLike(e)) {
EventHelper.stop(e, true);
}
actionHandler.callback(node.href);
};
const onClick = actionHandler.toDispose.add(new DomEmitter(anchor, 'click')).event;
const onClick = actionHandler.toDispose.add(new DomEmitter(anchor, EventType.CLICK)).event;
const onKeydown = actionHandler.toDispose.add(new DomEmitter(anchor, EventType.KEY_DOWN)).event;
const onSpaceOrEnter = actionHandler.toDispose.add(Event.chain(onKeydown)).filter(e => {
const event = new StandardKeyboardEvent(e);
return event.equals(KeyCode.Space) || event.equals(KeyCode.Enter);
}).event;
actionHandler.toDispose.add(Gesture.addTarget(anchor));
const onTap = actionHandler.toDispose.add(new DomEmitter(anchor, GestureEventType.Tap)).event;
Event.any(onClick, onTap)(onPointer, null, actionHandler.toDispose);
Event.any(onClick, onTap, onSpaceOrEnter)(handleOpen, null, actionHandler.toDispose);
}
messageContainer.appendChild(anchor);
@ -388,11 +400,6 @@ export class NotificationTemplateRenderer extends Disposable {
this.template.message.removeAttribute('title');
}
const links = this.template.message.querySelectorAll('a');
for (let i = 0; i < links.length; i++) {
links.item(i).tabIndex = -1; // prevent keyboard navigation to links to allow for better keyboard support within a message
}
return messageOverflows;
}