UNPKG

slate

Version:

A completely customizable framework for building rich text editors.

1,303 lines (1,251 loc) 287 kB
'use strict'; var immer = require('immer'); // eslint-disable-next-line no-redeclare var PathRef = { transform: function transform(ref, op) { var current = ref.current, affinity = ref.affinity; if (current == null) { return; } var path = Path.transform(current, op, { affinity: affinity }); ref.current = path; if (path == null) { ref.unref(); } } }; // eslint-disable-next-line no-redeclare var PointRef = { transform: function transform(ref, op) { var current = ref.current, affinity = ref.affinity; if (current == null) { return; } var point = Point.transform(current, op, { affinity: affinity }); ref.current = point; if (point == null) { ref.unref(); } } }; // eslint-disable-next-line no-redeclare var RangeRef = { transform: function transform(ref, op) { var current = ref.current, affinity = ref.affinity; if (current == null) { return; } var path = Range.transform(current, op, { affinity: affinity }); ref.current = path; if (path == null) { ref.unref(); } } }; var DIRTY_PATHS = new WeakMap(); var DIRTY_PATH_KEYS = new WeakMap(); var FLUSHING = new WeakMap(); var NORMALIZING = new WeakMap(); var PATH_REFS = new WeakMap(); var POINT_REFS = new WeakMap(); var RANGE_REFS = new WeakMap(); function unwrapExports (x) { return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; } function createCommonjsModule(fn, module) { return module = { exports: {} }, fn(module, module.exports), module.exports; } var arrayLikeToArray = createCommonjsModule(function (module) { function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } module.exports = _arrayLikeToArray, module.exports.__esModule = true, module.exports["default"] = module.exports; }); unwrapExports(arrayLikeToArray); var arrayWithoutHoles = createCommonjsModule(function (module) { function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return arrayLikeToArray(arr); } module.exports = _arrayWithoutHoles, module.exports.__esModule = true, module.exports["default"] = module.exports; }); unwrapExports(arrayWithoutHoles); var iterableToArray = createCommonjsModule(function (module) { function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); } module.exports = _iterableToArray, module.exports.__esModule = true, module.exports["default"] = module.exports; }); unwrapExports(iterableToArray); var unsupportedIterableToArray = createCommonjsModule(function (module) { function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return arrayLikeToArray(o, minLen); } module.exports = _unsupportedIterableToArray, module.exports.__esModule = true, module.exports["default"] = module.exports; }); unwrapExports(unsupportedIterableToArray); var nonIterableSpread = createCommonjsModule(function (module) { function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } module.exports = _nonIterableSpread, module.exports.__esModule = true, module.exports["default"] = module.exports; }); unwrapExports(nonIterableSpread); var toConsumableArray = createCommonjsModule(function (module) { function _toConsumableArray(arr) { return arrayWithoutHoles(arr) || iterableToArray(arr) || unsupportedIterableToArray(arr) || nonIterableSpread(); } module.exports = _toConsumableArray, module.exports.__esModule = true, module.exports["default"] = module.exports; }); var _toConsumableArray = unwrapExports(toConsumableArray); // eslint-disable-next-line no-redeclare var Path = { ancestors: function ancestors(path) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var _options$reverse = options.reverse, reverse = _options$reverse === void 0 ? false : _options$reverse; var paths = Path.levels(path, options); if (reverse) { paths = paths.slice(1); } else { paths = paths.slice(0, -1); } return paths; }, common: function common(path, another) { var common = []; for (var i = 0; i < path.length && i < another.length; i++) { var av = path[i]; var bv = another[i]; if (av !== bv) { break; } common.push(av); } return common; }, compare: function compare(path, another) { var min = Math.min(path.length, another.length); for (var i = 0; i < min; i++) { if (path[i] < another[i]) return -1; if (path[i] > another[i]) return 1; } return 0; }, endsAfter: function endsAfter(path, another) { var i = path.length - 1; var as = path.slice(0, i); var bs = another.slice(0, i); var av = path[i]; var bv = another[i]; return Path.equals(as, bs) && av > bv; }, endsAt: function endsAt(path, another) { var i = path.length; var as = path.slice(0, i); var bs = another.slice(0, i); return Path.equals(as, bs); }, endsBefore: function endsBefore(path, another) { var i = path.length - 1; var as = path.slice(0, i); var bs = another.slice(0, i); var av = path[i]; var bv = another[i]; return Path.equals(as, bs) && av < bv; }, equals: function equals(path, another) { return path.length === another.length && path.every(function (n, i) { return n === another[i]; }); }, hasPrevious: function hasPrevious(path) { return path[path.length - 1] > 0; }, isAfter: function isAfter(path, another) { return Path.compare(path, another) === 1; }, isAncestor: function isAncestor(path, another) { return path.length < another.length && Path.compare(path, another) === 0; }, isBefore: function isBefore(path, another) { return Path.compare(path, another) === -1; }, isChild: function isChild(path, another) { return path.length === another.length + 1 && Path.compare(path, another) === 0; }, isCommon: function isCommon(path, another) { return path.length <= another.length && Path.compare(path, another) === 0; }, isDescendant: function isDescendant(path, another) { return path.length > another.length && Path.compare(path, another) === 0; }, isParent: function isParent(path, another) { return path.length + 1 === another.length && Path.compare(path, another) === 0; }, isPath: function isPath(value) { return Array.isArray(value) && (value.length === 0 || typeof value[0] === 'number'); }, isSibling: function isSibling(path, another) { if (path.length !== another.length) { return false; } var as = path.slice(0, -1); var bs = another.slice(0, -1); var al = path[path.length - 1]; var bl = another[another.length - 1]; return al !== bl && Path.equals(as, bs); }, levels: function levels(path) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var _options$reverse2 = options.reverse, reverse = _options$reverse2 === void 0 ? false : _options$reverse2; var list = []; for (var i = 0; i <= path.length; i++) { list.push(path.slice(0, i)); } if (reverse) { list.reverse(); } return list; }, next: function next(path) { if (path.length === 0) { throw new Error("Cannot get the next path of a root path [".concat(path, "], because it has no next index.")); } var last = path[path.length - 1]; return path.slice(0, -1).concat(last + 1); }, operationCanTransformPath: function operationCanTransformPath(operation) { switch (operation.type) { case 'insert_node': case 'remove_node': case 'merge_node': case 'split_node': case 'move_node': return true; default: return false; } }, parent: function parent(path) { if (path.length === 0) { throw new Error("Cannot get the parent path of the root path [".concat(path, "].")); } return path.slice(0, -1); }, previous: function previous(path) { if (path.length === 0) { throw new Error("Cannot get the previous path of a root path [".concat(path, "], because it has no previous index.")); } var last = path[path.length - 1]; if (last <= 0) { throw new Error("Cannot get the previous path of a first child path [".concat(path, "] because it would result in a negative index.")); } return path.slice(0, -1).concat(last - 1); }, relative: function relative(path, ancestor) { if (!Path.isAncestor(ancestor, path) && !Path.equals(path, ancestor)) { throw new Error("Cannot get the relative path of [".concat(path, "] inside ancestor [").concat(ancestor, "], because it is not above or equal to the path.")); } return path.slice(ancestor.length); }, transform: function transform(path, operation) { var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; if (!path) return null; // PERF: use destructing instead of immer var p = _toConsumableArray(path); var _options$affinity = options.affinity, affinity = _options$affinity === void 0 ? 'forward' : _options$affinity; // PERF: Exit early if the operation is guaranteed not to have an effect. if (path.length === 0) { return p; } switch (operation.type) { case 'insert_node': { var op = operation.path; if (Path.equals(op, p) || Path.endsBefore(op, p) || Path.isAncestor(op, p)) { p[op.length - 1] += 1; } break; } case 'remove_node': { var _op = operation.path; if (Path.equals(_op, p) || Path.isAncestor(_op, p)) { return null; } else if (Path.endsBefore(_op, p)) { p[_op.length - 1] -= 1; } break; } case 'merge_node': { var _op2 = operation.path, position = operation.position; if (Path.equals(_op2, p) || Path.endsBefore(_op2, p)) { p[_op2.length - 1] -= 1; } else if (Path.isAncestor(_op2, p)) { p[_op2.length - 1] -= 1; p[_op2.length] += position; } break; } case 'split_node': { var _op3 = operation.path, _position = operation.position; if (Path.equals(_op3, p)) { if (affinity === 'forward') { p[p.length - 1] += 1; } else if (affinity === 'backward') ; else { return null; } } else if (Path.endsBefore(_op3, p)) { p[_op3.length - 1] += 1; } else if (Path.isAncestor(_op3, p) && path[_op3.length] >= _position) { p[_op3.length - 1] += 1; p[_op3.length] -= _position; } break; } case 'move_node': { var _op4 = operation.path, onp = operation.newPath; // If the old and new path are the same, it's a no-op. if (Path.equals(_op4, onp)) { return p; } if (Path.isAncestor(_op4, p) || Path.equals(_op4, p)) { var copy = onp.slice(); if (Path.endsBefore(_op4, onp) && _op4.length < onp.length) { copy[_op4.length - 1] -= 1; } return copy.concat(p.slice(_op4.length)); } else if (Path.isSibling(_op4, onp) && (Path.isAncestor(onp, p) || Path.equals(onp, p))) { if (Path.endsBefore(_op4, p)) { p[_op4.length - 1] -= 1; } else { p[_op4.length - 1] += 1; } } else if (Path.endsBefore(onp, p) || Path.equals(onp, p) || Path.isAncestor(onp, p)) { if (Path.endsBefore(_op4, p)) { p[_op4.length - 1] -= 1; } p[onp.length - 1] += 1; } else if (Path.endsBefore(_op4, p)) { if (Path.equals(onp, p)) { p[onp.length - 1] += 1; } p[_op4.length - 1] -= 1; } break; } } return p; } }; var _typeof_1 = createCommonjsModule(function (module) { function _typeof(o) { "@babel/helpers - typeof"; return (module.exports = _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, module.exports.__esModule = true, module.exports["default"] = module.exports), _typeof(o); } module.exports = _typeof, module.exports.__esModule = true, module.exports["default"] = module.exports; }); var _typeof = unwrapExports(_typeof_1); var toPrimitive = createCommonjsModule(function (module) { var _typeof = _typeof_1["default"]; function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } module.exports = _toPrimitive, module.exports.__esModule = true, module.exports["default"] = module.exports; }); unwrapExports(toPrimitive); var toPropertyKey = createCommonjsModule(function (module) { var _typeof = _typeof_1["default"]; function _toPropertyKey(arg) { var key = toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); } module.exports = _toPropertyKey, module.exports.__esModule = true, module.exports["default"] = module.exports; }); unwrapExports(toPropertyKey); var defineProperty = createCommonjsModule(function (module) { function _defineProperty(obj, key, value) { key = toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } module.exports = _defineProperty, module.exports.__esModule = true, module.exports["default"] = module.exports; }); var _defineProperty = unwrapExports(defineProperty); var arrayWithHoles = createCommonjsModule(function (module) { function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } module.exports = _arrayWithHoles, module.exports.__esModule = true, module.exports["default"] = module.exports; }); unwrapExports(arrayWithHoles); var iterableToArrayLimit = createCommonjsModule(function (module) { function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } } module.exports = _iterableToArrayLimit, module.exports.__esModule = true, module.exports["default"] = module.exports; }); unwrapExports(iterableToArrayLimit); var nonIterableRest = createCommonjsModule(function (module) { function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } module.exports = _nonIterableRest, module.exports.__esModule = true, module.exports["default"] = module.exports; }); unwrapExports(nonIterableRest); var slicedToArray = createCommonjsModule(function (module) { function _slicedToArray(arr, i) { return arrayWithHoles(arr) || iterableToArrayLimit(arr, i) || unsupportedIterableToArray(arr, i) || nonIterableRest(); } module.exports = _slicedToArray, module.exports.__esModule = true, module.exports["default"] = module.exports; }); var _slicedToArray = unwrapExports(slicedToArray); function _createForOfIteratorHelper$l(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$l(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; } function _unsupportedIterableToArray$l(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$l(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$l(o, minLen); } function _arrayLikeToArray$l(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } function ownKeys$e(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread$e(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$e(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$e(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } var insertChildren = function insertChildren(xs, index) { for (var _len = arguments.length, newValues = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { newValues[_key - 2] = arguments[_key]; } return [].concat(_toConsumableArray(xs.slice(0, index)), newValues, _toConsumableArray(xs.slice(index))); }; var replaceChildren = function replaceChildren(xs, index, removeCount) { for (var _len2 = arguments.length, newValues = new Array(_len2 > 3 ? _len2 - 3 : 0), _key2 = 3; _key2 < _len2; _key2++) { newValues[_key2 - 3] = arguments[_key2]; } return [].concat(_toConsumableArray(xs.slice(0, index)), newValues, _toConsumableArray(xs.slice(index + removeCount))); }; var removeChildren = replaceChildren; /** * Replace a descendant with a new node, replacing all ancestors */ var modifyDescendant = function modifyDescendant(editor, path, f) { if (path.length === 0) { throw new Error('Cannot modify the editor'); } var node = Node.get(editor, path); var slicedPath = path.slice(); var modifiedNode = f(node); while (slicedPath.length > 1) { var _index = slicedPath.pop(); var ancestorNode = Node.get(editor, slicedPath); modifiedNode = _objectSpread$e(_objectSpread$e({}, ancestorNode), {}, { children: replaceChildren(ancestorNode.children, _index, 1, modifiedNode) }); } var index = slicedPath.pop(); editor.children = replaceChildren(editor.children, index, 1, modifiedNode); }; /** * Replace the children of a node, replacing all ancestors */ var modifyChildren = function modifyChildren(editor, path, f) { if (path.length === 0) { editor.children = f(editor.children); } else { modifyDescendant(editor, path, function (node) { if (Text.isText(node)) { throw new Error("Cannot get the element at path [".concat(path, "] because it refers to a leaf node: ").concat(Scrubber.stringify(node))); } return _objectSpread$e(_objectSpread$e({}, node), {}, { children: f(node.children) }); }); } }; /** * Replace a leaf, replacing all ancestors */ var modifyLeaf = function modifyLeaf(editor, path, f) { return modifyDescendant(editor, path, function (node) { if (!Text.isText(node)) { throw new Error("Cannot get the leaf node at path [".concat(path, "] because it refers to a non-leaf node: ").concat(Scrubber.stringify(node))); } return f(node); }); }; // eslint-disable-next-line no-redeclare var GeneralTransforms = { transform: function transform(editor, op) { var transformSelection = false; switch (op.type) { case 'insert_node': { var path = op.path, node = op.node; modifyChildren(editor, Path.parent(path), function (children) { var index = path[path.length - 1]; if (index > children.length) { throw new Error("Cannot apply an \"insert_node\" operation at path [".concat(path, "] because the destination is past the end of the node.")); } return insertChildren(children, index, node); }); transformSelection = true; break; } case 'insert_text': { var _path = op.path, offset = op.offset, text = op.text; if (text.length === 0) break; modifyLeaf(editor, _path, function (node) { var before = node.text.slice(0, offset); var after = node.text.slice(offset); return _objectSpread$e(_objectSpread$e({}, node), {}, { text: before + text + after }); }); transformSelection = true; break; } case 'merge_node': { var _path2 = op.path; var index = _path2[_path2.length - 1]; var prevPath = Path.previous(_path2); var prevIndex = prevPath[prevPath.length - 1]; modifyChildren(editor, Path.parent(_path2), function (children) { var node = children[index]; var prev = children[prevIndex]; var newNode; if (Text.isText(node) && Text.isText(prev)) { newNode = _objectSpread$e(_objectSpread$e({}, prev), {}, { text: prev.text + node.text }); } else if (!Text.isText(node) && !Text.isText(prev)) { newNode = _objectSpread$e(_objectSpread$e({}, prev), {}, { children: prev.children.concat(node.children) }); } else { throw new Error("Cannot apply a \"merge_node\" operation at path [".concat(_path2, "] to nodes of different interfaces: ").concat(Scrubber.stringify(node), " ").concat(Scrubber.stringify(prev))); } return replaceChildren(children, prevIndex, 2, newNode); }); transformSelection = true; break; } case 'move_node': { var _path3 = op.path, newPath = op.newPath; var _index2 = _path3[_path3.length - 1]; if (Path.isAncestor(_path3, newPath)) { throw new Error("Cannot move a path [".concat(_path3, "] to new path [").concat(newPath, "] because the destination is inside itself.")); } var _node = Node.get(editor, _path3); modifyChildren(editor, Path.parent(_path3), function (children) { return removeChildren(children, _index2, 1); }); // This is tricky, but since the `path` and `newPath` both refer to // the same snapshot in time, there's a mismatch. After either // removing the original position, the second step's path can be out // of date. So instead of using the `op.newPath` directly, we // transform `op.path` to ascertain what the `newPath` would be after // the operation was applied. var truePath = Path.transform(_path3, op); var newIndex = truePath[truePath.length - 1]; modifyChildren(editor, Path.parent(truePath), function (children) { return insertChildren(children, newIndex, _node); }); transformSelection = true; break; } case 'remove_node': { var _path4 = op.path; var _index3 = _path4[_path4.length - 1]; modifyChildren(editor, Path.parent(_path4), function (children) { return removeChildren(children, _index3, 1); }); // Transform all the points in the value, but if the point was in the // node that was removed we need to update the range or remove it. if (editor.selection) { var selection = _objectSpread$e({}, editor.selection); var _iterator = _createForOfIteratorHelper$l(Range.points(selection)), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var _step$value = _slicedToArray(_step.value, 2), point = _step$value[0], key = _step$value[1]; var result = Point.transform(point, op); if (selection != null && result != null) { selection[key] = result; } else { var prev = void 0; var next = void 0; var _iterator2 = _createForOfIteratorHelper$l(Node.texts(editor)), _step2; try { for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { var _step2$value = _slicedToArray(_step2.value, 2), n = _step2$value[0], p = _step2$value[1]; if (Path.compare(p, _path4) === -1) { prev = [n, p]; } else { next = [n, p]; break; } } } catch (err) { _iterator2.e(err); } finally { _iterator2.f(); } var preferNext = false; if (prev && next) { if (Path.equals(next[1], _path4)) { preferNext = !Path.hasPrevious(next[1]); } else { preferNext = Path.common(prev[1], _path4).length < Path.common(next[1], _path4).length; } } if (prev && !preferNext) { selection[key] = { path: prev[1], offset: prev[0].text.length }; } else if (next) { selection[key] = { path: next[1], offset: 0 }; } else { selection = null; } } } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } if (!selection || !Range.equals(selection, editor.selection)) { editor.selection = selection; } } break; } case 'remove_text': { var _path5 = op.path, _offset = op.offset, _text = op.text; if (_text.length === 0) break; modifyLeaf(editor, _path5, function (node) { var before = node.text.slice(0, _offset); var after = node.text.slice(_offset + _text.length); return _objectSpread$e(_objectSpread$e({}, node), {}, { text: before + after }); }); transformSelection = true; break; } case 'set_node': { var _path6 = op.path, properties = op.properties, newProperties = op.newProperties; if (_path6.length === 0) { throw new Error("Cannot set properties on the root node!"); } modifyDescendant(editor, _path6, function (node) { var newNode = _objectSpread$e({}, node); for (var _key3 in newProperties) { if (_key3 === 'children' || _key3 === 'text') { throw new Error("Cannot set the \"".concat(_key3, "\" property of nodes!")); } var value = newProperties[_key3]; if (value == null) { delete newNode[_key3]; } else { newNode[_key3] = value; } } // properties that were previously defined, but are now missing, must be deleted for (var _key4 in properties) { if (!newProperties.hasOwnProperty(_key4)) { delete newNode[_key4]; } } return newNode; }); break; } case 'set_selection': { var _newProperties = op.newProperties; if (_newProperties == null) { editor.selection = null; break; } if (editor.selection == null) { if (!Range.isRange(_newProperties)) { throw new Error("Cannot apply an incomplete \"set_selection\" operation properties ".concat(Scrubber.stringify(_newProperties), " when there is no current selection.")); } editor.selection = _objectSpread$e({}, _newProperties); break; } var _selection = _objectSpread$e({}, editor.selection); for (var _key5 in _newProperties) { var value = _newProperties[_key5]; if (value == null) { if (_key5 === 'anchor' || _key5 === 'focus') { throw new Error("Cannot remove the \"".concat(_key5, "\" selection property")); } delete _selection[_key5]; } else { _selection[_key5] = value; } } editor.selection = _selection; break; } case 'split_node': { var _path7 = op.path, position = op.position, _properties = op.properties; var _index4 = _path7[_path7.length - 1]; if (_path7.length === 0) { throw new Error("Cannot apply a \"split_node\" operation at path [".concat(_path7, "] because the root node cannot be split.")); } modifyChildren(editor, Path.parent(_path7), function (children) { var node = children[_index4]; var newNode; var nextNode; if (Text.isText(node)) { var before = node.text.slice(0, position); var after = node.text.slice(position); newNode = _objectSpread$e(_objectSpread$e({}, node), {}, { text: before }); nextNode = _objectSpread$e(_objectSpread$e({}, _properties), {}, { text: after }); } else { var _before = node.children.slice(0, position); var _after = node.children.slice(position); newNode = _objectSpread$e(_objectSpread$e({}, node), {}, { children: _before }); nextNode = _objectSpread$e(_objectSpread$e({}, _properties), {}, { children: _after }); } return replaceChildren(children, _index4, 1, newNode, nextNode); }); transformSelection = true; break; } } if (transformSelection && editor.selection) { var _selection2 = _objectSpread$e({}, editor.selection); var _iterator3 = _createForOfIteratorHelper$l(Range.points(_selection2)), _step3; try { for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) { var _step3$value = _slicedToArray(_step3.value, 2), _point = _step3$value[0], _key6 = _step3$value[1]; _selection2[_key6] = Point.transform(_point, op); } } catch (err) { _iterator3.e(err); } finally { _iterator3.f(); } if (!Range.equals(_selection2, editor.selection)) { editor.selection = _selection2; } } } }; // eslint-disable-next-line no-redeclare var NodeTransforms = { insertNodes: function insertNodes(editor, nodes, options) { editor.insertNodes(nodes, options); }, liftNodes: function liftNodes(editor, options) { editor.liftNodes(options); }, mergeNodes: function mergeNodes(editor, options) { editor.mergeNodes(options); }, moveNodes: function moveNodes(editor, options) { editor.moveNodes(options); }, removeNodes: function removeNodes(editor, options) { editor.removeNodes(options); }, setNodes: function setNodes(editor, props, options) { editor.setNodes(props, options); }, splitNodes: function splitNodes(editor, options) { editor.splitNodes(options); }, unsetNodes: function unsetNodes(editor, props, options) { editor.unsetNodes(props, options); }, unwrapNodes: function unwrapNodes(editor, options) { editor.unwrapNodes(options); }, wrapNodes: function wrapNodes(editor, element, options) { editor.wrapNodes(element, options); } }; // eslint-disable-next-line no-redeclare var SelectionTransforms = { collapse: function collapse(editor, options) { editor.collapse(options); }, deselect: function deselect(editor) { editor.deselect(); }, move: function move(editor, options) { editor.move(options); }, select: function select(editor, target) { editor.select(target); }, setPoint: function setPoint(editor, props, options) { editor.setPoint(props, options); }, setSelection: function setSelection(editor, props) { editor.setSelection(props); } }; var isObject = function isObject(value) { return _typeof(value) === 'object' && value !== null; }; /* Custom deep equal comparison for Slate nodes. We don't need general purpose deep equality; Slate only supports plain values, Arrays, and nested objects. Complex values nested inside Arrays are not supported. Slate objects are designed to be serialised, so missing keys are deliberately normalised to undefined. */ var isDeepEqual = function isDeepEqual(node, another) { for (var key in node) { var a = node[key]; var b = another[key]; if (Array.isArray(a) && Array.isArray(b)) { if (a.length !== b.length) return false; for (var i = 0; i < a.length; i++) { if (a[i] !== b[i]) return false; } } else if (isObject(a) && isObject(b)) { if (!isDeepEqual(a, b)) return false; } else if (a !== b) { return false; } } /* Deep object equality is only necessary in one direction; in the reverse direction we are only looking for keys that are missing. As above, undefined keys are normalised to missing. */ for (var _key in another) { if (node[_key] === undefined && another[_key] !== undefined) { return false; } } return true; }; var objectWithoutPropertiesLoose = createCommonjsModule(function (module) { function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } module.exports = _objectWithoutPropertiesLoose, module.exports.__esModule = true, module.exports["default"] = module.exports; }); unwrapExports(objectWithoutPropertiesLoose); var objectWithoutProperties = createCommonjsModule(function (module) { function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } module.exports = _objectWithoutProperties, module.exports.__esModule = true, module.exports["default"] = module.exports; }); var _objectWithoutProperties = unwrapExports(objectWithoutProperties); var _excluded$4 = ["anchor", "focus"]; function ownKeys$d(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread$d(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$d(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$d(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } // eslint-disable-next-line no-redeclare var Range = { edges: function edges(range) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var _options$reverse = options.reverse, reverse = _options$reverse === void 0 ? false : _options$reverse; var anchor = range.anchor, focus = range.focus; return Range.isBackward(range) === reverse ? [anchor, focus] : [focus, anchor]; }, end: function end(range) { var _Range$edges = Range.edges(range), _Range$edges2 = _slicedToArray(_Range$edges, 2), end = _Range$edges2[1]; return end; }, equals: function equals(range, another) { return Point.equals(range.anchor, another.anchor) && Point.equals(range.focus, another.focus); }, surrounds: function surrounds(range, target) { var intersectionRange = Range.intersection(range, target); if (!intersectionRange) { return false; } return Range.equals(intersectionRange, target); }, includes: function includes(range, target) { if (Range.isRange(target)) { if (Range.includes(range, target.anchor) || Range.includes(range, target.focus)) { return true; } var _Range$edges3 = Range.edges(range), _Range$edges4 = _slicedToArray(_Range$edges3, 2), rs = _Range$edges4[0], re = _Range$edges4[1]; var _Range$edges5 = Range.edges(target), _Range$edges6 = _slicedToArray(_Range$edges5, 2), ts = _Range$edges6[0], te = _Range$edges6[1]; return Point.isBefore(rs, ts) && Point.isAfter(re, te); } var _Range$edges7 = Range.edges(range), _Range$edges8 = _slicedToArray(_Range$edges7, 2), start = _Range$edges8[0], end = _Range$edges8[1]; var isAfterStart = false; var isBeforeEnd = false; if (Point.isPoint(target)) { isAfterStart = Point.compare(target, start) >= 0; isBeforeEnd = Point.compare(target, end) <= 0; } else { isAfterStart = Path.compare(target, start.path) >= 0; isBeforeEnd = Path.compare(target, end.path) <= 0; } return isAfterStart && isBeforeEnd; }, intersection: function intersection(range, another) { range.anchor; range.focus; var rest = _objectWithoutProperties(range, _excluded$4); var _Range$edges9 = Range.edges(range), _Range$edges10 = _slicedToArray(_Range$edges9, 2), s1 = _Range$edges10[0], e1 = _Range$edges10[1]; var _Range$edges11 = Range.edges(another), _Range$edges12 = _slicedToArray(_Range$edges11, 2), s2 = _Range$edges12[0], e2 = _Range$edges12[1]; var start = Point.isBefore(s1, s2) ? s2 : s1; var end = Point.isBefore(e1, e2) ? e1 : e2; if (Point.isBefore(end, start)) { return null; } else { return _objectSpread$d({ anchor: start, focus: end }, rest); } }, isBackward: function isBackward(range) { var anchor = range.anchor, focus = range.focus; return Point.isAfter(anchor, focus); }, isCollapsed: function isCollapsed(range) { var anchor = range.anchor, focus = range.focus; return Point.equals(anchor, focus); }, isExpanded: function isExpanded(range) { return !Range.isCollapsed(range); }, isForward: function isForward(range) { return !Range.isBackward(range); }, isRange: function isRange(value) { return isObject(value) && Point.isPoint(value.anchor) && Point.isPoint(value.focus); }, points: function* points(range) { yield [range.anchor, 'anchor']; yield [range.focus, 'focus']; }, start: function start(range) { var _Range$edges13 = Range.edges(range), _Range$edges14 = _slicedToArray(_Range$edges13, 1), start = _Range$edges14[0]; return start; }, transform: function transform(range, op) { var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; if (range === null) { return null; } var _options$affinity = options.affinity, affinity = _options$affinity === void 0 ? 'inward' : _options$affinity; var affinityAnchor; var affinityFocus; if (affinity === 'inward') { // If the range is collapsed, make sure to use the same affinity to // avoid the two points passing each other and expanding in the opposite // direction var isCollapsed = Range.isCollapsed(range); if (Range.isForward(range)) { affinityAnchor = 'forward'; affinityFocus = isCollapsed ? affinityAnchor : 'backward'; } else { affinityAnchor = 'backward'; affinityFocus = isCollapsed ? affinityAnchor : 'forward'; } } else if (affinity === 'outward') { if (Range.isForward(range)) { affinityAnchor = 'backward'; affinityFocus = 'forward'; } else { affinityAnchor = 'forward'; affinityFocus = 'backward'; } } else { affinityAnchor = affinity; affinityFocus = affinity; } var anchor = Point.transform(range.anchor, op, { affinity: affinityAnchor }); var focus = Point.transform(range.focus, op, { affinity: affinityFocus }); if (!anchor || !focus) { return null; } return { anchor: anchor, focus: focus }; } }; /** * Shared the function with isElementType utility */ var isElement = function isElement(value) { var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, _ref$deep = _ref.deep, deep = _ref$deep === void 0 ? false : _ref$deep; if (!isObject(value)) return false; // PERF: No need to use the full Editor.isEditor here var isEditor = typeof value.apply === 'function'; if (isEditor) return false; var isChildrenValid = deep ? Node.isNodeList(value.children) : Array.isArray(value.children); return isChildrenValid; }; // eslint-disable-next-line no-redeclare var Element = { isAncestor: function isAncestor(value) { var _ref2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, _ref2$deep = _ref2.deep, deep = _ref2$deep === void 0 ? false : _ref2$deep; return isObject(value) && Node.isNodeList(value.children, { deep: deep }); }, isElement: isElement, isElementList: function isElementList(value) { var _ref3 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, _ref3$deep = _ref3.deep, deep = _ref3$deep === void 0 ? false : _ref3$deep; return Array.isArray(value) && value.every(function (val) { return Element.isElement(val, { deep: deep }); }); }, isElementProps: function isElementProps(props) { return props.children !== undefined; }, isElementType: function isElementType(value, elementVal) { var elementKey = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'type'; return isElement(value) && value[elementKey] === elementVal; }, matches: function matches(element, props) { for (var key in props) { if (key === 'children') { continue; } if (element[key] !== props[key]) { return false; } } return true; } }; var _excluded$3 = ["children"], _excluded2$3 = ["text"]; function _createForOfIteratorHelper$k(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$k(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; } function _unsupportedIterableToArray$k(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$k(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$k(o, minLen); } function _arrayLikeToArray$k(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } // eslint-disable-next-line no-redeclare var Node = { ancestor: function ancestor(root, path) { var node = Node.get(root, path); if (Text.isText(node)) { throw new Error("Cannot get the ancestor node at path [".concat(path, "] because it refers to a text node instead: ").concat(Scrubber.stringify(node))); } return node; }, ancestors: function ancestors(root, path) { var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; return function* () { var _iterator = _createForOfIteratorHelper$k(Path.ancestors(path, options)), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var p = _step.value; var n = Node.ancestor(root, p); var entry = [n, p]; yield entry; } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } }(); }, child: function child(root, index) { if (Text.isText(root)) { throw new Error("Cannot get the child of a text node: ".concat(Scrubber.stringify(root))); } var c = root.children[index]; if (c == null) { throw new Error("Cannot get child at index `".concat(index, "` in node: ").concat(Scrubber.stringify(root))); } return c; }, children: function children(root, path) { var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; return function* () { var _options$reverse = options.reverse, reverse = _options$reverse === void 0 ? false : _options$reverse; var ancestor = Node.ancestor(root, path); var children = ancestor.children; var index = reverse ? children.length - 1 : 0; while (reverse ? index >= 0 : index < children.length) { var child = Node.child(ancestor, index); var childPath = path.concat(index); yield [child, childPath]; index = reverse ? index - 1 : index + 1; } }(); }, common: function common(root, path, another) { var p = Path.common(path, another); var n = Node.get(root, p); return [n, p]; }, descendant: function descendant(root, path) { var node = Node.get(root, path); if (Editor.isEditor(node)) { throw new Error("Cannot get the descendant node at path [".concat(path, "] because it refers to the root editor node instead: ").concat(Scrubber.stringify(node))); } return node; }, descendants: function descendants(root) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; return function* () { var _iterator2 = _createForOfIteratorHelper