UNPKG

@antv/x6

Version:

JavaScript diagramming library that uses SVG and HTML for rendering

146 lines (124 loc) 3.58 kB
import { Dom, disposable } from '../common' import type { KeyValue } from '../common' import { highlighterCheck, highlighterRegistry } from '../registry' import type { HighlighterDefinition, HighlighterManualItem, HighlighterNativeItem, } from '../registry' import type { CellView } from '../view' import type { CellViewHighlightOptions } from '../view/cell/type' import { Base } from './base' import type { EventArgs } from './events' interface Cache { highlighter: HighlighterDefinition<KeyValue> cellView: CellView magnet: Element args: KeyValue } export type HighlightManagerOptions = | HighlighterNativeItem | HighlighterManualItem export class HighlightManager extends Base { protected readonly highlights: KeyValue<Cache> = {} protected init() { this.startListening() } protected startListening() { this.graph.on('cell:highlight', this.onCellHighlight, this) this.graph.on('cell:unhighlight', this.onCellUnhighlight, this) } protected stopListening() { this.graph.off('cell:highlight', this.onCellHighlight, this) this.graph.off('cell:unhighlight', this.onCellUnhighlight, this) } protected onCellHighlight({ view: cellView, magnet, options = {}, }: EventArgs['cell:highlight']) { const resolved = this.resolveHighlighter(options) if (!resolved) { return } const key = this.getHighlighterId(magnet, resolved) if (!this.highlights[key]) { const highlighter = resolved.highlighter highlighter.highlight(cellView, magnet, { ...resolved.args }) this.highlights[key] = { cellView, magnet, highlighter, args: resolved.args, } } } protected onCellUnhighlight({ magnet, options = {}, }: EventArgs['cell:unhighlight']) { const resolved = this.resolveHighlighter(options) if (!resolved) { return } const id = this.getHighlighterId(magnet, resolved) this.unhighlight(id) } protected resolveHighlighter(options: CellViewHighlightOptions) { const graphOptions = this.options let highlighterDef: string | undefined | HighlighterManualItem = options.highlighter if (highlighterDef == null) { // check for built-in types const type = options.type highlighterDef = (type && graphOptions.highlighting[type]) || graphOptions.highlighting.default } if (highlighterDef == null) { return null } const def: HighlighterManualItem = typeof highlighterDef === 'string' ? { name: highlighterDef, } : highlighterDef const name = def.name const highlighter = highlighterRegistry.get(name) if (highlighter == null) { return highlighterRegistry.onNotFound(name) } highlighterCheck(name, highlighter) return { name, highlighter, args: def.args || {}, } } protected getHighlighterId( magnet: Element, options: NonNullable< ReturnType<typeof HighlightManager.prototype.resolveHighlighter> >, ) { Dom.ensureId(magnet) return options.name + magnet.id + JSON.stringify(options.args) } protected unhighlight(id: string) { const highlight = this.highlights[id] if (highlight) { highlight.highlighter.unhighlight( highlight.cellView, highlight.magnet, highlight.args, ) delete this.highlights[id] } } @disposable() dispose() { Object.keys(this.highlights).forEach((id) => this.unhighlight(id)) this.stopListening() } }