UNPKG

@antv/x6

Version:

JavaScript diagramming library that uses SVG and HTML for rendering.

1,168 lines 38.9 kB
/* eslint-disable no-underscore-dangle */ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; import { ArrayExt, StringExt, ObjectExt, FunctionExt } from '../util'; import { Rectangle, Point } from '../geometry'; import { Basecoat } from '../common'; import { Attr } from '../registry'; import { Animation } from './animation'; import { Store } from './store'; export class Cell extends Basecoat { constructor(metadata = {}) { super(); const ctor = this.constructor; const defaults = ctor.getDefaults(true); const props = ObjectExt.merge({}, this.preprocess(defaults), this.preprocess(metadata)); this.id = props.id || StringExt.uuid(); this.store = new Store(props); this.animation = new Animation(this); this.setup(); this.init(); this.postprocess(metadata); } static config(presets) { const { markup, propHooks, attrHooks } = presets, others = __rest(presets, ["markup", "propHooks", "attrHooks"]); if (markup != null) { this.markup = markup; } if (propHooks) { this.propHooks = this.propHooks.slice(); if (Array.isArray(propHooks)) { this.propHooks.push(...propHooks); } else if (typeof propHooks === 'function') { this.propHooks.push(propHooks); } else { Object.keys(propHooks).forEach((name) => { const hook = propHooks[name]; if (typeof hook === 'function') { this.propHooks.push(hook); } }); } } if (attrHooks) { this.attrHooks = Object.assign(Object.assign({}, this.attrHooks), attrHooks); } this.defaults = ObjectExt.merge({}, this.defaults, others); } static getMarkup() { return this.markup; } static getDefaults(raw) { return (raw ? this.defaults : ObjectExt.cloneDeep(this.defaults)); } static getAttrHooks() { return this.attrHooks; } static applyPropHooks(cell, metadata) { return this.propHooks.reduce((memo, hook) => { return hook ? FunctionExt.call(hook, cell, memo) : memo; }, metadata); } // #endregion get [Symbol.toStringTag]() { return Cell.toStringTag; } init() { } // #region model get model() { return this._model; } set model(model) { if (this._model !== model) { this._model = model; } } // #endregion preprocess(metadata, ignoreIdCheck) { const id = metadata.id; const ctor = this.constructor; const props = ctor.applyPropHooks(this, metadata); if (id == null && ignoreIdCheck !== true) { props.id = StringExt.uuid(); } return props; } postprocess(metadata) { } // eslint-disable-line setup() { this.store.on('change:*', (metadata) => { const { key, current, previous, options } = metadata; this.notify('change:*', { key, options, current, previous, cell: this, }); this.notify(`change:${key}`, { options, current, previous, cell: this, }); const type = key; if (type === 'source' || type === 'target') { this.notify(`change:terminal`, { type, current, previous, options, cell: this, }); } }); this.store.on('changed', ({ options }) => this.notify('changed', { options, cell: this })); } notify(name, args) { this.trigger(name, args); const model = this.model; if (model) { model.notify(`cell:${name}`, args); if (this.isNode()) { model.notify(`node:${name}`, Object.assign(Object.assign({}, args), { node: this })); } else if (this.isEdge()) { model.notify(`edge:${name}`, Object.assign(Object.assign({}, args), { edge: this })); } } return this; } isNode() { return false; } isEdge() { return false; } isSameStore(cell) { return this.store === cell.store; } get view() { return this.store.get('view'); } get shape() { return this.store.get('shape', ''); } getProp(key, defaultValue) { if (key == null) { return this.store.get(); } return this.store.get(key, defaultValue); } setProp(key, value, options) { if (typeof key === 'string') { this.store.set(key, value, options); } else { const props = this.preprocess(key, true); this.store.set(ObjectExt.merge({}, this.getProp(), props), value); this.postprocess(key); } return this; } removeProp(key, options) { if (typeof key === 'string' || Array.isArray(key)) { this.store.removeByPath(key, options); } else { this.store.remove(options); } return this; } hasChanged(key) { return key == null ? this.store.hasChanged() : this.store.hasChanged(key); } getPropByPath(path) { return this.store.getByPath(path); } setPropByPath(path, value, options = {}) { if (this.model) { // update inner reference if (path === 'children') { this._children = value ? value .map((id) => this.model.getCell(id)) .filter((child) => child != null) : null; } else if (path === 'parent') { this._parent = value ? this.model.getCell(value) : null; } } this.store.setByPath(path, value, options); return this; } removePropByPath(path, options = {}) { const paths = Array.isArray(path) ? path : path.split('/'); // Once a property is removed from the `attrs` the CellView will // recognize a `dirty` flag and re-render itself in order to remove // the attribute from SVGElement. if (paths[0] === 'attrs') { options.dirty = true; } this.store.removeByPath(paths, options); return this; } prop(key, value, options) { if (key == null) { return this.getProp(); } if (typeof key === 'string' || Array.isArray(key)) { if (arguments.length === 1) { return this.getPropByPath(key); } if (value == null) { return this.removePropByPath(key, options || {}); } return this.setPropByPath(key, value, options || {}); } return this.setProp(key, value || {}); } previous(name) { return this.store.getPrevious(name); } // #endregion // #region zIndex get zIndex() { return this.getZIndex(); } set zIndex(z) { if (z == null) { this.removeZIndex(); } else { this.setZIndex(z); } } getZIndex() { return this.store.get('zIndex'); } setZIndex(z, options = {}) { this.store.set('zIndex', z, options); return this; } removeZIndex(options = {}) { this.store.remove('zIndex', options); return this; } toFront(options = {}) { const model = this.model; if (model) { let z = model.getMaxZIndex(); let cells; if (options.deep) { cells = this.getDescendants({ deep: true, breadthFirst: true }); cells.unshift(this); } else { cells = [this]; } z = z - cells.length + 1; const count = model.total(); let changed = model.indexOf(this) !== count - cells.length; if (!changed) { changed = cells.some((cell, index) => cell.getZIndex() !== z + index); } if (changed) { this.batchUpdate('to-front', () => { z += cells.length; cells.forEach((cell, index) => { cell.setZIndex(z + index, options); }); }); } } return this; } toBack(options = {}) { const model = this.model; if (model) { let z = model.getMinZIndex(); let cells; if (options.deep) { cells = this.getDescendants({ deep: true, breadthFirst: true }); cells.unshift(this); } else { cells = [this]; } let changed = model.indexOf(this) !== 0; if (!changed) { changed = cells.some((cell, index) => cell.getZIndex() !== z + index); } if (changed) { this.batchUpdate('to-back', () => { z -= cells.length; cells.forEach((cell, index) => { cell.setZIndex(z + index, options); }); }); } } return this; } // #endregion // #region markup get markup() { return this.getMarkup(); } set markup(value) { if (value == null) { this.removeMarkup(); } else { this.setMarkup(value); } } getMarkup() { let markup = this.store.get('markup'); if (markup == null) { const ctor = this.constructor; markup = ctor.getMarkup(); } return markup; } setMarkup(markup, options = {}) { this.store.set('markup', markup, options); return this; } removeMarkup(options = {}) { this.store.remove('markup', options); return this; } // #endregion // #region attrs get attrs() { return this.getAttrs(); } set attrs(value) { if (value == null) { this.removeAttrs(); } else { this.setAttrs(value); } } getAttrs() { const result = this.store.get('attrs'); return result ? Object.assign({}, result) : {}; } setAttrs(attrs, options = {}) { if (attrs == null) { this.removeAttrs(options); } else { const set = (attrs) => this.store.set('attrs', attrs, options); if (options.overwrite === true) { set(attrs); } else { const prev = this.getAttrs(); if (options.deep === false) { set(Object.assign(Object.assign({}, prev), attrs)); } else { set(ObjectExt.merge({}, prev, attrs)); } } } return this; } replaceAttrs(attrs, options = {}) { return this.setAttrs(attrs, Object.assign(Object.assign({}, options), { overwrite: true })); } updateAttrs(attrs, options = {}) { return this.setAttrs(attrs, Object.assign(Object.assign({}, options), { deep: false })); } removeAttrs(options = {}) { this.store.remove('attrs', options); return this; } getAttrDefinition(attrName) { if (!attrName) { return null; } const ctor = this.constructor; const hooks = ctor.getAttrHooks() || {}; let definition = hooks[attrName] || Attr.registry.get(attrName); if (!definition) { const name = StringExt.camelCase(attrName); definition = hooks[name] || Attr.registry.get(name); } return definition || null; } getAttrByPath(path) { if (path == null || path === '') { return this.getAttrs(); } return this.getPropByPath(this.prefixAttrPath(path)); } setAttrByPath(path, value, options = {}) { this.setPropByPath(this.prefixAttrPath(path), value, options); return this; } removeAttrByPath(path, options = {}) { this.removePropByPath(this.prefixAttrPath(path), options); return this; } prefixAttrPath(path) { return Array.isArray(path) ? ['attrs'].concat(path) : `attrs/${path}`; } attr(path, value, options) { if (path == null) { return this.getAttrByPath(); } if (typeof path === 'string' || Array.isArray(path)) { if (arguments.length === 1) { return this.getAttrByPath(path); } if (value == null) { return this.removeAttrByPath(path, options || {}); } return this.setAttrByPath(path, value, options || {}); } return this.setAttrs(path, (value || {})); } // #endregion // #region visible get visible() { return this.isVisible(); } set visible(value) { this.setVisible(value); } setVisible(visible, options = {}) { this.store.set('visible', visible, options); return this; } isVisible() { return this.store.get('visible') !== false; } show(options = {}) { if (!this.isVisible()) { this.setVisible(true, options); } return this; } hide(options = {}) { if (this.isVisible()) { this.setVisible(false, options); } return this; } toggleVisible(isVisible, options = {}) { const visible = typeof isVisible === 'boolean' ? isVisible : !this.isVisible(); const localOptions = typeof isVisible === 'boolean' ? options : isVisible; if (visible) { this.show(localOptions); } else { this.hide(localOptions); } return this; } // #endregion // #region data get data() { return this.getData(); } set data(val) { this.setData(val); } getData() { return this.store.get('data'); } setData(data, options = {}) { if (data == null) { this.removeData(options); } else { const set = (data) => this.store.set('data', data, options); if (options.overwrite === true) { set(data); } else { const prev = this.getData(); if (options.deep === false) { set(typeof data === 'object' ? Object.assign(Object.assign({}, prev), data) : data); } else { set(ObjectExt.merge({}, prev, data)); } } } return this; } replaceData(data, options = {}) { return this.setData(data, Object.assign(Object.assign({}, options), { overwrite: true })); } updateData(data, options = {}) { return this.setData(data, Object.assign(Object.assign({}, options), { deep: false })); } removeData(options = {}) { this.store.remove('data', options); return this; } // #endregion // #region parent children get parent() { return this.getParent(); } get children() { return this.getChildren(); } getParentId() { return this.store.get('parent'); } getParent() { let parent = this._parent; if (parent == null && this.store) { const parentId = this.getParentId(); if (parentId != null && this.model) { parent = this.model.getCell(parentId); this._parent = parent; } } return parent; } getChildren() { let children = this._children; if (children == null) { const childrenIds = this.store.get('children'); if (childrenIds && childrenIds.length && this.model) { children = childrenIds .map((id) => { var _a; return (_a = this.model) === null || _a === void 0 ? void 0 : _a.getCell(id); }) .filter((cell) => cell != null); this._children = children; } } return children ? [...children] : null; } hasParent() { return this.parent != null; } isParentOf(child) { return child != null && child.getParent() === this; } isChildOf(parent) { return parent != null && this.getParent() === parent; } eachChild(iterator, context) { if (this.children) { this.children.forEach(iterator, context); } return this; } filterChild(filter, context) { return this.children ? this.children.filter(filter, context) : []; } getChildCount() { return this.children == null ? 0 : this.children.length; } getChildIndex(child) { return this.children == null ? -1 : this.children.indexOf(child); } getChildAt(index) { return this.children != null && index >= 0 ? this.children[index] : null; } getAncestors(options = {}) { const ancestors = []; let parent = this.getParent(); while (parent) { ancestors.push(parent); parent = options.deep !== false ? parent.getParent() : null; } return ancestors; } getDescendants(options = {}) { if (options.deep !== false) { // breadth first if (options.breadthFirst) { const cells = []; const queue = this.getChildren() || []; while (queue.length > 0) { const parent = queue.shift(); const children = parent.getChildren(); cells.push(parent); if (children) { queue.push(...children); } } return cells; } // depth first { const cells = this.getChildren() || []; cells.forEach((cell) => { cells.push(...cell.getDescendants(options)); }); return cells; } } return this.getChildren() || []; } isDescendantOf(ancestor, options = {}) { if (ancestor == null) { return false; } if (options.deep !== false) { let current = this.getParent(); while (current) { if (current === ancestor) { return true; } current = current.getParent(); } return false; } return this.isChildOf(ancestor); } isAncestorOf(descendant, options = {}) { if (descendant == null) { return false; } return descendant.isDescendantOf(this, options); } contains(cell) { return this.isAncestorOf(cell); } getCommonAncestor(...cells) { return Cell.getCommonAncestor(this, ...cells); } setParent(parent, options = {}) { this._parent = parent; if (parent) { this.store.set('parent', parent.id, options); } else { this.store.remove('parent', options); } return this; } setChildren(children, options = {}) { this._children = children; if (children != null) { this.store.set('children', children.map((child) => child.id), options); } else { this.store.remove('children', options); } return this; } unembed(child, options = {}) { const children = this.children; if (children != null && child != null) { const index = this.getChildIndex(child); if (index !== -1) { children.splice(index, 1); child.setParent(null, options); this.setChildren(children, options); } } return this; } embed(child, options = {}) { child.addTo(this, options); return this; } addTo(target, options = {}) { if (Cell.isCell(target)) { target.addChild(this, options); } else { target.addCell(this, options); } return this; } insertTo(parent, index, options = {}) { parent.insertChild(this, index, options); return this; } addChild(child, options = {}) { return this.insertChild(child, undefined, options); } insertChild(child, index, options = {}) { if (child != null && child !== this) { const oldParent = child.getParent(); const changed = this !== oldParent; let pos = index; if (pos == null) { pos = this.getChildCount(); if (!changed) { pos -= 1; } } // remove from old parent if (oldParent) { const children = oldParent.getChildren(); if (children) { const index = children.indexOf(child); if (index >= 0) { child.setParent(null, options); children.splice(index, 1); oldParent.setChildren(children, options); } } } let children = this.children; if (children == null) { children = []; children.push(child); } else { children.splice(pos, 0, child); } child.setParent(this, options); this.setChildren(children, options); if (changed && this.model) { const incomings = this.model.getIncomingEdges(this); const outgoings = this.model.getOutgoingEdges(this); if (incomings) { incomings.forEach((edge) => edge.updateParent(options)); } if (outgoings) { outgoings.forEach((edge) => edge.updateParent(options)); } } if (this.model) { this.model.addCell(child, options); } } return this; } removeFromParent(options = {}) { const parent = this.getParent(); if (parent != null) { const index = parent.getChildIndex(this); parent.removeChildAt(index, options); } return this; } removeChild(child, options = {}) { const index = this.getChildIndex(child); return this.removeChildAt(index, options); } removeChildAt(index, options = {}) { const child = this.getChildAt(index); const children = this.children; if (children != null && child != null) { this.unembed(child, options); child.remove(options); } return child; } remove(options = {}) { this.batchUpdate('remove', () => { const parent = this.getParent(); if (parent) { parent.removeChild(this, options); } if (options.deep !== false) { this.eachChild((child) => child.remove(options)); } if (this.model) { this.model.removeCell(this, options); } }); return this; } transition(path, target, options = {}, delim = '/') { return this.animation.start(path, target, options, delim); } stopTransition(path, options, delim = '/') { this.animation.stop(path, options, delim); return this; } getTransitions() { return this.animation.get(); } // #endregion // #region transform // eslint-disable-next-line translate(tx, ty, options) { return this; } scale(sx, // eslint-disable-line sy, // eslint-disable-line origin, // eslint-disable-line options) { return this; } addTools(items, obj, options) { const toolItems = Array.isArray(items) ? items : [items]; const name = typeof obj === 'string' ? obj : null; const config = typeof obj === 'object' ? obj : typeof options === 'object' ? options : {}; if (config.reset) { return this.setTools({ name, items: toolItems, local: config.local }, config); } let tools = ObjectExt.cloneDeep(this.getTools()); if (tools == null || name == null || tools.name === name) { if (tools == null) { tools = {}; } if (!tools.items) { tools.items = []; } tools.name = name; tools.items = [...tools.items, ...toolItems]; return this.setTools(Object.assign({}, tools), config); } } setTools(tools, options = {}) { if (tools == null) { this.removeTools(); } else { this.store.set('tools', Cell.normalizeTools(tools), options); } return this; } getTools() { return this.store.get('tools'); } removeTools(options = {}) { this.store.remove('tools', options); return this; } hasTools(name) { const tools = this.getTools(); if (tools == null) { return false; } if (name == null) { return true; } return tools.name === name; } hasTool(name) { const tools = this.getTools(); if (tools == null) { return false; } return tools.items.some((item) => typeof item === 'string' ? item === name : item.name === name); } removeTool(nameOrIndex, options = {}) { const tools = ObjectExt.cloneDeep(this.getTools()); if (tools) { let updated = false; const items = tools.items.slice(); const remove = (index) => { items.splice(index, 1); updated = true; }; if (typeof nameOrIndex === 'number') { remove(nameOrIndex); } else { for (let i = items.length - 1; i >= 0; i -= 1) { const item = items[i]; const exist = typeof item === 'string' ? item === nameOrIndex : item.name === nameOrIndex; if (exist) { remove(i); } } } if (updated) { tools.items = items; this.setTools(tools, options); } } return this; } // #endregion // #region common // eslint-disable-next-line getBBox(options) { return new Rectangle(); } // eslint-disable-next-line getConnectionPoint(edge, type) { return new Point(); } toJSON(options = {}) { const props = Object.assign({}, this.store.get()); const toString = Object.prototype.toString; const cellType = this.isNode() ? 'node' : this.isEdge() ? 'edge' : 'cell'; if (!props.shape) { const ctor = this.constructor; throw new Error(`Unable to serialize ${cellType} missing "shape" prop, check the ${cellType} "${ctor.name || toString.call(ctor)}"`); } const ctor = this.constructor; const diff = options.diff === true; const attrs = props.attrs || {}; const presets = ctor.getDefaults(true); // When `options.diff` is `true`, we should process the custom options, // such as `width`, `height` etc. to ensure the comparing work correctly. const defaults = diff ? this.preprocess(presets, true) : presets; const defaultAttrs = defaults.attrs || {}; const finalAttrs = {}; Object.keys(props).forEach((key) => { const val = props[key]; if (val != null && !Array.isArray(val) && typeof val === 'object' && !ObjectExt.isPlainObject(val)) { throw new Error(`Can only serialize ${cellType} with plain-object props, but got a "${toString.call(val)}" type of key "${key}" on ${cellType} "${this.id}"`); } if (key !== 'attrs' && key !== 'shape' && diff) { const preset = defaults[key]; if (ObjectExt.isEqual(val, preset)) { delete props[key]; } } }); Object.keys(attrs).forEach((key) => { const attr = attrs[key]; const defaultAttr = defaultAttrs[key]; Object.keys(attr).forEach((name) => { const value = attr[name]; const defaultValue = defaultAttr ? defaultAttr[name] : null; if (value != null && typeof value === 'object' && !Array.isArray(value)) { Object.keys(value).forEach((subName) => { const subValue = value[subName]; if (defaultAttr == null || defaultValue == null || !ObjectExt.isObject(defaultValue) || !ObjectExt.isEqual(defaultValue[subName], subValue)) { if (finalAttrs[key] == null) { finalAttrs[key] = {}; } if (finalAttrs[key][name] == null) { finalAttrs[key][name] = {}; } const tmp = finalAttrs[key][name]; tmp[subName] = subValue; } }); } else if (defaultAttr == null || !ObjectExt.isEqual(defaultValue, value)) { // `value` is not an object, default attribute with `key` does not // exist or it is different than the attribute value set on the cell. if (finalAttrs[key] == null) { finalAttrs[key] = {}; } finalAttrs[key][name] = value; } }); }); const finalProps = Object.assign(Object.assign({}, props), { attrs: ObjectExt.isEmpty(finalAttrs) ? undefined : finalAttrs }); if (finalProps.attrs == null) { delete finalProps.attrs; } const ret = finalProps; if (ret.angle === 0) { delete ret.angle; } return ObjectExt.cloneDeep(ret); } clone(options = {}) { if (!options.deep) { const data = Object.assign({}, this.store.get()); if (!options.keepId) { delete data.id; } delete data.parent; delete data.children; const ctor = this.constructor; return new ctor(data); // eslint-disable-line new-cap } // Deep cloning. Clone the cell itself and all its children. const map = Cell.deepClone(this); return map[this.id]; } findView(graph) { return graph.renderer.findViewByCell(this); } // #endregion // #region batch startBatch(name, data = {}, model = this.model) { this.notify('batch:start', { name, data, cell: this }); if (model) { model.startBatch(name, Object.assign(Object.assign({}, data), { cell: this })); } return this; } stopBatch(name, data = {}, model = this.model) { if (model) { model.stopBatch(name, Object.assign(Object.assign({}, data), { cell: this })); } this.notify('batch:stop', { name, data, cell: this }); return this; } batchUpdate(name, execute, data) { // The model is null after cell was removed(remove batch). // So we should temp save model to trigger pairing batch event. const model = this.model; this.startBatch(name, data, model); const result = execute(); this.stopBatch(name, data, model); return result; } // #endregion // #region IDisposable dispose() { this.removeFromParent(); this.store.dispose(); } } Cell.defaults = {}; Cell.attrHooks = {}; Cell.propHooks = []; __decorate([ Basecoat.dispose() ], Cell.prototype, "dispose", null); (function (Cell) { function normalizeTools(raw) { if (typeof raw === 'string') { return { items: [raw] }; } if (Array.isArray(raw)) { return { items: raw }; } if (raw.items) { return raw; } return { items: [raw], }; } Cell.normalizeTools = normalizeTools; })(Cell || (Cell = {})); (function (Cell) { Cell.toStringTag = `X6.${Cell.name}`; function isCell(instance) { if (instance == null) { return false; } if (instance instanceof Cell) { return true; } const tag = instance[Symbol.toStringTag]; const cell = instance; if ((tag == null || tag === Cell.toStringTag) && typeof cell.isNode === 'function' && typeof cell.isEdge === 'function' && typeof cell.prop === 'function' && typeof cell.attr === 'function') { return true; } return false; } Cell.isCell = isCell; })(Cell || (Cell = {})); (function (Cell) { function getCommonAncestor(...cells) { const ancestors = cells .filter((cell) => cell != null) .map((cell) => cell.getAncestors()) .sort((a, b) => { return a.length - b.length; }); const first = ancestors.shift(); return (first.find((cell) => ancestors.every((item) => item.includes(cell))) || null); } Cell.getCommonAncestor = getCommonAncestor; function getCellsBBox(cells, options = {}) { let bbox = null; for (let i = 0, ii = cells.length; i < ii; i += 1) { const cell = cells[i]; let rect = cell.getBBox(options); if (rect) { if (cell.isNode()) { const angle = cell.getAngle(); if (angle != null && angle !== 0) { rect = rect.bbox(angle); } } bbox = bbox == null ? rect : bbox.union(rect); } } return bbox; } Cell.getCellsBBox = getCellsBBox; function deepClone(cell) { const cells = [cell, ...cell.getDescendants({ deep: true })]; return Cell.cloneCells(cells); } Cell.deepClone = deepClone; function cloneCells(cells) { const inputs = ArrayExt.uniq(cells); const cloneMap = inputs.reduce((map, cell) => { map[cell.id] = cell.clone(); return map; }, {}); inputs.forEach((cell) => { const clone = cloneMap[cell.id]; if (clone.isEdge()) { const sourceId = clone.getSourceCellId(); const targetId = clone.getTargetCellId(); if (sourceId && cloneMap[sourceId]) { // Source is a node and the node is among the clones. // Then update the source of the cloned edge. clone.setSource(Object.assign(Object.assign({}, clone.getSource()), { cell: cloneMap[sourceId].id })); } if (targetId && cloneMap[targetId]) { // Target is a node and the node is among the clones. // Then update the target of the cloned edge. clone.setTarget(Object.assign(Object.assign({}, clone.getTarget()), { cell: cloneMap[targetId].id })); } } // Find the parent of the original cell const parent = cell.getParent(); if (parent && cloneMap[parent.id]) { clone.setParent(cloneMap[parent.id]); } // Find the children of the original cell const children = cell.getChildren(); if (children && children.length) { const embeds = children.reduce((memo, child) => { // Embedded cells that are not being cloned can not be carried // over with other embedded cells. if (cloneMap[child.id]) { memo.push(cloneMap[child.id]); } return memo; }, []); if (embeds.length > 0) { clone.setChildren(embeds); } } }); return cloneMap; } Cell.cloneCells = cloneCells; })(Cell || (Cell = {})); (function (Cell) { Cell.config({ propHooks(_a) { var { tools } = _a, metadata = __rest(_a, ["tools"]); if (tools) { metadata.tools = Cell.normalizeTools(tools); } return metadata; }, }); })(Cell || (Cell = {})); //# sourceMappingURL=cell.js.map