mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-01-12 00:48:16 +00:00
complete router
This commit is contained in:
parent
45ffc98277
commit
dc8542a8fa
@ -57,7 +57,10 @@ export class BorderDetecting extends Component<{ host: BuiltinSimulatorHost }> {
|
||||
|
||||
@computed get current() {
|
||||
const host = this.props.host;
|
||||
const doc = host.document;
|
||||
const doc = host.currentDocument;
|
||||
if (!doc) {
|
||||
return null;
|
||||
}
|
||||
const selection = doc.selection;
|
||||
const current = host.designer.detecting.current;
|
||||
if (!current || current.document !== doc || selection.has(current.id)) {
|
||||
|
||||
@ -5,6 +5,7 @@ import classNames from 'classnames';
|
||||
import { SimulatorContext } from '../context';
|
||||
import { BuiltinSimulatorHost } from '../host';
|
||||
import { OffsetObserver, Designer } from '../../designer';
|
||||
import { Node } from '../../document';
|
||||
|
||||
@observer
|
||||
export default class BoxResizing extends Component<{ host: BuiltinSimulatorHost }> {
|
||||
@ -19,8 +20,8 @@ export default class BoxResizing extends Component<{ host: BuiltinSimulatorHost
|
||||
}
|
||||
|
||||
@computed get selecting() {
|
||||
const doc = this.host.document;
|
||||
if (doc.suspensed) {
|
||||
const doc = this.host.currentDocument;
|
||||
if (!doc || doc.suspensed) {
|
||||
return null;
|
||||
}
|
||||
const selection = doc.selection;
|
||||
@ -146,9 +147,9 @@ export class BoxResizingInstance extends Component<{
|
||||
metaData.experimental.callbacks &&
|
||||
typeof metaData.experimental.callbacks.onResize === 'function'
|
||||
) {
|
||||
e.trigger = direction;
|
||||
e.deltaX = moveX;
|
||||
e.deltaY = moveY;
|
||||
(e as any).trigger = direction;
|
||||
(e as any).deltaX = moveX;
|
||||
(e as any).deltaY = moveY;
|
||||
metaData.experimental.callbacks.onResize(e, node);
|
||||
}
|
||||
};
|
||||
@ -161,7 +162,7 @@ export class BoxResizingInstance extends Component<{
|
||||
metaData.experimental.callbacks &&
|
||||
typeof metaData.experimental.callbacks.onResizeStart === 'function'
|
||||
) {
|
||||
e.trigger = direction;
|
||||
(e as any).trigger = direction;
|
||||
metaData.experimental.callbacks.onResizeStart(e, node);
|
||||
}
|
||||
};
|
||||
@ -174,7 +175,7 @@ export class BoxResizingInstance extends Component<{
|
||||
metaData.experimental.callbacks &&
|
||||
typeof metaData.experimental.callbacks.onResizeEnd === 'function'
|
||||
) {
|
||||
e.trigger = direction;
|
||||
(e as any).trigger = direction;
|
||||
metaData.experimental.callbacks.onResizeStart(e, node);
|
||||
}
|
||||
|
||||
|
||||
@ -198,8 +198,8 @@ export class BorderSelecting extends Component<{ host: BuiltinSimulatorHost }> {
|
||||
}
|
||||
|
||||
@computed get selecting() {
|
||||
const doc = this.host.document;
|
||||
if (doc.suspensed || this.host.liveEditing.editing) {
|
||||
const doc = this.host.currentDocument;
|
||||
if (!doc || doc.suspensed || this.host.liveEditing.editing) {
|
||||
return null;
|
||||
}
|
||||
const selection = doc.selection;
|
||||
|
||||
@ -119,7 +119,7 @@ export class InsertionView extends Component<{ host: BuiltinSimulatorHost }> {
|
||||
|
||||
render() {
|
||||
const { host } = this.props;
|
||||
const loc = host.document.dropLocation;
|
||||
const loc = host.currentDocument?.dropLocation;
|
||||
if (!loc) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@ import { obx, autorun, computed, getPublicPath, hotkey, focusTracker } from '@al
|
||||
import { ISimulatorHost, Component, NodeInstance, ComponentInstance } from '../simulator';
|
||||
import Viewport from './viewport';
|
||||
import { createSimulator } from './create-simulator';
|
||||
import { Node, ParentalNode, DocumentModel, isNode, contains, isRootNode } from '../document';
|
||||
import { Node, ParentalNode, isNode, contains, isRootNode } from '../document';
|
||||
import ResourceConsumer from './resource-consumer';
|
||||
import {
|
||||
AssetLevel,
|
||||
@ -89,6 +89,10 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
|
||||
readonly designer = this.project.designer;
|
||||
|
||||
get currentDocument() {
|
||||
return this.project.currentDocument;
|
||||
}
|
||||
|
||||
@computed get device(): string {
|
||||
return this.get('device') || 'default';
|
||||
}
|
||||
@ -141,6 +145,10 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
return autorun(fn as any, true);
|
||||
}
|
||||
|
||||
autorun(fn: (context: { dispose: () => void; firstRun: boolean }) => void) {
|
||||
return autorun(fn as any, true);
|
||||
}
|
||||
|
||||
purge(): void {
|
||||
// todo
|
||||
}
|
||||
@ -245,9 +253,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
}
|
||||
|
||||
setupDragAndClick() {
|
||||
const documentModel = this.document;
|
||||
const selection = documentModel.selection;
|
||||
const designer = documentModel.designer;
|
||||
const designer = this.designer;
|
||||
const doc = this.contentDocument!;
|
||||
|
||||
// TODO: think of lock when edit a node
|
||||
@ -257,9 +263,11 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
(downEvent: MouseEvent) => {
|
||||
// fix for popups close logic
|
||||
document.dispatchEvent(new Event('mousedown'));
|
||||
if (this.liveEditing.editing) {
|
||||
const documentModel = this.project.currentDocument;
|
||||
if (this.liveEditing.editing || !documentModel) {
|
||||
return;
|
||||
}
|
||||
const selection = documentModel.selection;
|
||||
// stop response document focus event
|
||||
downEvent.stopPropagation();
|
||||
downEvent.preventDefault();
|
||||
@ -267,8 +275,9 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
// FIXME: dirty fix remove label-for fro liveEditing
|
||||
(downEvent.target as HTMLElement).removeAttribute('for');
|
||||
|
||||
|
||||
const nodeInst = this.getNodeInstanceFromElement(downEvent.target as Element);
|
||||
const node = nodeInst?.node || this.document.rootNode;
|
||||
const node = nodeInst?.node || documentModel.rootNode;
|
||||
const isMulti = downEvent.metaKey || downEvent.ctrlKey;
|
||||
const isLeftButton = downEvent.which === 1 || downEvent.button === 0;
|
||||
const checkSelect = (e: MouseEvent) => {
|
||||
@ -280,6 +289,8 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
selection.remove(id);
|
||||
} else {
|
||||
selection.select(id);
|
||||
|
||||
// dirty code should refector
|
||||
const editor = this.designer?.editor;
|
||||
const npm = node?.componentMeta?.npm;
|
||||
const selected =
|
||||
@ -303,7 +314,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
selection.add(node.id);
|
||||
ignoreUpSelected = true;
|
||||
}
|
||||
selection.remove(this.document.rootNode.id);
|
||||
selection.remove(documentModel.rootNode.id);
|
||||
// 获得顶层 nodes
|
||||
nodes = selection.getTopNodes();
|
||||
} else if (selection.containsNode(node, true)) {
|
||||
@ -359,7 +370,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
*/
|
||||
setupDetecting() {
|
||||
const doc = this.contentDocument!;
|
||||
const detecting = this.document.designer.detecting;
|
||||
const detecting = this.designer.detecting;
|
||||
const hover = (e: MouseEvent) => {
|
||||
if (!detecting.enable) {
|
||||
return;
|
||||
@ -368,7 +379,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
detecting.capture(nodeInst?.node || null);
|
||||
e.stopPropagation();
|
||||
};
|
||||
const leave = () => detecting.leave(this.document);
|
||||
const leave = () => detecting.leave(this.project.currentDocument);
|
||||
|
||||
doc.addEventListener('mouseover', hover, true);
|
||||
doc.addEventListener('mouseleave', leave, false);
|
||||
@ -383,7 +394,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
);
|
||||
|
||||
this.disableHovering = () => {
|
||||
detecting.leave(this.document);
|
||||
detecting.leave(this.project.currentDocument);
|
||||
doc.removeEventListener('mouseover', hover, true);
|
||||
doc.removeEventListener('mouseleave', leave, false);
|
||||
this.disableHovering = undefined;
|
||||
@ -406,7 +417,10 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
if (!nodeInst) {
|
||||
return;
|
||||
}
|
||||
const node = nodeInst.node || this.document.rootNode;
|
||||
const node = nodeInst.node || this.project.currentDocument?.rootNode;
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
|
||||
const rootElement = this.findDOMNodes(nodeInst.instance, node.componentMeta.rootSelector)?.find((item) =>
|
||||
item.contains(targetElement),
|
||||
@ -450,10 +464,12 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
if (!nodeInst) {
|
||||
return;
|
||||
}
|
||||
const node = nodeInst.node || this.document.rootNode;
|
||||
const node = nodeInst.node || this.project.currentDocument?.rootNode;
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
|
||||
// dirty code should refector
|
||||
const editor = this.designer?.editor;
|
||||
const npm = node?.componentMeta?.npm;
|
||||
const selected =
|
||||
@ -504,14 +520,15 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
}
|
||||
|
||||
createComponent(schema: ComponentSchema): Component | null {
|
||||
return this.renderer?.createComponent(schema) || null;
|
||||
return null;
|
||||
// return this.renderer?.createComponent(schema) || null;
|
||||
}
|
||||
|
||||
@obx private instancesMap: {
|
||||
[docId: string]: Map<string, ComponentInstance[]>;
|
||||
} = {};
|
||||
setInstance(docId: string, id: string, instances: ComponentInstance[] | null) {
|
||||
if (hasOwnProperty(this.instancesMap, docId)) {
|
||||
if (!hasOwnProperty(this.instancesMap, docId)) {
|
||||
this.instancesMap[docId] = new Map();
|
||||
}
|
||||
if (instances == null) {
|
||||
@ -524,17 +541,18 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
/**
|
||||
* @see ISimulator
|
||||
*/
|
||||
getComponentInstances(node: Node): ComponentInstance[] | null {
|
||||
getComponentInstances(node: Node, context?: NodeInstance): ComponentInstance[] | null {
|
||||
const docId = node.document.id;
|
||||
|
||||
return this.instancesMap[docId]?.get(node.id) || null;
|
||||
}
|
||||
let instances = this.instancesMap[docId]?.get(node.id) || null;
|
||||
if (!instances || !context) {
|
||||
return instances;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ISimulator
|
||||
*/
|
||||
getComponentInstanceId(instance: ComponentInstance) {
|
||||
throw new Error('Method not implemented.');
|
||||
// filter with context
|
||||
return instances.filter((instance) => {
|
||||
return this.getClosestNodeInstance(instance, context.nodeId)?.instance === context.instance
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -659,7 +677,9 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
if (!nodeIntance) {
|
||||
return null;
|
||||
}
|
||||
const node = this.document.getNode(nodeIntance.nodeId);
|
||||
const { docId } = nodeIntance;
|
||||
const doc = this.project.getDocument(docId)!;
|
||||
const node = doc.getNode(nodeIntance.nodeId);
|
||||
return {
|
||||
...nodeIntance,
|
||||
node,
|
||||
@ -782,9 +802,6 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
e.target = this.contentDocument!.elementFromPoint(e.canvasX!, e.canvasY!);
|
||||
}
|
||||
|
||||
// documentModel : 目标文档
|
||||
e.documentModel = this.document;
|
||||
|
||||
// 事件已订正
|
||||
e.fixed = true;
|
||||
return e;
|
||||
@ -815,6 +832,10 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
locate(e: LocateEvent): any {
|
||||
this.sensing = true;
|
||||
this.scroller.scrolling(e);
|
||||
const document = this.project.currentDocument;
|
||||
if (!document) {
|
||||
return null;
|
||||
}
|
||||
const dropContainer = this.getDropContainer(e);
|
||||
if (!dropContainer) {
|
||||
return null;
|
||||
@ -841,9 +862,9 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
};
|
||||
|
||||
const locationData = {
|
||||
target: container,
|
||||
target: container as ParentalNode,
|
||||
detail,
|
||||
source: 'simulator' + this.document.id,
|
||||
source: 'simulator' + document.id,
|
||||
event: e,
|
||||
};
|
||||
|
||||
@ -854,9 +875,9 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
e.dragObject.nodes[0].getPrototype()?.isModal()
|
||||
) {
|
||||
return this.designer.createLocation({
|
||||
target: this.document.rootNode,
|
||||
target: document.rootNode,
|
||||
detail,
|
||||
source: 'simulator' + this.document.id,
|
||||
source: 'simulator' + document.id,
|
||||
event: e,
|
||||
});
|
||||
}
|
||||
@ -960,7 +981,8 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
getDropContainer(e: LocateEvent): DropContainer | LocationData | null {
|
||||
const { target, dragObject } = e;
|
||||
const isAny = isDragAnyObject(dragObject);
|
||||
const { modalNode, currentRoot } = this.document;
|
||||
const document = this.project.currentDocument!;
|
||||
const { currentRoot } = document;
|
||||
let container: Node;
|
||||
let nodeInstance: NodeInstance<ComponentInstance> | undefined;
|
||||
|
||||
@ -984,11 +1006,6 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
container = container.parent || currentRoot;
|
||||
}
|
||||
|
||||
// check container if in modalNode layer, if not, use modalNode
|
||||
if (modalNode && !modalNode.contains(container)) {
|
||||
container = modalNode;
|
||||
}
|
||||
|
||||
// TODO: use spec container to accept specialData
|
||||
if (isAny) {
|
||||
// will return locationData
|
||||
@ -996,7 +1013,6 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
}
|
||||
|
||||
// get common parent, avoid drop container contains by dragObject
|
||||
// TODO: renderengine support pointerEvents: none for acceleration
|
||||
const drillDownExcludes = new Set<Node>();
|
||||
if (isDragNodeObject(dragObject)) {
|
||||
const nodes = dragObject.nodes;
|
||||
@ -1008,63 +1024,70 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
}
|
||||
}
|
||||
if (p !== container) {
|
||||
container = p || this.document.rootNode;
|
||||
container = p || document.rootNode;
|
||||
drillDownExcludes.add(container);
|
||||
}
|
||||
}
|
||||
|
||||
const ret: any = {
|
||||
container,
|
||||
};
|
||||
let instance: any;
|
||||
if (nodeInstance) {
|
||||
if (nodeInstance.node === container) {
|
||||
ret.instance = nodeInstance.instance;
|
||||
instance = nodeInstance.instance;
|
||||
} else {
|
||||
ret.instance = this.getClosestNodeInstance(nodeInstance.instance as any, container.id)?.instance;
|
||||
instance = this.getClosestNodeInstance(nodeInstance.instance as any, container.id)?.instance;
|
||||
}
|
||||
} else {
|
||||
ret.instance = this.getComponentInstances(container)?.[0];
|
||||
instance = this.getComponentInstances(container)?.[0];
|
||||
}
|
||||
|
||||
let dropContainer: DropContainer = {
|
||||
container: container as any,
|
||||
instance
|
||||
};
|
||||
|
||||
let res: any;
|
||||
let upward: any;
|
||||
// TODO: complete drill down logic
|
||||
let upward: DropContainer | null = null;
|
||||
while (container) {
|
||||
if (ret.container !== container) {
|
||||
ret.container = container;
|
||||
ret.instance = this.getClosestNodeInstance(ret.instance, container.id)?.instance;
|
||||
}
|
||||
res = this.handleAccept(ret, e);
|
||||
res = this.handleAccept(dropContainer, e);
|
||||
if (isLocationData(res)) {
|
||||
return res;
|
||||
}
|
||||
if (res === true) {
|
||||
return ret;
|
||||
return dropContainer;
|
||||
}
|
||||
if (!res) {
|
||||
drillDownExcludes.add(container);
|
||||
if (upward) {
|
||||
container = upward;
|
||||
dropContainer = upward;
|
||||
container = dropContainer.container;
|
||||
upward = null;
|
||||
} else if (container.parent) {
|
||||
container = container.parent;
|
||||
instance = this.getClosestNodeInstance(dropContainer.instance, container.id)?.instance;
|
||||
dropContainer = {
|
||||
container: container as ParentalNode,
|
||||
instance
|
||||
};
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else if (isNode(res)) {
|
||||
/* else if (res === DRILL_DOWN) {
|
||||
}/* else if (res === DRILL_DOWN) {
|
||||
if (!upward) {
|
||||
upward = container.parent;
|
||||
container = container.parent;
|
||||
instance = this.getClosestNodeInstance(dropContainer.instance, container.id)?.instance;
|
||||
upward = {
|
||||
container,
|
||||
instance
|
||||
};
|
||||
}
|
||||
container = this.getNearByContainer(container, drillExcludes, e);
|
||||
if (!container) {
|
||||
container = upward;
|
||||
dropContainer = this.getNearByContainer(dropContainer, drillDownExcludes, e);
|
||||
if (!dropContainer) {
|
||||
dropContainer = upward;
|
||||
upward = null;
|
||||
}
|
||||
} else if (isNode(res)) {
|
||||
// TODO:
|
||||
}*/
|
||||
container = res;
|
||||
upward = null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -1086,8 +1109,9 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
*/
|
||||
handleAccept({ container, instance }: DropContainer, e: LocateEvent) {
|
||||
const { dragObject } = e;
|
||||
const document = this.currentDocument!;
|
||||
if (isRootNode(container)) {
|
||||
return this.document.checkDropTarget(container, dragObject as any);
|
||||
return document.checkDropTarget(container, dragObject as any);
|
||||
}
|
||||
|
||||
const meta = (container as Node).componentMeta;
|
||||
@ -1126,36 +1150,44 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
}
|
||||
|
||||
// check nesting
|
||||
return this.document.checkNesting(container, dragObject as any);
|
||||
return document.checkNesting(container, dragObject as any);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找邻近容器
|
||||
*/
|
||||
getNearByContainer(container: ParentalNode, e: LocateEvent) {
|
||||
/*
|
||||
getNearByContainer({ container, instance }: DropContainer, drillDownExcludes: Set<Node>, e: LocateEvent) {
|
||||
const children = container.children;
|
||||
if (!children || children.length < 1) {
|
||||
const document = this.project.currentDocument!;
|
||||
if (!children || children.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let nearDistance: any = null;
|
||||
let nearBy: any = null;
|
||||
for (let i = 0, l = children.length; i < l; i++) {
|
||||
let child: any = children[i];
|
||||
if (!isElementNode(child)) {
|
||||
for (let i = 0, l = children.size; i < l; i++) {
|
||||
let child = children.get(i);
|
||||
|
||||
if (!child) {
|
||||
continue;
|
||||
}
|
||||
if (hasConditionFlow(child)) {
|
||||
const bn = child.conditionFlow;
|
||||
if (child.conditionGroup) {
|
||||
const bn = child.conditionGroup;
|
||||
i = bn.index + bn.length - 1;
|
||||
child = bn.visibleNode;
|
||||
}
|
||||
const rect = this.document.computeRect(child);
|
||||
if (!child.isParental() || drillDownExcludes.has(child)) {
|
||||
continue;
|
||||
}
|
||||
// TODO:
|
||||
this.findDOMNodes(instance);
|
||||
this.getComponentInstances(child)
|
||||
const rect = this.computeRect(child);
|
||||
if (!rect) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
if (isPointInRect(e, rect)) {
|
||||
return child;
|
||||
}
|
||||
@ -1164,11 +1196,10 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
if (nearDistance === null || distance < nearDistance) {
|
||||
nearDistance = distance;
|
||||
nearBy = child;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
return nearBy;
|
||||
*/
|
||||
}
|
||||
// #endregion
|
||||
}
|
||||
|
||||
@ -29,7 +29,7 @@ export class Detecting {
|
||||
}
|
||||
}
|
||||
|
||||
leave(document: DocumentModel) {
|
||||
leave(document: DocumentModel | undefined) {
|
||||
if (this.current && this.current.document === document) {
|
||||
this._current = null;
|
||||
}
|
||||
|
||||
@ -202,8 +202,7 @@ export class Dragon {
|
||||
|
||||
private emitter = new EventEmitter();
|
||||
|
||||
constructor(readonly designer: Designer) {
|
||||
}
|
||||
constructor(readonly designer: Designer) {}
|
||||
|
||||
/**
|
||||
* Quick listen a shell(container element) drag behavior
|
||||
@ -416,7 +415,8 @@ export class Dragon {
|
||||
if (!sourceDocument || sourceDocument === document) {
|
||||
evt.globalX = e.clientX;
|
||||
evt.globalY = e.clientY;
|
||||
} else { // event from simulator sandbox
|
||||
} else {
|
||||
// event from simulator sandbox
|
||||
let srcSim: ISimulatorHost | undefined;
|
||||
const lastSim = lastSensor && isSimulatorHost(lastSensor) ? lastSensor : null;
|
||||
// check source simulator
|
||||
@ -517,22 +517,30 @@ export class Dragon {
|
||||
}
|
||||
|
||||
private getMasterSensors(): ISimulatorHost[] {
|
||||
return this.designer.project.documents
|
||||
.map((doc) => {
|
||||
// TODO: not use actived,
|
||||
if (doc.actived && doc.simulator?.sensorAvailable) {
|
||||
return doc.simulator;
|
||||
}
|
||||
return null;
|
||||
})
|
||||
.filter(Boolean) as any;
|
||||
return Array.from(
|
||||
new Set(
|
||||
this.designer.project.documents
|
||||
.map((doc) => {
|
||||
// TODO: not use actived,
|
||||
if (doc.actived && doc.simulator?.sensorAvailable) {
|
||||
return doc.simulator;
|
||||
}
|
||||
return null;
|
||||
})
|
||||
.filter(Boolean) as any,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
private getSimulators() {
|
||||
return new Set(this.designer.project.documents.map(doc => doc.simulator));
|
||||
}
|
||||
|
||||
// #region ======== drag and drop helpers ============
|
||||
private setNativeSelection(enableFlag: boolean) {
|
||||
setNativeSelection(enableFlag);
|
||||
this.designer.project.documents.forEach((doc) => {
|
||||
doc.simulator?.setNativeSelection(enableFlag);
|
||||
this.getSimulators().forEach((sim) => {
|
||||
sim?.setNativeSelection(enableFlag);
|
||||
});
|
||||
}
|
||||
|
||||
@ -541,8 +549,8 @@ export class Dragon {
|
||||
*/
|
||||
private setDraggingState(state: boolean) {
|
||||
cursor.setDragging(state);
|
||||
this.designer.project.documents.forEach((doc) => {
|
||||
doc.simulator?.setDraggingState(state);
|
||||
this.getSimulators().forEach((sim) => {
|
||||
sim?.setDraggingState(state);
|
||||
});
|
||||
}
|
||||
|
||||
@ -551,8 +559,8 @@ export class Dragon {
|
||||
*/
|
||||
private setCopyState(state: boolean) {
|
||||
cursor.setCopy(state);
|
||||
this.designer.project.documents.forEach((doc) => {
|
||||
doc.simulator?.setCopyState(state);
|
||||
this.getSimulators().forEach((sim) => {
|
||||
sim?.setCopyState(state);
|
||||
});
|
||||
}
|
||||
|
||||
@ -561,8 +569,8 @@ export class Dragon {
|
||||
*/
|
||||
private clearState() {
|
||||
cursor.release();
|
||||
this.designer.project.documents.forEach((doc) => {
|
||||
doc.simulator?.clearState();
|
||||
this.getSimulators().forEach((sim) => {
|
||||
sim?.clearState();
|
||||
});
|
||||
}
|
||||
// #endregion
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
export * from './document-view';
|
||||
export * from './document-model';
|
||||
export * from './node';
|
||||
export * from './selection';
|
||||
|
||||
@ -28,6 +28,10 @@ export class ExclusiveGroup {
|
||||
return this.children[0]!;
|
||||
}
|
||||
|
||||
get index() {
|
||||
return this.firstNode.index;
|
||||
}
|
||||
|
||||
add(node: Node) {
|
||||
if (node.nextSibling && node.nextSibling.conditionGroup === this) {
|
||||
const i = this.children.indexOf(node.nextSibling);
|
||||
|
||||
@ -12,17 +12,9 @@
|
||||
background: transparent url(//img.alicdn.com/tfs/TB1xLKQAbj1gK0jSZFuXXcrHpXa-90-90.png) center 30% no-repeat;
|
||||
padding-top: 50%;
|
||||
}
|
||||
.lc-document {
|
||||
|
||||
.lc-simulator-shell {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
&-hidden {
|
||||
// todo:
|
||||
display: none;
|
||||
}
|
||||
|
||||
.lc-simulator-shell {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,8 +11,6 @@ export class Project {
|
||||
|
||||
private data: ProjectSchema = { version: '1.0.0', componentsMap: [], componentsTree: [] };
|
||||
|
||||
@obx.ref canvasDisplayMode: 'exclusive' | 'overview' = 'exclusive';
|
||||
|
||||
private _simulator?: ISimulatorHost;
|
||||
|
||||
/**
|
||||
@ -112,14 +110,26 @@ export class Project {
|
||||
| string,
|
||||
): any {}
|
||||
|
||||
|
||||
private documentsMap = new Map<string, DocumentModel>();
|
||||
getDocument(id: string): DocumentModel | null {
|
||||
return this.documentsMap.get(id) || null;
|
||||
}
|
||||
|
||||
createDocument(data?: RootSchema): DocumentModel {
|
||||
const doc = new DocumentModel(this, data);
|
||||
this.documents.push(doc);
|
||||
this.documentsMap.set(doc.id, doc);
|
||||
return doc;
|
||||
}
|
||||
|
||||
open(doc?: string | DocumentModel | RootSchema): DocumentModel | null {
|
||||
if (!doc) {
|
||||
const got = this.documents.find((item) => item.isBlank());
|
||||
if (got) {
|
||||
return got.open();
|
||||
}
|
||||
doc = new DocumentModel(this);
|
||||
this.documents.push(doc);
|
||||
doc = this.createDocument();
|
||||
return doc.open();
|
||||
}
|
||||
if (typeof doc === 'string') {
|
||||
@ -130,8 +140,7 @@ export class Project {
|
||||
|
||||
const data = this.data.componentsTree.find((data) => data.fileName === doc);
|
||||
if (data) {
|
||||
doc = new DocumentModel(this, data);
|
||||
this.documents.push(doc);
|
||||
doc = this.createDocument(data);
|
||||
return doc.open();
|
||||
}
|
||||
|
||||
@ -142,8 +151,7 @@ export class Project {
|
||||
return doc.open();
|
||||
}
|
||||
|
||||
doc = new DocumentModel(this, doc);
|
||||
this.documents.push(doc);
|
||||
doc = this.createDocument(doc);
|
||||
return doc.open();
|
||||
}
|
||||
|
||||
|
||||
@ -86,7 +86,6 @@ export class Trunk {
|
||||
}
|
||||
|
||||
registerSetter(type: string, setter: CustomView | RegisteredSetter) {
|
||||
// console.warn('Trunk.registerSetter is deprecated');
|
||||
registerSetter(type, setter);
|
||||
}
|
||||
|
||||
|
||||
@ -25,7 +25,7 @@ class Contents extends Component<{ area: Area }> {
|
||||
const top: any[] = [];
|
||||
const bottom: any[] = [];
|
||||
area.container.items.forEach((item) => {
|
||||
const content = <div id={`left-area-${item.name}`}>{item.content}</div>;
|
||||
const content = <div key={`left-area-${item.name}`}>{item.content}</div>;
|
||||
if (item.align === 'bottom') {
|
||||
bottom.push(content);
|
||||
} else {
|
||||
|
||||
@ -30,7 +30,7 @@ class Contents extends Component<{ area: Area, itemClassName?: string }> {
|
||||
return index1 === index2 ? 0 : (index1 > index2 ? 1 : -1);
|
||||
}).forEach(item => {
|
||||
const content = (
|
||||
<div className={itemClassName || ''} id={`top-area-${item.name}`}>
|
||||
<div className={itemClassName || ''} key={`top-area-${item.name}`}>
|
||||
{item.content}
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -82,9 +82,6 @@ export class OutlineMain implements ISensor, ITreeBoard, IScrollable {
|
||||
e.target = document.elementFromPoint(e.canvasX!, e.canvasY!);
|
||||
}
|
||||
|
||||
// documentModel : 目标文档
|
||||
e.documentModel = this._designer?.currentDocument;
|
||||
|
||||
// 事件已订正
|
||||
e.fixed = true;
|
||||
return e;
|
||||
|
||||
@ -2,6 +2,7 @@ import LowCodeRenderer from '@ali/lowcode-react-renderer';
|
||||
import { ReactInstance, Fragment, Component, createElement } from 'react';
|
||||
import { observer } from '@recore/obx-react';
|
||||
import { SimulatorRendererContainer, DocumentInstance } from './renderer';
|
||||
import { Router, Route, Switch } from 'react-router';
|
||||
import './renderer.less';
|
||||
|
||||
// patch cloneElement avoid lost keyProps
|
||||
@ -38,17 +39,19 @@ export default class SimulatorRendererView extends Component<{ rendererContainer
|
||||
render() {
|
||||
const { rendererContainer } = this.props;
|
||||
return (
|
||||
<Layout rendererContainer={rendererContainer}>
|
||||
<Router onChange={(currentPath: string) => {
|
||||
rendererContainer.redirect(currentPath);
|
||||
}}>
|
||||
{rendererContainer.getDocumentInstances().map((instance) => {
|
||||
return <Route path={instance.document.get('fileName')}>
|
||||
<Renderer documentInstance={instance} />
|
||||
</Route>
|
||||
})}
|
||||
</Router>
|
||||
</Layout>
|
||||
<Router history={rendererContainer.history}>
|
||||
<Layout rendererContainer={rendererContainer}>
|
||||
<Switch>
|
||||
{rendererContainer.documentInstances.map((instance) => (
|
||||
<Route
|
||||
path={instance.path}
|
||||
key={instance.id}
|
||||
render={(routeProps) => <Renderer documentInstance={instance} {...routeProps} />}
|
||||
/>
|
||||
))}
|
||||
</Switch>
|
||||
</Layout>
|
||||
</Router>
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -106,7 +109,6 @@ class Renderer extends Component<{ documentInstance: DocumentInstance }> {
|
||||
schema={documentInstance.schema}
|
||||
components={container.components}
|
||||
appHelper={container.context}
|
||||
// context={renderer.context}
|
||||
designMode={designMode}
|
||||
suspended={documentInstance.suspended}
|
||||
self={documentInstance.scope}
|
||||
@ -116,27 +118,44 @@ class Renderer extends Component<{ documentInstance: DocumentInstance }> {
|
||||
const leaf = documentInstance.getNode(__id);
|
||||
viewProps._leaf = leaf;
|
||||
viewProps._componentName = leaf?.componentName;
|
||||
let _children = leaf?.isContainer() ? (children == null ? [] : Array.isArray(children) ? children : [children]) : children;
|
||||
let _children = leaf?.isContainer()
|
||||
? children == null
|
||||
? []
|
||||
: Array.isArray(children)
|
||||
? children
|
||||
: [children]
|
||||
: children;
|
||||
if (props.children && props.children.length) {
|
||||
if (Array.isArray(props.children)) {
|
||||
_children = Array.isArray(_children) ? _children.concat(props.children) : props.children.unshift(_children);
|
||||
_children = Array.isArray(_children)
|
||||
? _children.concat(props.children)
|
||||
: props.children.unshift(_children);
|
||||
} else {
|
||||
Array.isArray(_children) && _children.push(props.children) || (_children = [_children].push(props.children));
|
||||
(Array.isArray(_children) && _children.push(props.children)) ||
|
||||
(_children = [_children].push(props.children));
|
||||
}
|
||||
}
|
||||
// 如果是容器 && 无children && 高宽为空 增加一个占位容器,方便拖动
|
||||
if (leaf?.isContainer() && (_children == null || !_children.length) && (!viewProps.style || Object.keys(viewProps.style).length == 0)){
|
||||
_children = <div style={{
|
||||
height:'66px',
|
||||
backgroundColor:'#f0f0f0',
|
||||
borderColor:'#a7b1bd',
|
||||
border: '1px dotted',
|
||||
color:'#a7b1bd',
|
||||
textAlign:'center',
|
||||
lineHeight:'66px'
|
||||
}}>
|
||||
拖拽组件或模板到这里
|
||||
</div>
|
||||
if (
|
||||
leaf?.isContainer() &&
|
||||
(_children == null || !_children.length) &&
|
||||
(!viewProps.style || Object.keys(viewProps.style).length == 0)
|
||||
) {
|
||||
_children = (
|
||||
<div
|
||||
style={{
|
||||
height: '66px',
|
||||
backgroundColor: '#f0f0f0',
|
||||
borderColor: '#a7b1bd',
|
||||
border: '1px dotted',
|
||||
color: '#a7b1bd',
|
||||
textAlign: 'center',
|
||||
lineHeight: '66px',
|
||||
}}
|
||||
>
|
||||
拖拽组件或模板到这里
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (viewProps._componentName === 'Menu') {
|
||||
@ -159,17 +178,13 @@ class Renderer extends Component<{ documentInstance: DocumentInstance }> {
|
||||
console.info('menuprops', viewProps);
|
||||
}
|
||||
|
||||
return createElement(
|
||||
getDeviceView(Component, device, designMode),
|
||||
viewProps,
|
||||
_children,
|
||||
);
|
||||
return createElement(getDeviceView(Component, device, designMode), viewProps, _children);
|
||||
}}
|
||||
onCompGetRef={(schema: any, ref: ReactInstance | null) => {
|
||||
documentInstance.mountInstance(schema.id, ref);
|
||||
}}
|
||||
//onCompGetCtx={(schema: any, ctx: object) => {
|
||||
// renderer.mountContext(schema.id, ctx);
|
||||
// documentInstance.mountContext(schema.id, ctx);
|
||||
//}}
|
||||
/>
|
||||
);
|
||||
|
||||
@ -9,8 +9,8 @@ import loader from './utils/loader';
|
||||
import { reactFindDOMNodes, FIBER_KEY } from './utils/react-find-dom-nodes';
|
||||
import { isESModule, isElement, cursor, setNativeSelection } from '@ali/lowcode-utils';
|
||||
import { RootSchema, NpmInfo, ComponentSchema, TransformStage } from '@ali/lowcode-types';
|
||||
// just use types
|
||||
import { BuiltinSimulatorRenderer, NodeInstance, Component, DocumentModel, Node } from '@ali/lowcode-designer';
|
||||
import { createMemoryHistory, MemoryHistory } from 'history';
|
||||
import Slot from './builtin-components/slot';
|
||||
import Leaf from './builtin-components/leaf';
|
||||
|
||||
@ -22,13 +22,13 @@ export class DocumentInstance {
|
||||
return this._schema;
|
||||
}
|
||||
|
||||
constructor(readonly container: SimulatorRendererContainer, readonly document: DocumentModel) {
|
||||
this.dispose = host.connect(this, () => {
|
||||
// sync layout config
|
||||
private dispose?: () => void;
|
||||
|
||||
constructor(readonly container: SimulatorRendererContainer, readonly document: DocumentModel) {
|
||||
this.dispose = host.autorun(() => {
|
||||
// sync schema
|
||||
this._schema = host.document.export(1);
|
||||
})
|
||||
this._schema = document.export(1);
|
||||
});
|
||||
}
|
||||
|
||||
@computed get suspended(): any {
|
||||
@ -38,6 +38,14 @@ export class DocumentInstance {
|
||||
return null;
|
||||
}
|
||||
|
||||
get path(): string {
|
||||
return '/' + this.document.fileName;
|
||||
}
|
||||
|
||||
get id() {
|
||||
return this.document.id;
|
||||
}
|
||||
|
||||
private unmountIntance(id: string, instance: ReactInstance) {
|
||||
const instances = this.instancesMap.get(id);
|
||||
if (instances) {
|
||||
@ -114,62 +122,6 @@ export class DocumentInstance {
|
||||
// this.ctxMap.set(id, ctx);
|
||||
}
|
||||
|
||||
createComponent(schema: ComponentSchema): Component | null {
|
||||
const _schema = {
|
||||
...schema,
|
||||
};
|
||||
_schema.methods = {};
|
||||
_schema.lifeCycles = {};
|
||||
|
||||
const processPropsSchema = (propsSchema: any, propsMap: any): any => {
|
||||
if (!propsSchema) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const result = {...propsSchema};
|
||||
const reg = /^(?:this\.props|props)\.(\S+)$/;
|
||||
Object.keys(propsSchema).map((key: string) => {
|
||||
if (propsSchema[key].type === 'JSExpression') {
|
||||
const { value } = propsSchema[key];
|
||||
const matched = reg.exec(value);
|
||||
if (matched) {
|
||||
const propName = matched[1];
|
||||
result[key] = propsMap[propName];
|
||||
}
|
||||
}
|
||||
});
|
||||
return result;
|
||||
};
|
||||
|
||||
const getElement = (componentsMap: any, schema: any, propsMap: any): ReactElement => {
|
||||
const Com = componentsMap[schema.componentName];
|
||||
let children = null;
|
||||
if (schema.children && schema.children.length > 0) {
|
||||
children = schema.children.map((item: any) => getElement(componentsMap, item, propsMap));
|
||||
}
|
||||
const _leaf = this.document.designer.currentDocument?.createNode(schema);
|
||||
const node = this.document.createNode(schema);
|
||||
let props = processPropsSchema(schema.props, propsMap);
|
||||
props = this.document.designer.transformProps(props, node, TransformStage.Init);
|
||||
props = this.document.designer.transformProps(props, node, TransformStage.Render);
|
||||
return createElement(Com, {...props, _leaf}, children);
|
||||
}
|
||||
|
||||
const container = this.container;
|
||||
class Com extends React.Component {
|
||||
render() {
|
||||
const componentsMap = container.componentsMap;
|
||||
let children = null;
|
||||
if (_schema.children && Array.isArray(_schema.children)) {
|
||||
children = _schema.children?.map((item:any) => getElement(componentsMap, item, this.props));
|
||||
}
|
||||
return createElement(React.Fragment, {}, children);
|
||||
}
|
||||
}
|
||||
|
||||
return Com;
|
||||
}
|
||||
|
||||
getNode(id: string): Node | null {
|
||||
return this.document.getNode(id);
|
||||
}
|
||||
@ -178,12 +130,14 @@ export class DocumentInstance {
|
||||
export class SimulatorRendererContainer implements BuiltinSimulatorRenderer {
|
||||
readonly isSimulatorRenderer = true;
|
||||
private dispose?: () => void;
|
||||
readonly history: MemoryHistory;
|
||||
|
||||
@obx.ref private _documentInstances: DocumentInstance[] = [];
|
||||
get documentInstances() {
|
||||
return this._documentInstances;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
if (!host) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.dispose = host.connect(this, () => {
|
||||
// sync layout config
|
||||
// todo: split with others, not all should recompute
|
||||
@ -199,6 +153,27 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer {
|
||||
// sync device
|
||||
this._device = host.device;
|
||||
});
|
||||
const documentInstanceMap = new Map<string, DocumentInstance>();
|
||||
host.autorun(() => {
|
||||
this._documentInstances = host.project.documents.map((doc) => {
|
||||
let inst = documentInstanceMap.get(doc.id);
|
||||
if (!inst) {
|
||||
inst = new DocumentInstance(this, doc);
|
||||
documentInstanceMap.set(doc.id, inst);
|
||||
}
|
||||
return inst;
|
||||
});
|
||||
console.info('instances', this._documentInstances);
|
||||
});
|
||||
const initialEntry = host.project.currentDocument
|
||||
? documentInstanceMap.get(host.project.currentDocument.id)!.path
|
||||
: '/';
|
||||
this.history = createMemoryHistory({
|
||||
initialEntries: [initialEntry],
|
||||
});
|
||||
this.history.listen((location, action) => {
|
||||
console.info(location);
|
||||
});
|
||||
host.componentsConsumer.consume(async (componentsAsset) => {
|
||||
if (componentsAsset) {
|
||||
await this.load(componentsAsset);
|
||||
@ -208,10 +183,13 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer {
|
||||
host.injectionConsumer.consume((data) => {
|
||||
// sync utils, i18n, contants,... config
|
||||
this._appContext = {
|
||||
utils: {},
|
||||
constants: {
|
||||
name: 'demo',
|
||||
utils: {
|
||||
router: {
|
||||
push() {},
|
||||
replace() {},
|
||||
},
|
||||
},
|
||||
constants: {},
|
||||
};
|
||||
});
|
||||
}
|
||||
@ -255,13 +233,6 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer {
|
||||
return loader.load(asset);
|
||||
}
|
||||
|
||||
private documentInstanceMap = new Map<string, DocumentInstance>();
|
||||
|
||||
|
||||
redirect(path: string) {
|
||||
|
||||
}
|
||||
|
||||
getComponent(componentName: string) {
|
||||
const paths = componentName.split('.');
|
||||
const subs: string[] = [];
|
||||
@ -308,6 +279,66 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer {
|
||||
cursor.release();
|
||||
}
|
||||
|
||||
createComponent(schema: ComponentSchema): Component | null {
|
||||
return null;
|
||||
// TODO: use ComponentEngine refactor
|
||||
/*
|
||||
const _schema = {
|
||||
...schema,
|
||||
};
|
||||
_schema.methods = {};
|
||||
_schema.lifeCycles = {};
|
||||
|
||||
const processPropsSchema = (propsSchema: any, propsMap: any): any => {
|
||||
if (!propsSchema) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const result = { ...propsSchema };
|
||||
const reg = /^(?:this\.props|props)\.(\S+)$/;
|
||||
Object.keys(propsSchema).map((key: string) => {
|
||||
if (propsSchema[key].type === 'JSExpression') {
|
||||
const { value } = propsSchema[key];
|
||||
const matched = reg.exec(value);
|
||||
if (matched) {
|
||||
const propName = matched[1];
|
||||
result[key] = propsMap[propName];
|
||||
}
|
||||
}
|
||||
});
|
||||
return result;
|
||||
};
|
||||
|
||||
const getElement = (componentsMap: any, schema: any, propsMap: any): ReactElement => {
|
||||
const Com = componentsMap[schema.componentName];
|
||||
let children = null;
|
||||
if (schema.children && schema.children.length > 0) {
|
||||
children = schema.children.map((item: any) => getElement(componentsMap, item, propsMap));
|
||||
}
|
||||
const _leaf = this.document.designer.currentDocument?.createNode(schema);
|
||||
const node = this.document.createNode(schema);
|
||||
let props = processPropsSchema(schema.props, propsMap);
|
||||
props = this.document.designer.transformProps(props, node, TransformStage.Init);
|
||||
props = this.document.designer.transformProps(props, node, TransformStage.Render);
|
||||
return createElement(Com, { ...props, _leaf }, children);
|
||||
};
|
||||
|
||||
const container = this;
|
||||
class Com extends React.Component {
|
||||
render() {
|
||||
const componentsMap = container.componentsMap;
|
||||
let children = null;
|
||||
if (_schema.children && Array.isArray(_schema.children)) {
|
||||
children = _schema.children?.map((item: any) => getElement(componentsMap, item, this.props));
|
||||
}
|
||||
return createElement(React.Fragment, {}, children);
|
||||
}
|
||||
}
|
||||
|
||||
return Com;
|
||||
*/
|
||||
}
|
||||
|
||||
private _running = false;
|
||||
run() {
|
||||
if (this._running) {
|
||||
@ -321,6 +352,7 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer {
|
||||
document.body.appendChild(container);
|
||||
container.id = containerId;
|
||||
}
|
||||
|
||||
// ==== compatiable vision
|
||||
document.documentElement.classList.add('engine-page');
|
||||
document.body.classList.add('engine-document'); // important! Stylesheet.invoke depends
|
||||
@ -401,9 +433,12 @@ const builtinComponents = {
|
||||
Leaf,
|
||||
};
|
||||
|
||||
function buildComponents(libraryMap: LibraryMap, componentsMap: { [componentName: string]: NpmInfo | ComponentType<any> }) {
|
||||
function buildComponents(
|
||||
libraryMap: LibraryMap,
|
||||
componentsMap: { [componentName: string]: NpmInfo | ComponentType<any> },
|
||||
) {
|
||||
const components: any = {
|
||||
...builtinComponents
|
||||
...builtinComponents,
|
||||
};
|
||||
Object.keys(componentsMap).forEach((componentName) => {
|
||||
let component = componentsMap[componentName];
|
||||
|
||||
@ -42,7 +42,7 @@ export class Cursor {
|
||||
}
|
||||
}
|
||||
|
||||
private addState(state: string) {
|
||||
addState(state: string) {
|
||||
if (!this.states.has(state)) {
|
||||
this.states.add(state);
|
||||
document.documentElement.classList.add(`lc-cursor-${state}`);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user