Skip to content

Commit

Permalink
Merge pull request #18 from Sczlog/machine-matcher
Browse files Browse the repository at this point in the history
enhance matcher, add dragging, special-key and file-input event.
  • Loading branch information
netweng authored Jul 20, 2021
2 parents 42ba741 + 0c6c922 commit 6036505
Show file tree
Hide file tree
Showing 22 changed files with 917 additions and 104 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"@types/eventemitter2": "^4.1.0",
"@types/jest": "^26.0.23",
"@types/puppeteer": "^5.4.3",
"@types/wicg-entries-api": "^2020.8.2",
"@typescript-eslint/eslint-plugin": "^4.27.0",
"@typescript-eslint/parser": "^4.27.0",
"cross-env": "^7.0.3",
Expand Down
22 changes: 17 additions & 5 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
export * from './matcher';
export * from './observers';
export * from './types';
export * from './recorder';
export * from './builtin';
export * as Matcher from './matcher';
export * as Observer from './observers';
export * as Types from './types';
import * as BaseRecorder from './recorder';
import * as BuiltInRecorder from './builtin';

export const Recorder = {
Recorder: BaseRecorder,
BuiltInRecorder,
};

import * as UtilsFn from './util/fn';
import * as Throttler from './util/throttler';
import * as Metaquerier from './util/metaquerier';
import * as EntryReader from './util/entry-reader';

export const Utils = { UtilsFn, Throttler, Metaquerier, EntryReader };
182 changes: 178 additions & 4 deletions src/matcher/machine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,18 @@ import {
StateValue,
} from 'xstate';
import { toSCXMLEvent } from 'xstate/lib/utils';
import { MatcherStep } from '..';
import { MatcherStep } from './index';
import { isSpecialKey } from '../util/special-key-map';
import { isInputLikeElement } from '../util/fn';
import {
MatcherSchema,
MatcherEvent,
MatcherState,
MatcherContext,
} from './types';

const dblclickMaxGap = 350;

export class MatcherMachine {
private _machine: StateMachine<
MatcherContext,
Expand All @@ -34,11 +38,18 @@ export class MatcherMachine {
MatcherState
>;

private emit: (step: MatcherStep) => void;

private getTargetStateNode(
state: State<MatcherContext, MatcherEvent, MatcherSchema, MatcherState>,
event: MatcherEvent,
): StateValue {
const _state = this.machine.resolveState(state!);
/**
* FIXME: the _transition function is a private functon.
* I use this function here is due to assign action in entry cannot get correct state node.
* when the bug is fixed, make newEvent action not assign type for new step event, and make an entry action to assign the type.
*/
const transitions = this.machine['_transition'](
_state.value,
_state,
Expand All @@ -57,8 +68,6 @@ export class MatcherMachine {
return this._service;
}

private emit: (step: MatcherStep) => void;

constructor(emit: (step: MatcherStep) => void) {
this.emit = emit;
this._machine = Machine<MatcherContext, MatcherSchema, MatcherEvent>(
Expand All @@ -71,6 +80,11 @@ export class MatcherMachine {
},
on: {
mousedown: [
{
target: 'RIGHT_CLICK',
actions: ['emitStep', 'newStep'],
cond: (_c, { data: event }) => event.button === 2,
},
{
target: 'CLICK',
actions: ['emitStep', 'newStep'],
Expand All @@ -80,6 +94,15 @@ export class MatcherMachine {
{
target: 'TEXT',
actions: ['emitStep', 'newStep'],
cond: (_c, { data: event, target }) =>
!!target &&
isInputLikeElement(target) &&
!isSpecialKey(event.key),
},
{
target: 'KEYPRESS',
actions: ['emitStep', 'newStep'],
cond: (_c, { target }) => !!target,
},
],
text_input: {
Expand All @@ -90,16 +113,29 @@ export class MatcherMachine {
target: 'TEXT',
actions: ['emitStep', 'newStep'],
},
drop: {
target: 'DROP_FILE',
actions: ['emitStep', 'newStep'],
cond: (c, event) => !!event.data.items.length,
},
wheel: {
target: 'SCROLL',
actions: ['emitStep', 'newStep'],
},
blur: {
actions: 'emitStep',
cond: ({ currentStep }, { target }) => {
return !!currentStep && target === window;
return (
!!currentStep &&
target === window &&
currentStep.type !== 'BROWSE_FILE'
);
},
},
file: {
target: 'BROWSE_FILE',
actions: ['emitStep', 'newStep'],
},
'*': {
target: 'UNKNOWN',
actions: ['emitStep', 'newStep'],
Expand All @@ -112,6 +148,46 @@ export class MatcherMachine {
CLICK: {
on: {
mousedown: [
{
target: 'DBLCLICK',
cond: ({ currentStep }, { data: event, target }) => {
if (!currentStep) {
return false;
}
const lastEvent =
currentStep.events[currentStep.events.length - 1];
return (
lastEvent.type === 'click' &&
event.button === lastEvent.button &&
event.timestamp - lastEvent.timestamp <= dblclickMaxGap &&
currentStep.target === target
);
},
actions: 'mergeStep',
},
{
cond: ({ currentStep }) => {
if (!currentStep) {
return false;
}
return (
currentStep.type === 'CLICK' &&
currentStep.events.filter(
(event) => event.type === 'mousedown',
).length ===
currentStep.events.filter(
(event) => event.type === 'mouseup',
).length +
1
);
},
actions: 'mergeStep',
},
{
target: 'RIGHT_CLICK',
actions: ['emitStep', 'newStep'],
cond: (_c, { data: event }) => event.button === 2,
},
{
actions: ['emitStep', 'newStep'],
},
Expand Down Expand Up @@ -144,13 +220,49 @@ export class MatcherMachine {
mouseup: {
actions: 'mergeStep',
},
auxclick: {
actions: 'mergeStep',
},
click: [
{
target: 'BROWSE_FILE',
actions: 'mergeStep',
cond: (_c, { target }) => {
return (
target?.tagName === 'INPUT' &&
(target as HTMLInputElement).type === 'file'
);
},
},
{
actions: 'mergeStep',
},
],
},
},
RIGHT_CLICK: {
on: {
mouseup: {
actions: 'mergeStep',
},
auxclick: {
actions: 'mergeStep',
},
},
},
DBLCLICK: {
on: {
mouseup: {
actions: 'mergeStep',
},
click: {
actions: 'mergeStep',
},
dblclick: {
actions: 'mergeStep',
},
},
},
DRAG: {
on: {
mousemove: {
Expand All @@ -162,11 +274,61 @@ export class MatcherMachine {
click: {
actions: 'mergeStep',
},
drag: {
actions: 'mergeStep',
},
dragstart: {
actions: 'mergeStep',
},
dragenter: {
actions: 'mergeStep',
},
dragleave: {
actions: 'mergeStep',
},
dragover: {
actions: 'mergeStep',
},
drop: {
actions: 'mergeStep',
},
},
},
KEYPRESS: {
on: {
keydown: [
{
actions: 'mergeStep',
cond: ({ currentStep }) =>
!!currentStep &&
currentStep.events.filter(
(event) => event.type === 'keydown',
) >
currentStep.events.filter(
(event) => event.type === 'keyup',
),
},
{
actions: ['emitStep', 'newStep'],
},
],
keypress: {
actions: 'mergeStep',
},
keyup: {
actions: 'mergeStep',
},
},
},
TEXT: {
on: {
keydown: [
{
target: 'KEYPRESS',
actions: ['emitStep', 'newStep'],
cond: ({ currentStep }, { data: event, target }) =>
isSpecialKey(event.key) || currentStep?.target !== target,
},
{
actions: 'mergeStep',
},
Expand Down Expand Up @@ -199,13 +361,25 @@ export class MatcherMachine {
],
},
},
BROWSE_FILE: {
on: {
file: {
target: 'BROWSE_FILE',
actions: 'mergeStep',
},
},
},
DROP_FILE: {},
NAVIGATION: {},
SCROLL: {
on: {
scroll: {
actions: 'mergeStep',
},
},
},
REFRESH: {},
RESIZE: {},
UNKNOWN: {},
},
},
Expand Down
Loading

0 comments on commit 6036505

Please sign in to comment.