UNPKG

@atlaskit/editor-common

Version:

A package that contains common classes and components for editor and renderer

103 lines (101 loc) 3.13 kB
import _defineProperty from "@babel/runtime/helpers/defineProperty"; import ReactNodeView from '../react-node-view'; /** * A ReactNodeView that handles React components sensitive * to selection changes. * * If the selection changes, it will attempt to re-render the * React component. Otherwise it does nothing. * * You can subclass `viewShouldUpdate` to include other * props that your component might want to consider before * entering the React lifecycle. These are usually props you * compare in `shouldComponentUpdate`. * * An example: * * ``` * viewShouldUpdate(nextNode) { * if (nextNode.attrs !== this.node.attrs) { * return true; * } * * return super.viewShouldUpdate(nextNode); * }``` */ export class SelectionBasedNodeView extends ReactNodeView { constructor(node, view, getPos, portalProviderAPI, eventDispatcher, reactComponentProps, reactComponent, hasContext = false, viewShouldUpdate, hasIntlContext = false) { super(node, view, getPos, portalProviderAPI, eventDispatcher, reactComponentProps, reactComponent, hasContext, viewShouldUpdate, hasIntlContext); _defineProperty(this, "isSelectedNode", false); _defineProperty(this, "isNodeInsideSelection", (from, to, pos, posEnd) => { ({ pos, posEnd } = this.getPositionsWithDefault(pos, posEnd)); if (typeof pos !== 'number' || typeof posEnd !== 'number') { return false; } return from <= pos && to >= posEnd; }); _defineProperty(this, "isSelectionInsideNode", (from, to, pos, posEnd) => { ({ pos, posEnd } = this.getPositionsWithDefault(pos, posEnd)); if (typeof pos !== 'number' || typeof posEnd !== 'number') { return false; } return pos < from && to < posEnd; }); _defineProperty(this, "insideSelection", () => { const { selection: { from, to } } = this.view.state; return this.isSelectedNode || this.isSelectionInsideNode(from, to); }); _defineProperty(this, "nodeInsideSelection", () => { const { selection } = this.view.state; const { from, to } = selection; return this.isSelectedNode || this.isNodeInsideSelection(from, to); }); this.updatePos(); } /** * Update current node's start and end positions. * * Prefer `this.pos` rather than getPos(), because calling getPos is * expensive, unless you know you're definitely going to render. */ updatePos() { if (typeof this.getPos === 'boolean') { return; } const pos = this.getPos(); if (typeof pos === 'number') { this.pos = pos; this.posEnd = pos + this.node.nodeSize; } } getPositionsWithDefault(pos, posEnd) { return { pos: typeof pos !== 'number' ? this.pos : pos, posEnd: typeof posEnd !== 'number' ? this.posEnd : posEnd }; } selectNode() { this.isSelectedNode = true; this.update(this.node, this.decorations); } deselectNode() { this.isSelectedNode = false; this.update(this.node, this.decorations); } }