function contextmenu(
  target,
  defaultPayload,
  {pointerType = 'mouse', modified} = {},
) {
  const dispatch = arg => target.dispatchEvent(arg);

  const payload = {
    pointerId: defaultPointerId,
    pointerType,
    ...defaultPayload,
  };

  const preventDefault = payload.preventDefault;

  if (pointerType === 'touch') {
    if (hasPointerEvent()) {
      dispatch(
        domEvents.pointerdown({
          ...payload,
          button: buttonType.primary,
          buttons: buttonsType.primary,
        }),
      );
    }
    const touch = createTouch(target, payload);
    touchStore.addTouch(touch);
    const touchEventPayload = createTouchEventPayload(target, touch, payload);
    dispatch(domEvents.touchstart(touchEventPayload));
    dispatch(
      domEvents.contextmenu({
        button: buttonType.primary,
        buttons: buttonsType.none,
        preventDefault,
      }),
    );
    touchStore.removeTouch(touch);
  } else if (pointerType === 'mouse') {
    if (modified === true) {
      const button = buttonType.primary;
      const buttons = buttonsType.primary;
      const ctrlKey = true;
      if (hasPointerEvent()) {
        dispatch(
          domEvents.pointerdown({button, buttons, ctrlKey, pointerType}),
        );
      }
      dispatch(domEvents.mousedown({button, buttons, ctrlKey}));
      if (platform.get() === 'mac') {
        dispatch(
          domEvents.contextmenu({button, buttons, ctrlKey, preventDefault}),
        );
      }
    } else {
      const button = buttonType.secondary;
      const buttons = buttonsType.secondary;
      if (hasPointerEvent()) {
        dispatch(domEvents.pointerdown({button, buttons, pointerType}));
      }
      dispatch(domEvents.mousedown({button, buttons}));
      dispatch(domEvents.contextmenu({button, buttons, preventDefault}));
    }
  }
}
Pointer events sequences.

Creates representative browser event sequences for high-level gestures based on pointers.
This allows unit tests to be written in terms of simple pointer interactions while testing
that the responses to those interactions account for the complex sequence of events that
browsers produce as a result.

Every time a new pointer touches the surface a 'touchstart' event should be dispatched.
- 'changedTouches' contains the new touch.
- 'targetTouches' contains all the active pointers for the target.
- 'touches' contains all the active pointers on the surface.

Every time an existing pointer moves a 'touchmove' event should be dispatched.
- 'changedTouches' contains the updated touch.

Every time an existing pointer leaves the surface a 'touchend' event should be dispatched.
- 'changedTouches' contains the released touch.
- 'targetTouches' contains any of the remaining active pointers for the target.