mirror of
https://github.com/streetwriters/notesnook.git
synced 2025-12-16 19:57:52 +01:00
165 lines
7.2 KiB
JavaScript
165 lines
7.2 KiB
JavaScript
var __extends = (this && this.__extends) || (function () {
|
|
var extendStatics = function (d, b) {
|
|
extendStatics = Object.setPrototypeOf ||
|
|
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
return extendStatics(d, b);
|
|
};
|
|
return function (d, b) {
|
|
if (typeof b !== "function" && b !== null)
|
|
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
extendStatics(d, b);
|
|
function __() { this.constructor = d; }
|
|
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
};
|
|
})();
|
|
var __assign = (this && this.__assign) || function () {
|
|
__assign = Object.assign || function(t) {
|
|
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
s = arguments[i];
|
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
t[p] = s[p];
|
|
}
|
|
return t;
|
|
};
|
|
return __assign.apply(this, arguments);
|
|
};
|
|
import { DecorationSet } from "prosemirror-view";
|
|
import { NodeSelection } from "prosemirror-state";
|
|
import { stateKey as SelectionChangePluginKey, } from "./plugin";
|
|
import ReactNodeView from "./ReactNodeView";
|
|
/**
|
|
* 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);
|
|
* }```
|
|
*/
|
|
var SelectionBasedNodeView = /** @class */ (function (_super) {
|
|
__extends(SelectionBasedNodeView, _super);
|
|
function SelectionBasedNodeView(node, editor, getPos, portalProviderAPI, eventDispatcher, options) {
|
|
var _this = _super.call(this, node, editor, getPos, portalProviderAPI, eventDispatcher, options) || this;
|
|
_this.isNodeInsideSelection = function (from, to, pos, posEnd) {
|
|
var _a;
|
|
(_a = _this.getPositionsWithDefault(pos, posEnd), pos = _a.pos, posEnd = _a.posEnd);
|
|
if (typeof pos !== "number" || typeof posEnd !== "number") {
|
|
return false;
|
|
}
|
|
return from <= pos && to >= posEnd;
|
|
};
|
|
_this.isSelectionInsideNode = function (from, to, pos, posEnd) {
|
|
var _a;
|
|
(_a = _this.getPositionsWithDefault(pos, posEnd), pos = _a.pos, posEnd = _a.posEnd);
|
|
if (typeof pos !== "number" || typeof posEnd !== "number") {
|
|
return false;
|
|
}
|
|
return pos < from && to < posEnd;
|
|
};
|
|
_this.isSelectedNode = function (selection) {
|
|
if (selection instanceof NodeSelection) {
|
|
var _a = _this.editor.view.state.selection, from = _a.from, to = _a.to;
|
|
return (selection.node === _this.node ||
|
|
// If nodes are not the same object, we check if they are referring to the same document node
|
|
(_this.pos === from &&
|
|
_this.posEnd === to &&
|
|
selection.node.eq(_this.node)));
|
|
}
|
|
return false;
|
|
};
|
|
_this.insideSelection = function () {
|
|
var _a = _this.editor.view.state.selection, from = _a.from, to = _a.to;
|
|
return (_this.isSelectedNode(_this.editor.view.state.selection) ||
|
|
_this.isSelectionInsideNode(from, to));
|
|
};
|
|
_this.nodeInsideSelection = function () {
|
|
var selection = _this.editor.view.state.selection;
|
|
var from = selection.from, to = selection.to;
|
|
return (_this.isSelectedNode(selection) || _this.isNodeInsideSelection(from, to));
|
|
};
|
|
_this.onSelectionChange = function () {
|
|
_this.update(_this.node, [], DecorationSet.empty);
|
|
};
|
|
_this.updatePos();
|
|
_this.oldSelection = editor.view.state.selection;
|
|
_this.selectionChangeState = SelectionChangePluginKey.getState(_this.editor.view.state);
|
|
_this.selectionChangeState.subscribe(_this.onSelectionChange);
|
|
return _this;
|
|
}
|
|
/**
|
|
* 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.
|
|
*/
|
|
SelectionBasedNodeView.prototype.updatePos = function () {
|
|
if (typeof this.getPos === "boolean") {
|
|
return;
|
|
}
|
|
this.pos = this.getPos();
|
|
this.posEnd = this.pos + this.node.nodeSize;
|
|
};
|
|
SelectionBasedNodeView.prototype.getPositionsWithDefault = function (pos, posEnd) {
|
|
return {
|
|
pos: typeof pos !== "number" ? this.pos : pos,
|
|
posEnd: typeof posEnd !== "number" ? this.posEnd : posEnd,
|
|
};
|
|
};
|
|
SelectionBasedNodeView.prototype.viewShouldUpdate = function (_nextNode) {
|
|
var selection = this.editor.view.state.selection;
|
|
// update selection
|
|
var oldSelection = this.oldSelection;
|
|
this.oldSelection = selection;
|
|
// update cached positions
|
|
var _a = this, oldPos = _a.pos, oldPosEnd = _a.posEnd;
|
|
this.updatePos();
|
|
var from = selection.from, to = selection.to;
|
|
var oldFrom = oldSelection.from, oldTo = oldSelection.to;
|
|
if (this.node.type.spec.selectable) {
|
|
var newNodeSelection = selection instanceof NodeSelection && selection.from === this.pos;
|
|
var oldNodeSelection = oldSelection instanceof NodeSelection && oldSelection.from === this.pos;
|
|
if ((newNodeSelection && !oldNodeSelection) ||
|
|
(oldNodeSelection && !newNodeSelection)) {
|
|
return true;
|
|
}
|
|
}
|
|
var movedInToSelection = this.isNodeInsideSelection(from, to) &&
|
|
!this.isNodeInsideSelection(oldFrom, oldTo);
|
|
var movedOutOfSelection = !this.isNodeInsideSelection(from, to) &&
|
|
this.isNodeInsideSelection(oldFrom, oldTo);
|
|
var moveOutFromOldSelection = this.isNodeInsideSelection(from, to, oldPos, oldPosEnd) &&
|
|
!this.isNodeInsideSelection(from, to);
|
|
if (movedInToSelection || movedOutOfSelection || moveOutFromOldSelection) {
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
SelectionBasedNodeView.prototype.destroy = function () {
|
|
this.selectionChangeState.unsubscribe(this.onSelectionChange);
|
|
_super.prototype.destroy.call(this);
|
|
};
|
|
SelectionBasedNodeView.fromComponent = function (component, options) {
|
|
return function (_a) {
|
|
var node = _a.node, getPos = _a.getPos, editor = _a.editor;
|
|
return new SelectionBasedNodeView(node, editor, getPos, editor.storage.portalProviderAPI, editor.storage.eventDispatcher, __assign(__assign({}, options), { component: component })).init();
|
|
};
|
|
};
|
|
return SelectionBasedNodeView;
|
|
}(ReactNodeView));
|
|
export { SelectionBasedNodeView };
|