Skip to content

Commit

Permalink
Refactor Events definition; add support for linkEvent
Browse files Browse the repository at this point in the history
  • Loading branch information
as-com committed Mar 1, 2018
1 parent 7586b89 commit 095cfd2
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 204 deletions.
6 changes: 3 additions & 3 deletions packages/inferno-router/src/Link.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { linkEvent, createVNode, VNode } from 'inferno';
import { linkEvent, createVNode, VNode, MouseEvent } from 'inferno';
import { ChildFlags, VNodeFlags } from 'inferno-vnode-flags';
import { invariant } from './utils';

const isModifiedEvent = (event): boolean => Boolean(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey);
const isModifiedEvent = (event: MouseEvent<any>): boolean => Boolean(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey);

export interface ILinkProps {
children: any;
Expand All @@ -14,7 +14,7 @@ export interface ILinkProps {
innerRef: any;
}

function handleClick({ props, context }, event) {
function handleClick({ props, context }, event: MouseEvent<any>) {
if (props.onClick) {
props.onClick(event);
}
Expand Down
3 changes: 2 additions & 1 deletion packages/inferno/src/DOM/events/delegation.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { isNull } from 'inferno-shared';
import { SemiSyntheticEvent } from "inferno";

const attachedEventCounts = {};
const attachedEvents = {};
Expand Down Expand Up @@ -32,7 +33,7 @@ export function handleEvent(name: string, nextEvent: Function | null, dom) {
}
}

function dispatchEvents(event, target, isClick: boolean, name: string, eventData: IEventData) {
function dispatchEvents(event: SemiSyntheticEvent<any>, target, isClick: boolean, name: string, eventData: IEventData) {
let dom = target;
while (!isNull(dom)) {
// Html Nodes can be nested fe: span inside button in that scenario browser does not handle disabled attribute on parent,
Expand Down
61 changes: 61 additions & 0 deletions packages/inferno/src/DOM/events/events.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//
// Event System
// ----------------------------------------------------------------------

import {
NativeAnimationEvent, NativeClipboardEvent, NativeCompositionEvent, NativeDragEvent, NativeFocusEvent,
NativeKeyboardEvent,
NativeMouseEvent, NativeTouchEvent, NativeTransitionEvent, NativeUIEvent, NativeWheelEvent
} from "../../JSX";
import { LinkedEvent } from "./linkEvent";

export interface SemiSyntheticEvent<T> extends Event {
/**
* A reference to the element on which the event listener is registered.
*/
currentTarget: EventTarget & T;
}

export type ClipboardEvent<T> = SemiSyntheticEvent<T> & NativeClipboardEvent;
export type CompositionEvent<T> = SemiSyntheticEvent<T> & NativeCompositionEvent;
export type DragEvent<T> = MouseEvent<T> & NativeDragEvent;
export type FocusEvent<T> = SemiSyntheticEvent<T> & NativeFocusEvent;
export type FormEvent<T> = SemiSyntheticEvent<T>;

export interface InvalidEvent<T> extends SemiSyntheticEvent<T> {
target: EventTarget & T;
}

export interface ChangeEvent<T> extends SemiSyntheticEvent<T> {
target: EventTarget & T;
}

export type KeyboardEvent<T> = SemiSyntheticEvent<T> & NativeKeyboardEvent;
export type MouseEvent<T> = SemiSyntheticEvent<T> & NativeMouseEvent;
export type TouchEvent<T> = SemiSyntheticEvent<T> & NativeTouchEvent;
export type UIEvent<T> = SemiSyntheticEvent<T> & NativeUIEvent;
export type WheelEvent<T> = MouseEvent<T> & NativeWheelEvent;
export type AnimationEvent<T> = SemiSyntheticEvent<T> & NativeAnimationEvent;
export type TransitionEvent<T> = SemiSyntheticEvent<T> & NativeTransitionEvent;

//
// Event Handler Types
// ----------------------------------------------------------------------

export type EventHandler<E extends SemiSyntheticEvent<any>> = { bivarianceHack(event: E): void }["bivarianceHack"] | LinkedEvent<any, E>;

export type InfernoEventHandler<T> = EventHandler<SemiSyntheticEvent<T>>;

export type ClipboardEventHandler<T> = EventHandler<ClipboardEvent<T>>;
export type CompositionEventHandler<T> = EventHandler<CompositionEvent<T>>;
export type DragEventHandler<T> = EventHandler<DragEvent<T>>;
export type FocusEventHandler<T> = EventHandler<FocusEvent<T>>;
export type FormEventHandler<T> = EventHandler<FormEvent<T>>;
export type ChangeEventHandler<T> = EventHandler<ChangeEvent<T>>;
export type KeyboardEventHandler<T> = EventHandler<KeyboardEvent<T>>;
export type MouseEventHandler<T> = EventHandler<MouseEvent<T>>;
export type TouchEventHandler<T> = EventHandler<TouchEvent<T>>;
export type UIEventHandler<T> = EventHandler<UIEvent<T>>;
export type WheelEventHandler<T> = EventHandler<WheelEvent<T>>;
export type AnimationEventHandler<T> = EventHandler<AnimationEvent<T>>;
export type TransitionEventHandler<T> = EventHandler<TransitionEvent<T>>;
7 changes: 6 additions & 1 deletion packages/inferno/src/DOM/events/linkEvent.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import { isFunction } from 'inferno-shared';

export interface LinkedEvent<T, E extends Event> {
data: T;
event: (data: T, event: E) => void;
}

/**
* Links given data to event as first parameter
* @param {*} data data to be linked, it will be available in function as first parameter
* @param {Function} event Function to be called when event occurs
* @returns {{data: *, event: Function}}
*/
export function linkEvent(data, event) {
export function linkEvent<T, E extends Event>(data: T, event: (data: T, event: E) => void): LinkedEvent<T, E> | null {
if (isFunction(event)) {
return { data, event };
}
Expand Down
215 changes: 18 additions & 197 deletions packages/inferno/src/JSX.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,21 @@
import { Component, ComponentClass, StatelessComponent, InfernoChildren, SFC, VNode } from "inferno";
import {
Component, ComponentClass, StatelessComponent, InfernoChildren, SFC, VNode,
InfernoEventHandler, KeyboardEventHandler, FormEventHandler, CompositionEventHandler, ClipboardEventHandler,
FocusEventHandler, MouseEventHandler, DragEventHandler, WheelEventHandler, UIEventHandler, TouchEventHandler,
AnimationEventHandler, TransitionEventHandler, ChangeEventHandler
} from "inferno";

export type NativeAnimationEvent = AnimationEvent;
export type NativeClipboardEvent = ClipboardEvent;
export type NativeCompositionEvent = CompositionEvent;
export type NativeDragEvent = DragEvent;
export type NativeFocusEvent = FocusEvent;
export type NativeKeyboardEvent = KeyboardEvent;
export type NativeMouseEvent = MouseEvent;
export type NativeTouchEvent = TouchEvent;
export type NativeTransitionEvent = TransitionEvent;
export type NativeUIEvent = UIEvent;
export type NativeWheelEvent = WheelEvent;

declare global {
// Based on Type definitions for React 16.0
Expand All @@ -22,18 +39,6 @@ declare global {

/// <reference path="global.d.ts" />

type NativeAnimationEvent = AnimationEvent;
type NativeClipboardEvent = ClipboardEvent;
type NativeCompositionEvent = CompositionEvent;
type NativeDragEvent = DragEvent;
type NativeFocusEvent = FocusEvent;
type NativeKeyboardEvent = KeyboardEvent;
type NativeMouseEvent = MouseEvent;
type NativeTouchEvent = TouchEvent;
type NativeTransitionEvent = TransitionEvent;
type NativeUIEvent = UIEvent;
type NativeWheelEvent = WheelEvent;

// tslint:disable-next-line:export-just-namespace
// export = InfernoJSX;
// export as namespace InfernoJSX;
Expand Down Expand Up @@ -308,190 +313,6 @@ declare global {
// [propertyName: string]: any;
// }

//
// Event System
// ----------------------------------------------------------------------

interface SyntheticEvent<T> {
bubbles: boolean;
/**
* A reference to the element on which the event listener is registered.
*/
currentTarget: EventTarget & T;
cancelable: boolean;
defaultPrevented: boolean;
eventPhase: number;
isTrusted: boolean;
nativeEvent: Event;

preventDefault(): void;

isDefaultPrevented(): boolean;

stopPropagation(): void;

isPropagationStopped(): boolean;

persist(): void;

// If you thought this should be `EventTarget & T`, see https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12239
/**
* A reference to the element from which the event was originally dispatched.
* This might be a child element to the element on which the event listener is registered.
*
* @see currentTarget
*/
target: EventTarget;
timeStamp: number;
type: string;
}

interface ClipboardEvent<T> extends SyntheticEvent<T> {
clipboardData: DataTransfer;
nativeEvent: NativeClipboardEvent;
}

interface CompositionEvent<T> extends SyntheticEvent<T> {
data: string;
nativeEvent: NativeCompositionEvent;
}

interface DragEvent<T> extends MouseEvent<T> {
dataTransfer: DataTransfer;
nativeEvent: NativeDragEvent;
}

interface FocusEvent<T> extends SyntheticEvent<T> {
nativeEvent: NativeFocusEvent;
relatedTarget: EventTarget;
}

// tslint:disable-next-line:no-empty-interface
interface FormEvent<T> extends SyntheticEvent<T> {
}

interface InvalidEvent<T> extends SyntheticEvent<T> {
target: EventTarget & T;
}

interface ChangeEvent<T> extends SyntheticEvent<T> {
target: EventTarget & T;
}

interface KeyboardEvent<T> extends SyntheticEvent<T> {
altKey: boolean;
charCode: number;
ctrlKey: boolean;

/**
* See [DOM Level 3 Events spec](https://www.w3.org/TR/uievents-key/#keys-modifier). for a list of valid (case-sensitive) arguments to this method.
*/
getModifierState(key: string): boolean;

/**
* See the [DOM Level 3 Events spec](https://www.w3.org/TR/uievents-key/#named-key-attribute-values). for possible values
*/
key: string;
keyCode: number;
locale: string;
location: number;
metaKey: boolean;
nativeEvent: NativeKeyboardEvent;
repeat: boolean;
shiftKey: boolean;
which: number;
}

interface MouseEvent<T> extends SyntheticEvent<T> {
altKey: boolean;
button: number;
buttons: number;
clientX: number;
clientY: number;
ctrlKey: boolean;

/**
* See [DOM Level 3 Events spec](https://www.w3.org/TR/uievents-key/#keys-modifier). for a list of valid (case-sensitive) arguments to this method.
*/
getModifierState(key: string): boolean;

metaKey: boolean;
nativeEvent: NativeMouseEvent;
pageX: number;
pageY: number;
relatedTarget: EventTarget;
screenX: number;
screenY: number;
shiftKey: boolean;
}

interface TouchEvent<T> extends SyntheticEvent<T> {
altKey: boolean;
changedTouches: TouchList;
ctrlKey: boolean;

/**
* See [DOM Level 3 Events spec](https://www.w3.org/TR/uievents-key/#keys-modifier). for a list of valid (case-sensitive) arguments to this method.
*/
getModifierState(key: string): boolean;

metaKey: boolean;
nativeEvent: NativeTouchEvent;
shiftKey: boolean;
targetTouches: TouchList;
touches: TouchList;
}

interface UIEvent<T> extends SyntheticEvent<T> {
detail: number;
nativeEvent: NativeUIEvent;
view: AbstractView;
}

interface WheelEvent<T> extends MouseEvent<T> {
deltaMode: number;
deltaX: number;
deltaY: number;
deltaZ: number;
nativeEvent: NativeWheelEvent;
}

interface AnimationEvent<T> extends SyntheticEvent<T> {
animationName: string;
elapsedTime: number;
nativeEvent: NativeAnimationEvent;
pseudoElement: string;
}

interface TransitionEvent<T> extends SyntheticEvent<T> {
elapsedTime: number;
nativeEvent: NativeTransitionEvent;
propertyName: string;
pseudoElement: string;
}

//
// Event Handler Types
// ----------------------------------------------------------------------

type EventHandler<E extends SyntheticEvent<any>> = { bivarianceHack(event: E): void }["bivarianceHack"];

type InfernoEventHandler<T> = EventHandler<SyntheticEvent<T>>;

type ClipboardEventHandler<T> = EventHandler<ClipboardEvent<T>>;
type CompositionEventHandler<T> = EventHandler<CompositionEvent<T>>;
type DragEventHandler<T> = EventHandler<DragEvent<T>>;
type FocusEventHandler<T> = EventHandler<FocusEvent<T>>;
type FormEventHandler<T> = EventHandler<FormEvent<T>>;
type ChangeEventHandler<T> = EventHandler<ChangeEvent<T>>;
type KeyboardEventHandler<T> = EventHandler<KeyboardEvent<T>>;
type MouseEventHandler<T> = EventHandler<MouseEvent<T>>;
type TouchEventHandler<T> = EventHandler<TouchEvent<T>>;
type UIEventHandler<T> = EventHandler<UIEvent<T>>;
type WheelEventHandler<T> = EventHandler<WheelEvent<T>>;
type AnimationEventHandler<T> = EventHandler<AnimationEvent<T>>;
type TransitionEventHandler<T> = EventHandler<TransitionEvent<T>>;

//
// Props / DOM Attributes
// ----------------------------------------------------------------------
Expand Down
5 changes: 3 additions & 2 deletions packages/inferno/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
Refs,
VNode
} from './core/implementation';
import { linkEvent } from './DOM/events/linkEvent';
import { linkEvent, LinkedEvent } from './DOM/events/linkEvent';
import { createPortal, createRenderer, render } from './DOM/rendering';
import { EMPTY_OBJ } from './DOM/utils/common';
import {
Expand All @@ -27,7 +27,7 @@ import { getNumberStyleValue } from './DOM/props';
import { hydrate } from './DOM/hydration';

import * as JSX from "./JSX";

export * from "./DOM/events/events";

if (process.env.NODE_ENV !== 'production') {
/* tslint:disable-next-line:no-empty */
Expand Down Expand Up @@ -67,6 +67,7 @@ export {
getNumberStyleValue,
hydrate,
linkEvent,
LinkedEvent,
normalizeProps,
options,
render,
Expand Down

0 comments on commit 095cfd2

Please sign in to comment.