281 lines
11 KiB
Java
281 lines
11 KiB
Java
![]() |
import { __extends } from "tslib";
|
|||
|
import { each, isArray, isFunction, isString, debounce, throttle } from '@antv/util';
|
|||
|
import { createAction, createCallbackAction } from './action/register';
|
|||
|
import InteractionContext from './context';
|
|||
|
import Interaction from './interaction';
|
|||
|
// 将字符串转换成 action
|
|||
|
function parseAction(actionStr, context) {
|
|||
|
var arr = actionStr.split(':');
|
|||
|
var actionName = arr[0];
|
|||
|
// 如果已经初始化过 action ,则直接引用之前的 action
|
|||
|
var action = context.getAction(actionName) || createAction(actionName, context);
|
|||
|
if (!action) {
|
|||
|
throw new Error("There is no action named " + actionName);
|
|||
|
}
|
|||
|
var methodName = arr[1];
|
|||
|
return {
|
|||
|
action: action,
|
|||
|
methodName: methodName,
|
|||
|
};
|
|||
|
}
|
|||
|
// 执行 Action
|
|||
|
function executeAction(actionObject) {
|
|||
|
var action = actionObject.action, methodName = actionObject.methodName;
|
|||
|
if (action[methodName]) {
|
|||
|
action[methodName]();
|
|||
|
}
|
|||
|
else {
|
|||
|
throw new Error("Action(" + action.name + ") doesn't have a method called " + methodName);
|
|||
|
}
|
|||
|
}
|
|||
|
var STEP_NAMES = {
|
|||
|
START: 'start',
|
|||
|
SHOW_ENABLE: 'showEnable',
|
|||
|
END: 'end',
|
|||
|
ROLLBACK: 'rollback',
|
|||
|
PROCESSING: 'processing',
|
|||
|
};
|
|||
|
/**
|
|||
|
* 支持语法的交互类
|
|||
|
*/
|
|||
|
var GrammarInteraction = /** @class */ (function (_super) {
|
|||
|
__extends(GrammarInteraction, _super);
|
|||
|
function GrammarInteraction(view, steps) {
|
|||
|
var _this = _super.call(this, view, steps) || this;
|
|||
|
_this.callbackCaches = {};
|
|||
|
// 某个触发和反馈在本环节是否执行或
|
|||
|
_this.emitCaches = {};
|
|||
|
_this.steps = steps;
|
|||
|
return _this;
|
|||
|
}
|
|||
|
/**
|
|||
|
* 初始化
|
|||
|
*/
|
|||
|
GrammarInteraction.prototype.init = function () {
|
|||
|
this.initContext();
|
|||
|
_super.prototype.init.call(this);
|
|||
|
};
|
|||
|
/**
|
|||
|
* 清理资源
|
|||
|
*/
|
|||
|
GrammarInteraction.prototype.destroy = function () {
|
|||
|
_super.prototype.destroy.call(this); // 先清理事件
|
|||
|
this.steps = null;
|
|||
|
if (this.context) {
|
|||
|
this.context.destroy();
|
|||
|
this.context = null;
|
|||
|
}
|
|||
|
this.callbackCaches = null;
|
|||
|
this.view = null;
|
|||
|
};
|
|||
|
/**
|
|||
|
* 绑定事件
|
|||
|
*/
|
|||
|
GrammarInteraction.prototype.initEvents = function () {
|
|||
|
var _this = this;
|
|||
|
each(this.steps, function (stepArr, stepName) {
|
|||
|
each(stepArr, function (step) {
|
|||
|
var callback = _this.getActionCallback(stepName, step);
|
|||
|
if (callback) {
|
|||
|
// 如果存在 callback,才绑定,有时候会出现无 callback 的情况
|
|||
|
_this.bindEvent(step.trigger, callback);
|
|||
|
}
|
|||
|
});
|
|||
|
});
|
|||
|
};
|
|||
|
/**
|
|||
|
* 清理绑定的事件
|
|||
|
*/
|
|||
|
GrammarInteraction.prototype.clearEvents = function () {
|
|||
|
var _this = this;
|
|||
|
each(this.steps, function (stepArr, stepName) {
|
|||
|
each(stepArr, function (step) {
|
|||
|
var callback = _this.getActionCallback(stepName, step);
|
|||
|
if (callback) {
|
|||
|
_this.offEvent(step.trigger, callback);
|
|||
|
}
|
|||
|
});
|
|||
|
});
|
|||
|
};
|
|||
|
// 初始化上下文,并初始化 action
|
|||
|
GrammarInteraction.prototype.initContext = function () {
|
|||
|
var view = this.view;
|
|||
|
var context = new InteractionContext(view);
|
|||
|
this.context = context;
|
|||
|
var steps = this.steps;
|
|||
|
// 生成具体的 Action
|
|||
|
each(steps, function (subSteps) {
|
|||
|
each(subSteps, function (step) {
|
|||
|
if (isFunction(step.action)) {
|
|||
|
// 如果传入回调函数,则直接生成 CallbackAction
|
|||
|
step.actionObject = {
|
|||
|
action: createCallbackAction(step.action, context),
|
|||
|
methodName: 'execute',
|
|||
|
};
|
|||
|
}
|
|||
|
else if (isString(step.action)) {
|
|||
|
// 如果是字符串
|
|||
|
step.actionObject = parseAction(step.action, context);
|
|||
|
}
|
|||
|
else if (isArray(step.action)) {
|
|||
|
// 如果是数组
|
|||
|
var actionArr = step.action;
|
|||
|
step.actionObject = [];
|
|||
|
each(actionArr, function (actionStr) {
|
|||
|
step.actionObject.push(parseAction(actionStr, context));
|
|||
|
});
|
|||
|
}
|
|||
|
// 如果 action 既不是字符串,也不是函数,则不会生成 actionObject
|
|||
|
});
|
|||
|
});
|
|||
|
};
|
|||
|
// 是否允许指定阶段名称执行
|
|||
|
GrammarInteraction.prototype.isAllowStep = function (stepName) {
|
|||
|
var currentStepName = this.currentStepName;
|
|||
|
var steps = this.steps;
|
|||
|
// 相同的阶段允许同时执行
|
|||
|
if (currentStepName === stepName) {
|
|||
|
return true;
|
|||
|
}
|
|||
|
if (stepName === STEP_NAMES.SHOW_ENABLE) {
|
|||
|
// 示能在整个过程中都可用
|
|||
|
return true;
|
|||
|
}
|
|||
|
if (stepName === STEP_NAMES.PROCESSING) {
|
|||
|
// 只有当前是 start 时,才允许 processing
|
|||
|
return currentStepName === STEP_NAMES.START;
|
|||
|
}
|
|||
|
if (stepName === STEP_NAMES.START) {
|
|||
|
// 如果当前是 processing,则无法 start,必须等待 end 后才能执行
|
|||
|
return currentStepName !== STEP_NAMES.PROCESSING;
|
|||
|
}
|
|||
|
if (stepName === STEP_NAMES.END) {
|
|||
|
return currentStepName === STEP_NAMES.PROCESSING || currentStepName === STEP_NAMES.START;
|
|||
|
}
|
|||
|
if (stepName === STEP_NAMES.ROLLBACK) {
|
|||
|
if (steps[STEP_NAMES.END]) {
|
|||
|
// 如果定义了 end, 只有 end 时才允许回滚
|
|||
|
return currentStepName === STEP_NAMES.END;
|
|||
|
}
|
|||
|
else if (currentStepName === STEP_NAMES.START) {
|
|||
|
// 如果未定义 end, 则判断是否是开始
|
|||
|
return true;
|
|||
|
}
|
|||
|
}
|
|||
|
return false;
|
|||
|
};
|
|||
|
// 具体的指定阶段是否允许执行
|
|||
|
GrammarInteraction.prototype.isAllowExcute = function (stepName, step) {
|
|||
|
if (this.isAllowStep(stepName)) {
|
|||
|
var key = this.getKey(stepName, step);
|
|||
|
// 如果是在本环节内仅允许触发一次,同时已经触发过,则不允许再触发
|
|||
|
if (step.once && this.emitCaches[key]) {
|
|||
|
return false;
|
|||
|
}
|
|||
|
// 如果是允许的阶段,则验证 isEnable 方法
|
|||
|
if (step.isEnable) {
|
|||
|
return step.isEnable(this.context);
|
|||
|
}
|
|||
|
return true; // 如果没有 isEnable 则允许执行
|
|||
|
}
|
|||
|
return false;
|
|||
|
};
|
|||
|
GrammarInteraction.prototype.enterStep = function (stepName) {
|
|||
|
this.currentStepName = stepName;
|
|||
|
this.emitCaches = {}; // 清除所有本环节触发的缓存
|
|||
|
};
|
|||
|
// 执行完某个触发和反馈(子环节)
|
|||
|
GrammarInteraction.prototype.afterExecute = function (stepName, step) {
|
|||
|
// show enable 不计入正常的流程,其他情况则设置当前的 step
|
|||
|
if (stepName !== STEP_NAMES.SHOW_ENABLE && this.currentStepName !== stepName) {
|
|||
|
this.enterStep(stepName);
|
|||
|
}
|
|||
|
var key = this.getKey(stepName, step);
|
|||
|
// 一旦执行,则缓存标记为,一直保持到跳出改环节
|
|||
|
this.emitCaches[key] = true;
|
|||
|
};
|
|||
|
// 获取某个环节的唯一的键值
|
|||
|
GrammarInteraction.prototype.getKey = function (stepName, step) {
|
|||
|
return stepName + step.trigger + step.action;
|
|||
|
};
|
|||
|
// 获取 step 的回调函数,如果已经生成,则直接返回,如果未生成,则创建
|
|||
|
GrammarInteraction.prototype.getActionCallback = function (stepName, step) {
|
|||
|
var _this = this;
|
|||
|
var context = this.context;
|
|||
|
var callbackCaches = this.callbackCaches;
|
|||
|
var actionObject = step.actionObject;
|
|||
|
if (step.action && actionObject) {
|
|||
|
var key = this.getKey(stepName, step);
|
|||
|
if (!callbackCaches[key]) {
|
|||
|
// 动态生成执行的方法,执行对应 action 的名称
|
|||
|
var actionCallback = function (event) {
|
|||
|
context.event = event; // 保证检测时的 event
|
|||
|
if (_this.isAllowExcute(stepName, step)) {
|
|||
|
// 如果是数组时,则依次执行
|
|||
|
if (isArray(actionObject)) {
|
|||
|
each(actionObject, function (obj) {
|
|||
|
context.event = event; // 可能触发新的事件,保证执行前的 context.event 是正确的
|
|||
|
executeAction(obj);
|
|||
|
});
|
|||
|
}
|
|||
|
else {
|
|||
|
context.event = event; // 保证执行前的 context.event 是正确的
|
|||
|
executeAction(actionObject);
|
|||
|
}
|
|||
|
_this.afterExecute(stepName, step);
|
|||
|
if (step.callback) {
|
|||
|
context.event = event; // 保证执行前的 context.event 是正确的
|
|||
|
step.callback(context);
|
|||
|
}
|
|||
|
}
|
|||
|
else {
|
|||
|
// 如果未通过验证,则事件不要绑定在上面
|
|||
|
context.event = null;
|
|||
|
}
|
|||
|
};
|
|||
|
// 如果设置了 debounce
|
|||
|
if (step.debounce) {
|
|||
|
callbackCaches[key] = debounce(actionCallback, step.debounce.wait, step.debounce.immediate);
|
|||
|
}
|
|||
|
else if (step.throttle) { // 设置 throttle
|
|||
|
callbackCaches[key] = throttle(actionCallback, step.throttle.wait, {
|
|||
|
leading: step.throttle.leading,
|
|||
|
trailing: step.throttle.trailing
|
|||
|
});
|
|||
|
}
|
|||
|
else { // 直接设置
|
|||
|
callbackCaches[key] = actionCallback;
|
|||
|
}
|
|||
|
}
|
|||
|
return callbackCaches[key];
|
|||
|
}
|
|||
|
return null;
|
|||
|
};
|
|||
|
GrammarInteraction.prototype.bindEvent = function (eventName, callback) {
|
|||
|
var nameArr = eventName.split(':');
|
|||
|
if (nameArr[0] === 'window') {
|
|||
|
window.addEventListener(nameArr[1], callback);
|
|||
|
}
|
|||
|
else if (nameArr[0] === 'document') {
|
|||
|
document.addEventListener(nameArr[1], callback);
|
|||
|
}
|
|||
|
else {
|
|||
|
this.view.on(eventName, callback);
|
|||
|
}
|
|||
|
};
|
|||
|
GrammarInteraction.prototype.offEvent = function (eventName, callback) {
|
|||
|
var nameArr = eventName.split(':');
|
|||
|
if (nameArr[0] === 'window') {
|
|||
|
window.removeEventListener(nameArr[1], callback);
|
|||
|
}
|
|||
|
else if (nameArr[0] === 'document') {
|
|||
|
document.removeEventListener(nameArr[1], callback);
|
|||
|
}
|
|||
|
else {
|
|||
|
this.view.off(eventName, callback);
|
|||
|
}
|
|||
|
};
|
|||
|
return GrammarInteraction;
|
|||
|
}(Interaction));
|
|||
|
export default GrammarInteraction;
|
|||
|
//# sourceMappingURL=grammar-interaction.js.map
|