UNPKG

tiptap-extensions

Version:

Extensions for tiptap

1,683 lines (1,474 loc) 84.5 kB
/*! * tiptap-extensions v1.32.1 * (c) 2020 überdosis GbR (limited liability) * @license MIT */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('tiptap'), require('tiptap-commands'), require('lowlight/lib/core'), require('prosemirror-view'), require('prosemirror-utils'), require('prosemirror-state'), require('regenerator-runtime/runtime'), require('prosemirror-tables'), require('tiptap-utils'), require('prosemirror-transform'), require('prosemirror-collab'), require('prosemirror-history')) : typeof define === 'function' && define.amd ? define(['exports', 'tiptap', 'tiptap-commands', 'lowlight/lib/core', 'prosemirror-view', 'prosemirror-utils', 'prosemirror-state', 'regenerator-runtime/runtime', 'prosemirror-tables', 'tiptap-utils', 'prosemirror-transform', 'prosemirror-collab', 'prosemirror-history'], factory) : (global = global || self, factory(global.tiptapExtensions = {}, global.tiptap, global.tiptapCommands, global.low, global.prosemirrorView, global.prosemirrorUtils, global.prosemirrorState, null, global.prosemirrorTables, global.tiptapUtils, global.prosemirrorTransform, global.prosemirrorCollab, global.prosemirrorHistory)); }(this, (function (exports, tiptap, tiptapCommands, low, prosemirrorView, prosemirrorUtils, prosemirrorState, runtime, prosemirrorTables, tiptapUtils, prosemirrorTransform, prosemirrorCollab, prosemirrorHistory) { 'use strict'; low = low && Object.prototype.hasOwnProperty.call(low, 'default') ? low['default'] : low; function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread2(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _possibleConstructorReturn(self, call) { if (call && (typeof call === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); } function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } 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); } 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; } 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."); } 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."); } var Blockquote = /*#__PURE__*/function (_Node) { _inherits(Blockquote, _Node); var _super = _createSuper(Blockquote); function Blockquote() { _classCallCheck(this, Blockquote); return _super.apply(this, arguments); } _createClass(Blockquote, [{ key: "commands", value: function commands(_ref) { var type = _ref.type, schema = _ref.schema; return function () { return tiptapCommands.toggleWrap(type, schema.nodes.paragraph); }; } }, { key: "keys", value: function keys(_ref2) { var type = _ref2.type; return { 'Ctrl->': tiptapCommands.toggleWrap(type) }; } }, { key: "inputRules", value: function inputRules(_ref3) { var type = _ref3.type; return [tiptapCommands.wrappingInputRule(/^\s*>\s$/, type)]; } }, { key: "name", get: function get() { return 'blockquote'; } }, { key: "schema", get: function get() { return { content: 'block*', group: 'block', defining: true, draggable: false, parseDOM: [{ tag: 'blockquote' }], toDOM: function toDOM() { return ['blockquote', 0]; } }; } }]); return Blockquote; }(tiptap.Node); var BulletList = /*#__PURE__*/function (_Node) { _inherits(BulletList, _Node); var _super = _createSuper(BulletList); function BulletList() { _classCallCheck(this, BulletList); return _super.apply(this, arguments); } _createClass(BulletList, [{ key: "commands", value: function commands(_ref) { var type = _ref.type, schema = _ref.schema; return function () { return tiptapCommands.toggleList(type, schema.nodes.list_item); }; } }, { key: "keys", value: function keys(_ref2) { var type = _ref2.type, schema = _ref2.schema; return { 'Shift-Ctrl-8': tiptapCommands.toggleList(type, schema.nodes.list_item) }; } }, { key: "inputRules", value: function inputRules(_ref3) { var type = _ref3.type; return [tiptapCommands.wrappingInputRule(/^\s*([-+*])\s$/, type)]; } }, { key: "name", get: function get() { return 'bullet_list'; } }, { key: "schema", get: function get() { return { content: 'list_item+', group: 'block', parseDOM: [{ tag: 'ul' }], toDOM: function toDOM() { return ['ul', 0]; } }; } }]); return BulletList; }(tiptap.Node); var CodeBlock = /*#__PURE__*/function (_Node) { _inherits(CodeBlock, _Node); var _super = _createSuper(CodeBlock); function CodeBlock() { _classCallCheck(this, CodeBlock); return _super.apply(this, arguments); } _createClass(CodeBlock, [{ key: "commands", value: function commands(_ref) { var type = _ref.type, schema = _ref.schema; return function () { return tiptapCommands.toggleBlockType(type, schema.nodes.paragraph); }; } }, { key: "keys", value: function keys(_ref2) { var type = _ref2.type; return { 'Shift-Ctrl-\\': tiptapCommands.setBlockType(type) }; } }, { key: "inputRules", value: function inputRules(_ref3) { var type = _ref3.type; return [tiptapCommands.textblockTypeInputRule(/^```$/, type)]; } }, { key: "name", get: function get() { return 'code_block'; } }, { key: "schema", get: function get() { return { content: 'text*', marks: '', group: 'block', code: true, defining: true, draggable: false, parseDOM: [{ tag: 'pre', preserveWhitespace: 'full' }], toDOM: function toDOM() { return ['pre', ['code', 0]]; } }; } }]); return CodeBlock; }(tiptap.Node); function getDecorations(_ref) { var doc = _ref.doc, name = _ref.name; var decorations = []; var blocks = prosemirrorUtils.findBlockNodes(doc).filter(function (item) { return item.node.type.name === name; }); var flatten = function flatten(list) { return list.reduce(function (a, b) { return a.concat(Array.isArray(b) ? flatten(b) : b); }, []); }; function parseNodes(nodes) { var className = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; return nodes.map(function (node) { var classes = [].concat(_toConsumableArray(className), _toConsumableArray(node.properties ? node.properties.className : [])); if (node.children) { return parseNodes(node.children, classes); } return { text: node.value, classes: classes }; }); } blocks.forEach(function (block) { var startPos = block.pos + 1; var nodes = low.highlightAuto(block.node.textContent).value; flatten(parseNodes(nodes)).map(function (node) { var from = startPos; var to = from + node.text.length; startPos = to; return _objectSpread2(_objectSpread2({}, node), {}, { from: from, to: to }); }).forEach(function (node) { var decoration = prosemirrorView.Decoration.inline(node.from, node.to, { class: node.classes.join(' ') }); decorations.push(decoration); }); }); return prosemirrorView.DecorationSet.create(doc, decorations); } function HighlightPlugin(_ref2) { var name = _ref2.name; return new tiptap.Plugin({ name: new tiptap.PluginKey('highlight'), state: { init: function init(_, _ref3) { var doc = _ref3.doc; return getDecorations({ doc: doc, name: name }); }, apply: function apply(transaction, decorationSet, oldState, newState) { // TODO: find way to cache decorations // https://discuss.prosemirror.net/t/how-to-update-multiple-inline-decorations-on-node-change/1493 var oldNodeName = oldState.selection.$head.parent.type.name; var newNodeName = newState.selection.$head.parent.type.name; var oldNodes = prosemirrorUtils.findBlockNodes(oldState.doc).filter(function (item) { return item.node.type.name === name; }); var newNodes = prosemirrorUtils.findBlockNodes(newState.doc).filter(function (item) { return item.node.type.name === name; }); // Apply decorations if selection includes named node, or transaction changes named node. if (transaction.docChanged && ([oldNodeName, newNodeName].includes(name) || newNodes.length !== oldNodes.length)) { return getDecorations({ doc: transaction.doc, name: name }); } return decorationSet.map(transaction.mapping, transaction.doc); } }, props: { decorations: function decorations(state) { return this.getState(state); } } }); } var CodeBlockHighlight = /*#__PURE__*/function (_Node) { _inherits(CodeBlockHighlight, _Node); var _super = _createSuper(CodeBlockHighlight); function CodeBlockHighlight() { var _this; var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; _classCallCheck(this, CodeBlockHighlight); _this = _super.call(this, options); try { Object.entries(_this.options.languages).forEach(function (_ref) { var _ref2 = _slicedToArray(_ref, 2), name = _ref2[0], mapping = _ref2[1]; low.registerLanguage(name, mapping); }); } catch (err) { throw new Error('Invalid syntax highlight definitions: define at least one highlight.js language mapping'); } return _this; } _createClass(CodeBlockHighlight, [{ key: "commands", value: function commands(_ref3) { var type = _ref3.type, schema = _ref3.schema; return function () { return tiptapCommands.toggleBlockType(type, schema.nodes.paragraph); }; } }, { key: "keys", value: function keys(_ref4) { var type = _ref4.type; return { 'Shift-Ctrl-\\': tiptapCommands.setBlockType(type) }; } }, { key: "inputRules", value: function inputRules(_ref5) { var type = _ref5.type; return [tiptapCommands.textblockTypeInputRule(/^```$/, type)]; } }, { key: "name", get: function get() { return 'code_block'; } }, { key: "defaultOptions", get: function get() { return { languages: {} }; } }, { key: "schema", get: function get() { return { content: 'text*', marks: '', group: 'block', code: true, defining: true, draggable: false, parseDOM: [{ tag: 'pre', preserveWhitespace: 'full' }], toDOM: function toDOM() { return ['pre', ['code', 0]]; } }; } }, { key: "plugins", get: function get() { return [HighlightPlugin({ name: this.name })]; } }]); return CodeBlockHighlight; }(tiptap.Node); var HardBreak = /*#__PURE__*/function (_Node) { _inherits(HardBreak, _Node); var _super = _createSuper(HardBreak); function HardBreak() { _classCallCheck(this, HardBreak); return _super.apply(this, arguments); } _createClass(HardBreak, [{ key: "keys", value: function keys(_ref) { var type = _ref.type; var command = tiptapCommands.chainCommands(tiptapCommands.exitCode, function (state, dispatch) { dispatch(state.tr.replaceSelectionWith(type.create()).scrollIntoView()); return true; }); return { 'Mod-Enter': command, 'Shift-Enter': command }; } }, { key: "name", get: function get() { return 'hard_break'; } }, { key: "schema", get: function get() { return { inline: true, group: 'inline', selectable: false, parseDOM: [{ tag: 'br' }], toDOM: function toDOM() { return ['br']; } }; } }]); return HardBreak; }(tiptap.Node); var Heading = /*#__PURE__*/function (_Node) { _inherits(Heading, _Node); var _super = _createSuper(Heading); function Heading() { _classCallCheck(this, Heading); return _super.apply(this, arguments); } _createClass(Heading, [{ key: "commands", value: function commands(_ref) { var type = _ref.type, schema = _ref.schema; return function (attrs) { return tiptapCommands.toggleBlockType(type, schema.nodes.paragraph, attrs); }; } }, { key: "keys", value: function keys(_ref2) { var type = _ref2.type; return this.options.levels.reduce(function (items, level) { return _objectSpread2(_objectSpread2({}, items), _defineProperty({}, "Shift-Ctrl-".concat(level), tiptapCommands.setBlockType(type, { level: level }))); }, {}); } }, { key: "inputRules", value: function inputRules(_ref3) { var type = _ref3.type; return this.options.levels.map(function (level) { return tiptapCommands.textblockTypeInputRule(new RegExp("^(#{1,".concat(level, "})\\s$")), type, function () { return { level: level }; }); }); } }, { key: "name", get: function get() { return 'heading'; } }, { key: "defaultOptions", get: function get() { return { levels: [1, 2, 3, 4, 5, 6] }; } }, { key: "schema", get: function get() { return { attrs: { level: { default: 1 } }, content: 'inline*', group: 'block', defining: true, draggable: false, parseDOM: this.options.levels.map(function (level) { return { tag: "h".concat(level), attrs: { level: level } }; }), toDOM: function toDOM(node) { return ["h".concat(node.attrs.level), 0]; } }; } }]); return Heading; }(tiptap.Node); var HorizontalRule = /*#__PURE__*/function (_Node) { _inherits(HorizontalRule, _Node); var _super = _createSuper(HorizontalRule); function HorizontalRule() { _classCallCheck(this, HorizontalRule); return _super.apply(this, arguments); } _createClass(HorizontalRule, [{ key: "commands", value: function commands(_ref) { var type = _ref.type; return function () { return function (state, dispatch) { return dispatch(state.tr.replaceSelectionWith(type.create())); }; }; } }, { key: "inputRules", value: function inputRules(_ref2) { var type = _ref2.type; return [tiptapCommands.nodeInputRule(/^(?:---|___\s|\*\*\*\s)$/, type)]; } }, { key: "name", get: function get() { return 'horizontal_rule'; } }, { key: "schema", get: function get() { return { group: 'block', parseDOM: [{ tag: 'hr' }], toDOM: function toDOM() { return ['hr']; } }; } }]); return HorizontalRule; }(tiptap.Node); /** * Matches following attributes in Markdown-typed image: [, alt, src, title] * * Example: * ![Lorem](image.jpg) -> [, "Lorem", "image.jpg"] * ![](image.jpg "Ipsum") -> [, "", "image.jpg", "Ipsum"] * ![Lorem](image.jpg "Ipsum") -> [, "Lorem", "image.jpg", "Ipsum"] */ var IMAGE_INPUT_REGEX = /!\[(.+|:?)]\((\S+)(?:(?:\s+)["'](\S+)["'])?\)/; var Image = /*#__PURE__*/function (_Node) { _inherits(Image, _Node); var _super = _createSuper(Image); function Image() { _classCallCheck(this, Image); return _super.apply(this, arguments); } _createClass(Image, [{ key: "commands", value: function commands(_ref) { var type = _ref.type; return function (attrs) { return function (state, dispatch) { var selection = state.selection; var position = selection.$cursor ? selection.$cursor.pos : selection.$to.pos; var node = type.create(attrs); var transaction = state.tr.insert(position, node); dispatch(transaction); }; }; } }, { key: "inputRules", value: function inputRules(_ref2) { var type = _ref2.type; return [tiptapCommands.nodeInputRule(IMAGE_INPUT_REGEX, type, function (match) { var _match = _slicedToArray(match, 4), alt = _match[1], src = _match[2], title = _match[3]; return { src: src, alt: alt, title: title }; })]; } }, { key: "name", get: function get() { return 'image'; } }, { key: "schema", get: function get() { return { inline: true, attrs: { src: {}, alt: { default: null }, title: { default: null } }, group: 'inline', draggable: true, parseDOM: [{ tag: 'img[src]', getAttrs: function getAttrs(dom) { return { src: dom.getAttribute('src'), title: dom.getAttribute('title'), alt: dom.getAttribute('alt') }; } }], toDOM: function toDOM(node) { return ['img', node.attrs]; } }; } }, { key: "plugins", get: function get() { return [new tiptap.Plugin({ props: { handleDOMEvents: { drop: function drop(view, event) { var hasFiles = event.dataTransfer && event.dataTransfer.files && event.dataTransfer.files.length; if (!hasFiles) { return; } var images = Array.from(event.dataTransfer.files).filter(function (file) { return /image/i.test(file.type); }); if (images.length === 0) { return; } event.preventDefault(); var schema = view.state.schema; var coordinates = view.posAtCoords({ left: event.clientX, top: event.clientY }); images.forEach(function (image) { var reader = new FileReader(); reader.onload = function (readerEvent) { var node = schema.nodes.image.create({ src: readerEvent.target.result }); var transaction = view.state.tr.insert(coordinates.pos, node); view.dispatch(transaction); }; reader.readAsDataURL(image); }); } } } })]; } }]); return Image; }(tiptap.Node); var ListItem = /*#__PURE__*/function (_Node) { _inherits(ListItem, _Node); var _super = _createSuper(ListItem); function ListItem() { _classCallCheck(this, ListItem); return _super.apply(this, arguments); } _createClass(ListItem, [{ key: "keys", value: function keys(_ref) { var type = _ref.type; return { Enter: tiptapCommands.splitListItem(type), Tab: tiptapCommands.sinkListItem(type), 'Shift-Tab': tiptapCommands.liftListItem(type) }; } }, { key: "name", get: function get() { return 'list_item'; } }, { key: "schema", get: function get() { return { content: 'paragraph block*', defining: true, draggable: false, parseDOM: [{ tag: 'li' }], toDOM: function toDOM() { return ['li', 0]; } }; } }]); return ListItem; }(tiptap.Node); function triggerCharacter(_ref) { var _ref$char = _ref.char, char = _ref$char === void 0 ? '@' : _ref$char, _ref$allowSpaces = _ref.allowSpaces, allowSpaces = _ref$allowSpaces === void 0 ? false : _ref$allowSpaces, _ref$startOfLine = _ref.startOfLine, startOfLine = _ref$startOfLine === void 0 ? false : _ref$startOfLine; return function ($position) { // cancel if top level node if ($position.depth <= 0) { return false; } // Matching expressions used for later var escapedChar = "\\".concat(char); var suffix = new RegExp("\\s".concat(escapedChar, "$")); var prefix = startOfLine ? '^' : ''; var regexp = allowSpaces ? new RegExp("".concat(prefix).concat(escapedChar, ".*?(?=\\s").concat(escapedChar, "|$)"), 'gm') : new RegExp("".concat(prefix, "(?:^)?").concat(escapedChar, "[^\\s").concat(escapedChar, "]*"), 'gm'); // Lookup the boundaries of the current node var textFrom = $position.before(); var textTo = $position.end(); var text = $position.doc.textBetween(textFrom, textTo, '\0', '\0'); var match = regexp.exec(text); var position; while (match !== null) { // JavaScript doesn't have lookbehinds; this hacks a check that first character is " " // or the line beginning var matchPrefix = match.input.slice(Math.max(0, match.index - 1), match.index); if (/^[\s\0]?$/.test(matchPrefix)) { // The absolute position of the match in the document var from = match.index + $position.start(); var to = from + match[0].length; // Edge case handling; if spaces are allowed and we're directly in between // two triggers if (allowSpaces && suffix.test(text.slice(to - 1, to + 1))) { match[0] += ' '; to += 1; } // If the $position is located within the matched substring, return that range if (from < $position.pos && to >= $position.pos) { position = { range: { from: from, to: to }, query: match[0].slice(char.length), text: match[0] }; } } match = regexp.exec(text); } return position; }; } function SuggestionsPlugin(_ref2) { var _ref2$matcher = _ref2.matcher, matcher = _ref2$matcher === void 0 ? { char: '@', allowSpaces: false, startOfLine: false } : _ref2$matcher, _ref2$appendText = _ref2.appendText, appendText = _ref2$appendText === void 0 ? null : _ref2$appendText, _ref2$suggestionClass = _ref2.suggestionClass, suggestionClass = _ref2$suggestionClass === void 0 ? 'suggestion' : _ref2$suggestionClass, _ref2$command = _ref2.command, _command = _ref2$command === void 0 ? function () { return false; } : _ref2$command, _ref2$items = _ref2.items, items = _ref2$items === void 0 ? [] : _ref2$items, _ref2$onEnter = _ref2.onEnter, onEnter = _ref2$onEnter === void 0 ? function () { return false; } : _ref2$onEnter, _ref2$onChange = _ref2.onChange, onChange = _ref2$onChange === void 0 ? function () { return false; } : _ref2$onChange, _ref2$onExit = _ref2.onExit, onExit = _ref2$onExit === void 0 ? function () { return false; } : _ref2$onExit, _ref2$onKeyDown = _ref2.onKeyDown, onKeyDown = _ref2$onKeyDown === void 0 ? function () { return false; } : _ref2$onKeyDown, _ref2$onFilter = _ref2.onFilter, onFilter = _ref2$onFilter === void 0 ? function (searchItems, query) { if (!query) { return searchItems; } return searchItems.filter(function (item) { return JSON.stringify(item).toLowerCase().includes(query.toLowerCase()); }); } : _ref2$onFilter; return new prosemirrorState.Plugin({ key: new prosemirrorState.PluginKey('suggestions'), view: function view() { var _this = this; return { update: function () { var _update = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(view, prevState) { var prev, next, moved, started, stopped, changed, handleStart, handleChange, handleExit, state, decorationNode, virtualNode, props; return regeneratorRuntime.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: prev = _this.key.getState(prevState); next = _this.key.getState(view.state); // See how the state changed moved = prev.active && next.active && prev.range.from !== next.range.from; started = !prev.active && next.active; stopped = prev.active && !next.active; changed = !started && !stopped && prev.query !== next.query; handleStart = started || moved; handleChange = changed && !moved; handleExit = stopped || moved; // Cancel when suggestion isn't active if (!(!handleStart && !handleChange && !handleExit)) { _context.next = 11; break; } return _context.abrupt("return"); case 11: state = handleExit ? prev : next; decorationNode = document.querySelector("[data-decoration-id=\"".concat(state.decorationId, "\"]")); // build a virtual node for popper.js or tippy.js // this can be used for building popups without a DOM node virtualNode = decorationNode ? { getBoundingClientRect: function getBoundingClientRect() { return decorationNode.getBoundingClientRect(); }, clientWidth: decorationNode.clientWidth, clientHeight: decorationNode.clientHeight } : null; _context.t0 = view; _context.t1 = state.range; _context.t2 = state.query; _context.t3 = state.text; _context.t4 = decorationNode; _context.t5 = virtualNode; if (!(handleChange || handleStart)) { _context.next = 36; break; } _context.t7 = onFilter; if (!Array.isArray(items)) { _context.next = 26; break; } _context.t8 = items; _context.next = 29; break; case 26: _context.next = 28; return items(); case 28: _context.t8 = _context.sent; case 29: _context.t9 = _context.t8; _context.t10 = state.query; _context.next = 33; return (0, _context.t7)(_context.t9, _context.t10); case 33: _context.t6 = _context.sent; _context.next = 37; break; case 36: _context.t6 = []; case 37: _context.t11 = _context.t6; _context.t12 = function command(_ref3) { var range = _ref3.range, attrs = _ref3.attrs; _command({ range: range, attrs: attrs, schema: view.state.schema })(view.state, view.dispatch, view); if (appendText) { tiptapCommands.insertText(appendText)(view.state, view.dispatch, view); } }; props = { view: _context.t0, range: _context.t1, query: _context.t2, text: _context.t3, decorationNode: _context.t4, virtualNode: _context.t5, items: _context.t11, command: _context.t12 }; // Trigger the hooks when necessary if (handleExit) { onExit(props); } if (handleChange) { onChange(props); } if (handleStart) { onEnter(props); } case 43: case "end": return _context.stop(); } } }, _callee); })); function update(_x, _x2) { return _update.apply(this, arguments); } return update; }() }; }, state: { // Initialize the plugin's internal state. init: function init() { return { active: false, range: {}, query: null, text: null }; }, // Apply changes to the plugin state from a view transaction. apply: function apply(tr, prev) { var selection = tr.selection; var next = _objectSpread2({}, prev); // We can only be suggesting if there is no selection if (selection.from === selection.to) { // Reset active state if we just left the previous suggestion range if (selection.from < prev.range.from || selection.from > prev.range.to) { next.active = false; } // Try to match against where our cursor currently is var $position = selection.$from; var match = triggerCharacter(matcher)($position); var decorationId = (Math.random() + 1).toString(36).substr(2, 5); // If we found a match, update the current state to show it if (match) { next.active = true; next.decorationId = prev.decorationId ? prev.decorationId : decorationId; next.range = match.range; next.query = match.query; next.text = match.text; } else { next.active = false; } } else { next.active = false; } // Make sure to empty the range if suggestion is inactive if (!next.active) { next.decorationId = null; next.range = {}; next.query = null; next.text = null; } return next; } }, props: { // Call the keydown hook if suggestion is active. handleKeyDown: function handleKeyDown(view, event) { var _this$getState = this.getState(view.state), active = _this$getState.active, range = _this$getState.range; if (!active) return false; return onKeyDown({ view: view, event: event, range: range }); }, // Setup decorator on the currently active suggestion. decorations: function decorations(editorState) { var _this$getState2 = this.getState(editorState), active = _this$getState2.active, range = _this$getState2.range, decorationId = _this$getState2.decorationId; if (!active) return null; return prosemirrorView.DecorationSet.create(editorState.doc, [prosemirrorView.Decoration.inline(range.from, range.to, { nodeName: 'span', class: suggestionClass, 'data-decoration-id': decorationId })]); } } }); } var Mention = /*#__PURE__*/function (_Node) { _inherits(Mention, _Node); var _super = _createSuper(Mention); function Mention() { _classCallCheck(this, Mention); return _super.apply(this, arguments); } _createClass(Mention, [{ key: "commands", value: function commands(_ref) { var _this = this; var schema = _ref.schema; return function (attrs) { return tiptapCommands.replaceText(null, schema.nodes[_this.name], attrs); }; } }, { key: "name", get: function get() { return 'mention'; } }, { key: "defaultOptions", get: function get() { return { matcher: { char: '@', allowSpaces: false, startOfLine: false }, mentionClass: 'mention', suggestionClass: 'mention-suggestion' }; } }, { key: "schema", get: function get() { var _this2 = this; return { attrs: { id: {}, label: {} }, group: 'inline', inline: true, selectable: false, atom: true, toDOM: function toDOM(node) { return ['span', { class: _this2.options.mentionClass, 'data-mention-id': node.attrs.id }, "".concat(_this2.options.matcher.char).concat(node.attrs.label)]; }, parseDOM: [{ tag: 'span[data-mention-id]', getAttrs: function getAttrs(dom) { var id = dom.getAttribute('data-mention-id'); var label = dom.innerText.split(_this2.options.matcher.char).join(''); return { id: id, label: label }; } }] }; } }, { key: "plugins", get: function get() { var _this3 = this; return [SuggestionsPlugin({ command: function command(_ref2) { var range = _ref2.range, attrs = _ref2.attrs, schema = _ref2.schema; return tiptapCommands.replaceText(range, schema.nodes[_this3.name], attrs); }, appendText: ' ', matcher: this.options.matcher, items: this.options.items, onEnter: this.options.onEnter, onChange: this.options.onChange, onExit: this.options.onExit, onKeyDown: this.options.onKeyDown, onFilter: this.options.onFilter, suggestionClass: this.options.suggestionClass })]; } }]); return Mention; }(tiptap.Node); var OrderedList = /*#__PURE__*/function (_Node) { _inherits(OrderedList, _Node); var _super = _createSuper(OrderedList); function OrderedList() { _classCallCheck(this, OrderedList); return _super.apply(this, arguments); } _createClass(OrderedList, [{ key: "commands", value: function commands(_ref) { var type = _ref.type, schema = _ref.schema; return function () { return tiptapCommands.toggleList(type, schema.nodes.list_item); }; } }, { key: "keys", value: function keys(_ref2) { var type = _ref2.type, schema = _ref2.schema; return { 'Shift-Ctrl-9': tiptapCommands.toggleList(type, schema.nodes.list_item) }; } }, { key: "inputRules", value: function inputRules(_ref3) { var type = _ref3.type; return [tiptapCommands.wrappingInputRule(/^(\d+)\.\s$/, type, function (match) { return { order: +match[1] }; }, function (match, node) { return node.childCount + node.attrs.order === +match[1]; })]; } }, { key: "name", get: function get() { return 'ordered_list'; } }, { key: "schema", get: function get() { return { attrs: { order: { default: 1 } }, content: 'list_item+', group: 'block', parseDOM: [{ tag: 'ol', getAttrs: function getAttrs(dom) { return { order: dom.hasAttribute('start') ? +dom.getAttribute('start') : 1 }; } }], toDOM: function toDOM(node) { return node.attrs.order === 1 ? ['ol', 0] : ['ol', { start: node.attrs.order }, 0]; } }; } }]); return OrderedList; }(tiptap.Node); var TableNodes = prosemirrorTables.tableNodes({ tableGroup: 'block', cellContent: 'block+', cellAttributes: { background: { default: null, getFromDOM: function getFromDOM(dom) { return dom.style.backgroundColor || null; }, setDOMAttr: function setDOMAttr(value, attrs) { if (value) { var style = { style: "".concat(attrs.style || '', "background-color: ").concat(value, ";") }; Object.assign(attrs, style); } } } } }); var Table = /*#__PURE__*/function (_Node) { _inherits(Table, _Node); var _super = _createSuper(Table); function Table() { _classCallCheck(this, Table); return _super.apply(this, arguments); } _createClass(Table, [{ key: "commands", value: function commands(_ref) { var schema = _ref.schema; return { createTable: function createTable(_ref2) { var rowsCount = _ref2.rowsCount, colsCount = _ref2.colsCount, withHeaderRow = _ref2.withHeaderRow; return function (state, dispatch) { var offset = state.tr.selection.anchor + 1; var nodes = prosemirrorUtils.createTable(schema, rowsCount, colsCount, withHeaderRow); var tr = state.tr.replaceSelectionWith(nodes).scrollIntoView(); var resolvedPos = tr.doc.resolve(offset); tr.setSelection(prosemirrorState.TextSelection.near(resolvedPos)); dispatch(tr); }; }, addColumnBefore: function addColumnBefore() { return prosemirrorTables.addColumnBefore; }, addColumnAfter: function addColumnAfter() { return prosemirrorTables.addColumnAfter; }, deleteColumn: function deleteColumn() { return prosemirrorTables.deleteColumn; }, addRowBefore: function addRowBefore() { return prosemirrorTables.addRowBefore; }, addRowAfter: function addRowAfter() { return prosemirrorTables.addRowAfter; }, deleteRow: function deleteRow() { return prosemirrorTables.deleteRow; }, deleteTable: function deleteTable() { return prosemirrorTables.deleteTable; }, toggleCellMerge: function toggleCellMerge() { return function (state, dispatch) { if (prosemirrorTables.mergeCells(state, dispatch)) { return; } prosemirrorTables.splitCell(state, dispatch); }; }, mergeCells: function mergeCells() { return prosemirrorTables.mergeCells; }, splitCell: function splitCell() { return prosemirrorTables.splitCell; }, toggleHeaderColumn: function toggleHeaderColumn() { return prosemirrorTables.toggleHeaderColumn; }, toggleHeaderRow: function toggleHeaderRow() { return prosemirrorTables.toggleHeaderRow; }, toggleHeaderCell: function toggleHeaderCell() { return prosemirrorTables.toggleHeaderCell; }, setCellAttr: function setCellAttr() { return prosemirrorTables.setCellAttr; }, fixTables: function fixTables() { return prosemirrorTables.fixTables; } }; } }, { key: "keys", value: function keys() { return { Tab: prosemirrorTables.goToNextCell(1), 'Shift-Tab': prosemirrorTables.goToNextCell(-1) }; } }, { key: "name", get: function get() { return 'table'; } }, { key: "defaultOptions", get: function get() { return { resizable: false }; } }, { key: "schema", get: function get() { return TableNodes.table; } }, { key: "plugins", get: function get() { return [].concat(_toConsumableArray(this.options.resizable ? [prosemirrorTables.columnResizing()] : []), [prosemirrorTables.tableEditing()]); } }]); return Table; }(tiptap.Node); var TableHeader = /*#__PURE__*/function (_Node) { _inherits(TableHeader, _Node); var _super = _createSuper(TableHeader); function TableHeader() { _classCallCheck(this, TableHeader); return _super.apply(this, arguments); } _createClass(TableHeader, [{ key: "name", get: function get() { return 'table_header'; } }, { key: "schema", get: function get() { ret