mirror of
https://github.com/streetwriters/notesnook.git
synced 2026-02-24 04:00:59 +01:00
185 lines
8.4 KiB
JavaScript
185 lines
8.4 KiB
JavaScript
"use strict";
|
|
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);
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.createSelectionBasedNodeView = exports.SelectionBasedNodeView = void 0;
|
|
var jsx_runtime_1 = require("react/jsx-runtime");
|
|
var prosemirror_view_1 = require("prosemirror-view");
|
|
var prosemirror_state_1 = require("prosemirror-state");
|
|
var plugin_1 = require("./plugin");
|
|
var reactnodeview_1 = require("./reactnodeview");
|
|
var emotion_theming_1 = require("emotion-theming");
|
|
/**
|
|
* 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, options) {
|
|
var _this = _super.call(this, node, editor, getPos, options) || this;
|
|
_this.pos = -1;
|
|
_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 prosemirror_state_1.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, [], prosemirror_view_1.DecorationSet.empty);
|
|
};
|
|
_this.updatePos();
|
|
_this.oldSelection = editor.view.state.selection;
|
|
_this.selectionChangeState = plugin_1.stateKey.getState(_this.editor.view.state);
|
|
_this.selectionChangeState.subscribe(_this.onSelectionChange);
|
|
return _this;
|
|
}
|
|
SelectionBasedNodeView.prototype.render = function (props, forwardRef) {
|
|
var _this = this;
|
|
if (props === void 0) { props = {}; }
|
|
if (!this.options.component)
|
|
return null;
|
|
var theme = this.editor.storage.theme;
|
|
var isSelected = this.editor.isEditable &&
|
|
(this.insideSelection() || this.nodeInsideSelection());
|
|
return ((0, jsx_runtime_1.jsx)(emotion_theming_1.ThemeProvider, __assign({ theme: theme }, { children: (0, jsx_runtime_1.jsx)(this.options.component, __assign({}, props, { editor: this.editor, getPos: this.getPos, node: this.node, forwardRef: forwardRef, selected: isSelected, updateAttributes: function (attr) { return _this.updateAttributes(attr, _this.pos); } })) })));
|
|
};
|
|
/**
|
|
* 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) {
|
|
if (_super.prototype.viewShouldUpdate.call(this, nextNode))
|
|
return true;
|
|
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 prosemirror_state_1.NodeSelection && selection.from === this.pos;
|
|
var oldNodeSelection = oldSelection instanceof prosemirror_state_1.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);
|
|
};
|
|
return SelectionBasedNodeView;
|
|
}(reactnodeview_1.ReactNodeView));
|
|
exports.SelectionBasedNodeView = SelectionBasedNodeView;
|
|
function createSelectionBasedNodeView(component, options) {
|
|
return function (_a) {
|
|
var node = _a.node, getPos = _a.getPos, editor = _a.editor;
|
|
var _getPos = function () { return (typeof getPos === "boolean" ? -1 : getPos()); };
|
|
return new SelectionBasedNodeView(node, editor, _getPos, __assign(__assign({}, options), { component: component })).init();
|
|
};
|
|
}
|
|
exports.createSelectionBasedNodeView = createSelectionBasedNodeView;
|