UNPKG

@antv/x6

Version:

JavaScript diagramming library that uses SVG and HTML for rendering.

185 lines 6.16 kB
import { ToolsView } from '../../view/tool'; import { Point } from '../../geometry'; import { Dom, FunctionExt } from '../../util'; export class CellEditor extends ToolsView.ToolItem { constructor() { super(...arguments); this.labelIndex = -1; this.distance = 0.5; } render() { this.createElement(); this.update(); this.autoFocus(); this.delegateDocumentEvents(this.options.documentEvents); return this; } createElement() { const { cell } = this; const classNames = [ this.prefixClassName(`${cell.isEdge() ? 'edge' : 'node'}-tool-editor`), this.prefixClassName('cell-tool-editor'), ]; this.editor = ToolsView.createElement('div', false); this.addClass(classNames, this.editor); this.editor.contentEditable = 'true'; this.container.appendChild(this.editor); } update() { const { graph, cell, editor } = this; const style = editor.style; // set tool position let pos = new Point(); let minWidth = 20; if (cell.isNode()) { pos = cell.getBBox().center; minWidth = cell.size().width - 4; } else if (cell.isEdge()) { const e = this.options.event; const target = e.target; const parent = target.parentElement; const isEdgeLabel = parent && Dom.hasClass(parent, this.prefixClassName('edge-label')); if (isEdgeLabel) { const index = parent.getAttribute('data-index') || '0'; this.labelIndex = parseInt(index, 10); const matrix = parent.getAttribute('transform'); const { translation } = Dom.parseTransformString(matrix); pos = new Point(translation.tx, translation.ty); minWidth = Dom.getBBox(target).width; } else { pos = graph.clientToLocal(Point.create(e.clientX, e.clientY)); const view = this.cellView; const d = view.path.closestPointLength(pos); this.distance = d; } } pos = graph.localToGraph(pos); style.left = `${pos.x}px`; style.top = `${pos.y}px`; style.minWidth = `${minWidth}px`; // set tool transform const scale = graph.scale(); style.transform = `scale(${scale.sx}, ${scale.sy}) translate(-50%, -50%)`; // set font style const attrs = this.options.attrs; style.fontSize = `${attrs.fontSize}px`; style.fontFamily = attrs.fontFamily; style.color = attrs.color; style.backgroundColor = attrs.backgroundColor; // set init value const getText = this.options.getText; let text; if (typeof getText === 'function') { text = FunctionExt.call(getText, this.cellView, { cell: this.cell, index: this.labelIndex, }); } editor.innerText = text || ''; return this; } onDocumentMouseDown(e) { if (e.target !== this.editor) { const cell = this.cell; const value = this.editor.innerText.replace(/\n$/, '') || ''; // set value const setText = this.options.setText; if (typeof setText === 'function') { FunctionExt.call(setText, this.cellView, { cell: this.cell, value, index: this.labelIndex, distance: this.distance, }); } // remove tool cell.removeTool(cell.isEdge() ? 'edge-editor' : 'node-editor'); this.undelegateDocumentEvents(); } } onDblClick(e) { e.stopPropagation(); } onMouseDown(e) { e.stopPropagation(); } autoFocus() { setTimeout(() => { this.editor.focus(); this.selectText(); }); } selectText() { if (window.getSelection) { const range = document.createRange(); const selection = window.getSelection(); range.selectNodeContents(this.editor); selection.removeAllRanges(); selection.addRange(range); } } } (function (CellEditor) { CellEditor.config({ tagName: 'div', isSVGElement: false, events: { dblclick: 'onDblClick', mousedown: 'onMouseDown', }, documentEvents: { mousedown: 'onDocumentMouseDown', }, }); })(CellEditor || (CellEditor = {})); (function (CellEditor) { CellEditor.NodeEditor = CellEditor.define({ attrs: { fontSize: 14, fontFamily: 'Arial, helvetica, sans-serif', color: '#000', backgroundColor: '#fff', }, getText({ cell }) { return cell.attr('text/text'); }, setText({ cell, value }) { cell.attr('text/text', value); }, }); CellEditor.EdgeEditor = CellEditor.define({ attrs: { fontSize: 14, fontFamily: 'Arial, helvetica, sans-serif', color: '#000', backgroundColor: '#fff', }, getText({ cell, index }) { if (index === -1) { return ''; } return cell.prop(`labels/${index}/attrs/label/text`); }, setText({ cell, value, index, distance }) { const edge = cell; if (index === -1) { edge.appendLabel({ position: { distance: distance, }, attrs: { label: { text: value, }, }, }); } else { edge.prop(`labels/${index}/attrs/label/text`, value); } }, }); })(CellEditor || (CellEditor = {})); //# sourceMappingURL=editor.js.map