Skip to content

Commit

Permalink
refactor(core): Add an ActionResolver option to Dispatcher. (angular#…
Browse files Browse the repository at this point in the history
…55757)

This will enable internal usages to migrate from ActionResolver in
EventContrat to ActionResolver in Dispatcher.

PR Close angular#55757
  • Loading branch information
tbondwilkinson authored and atscott committed May 14, 2024
1 parent caedd10 commit f1e3ec2
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 18 deletions.
7 changes: 4 additions & 3 deletions goldens/public-api/core/primitives/event-dispatch/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ export function bootstrapEarlyEventContract(field: string, container: HTMLElemen

// @public
export class Dispatcher {
constructor(dispatchDelegate: (eventInfoWrapper: EventInfoWrapper) => void, { eventReplayer }?: {
constructor(dispatchDelegate: (eventInfoWrapper: EventInfoWrapper) => void, { actionResolver, eventReplayer, }?: {
actionResolver?: ActionResolver;
eventReplayer?: Replayer;
});
dispatch(eventInfo: EventInfo): void;
Expand All @@ -23,14 +24,14 @@ export interface EarlyJsactionDataContainer {

// @public
export class EventContract implements UnrenamedEventContract {
constructor(containerManager: EventContractContainerManager);
constructor(containerManager: EventContractContainerManager, useActionResolver?: boolean);
// (undocumented)
static A11Y_CLICK_SUPPORT: boolean;
addA11yClickSupport(): void;
addEvent(eventType: string, prefixedEventType?: string): void;
cleanUp(): void;
// (undocumented)
ecaacs?: (updateEventInfoForA11yClick: typeof a11yClickLib.updateEventInfoForA11yClick, preventDefaultForA11yClick: typeof a11yClickLib.preventDefaultForA11yClick, populateClickOnlyAction: typeof a11yClickLib.populateClickOnlyAction) => void;
ecaacs?: (updateEventInfoForA11yClick: typeof a11yClick.updateEventInfoForA11yClick, preventDefaultForA11yClick: typeof a11yClick.preventDefaultForA11yClick, populateClickOnlyAction: typeof a11yClick.populateClickOnlyAction) => void;
ecrd(dispatcher: Dispatcher_2, restriction: Restriction): void;
exportAddA11yClickSupport(): void;
handler(eventType: string): EventHandler | undefined;
Expand Down
17 changes: 14 additions & 3 deletions packages/core/primitives/event-dispatch/src/dispatcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {EventType} from './event_type';
import {Restriction} from './restriction';
import {UnrenamedEventContract} from './eventcontract';
import * as eventLib from './event';
import {ActionResolver} from './action_resolver';

/**
* A replayer is a function that is called when there are queued events,
Expand All @@ -35,13 +36,18 @@ export type GlobalHandler = (event: Event) => boolean | void;
* jsaction.
*/
export class Dispatcher {
/** The queue of events. */
private readonly replayEventInfoWrappers: EventInfoWrapper[] = [];
// The ActionResolver to use to resolve actions.
private actionResolver?: ActionResolver;

/** The replayer function to be called when there are queued events. */
private eventReplayer?: Replayer;

/** Whether the event replay is scheduled. */
private eventReplayScheduled = false;

/** The queue of events. */
private readonly replayEventInfoWrappers: EventInfoWrapper[] = [];

/**
* Options are:
* 1. `eventReplayer`: When the event contract dispatches replay events
Expand All @@ -51,8 +57,12 @@ export class Dispatcher {
*/
constructor(
private readonly dispatchDelegate: (eventInfoWrapper: EventInfoWrapper) => void,
{eventReplayer = undefined}: {eventReplayer?: Replayer} = {},
{
actionResolver = undefined,
eventReplayer = undefined,
}: {actionResolver?: ActionResolver; eventReplayer?: Replayer} = {},
) {
this.actionResolver = actionResolver;
this.eventReplayer = eventReplayer;
}

Expand All @@ -78,6 +88,7 @@ export class Dispatcher {
*/
dispatch(eventInfo: EventInfo): void {
const eventInfoWrapper = new EventInfoWrapper(eventInfo);
this.actionResolver?.resolve(eventInfo);
const action = eventInfoWrapper.getAction();
if (action && shouldPreventDefaultBeforeDispatching(action.element, eventInfoWrapper)) {
eventLib.preventDefault(eventInfoWrapper.getEvent());
Expand Down
30 changes: 20 additions & 10 deletions packages/core/primitives/event-dispatch/src/eventcontract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,7 @@ export class EventContract implements UnrenamedEventContract {

private containerManager: EventContractContainerManager | null;

private readonly actionResolver = new ActionResolver({
syntheticMouseEventSupport: EventContract.MOUSE_SPECIAL_SUPPORT,
});
private readonly actionResolver?: ActionResolver;

/**
* The DOM events which this contract covers. Used to prevent double
Expand Down Expand Up @@ -127,8 +125,16 @@ export class EventContract implements UnrenamedEventContract {
populateClickOnlyAction: typeof a11yClickLib.populateClickOnlyAction,
) => void;

constructor(containerManager: EventContractContainerManager) {
constructor(
containerManager: EventContractContainerManager,
private readonly useActionResolver = true,
) {
this.containerManager = containerManager;
if (this.useActionResolver) {
this.actionResolver = new ActionResolver({
syntheticMouseEventSupport: EventContract.MOUSE_SPECIAL_SUPPORT,
});
}
if (EventContract.A11Y_CLICK_SUPPORT) {
// Add a11y click support to the `EventContract`.
this.addA11yClickSupport();
Expand Down Expand Up @@ -156,7 +162,9 @@ export class EventContract implements UnrenamedEventContract {
this.queuedEventInfos?.push(eventInfo);
return;
}
this.actionResolver.resolve(eventInfo);
if (this.useActionResolver) {
this.actionResolver!.resolve(eventInfo);
}
this.dispatcher(eventInfo);
}

Expand Down Expand Up @@ -347,11 +355,13 @@ export class EventContract implements UnrenamedEventContract {
populateClickOnlyAction: typeof a11yClickLib.populateClickOnlyAction,
) {
this.addA11yClickListener = true;
this.actionResolver.addA11yClickSupport(
updateEventInfoForA11yClick,
preventDefaultForA11yClick,
populateClickOnlyAction,
);
if (this.useActionResolver) {
this.actionResolver!.addA11yClickSupport(
updateEventInfoForA11yClick,
preventDefaultForA11yClick,
populateClickOnlyAction,
);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {EventInfo, EventInfoWrapper} from './event_info';
import {EventType} from './event_type';
import {UnrenamedEventContract} from './eventcontract';
import {Restriction} from './restriction';
import {ActionResolver} from './action_resolver';

/** Re-exports that should eventually be moved into this file. */
export type {
Expand Down Expand Up @@ -79,16 +80,18 @@ export class LegacyDispatcher {
eventInfoWrapper: EventInfoWrapper,
) => EventInfoWrapperHandler | void,
{
actionResolver,
eventReplayer,
stopPropagation = false,
eventReplayer = undefined,
}: {stopPropagation?: boolean; eventReplayer?: Replayer} = {},
}: {actionResolver?: ActionResolver; eventReplayer?: Replayer; stopPropagation?: boolean} = {},
) {
this.eventReplayer = eventReplayer;
this.dispatcher = new Dispatcher(
(eventInfoWrapper: EventInfoWrapper) => {
this.dispatchToHandler(eventInfoWrapper);
},
{
actionResolver,
eventReplayer: (eventInfoWrappers) => {
this.eventInfoWrapperQueue = eventInfoWrappers;
this.eventReplayer?.(this.eventInfoWrapperQueue, this);
Expand Down

0 comments on commit f1e3ec2

Please sign in to comment.